Flatten symtab to file - gdb works, check breaks.
authornorly <ny-git@enpas.org>
Sat, 15 Jun 2013 12:27:42 +0000 (13:27 +0100)
committernorly <ny-git@enpas.org>
Sat, 15 Jun 2013 12:32:17 +0000 (13:32 +0100)
Makefile
include/libelfu/types.h
src/modelops/fromFile.c
src/modelops/relocate.c
src/modelops/toFile.c

index fc7c567fe1940daaec46a038d9702dc37b5c812b..641817907db2fd85c684f8b4b4991d0120f9eac3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@ default: $(EXE)
 
 .PHONY: check
 check: $(EXE)
+       $(error the re-layouting has broken make check for now, sorry.)
        $(EXE) $(EXE) -o testexe
        @cmp $(EXE) testexe
        @rm testexe
index 46fbc6924092ba9c5c15830bdbda33f5870853b7..37e25fa6c574553e290451c47a33bfc5be11e6c6 100644 (file)
@@ -8,7 +8,8 @@
 
 
 typedef struct ElfuSym {
-  char *name;
+  GElf_Word name;
+  char *nameptr;
 
   GElf_Addr value;
   GElf_Word size;
@@ -92,6 +93,8 @@ typedef struct {
   CIRCLEQ_HEAD(OrphanScnList, ElfuScn) orphanScnList;
 
   ElfuScn *shstrtab;
+
+  ElfuScn *symtab;
 } ElfuElf;
 
 #endif
index 85afe20165f1283092a139706acc84a77e578c93..c46dd6c38dd727af0aaeec5aa0c569e65c010a65 100644 (file)
@@ -30,7 +30,8 @@ static void parseSymtab32(ElfuScn *ms, ElfuScn**origScnArr)
     ElfuSym *sym = malloc(sizeof(*sym));
     assert(sym);
 
-    sym->name = symstr(ms, cursym->st_name);
+    sym->name = cursym->st_name;
+    sym->nameptr = symstr(ms, cursym->st_name);
     sym->value = cursym->st_value;
     sym->size = cursym->st_size;
     sym->bind = ELF32_ST_BIND(cursym->st_info);
@@ -256,6 +257,7 @@ ElfuElf* elfu_mFromElf(Elf *e)
   CIRCLEQ_INIT(&me->phdrList);
   CIRCLEQ_INIT(&me->orphanScnList);
   me->shstrtab = NULL;
+  me->symtab = NULL;
 
   me->elfclass = gelf_getclass(e);
   assert(me->elfclass != ELFCLASSNONE);
@@ -368,6 +370,7 @@ ElfuElf* elfu_mFromElf(Elf *e)
 
       switch (ms->shdr.sh_type) {
         case SHT_SYMTAB:
+          me->symtab = ms;
         case SHT_DYNSYM:
           if (me->elfclass == ELFCLASS32) {
             parseSymtab32(ms, secArray);
index 679f57f2d44fdafd7949bba8c0d018d06273f9c3..0bd8ee80fe1609fea2a06fd879dfc8401085e77f 100644 (file)
@@ -58,11 +58,11 @@ static GElf_Word pltLookupVal(ElfuElf *metarget, char *name)
       sym = CIRCLEQ_NEXT(sym, elem);
     }
 
-    if (!sym->name) {
+    if (!sym->nameptr) {
       continue;
     }
 
-    if (!strcmp(sym->name, name)) {
+    if (!strcmp(sym->nameptr, name)) {
       /* If this is the symbol we are looking for, then in an x86 binary
        * the jump to the dynamic symbol is probably at offset (j * 16)
        * from the start of the PLT, where j is the PLT entry and 16 is
@@ -105,7 +105,7 @@ static GElf_Word symtabLookupVal(ElfuElf *metarget, ElfuScn *msst, GElf_Word ent
         /* Look the symbol up in .dyn.plt. If it cannot be found there then
          * .rel.dyn may need to be expanded with a COPY relocation so the
          * dynamic linker fixes up the (TODO). */
-        return pltLookupVal(metarget, sym->name);
+        return pltLookupVal(metarget, sym->nameptr);
       } else if (sym->shndx == SHN_ABS) {
         return sym->value;
       } else {
@@ -121,7 +121,7 @@ static GElf_Word symtabLookupVal(ElfuElf *metarget, ElfuScn *msst, GElf_Word ent
       ELFU_WARN("symtabLookupVal: Symbol type FILE is not supported, using 0.\n");
       return 0;
     default:
-      ELFU_WARN("symtabLookupVal: Unknown symbol type %d for %s.\n", sym->type, sym->name);
+      ELFU_WARN("symtabLookupVal: Unknown symbol type %d for %s.\n", sym->type, sym->nameptr);
       return 0;
   }
 }
index da06f4a07af8c2608c2ef637ddf3f7e5ef5c5414..66109dfb8a2dfefeaad3e5084ee91d3cc7782cce 100644 (file)
@@ -1,7 +1,62 @@
+#include <assert.h>
 #include <stdlib.h>
+#include <string.h>
 #include <libelfu/libelfu.h>
 
 
+static void flattenSymtab(ElfuElf *me)
+{
+  ElfuSym *sym;
+  size_t numsyms = 0;
+
+  elfu_mLayoutAuto(me);
+
+  CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
+    if (sym->scnptr) {
+      sym->shndx = elfu_mScnIndex(me, sym->scnptr);
+    }
+
+    numsyms++;
+  }
+
+  if (me->elfclass == ELFCLASS32) {
+    size_t newsize = (numsyms + 1) * sizeof(Elf32_Sym);
+    size_t i;
+
+    if (me->symtab->data.d_buf) {
+      free(me->symtab->data.d_buf);
+    }
+    me->symtab->data.d_buf = malloc(newsize);
+    assert(me->symtab->data.d_buf);
+
+    me->symtab->data.d_size = newsize;
+    me->symtab->shdr.sh_size = newsize;
+    memset(me->symtab->data.d_buf, 0, newsize);
+
+    i = 1;
+    CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
+      Elf32_Sym *es = ((Elf32_Sym*)me->symtab->data.d_buf) + i;
+
+      es->st_name = sym->name;
+      es->st_value = sym->value;
+      es->st_size = sym->size;
+      es->st_info = ELF32_ST_INFO(sym->bind, sym->type);
+      es->st_other = sym->other;
+      es->st_shndx = sym->shndx;
+
+      i++;
+    }
+  } else if (me->elfclass == ELFCLASS64) {
+    // TODO
+    assert(0);
+  } else {
+    // Never reached
+    assert(0);
+  }
+
+  elfu_mLayoutAuto(me);
+}
+
 
 static void modelToPhdrs(ElfuElf *me, Elf *e)
 {
@@ -81,6 +136,11 @@ static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
 
 void elfu_mToElf(ElfuElf *me, Elf *e)
 {
+  if (me->symtab) {
+    flattenSymtab(me);
+  }
+
+
   /* We control the ELF file's layout now. */
   /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections,
    * but we don't want that since we filtered it out in the reading stage