Added a.out format for NED binaries to track symbols through to the disassembler.
[ned1] / nedsim / nedsim.c
index 9bdaa59..9d5a045 100644 (file)
@@ -16,7 +16,9 @@
 #include <termios.h>
 #include <signal.h>
 
 #include <termios.h>
 #include <signal.h>
 
-#define VERSION 1
+#include "../common/a.out.h"
+
+#define VERSION 2
 
 /* Bytes per word. */
 #define BPW 4
 
 /* Bytes per word. */
 #define BPW 4
@@ -541,6 +543,53 @@ wait_for_next_clock_cycle(struct NEDstate * state)
     }
 }
 
     }
 }
 
+void
+parse_aout_file(FILE * input, struct exec * aout_exec, uint8_t * text_segment)
+{
+    uint32_t read_count = 0;
+
+    /* Read in and check the a.out header. */
+    for (uint32_t i=0; i<8; i++) {
+        switch (i) {
+            case 0: read_count = fread(&(aout_exec->a_midmag), 4, 1, input); break;
+            case 1: read_count = fread(&(aout_exec->a_text),   4, 1, input); break;
+            case 2: read_count = fread(&(aout_exec->a_data),   4, 1, input); break;
+            case 3: read_count = fread(&(aout_exec->a_bss),    4, 1, input); break;
+            case 4: read_count = fread(&(aout_exec->a_syms),   4, 1, input); break;
+            case 5: read_count = fread(&(aout_exec->a_entry),  4, 1, input); break;
+            case 6: read_count = fread(&(aout_exec->a_trsize), 4, 1, input); break;
+            case 7: read_count = fread(&(aout_exec->a_drsize), 4, 1, input); break;
+        }
+        if (read_count != 1) {
+            fprintf(stderr, "ERROR: Invalid a.out header.\n");
+            exit(EXIT_FAILURE);
+        }
+    }
+    if (N_BADMAG(*aout_exec)) {
+        fprintf(stderr, "ERROR: Invalid magic number in a.out header.\n");
+        exit(EXIT_FAILURE);
+    } else if (N_GETMID(*aout_exec) != MID_NED) {
+        fprintf(stderr, "ERROR: Executable not intended for NED Machine ID.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    /* Read in the text segment. */
+    uint32_t text_segment_size = (N_DATOFF(*aout_exec) - N_TXTOFF(*aout_exec));
+    read_count = fread(text_segment, 1, text_segment_size, input);
+    if (read_count != text_segment_size) {
+        fprintf(stderr, "ERROR: Failed to read entire text segment.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    /* Correct the byte order. */
+    for (uint32_t i=0; i < (text_segment_size / 4); i++) {
+        uint8_t temp_word[4];
+        for (uint8_t j=0; j<4; j++) temp_word[j] = text_segment[((i*4)+j)];
+        for (uint8_t j=0; j<4; j++) text_segment[((i*4)+j)] = temp_word[(3-j)];
+    }
+}
+
+
 int
 main(int argc, char ** argv)
 {
 int
 main(int argc, char ** argv)
 {
@@ -555,6 +604,7 @@ main(int argc, char ** argv)
             case 'i':
                 if ((input = fopen(optarg, "r")) == NULL) {
                     fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
             case 'i':
                 if ((input = fopen(optarg, "r")) == NULL) {
                     fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
+                    exit(EXIT_FAILURE);
                 }
                 break;
             case 'p':
                 }
                 break;
             case 'p':
@@ -563,7 +613,7 @@ main(int argc, char ** argv)
                     if (1 <= temp_p && temp_p <= 1000000000) {
                         clock_period = temp_p;
                     } else {
                     if (1 <= temp_p && temp_p <= 1000000000) {
                         clock_period = temp_p;
                     } else {
-                        fprintf(stderr, "ERROR: Clock period out of range.\n");
+                        fprintf(stderr, "WARN: Clock period out of range.\n");
                     }
                     break;
                 }
                     }
                     break;
                 }
@@ -603,12 +653,9 @@ main(int argc, char ** argv)
     signal(SIGINT, ned_sigint_handler);
 
     /* Load an initial image into memory. */
     signal(SIGINT, ned_sigint_handler);
 
     /* Load an initial image into memory. */
-    uint32_t temp_word;
     uint32_t address = 0x20000000;
     uint32_t address = 0x20000000;
-    while(fread(&temp_word, 4, 1, input)) {
-        ram_w_word(state, address, temp_word);
-        address += 4;
-    }
+    struct exec aout_exec;
+    parse_aout_file(input, &aout_exec, &(state->ram[address]));
     fclose(input);
 
     /*
     fclose(input);
 
     /*