r5e.c (2442B)
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <string.h> 5 6 #include "risc5emu.h" 7 8 int main(int argc, char** argv) { 9 bool trace = false; 10 bool no_cycle_limit = false; 11 const char* fn = NULL; 12 int args = 0; 13 14 while (argc > 1) { 15 if (!strcmp(argv[1], "--")) { 16 args = argc - 2; 17 argv += 2; 18 break; 19 } else if (!strcmp(argv[1], "-n")) { 20 no_cycle_limit = true; 21 } else if (!strcmp(argv[1], "-t")) { 22 trace = true; 23 } else if (argv[1][0] == '-') { 24 fprintf(stderr, "r5e: unknown option: %s\n", argv[1]); 25 return -1; 26 } else { 27 if (fn != NULL) { 28 fprintf(stderr, "r5e: multiple images not supported\n"); 29 return -1; 30 } 31 fn = argv[1]; 32 } 33 argc--; 34 argv++; 35 } 36 37 if (fn == NULL) { 38 fprintf(stderr, 39 "usage: r5e <options>* <binary> [ -- <arg>* ]\n" 40 "\n" 41 "options: -n no cycle limit (run forever)\n" 42 " -t trace execution\n" 43 "\n" 44 "args: passed on to emulated program\n" 45 ); 46 return -1; 47 } 48 49 risc_t *r = risc_new(false); 50 51 // load image 52 int fd = open(fn, O_RDONLY); 53 if (fd < 0) { 54 fprintf(stderr, "r5e: cannot open: %s\n", fn); 55 return -1; 56 } 57 unsigned n = 0; 58 uint32_t w; 59 while (read(fd, &w, sizeof(w)) == 4) { 60 risc_store_word(r, n, w); 61 n += 4; 62 } 63 64 // setup entry environment 65 uint32_t sp = 0x100000; 66 67 // exit shim 68 sp -= 16; 69 uint32_t lr = sp; 70 risc_store_word(r, lr+0, 0x51000000); // mov r1, 0xffff0000 71 risc_store_word(r, lr+4, 0xa0100100); // stw r0, [r1, 256] 72 risc_store_word(r, lr+8, 0xe7ffffff); // b . 73 // point LR at shim 74 risc_set_register(r, 15, lr); 75 76 // r0/r1 is an [][]byte of commandline args 77 uint32_t r0 = 0; 78 uint32_t r1 = 0; 79 if (args) { 80 sp -= args * 8; 81 uint32_t p = sp; 82 r0 = p; 83 r1 = args; 84 while (args > 0) { 85 fprintf(stderr, "E %s\n", argv[0]); 86 uint32_t n = strlen(argv[0]); 87 sp -= (n + 3) & (~3); 88 for (uint32_t i = 0; i < n; i++) { 89 risc_store_byte(r, sp + i, argv[0][i]); 90 } 91 risc_store_word(r, p+0, sp); 92 risc_store_word(r, p+4, n); 93 p += 8; 94 args--; 95 argv++; 96 } 97 } 98 risc_set_register(r, 0, r0); 99 risc_set_register(r, 1, r1); 100 101 // set SP 102 risc_set_register(r, 14, sp); 103 104 if (trace) { 105 risc_trace(r, true); 106 printf(" SP = %08x\n", sp); 107 printf(" LR = %08x (exit shim)\n", lr); 108 printf(" R0 = %08x **argv\n", r0); 109 printf(" R1 = %08x argc\n", r1); 110 } 111 112 do { 113 risc_run(r, 100000000); 114 } while (no_cycle_limit); 115 116 return 0; 117 }