Commit ccb3592f51c9333b9332c59102c11eae61c973c0
authorMichel Pollet <buserror@gmail.com>
Mon, 12 Aug 2013 10:31:57 +0000 (11:31 +0100)
committerMichel Pollet <buserror@gmail.com>
Thu, 5 Sep 2013 12:58:31 +0000 (13:58 +0100)
Old symbol loader had been geared for the 'trace' functionality, and was
partitularly bad since it didnt know the size of the code it was
loading.

New version loads a (sorted) array of symbols, and let the firmware
loader code deal with the old 'codeline' array. The new loaded symbol
table can be used separately (board code can look into it).

Also changed the avr_symbol_t to inline the symbol name, instead of
using a separate pointer.

Signed-off-by: Michel Pollet <buserror@gmail.com>
3 files changed:
simavr/sim/sim_avr.h
simavr/sim/sim_elf.c
simavr/sim/sim_elf.h

index f391902e31910d366738dc3a5ca6b2997f2d556d..dde8873527f6904dcb5f88d8c860ab48f9985d04 100644 (file)
@@ -298,8 +298,8 @@ typedef struct avr_kind_t {
 
 // a symbol loaded from the .elf file
 typedef struct avr_symbol_t {
-       const char * symbol;
        uint32_t        addr;
+       const char  symbol[0];
 } avr_symbol_t;
 
 // locate the maker for mcu "name" and allocates a new avr instance
index af4ab2dad0887c282ab361a7a6866910e7502edb..37cd653462096462b622dd28e7543a8e04ed6126 100644 (file)
@@ -50,8 +50,23 @@ void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware)
                avr->avcc = firmware->avcc;
        if (firmware->aref)
                avr->aref = firmware->aref;
-#if CONFIG_SIMAVR_TRACE
-       avr->trace_data->codeline = firmware->codeline;
+#if CONFIG_SIMAVR_TRACE && ELF_SYMBOLS
+       int scount = firmware->flashsize >> 1;
+       avr->trace_data->codeline = malloc(scount * sizeof(avr_symbol_t*));
+       memset(avr->trace_data->codeline, 0, scount * sizeof(avr_symbol_t*));
+
+       for (int i = 0; i < firmware->symbolcount; i++)
+               if (!(firmware->symbol[i]->addr >> 20)) // code address
+                       avr->trace_data->codeline[firmware->symbol[i]->addr >> 1] = 
+                               firmware->symbol[i];
+       // "spread" the pointers for known symbols forward
+       avr_symbol_t * last = NULL;
+       for (int i = 0; i < scount; i++) {
+               if (!avr->trace_data->codeline[i])
+                       avr->trace_data->codeline[i] = last;
+               else
+                       last = avr->trace_data->codeline[i];
+       }
 #endif
 
        avr_loadcode(avr, firmware->flash, firmware->flashsize, firmware->flashbase);
@@ -199,11 +214,8 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware)
 
        memset(firmware, 0, sizeof(*firmware));
 #if ELF_SYMBOLS
-       //int bitesize = ((avr->flashend+1) >> 1) * sizeof(avr_symbol_t);
-       firmware->codesize = 32768;
-       int bitesize = firmware->codesize * sizeof(avr_symbol_t);
-       firmware->codeline = malloc(bitesize);
-       memset(firmware->codeline,0, bitesize);
+       firmware->symbolcount = 0;
+       firmware->symbol = NULL;
 #endif
 
        /* this is actually mandatory !! otherwise elf_begin() fails */
@@ -254,37 +266,37 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware)
                                gelf_getsym(edata, i, &sym);
 
                                // print out the value and size
-                       //      printf("%08x %08d ", sym.st_value, sym.st_size);
                                if (ELF32_ST_BIND(sym.st_info) == STB_GLOBAL || 
                                                ELF32_ST_TYPE(sym.st_info) == STT_FUNC || 
                                                ELF32_ST_TYPE(sym.st_info) == STT_OBJECT) {
                                        const char * name = elf_strptr(elf, shdr.sh_link, sym.st_name);
 
-                                       // type of symbol
-                                       if (sym.st_value & 0xfff00000) {
-
-                                       } else {
-                                               // code
-                                               if (firmware->codeline[sym.st_value >> 1] == NULL) {
-                                                       avr_symbol_t * s = firmware->codeline[sym.st_value >> 1] = malloc(sizeof(avr_symbol_t));
-                                                       s->symbol = strdup(name);
-                                                       s->addr = sym.st_value;
-                                               }
-                                       }
+                                       avr_symbol_t * s = malloc(sizeof(avr_symbol_t) + strlen(name) + 1);
+                                       strcpy((char*)s->symbol, name);
+                                       s->addr = sym.st_value;
+                                       if (!(firmware->symbolcount % 8))
+                                               firmware->symbol = realloc(
+                                                       firmware->symbol, 
+                                                       (firmware->symbolcount + 8) * sizeof(firmware->symbol[0]));
+                                       
+                                       // insert new element, keep the array sorted
+                                       int insert = -1;
+                                       for (int si = 0; si < firmware->symbolcount && insert == -1; si++)
+                                               if (firmware->symbol[si]->addr >= s->addr)
+                                                       insert = si;
+                                       if (insert == -1)
+                                               insert = firmware->symbolcount;
+                                       else
+                                               memmove(firmware->symbol + insert + 1, 
+                                                               firmware->symbol + insert,
+                                                               (firmware->symbolcount - insert) * sizeof(firmware->symbol[0]));
+                                       firmware->symbol[insert] = s;                                   
+                                       firmware->symbolcount++;
                                }
                        }
                }
 #endif
        }
-#if ELF_SYMBOLS
-       avr_symbol_t * last = NULL;
-       for (int i = 0; i < firmware->codesize; i++) {
-               if (!firmware->codeline[i])
-                       firmware->codeline[i] = last;
-               else
-                       last = firmware->codeline[i];
-       }
-#endif
        uint32_t offset = 0;
        firmware->flashsize =
                        (data_text ? data_text->d_size : 0) +
index ed760d53ed28065560b6172d53e2482499c6c886..d91b0e5d93669928215e13a6dd7a752c4574fbcd 100644 (file)
@@ -68,8 +68,8 @@ typedef struct elf_firmware_t {
        uint32_t        eesize;
 
 #if ELF_SYMBOLS
-       avr_symbol_t **  codeline;
-       uint32_t                codesize;       // in elements
+       avr_symbol_t **  symbol;
+       uint32_t                symbolcount;
 #endif
 } elf_firmware_t ;