Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow loading more than one ELF binary #274

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,9 @@ static struct option options[] = {

static void print_usage(const char *argv0, int ec)
{
fprintf(stdout, "Usage: %s [options] <elf_file> [<elf_file> ...]\n", argv0);
#ifdef RVFI_DII
fprintf(stdout,
"Usage: %s [options] <elf_file>\n %s [options] -r <port>\n",
argv0, argv0);
#else
fprintf(stdout, "Usage: %s [options] <elf_file>\n", argv0);
fprintf(stdout, " %s [options] -r <port>\n", argv0);
#endif
struct option *opt = options;
while (opt->name) {
Expand Down Expand Up @@ -217,7 +214,14 @@ static void read_dtb(const char *path)
fprintf(stdout, "Read %zd bytes of DTB from %s.\n", dtb_len, path);
}

char *process_args(int argc, char **argv)
/**
* Parses the command line arguments and returns the argv index for the first
* ELF file that should be loaded. As getopt transforms the argv array, all
* argv values following that index are non-options and can be treated as
* additional ELF files that should be loaded into memory (but not scanned
* for the magic tohost/{begin,end}_signature symbols).
*/
static int process_args(int argc, char **argv)
{
int c;
uint64_t ram_size = 0;
Expand Down Expand Up @@ -375,7 +379,7 @@ char *process_args(int argc, char **argv)
if (!rvfi_dii)
#endif
fprintf(stdout, "Running file %s.\n", argv[optind]);
return argv[optind];
return optind;
}

void check_elf(bool is32bit)
Expand All @@ -394,13 +398,17 @@ void check_elf(bool is32bit)
}
}
}
uint64_t load_sail(char *f)
uint64_t load_sail(char *f, bool main_file)
{
bool is32bit;
uint64_t entry;
uint64_t begin_sig, end_sig;
load_elf(f, &is32bit, &entry);
check_elf(is32bit);
if (!main_file) {
/* Don't scan for test-signature/htif symbols for additional ELF files. */
return entry;
}
fprintf(stdout, "ELF Entry @ 0x%" PRIx64 "\n", entry);
/* locate htif ports */
if (lookup_sym(f, "tohost", &rv_htif_tohost) < 0) {
Expand Down Expand Up @@ -1022,7 +1030,8 @@ int main(int argc, char **argv)
// Initialize model so that we can check or report its architecture.
preinit_sail();

char *file = process_args(argc, argv);
int files_start = process_args(argc, argv);
char *initial_elf_file = argv[files_start];
init_logs();

if (gettimeofday(&init_start, NULL) < 0) {
Expand Down Expand Up @@ -1088,15 +1097,20 @@ int main(int argc, char **argv)
}
printf("Connected\n");
} else
entry = load_sail(file);
entry = load_sail(initial_elf_file, /*main_file=*/true);
#else
uint64_t entry = load_sail(file);
uint64_t entry = load_sail(initial_elf_file, /*main_file=*/true);
#endif
/* Load any additional ELF files into memory */
for (int i = files_start + 1; i < argc; i++) {
fprintf(stdout, "Loading additional ELF file %s.\n", argv[i]);
arichardson marked this conversation as resolved.
Show resolved Hide resolved
(void)load_sail(argv[i], /*main_file=*/false);
}

/* initialize spike before sail so that we can access the device-tree blob,
* until we roll our own.
*/
init_spike(file, entry, rv_ram_size);
init_spike(initial_elf_file, entry, rv_ram_size);
init_sail(entry);

if (!init_check(s))
Expand Down
Loading