Clean up code using ElfuScn
authornorly <ny-git@enpas.org>
Thu, 20 Jun 2013 18:02:44 +0000 (19:02 +0100)
committernorly <ny-git@enpas.org>
Thu, 20 Jun 2013 21:10:25 +0000 (22:10 +0100)
16 files changed:
Makefile
include/libelfu/modelops.h
include/libelfu/types.h
src/libelfu/model/phdr.c [new file with mode: 0644]
src/libelfu/model/section.c [new file with mode: 0644]
src/libelfu/model/symtab.c [new file with mode: 0644]
src/libelfu/modelops/clone.c
src/libelfu/modelops/detour.c
src/libelfu/modelops/fromFile.c
src/libelfu/modelops/layout.c
src/libelfu/modelops/phdr.c [deleted file]
src/libelfu/modelops/reladd.c
src/libelfu/modelops/relocate.c
src/libelfu/modelops/section.c [deleted file]
src/libelfu/modelops/symtab.c [deleted file]
src/libelfu/modelops/toFile.c

index e063a29cdbd1abfd19308c66d034a52654e9a132..8cef4c90107aa18f0630619874dac4d78dbe5f51 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ LIBOBJS := $(patsubst %.c, $(BUILDDIR)/%.o, $(LIBSRCS))
 EXEOBJS := $(patsubst %.c, $(BUILDDIR)/%.o, $(EXESRCS))
 
 INCLUDES := $(patsubst %, -I%, $(INCLUDEDIR) $(SRCDIR)) $(shell pkg-config --cflags-only-I $(LIBRARIES))
-CFLAGS   := -g -Wall -pedantic -Wno-variadic-macros -fPIC $(shell pkg-config --cflags-only-other $(LIBRARIES))
+CFLAGS   := -g -Wall -std=gnu99 -pedantic -fPIC $(shell pkg-config --cflags-only-other $(LIBRARIES))
 LDFLAGS  := $(shell pkg-config --libs $(LIBRARIES))
 
 
index fec6821add902d67204b49f176eacdf29e78bd85..4dacd43235fd88f80eb5d2d2dfb73062d579a962 100644 (file)
@@ -7,7 +7,7 @@
 #include <libelfu/types.h>
 
 
-#define ELFU_SYMSTR(symtabscn, off) (((char*)(symtabscn)->linkptr->data.d_buf) + (off))
+#define ELFU_SYMSTR(symtabscn, off) ((symtabscn)->linkptr->databuf + (off))
 
 
 GElf_Word elfu_mSymtabLookupVal(ElfuElf *me, ElfuScn *msst, GElf_Word entry);
@@ -29,6 +29,7 @@ typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *a
  ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn);
     char* elfu_mScnName(ElfuElf *me, ElfuScn *ms);
 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count);
+ElfuScn* elfu_mScnAlloc();
 
 
 GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
index e4dd26cc2e99cc1e9c2d0e4884ddd5eca40e87cc..ab9f76ceee987ede5acd898a3446c3c8bc3bf177 100644 (file)
@@ -58,10 +58,9 @@ typedef struct ElfuReltab {
 typedef struct ElfuScn {
   GElf_Shdr shdr;
 
-  Elf_Data data;
-
   struct ElfuScn *linkptr;
   struct ElfuScn *infoptr;
+  char *databuf;
 
   struct ElfuScn *oldptr;
 
diff --git a/src/libelfu/model/phdr.c b/src/libelfu/model/phdr.c
new file mode 100644 (file)
index 0000000..d26eb77
--- /dev/null
@@ -0,0 +1,36 @@
+#include <assert.h>
+#include <libelfu/libelfu.h>
+
+
+size_t elfu_mPhdrCount(ElfuElf *me)
+{
+  ElfuPhdr *mp;
+  size_t i = 0;
+
+  assert(me);
+
+  CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
+    i++;
+  }
+
+  return i;
+}
+
+
+
+void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp)
+{
+  ElfuScn *ms;
+  ElfuPhdr *mpc;
+
+  assert(mp);
+  assert(mp->phdr.p_type == PT_LOAD);
+
+  CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) {
+    mpc->phdr.p_offset = mp->phdr.p_offset + (mpc->phdr.p_vaddr - mp->phdr.p_vaddr);
+  }
+
+  CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
+    ms->shdr.sh_offset = mp->phdr.p_offset + (ms->shdr.sh_addr - mp->phdr.p_vaddr);
+  }
+}
diff --git a/src/libelfu/model/section.c b/src/libelfu/model/section.c
new file mode 100644 (file)
index 0000000..c93c5c8
--- /dev/null
@@ -0,0 +1,221 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libelfu/libelfu.h>
+
+
+/* Meta-functions */
+
+void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2)
+{
+  ElfuPhdr *mp;
+  ElfuScn *ms;
+
+  // TODO: Sort PHDRs by offset before interating
+
+  CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
+    if (mp->phdr.p_type != PT_LOAD) {
+      continue;
+    }
+
+    CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
+      void *rv = f(me, ms, aux1, aux2);
+
+      if (rv) {
+        return rv;
+      }
+    }
+  }
+
+  CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
+    void *rv = f(me, ms, aux1, aux2);
+
+    if (rv) {
+      return rv;
+    }
+  }
+
+  return NULL;
+}
+
+
+
+
+/* Counting */
+
+static void* subCounter(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
+{
+  size_t *i = (size_t*)aux1;
+  ElfuScn *otherScn = (ElfuScn*)aux2;
+
+  if (ms == otherScn) {
+    return ms;
+  }
+
+  *i += 1;
+
+  /* Continue */
+  return NULL;
+}
+
+
+size_t elfu_mScnCount(ElfuElf *me)
+{
+  /* NULL section *is not* counted */
+  size_t i = 0;
+
+  assert(me);
+
+  elfu_mScnForall(me, subCounter, &i, NULL);
+
+  return i;
+}
+
+
+/* Returns the index a section would have in the flattened ELF */
+size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms)
+{
+  /* NULL section *is* counted */
+  size_t i = 1;
+
+  assert(me);
+  assert(ms);
+
+  elfu_mScnForall(me, subCounter, &i, ms);
+
+  /* If this assertion is broken then ms is not a section in me. */
+  assert(i <= elfu_mScnCount(me));
+  return i;
+}
+
+
+static void* subOldscn(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
+{
+  ElfuScn *otherScn = (ElfuScn*)aux1;
+  (void)aux2;
+
+  if (ms->oldptr == otherScn) {
+    return ms;
+  }
+
+  /* Continue */
+  return NULL;
+}
+
+/* Returns the section with oldscn == oldscn */
+ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn)
+{
+  assert(me);
+  assert(oldscn);
+
+  return elfu_mScnForall(me, subOldscn, oldscn, NULL);
+}
+
+
+
+
+/* Convenience */
+
+char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
+{
+  assert(me);
+  assert(ms);
+
+  if (!me->shstrtab) {
+    return NULL;
+  }
+
+  if (!me->shstrtab->databuf) {
+    return NULL;
+  }
+
+  return &me->shstrtab->databuf[ms->shdr.sh_name];
+}
+
+
+static void* subScnsToArray(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
+{
+  ElfuScn **arr = (ElfuScn**)aux1;
+  size_t *i = (size_t*)aux2;
+
+  arr[(*i)] = ms;
+  *i += 1;
+
+  /* Continue */
+  return NULL;
+}
+
+static int cmpScnOffs(const void *ms1, const void *ms2)
+{
+  ElfuScn *s1;
+  ElfuScn *s2;
+
+  assert(ms1);
+  assert(ms2);
+
+  s1 = *(ElfuScn**)ms1;
+  s2 = *(ElfuScn**)ms2;
+
+  assert(s1);
+  assert(s2);
+
+
+  if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
+    return -1;
+  } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
+    return 0;
+  } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
+    return 1;
+  }
+}
+
+ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
+{
+  size_t numSecs;
+  ElfuScn **sortedSecs;
+  size_t i;
+
+  assert(me);
+
+  /* Sort sections by offset in file */
+  numSecs = elfu_mScnCount(me);
+  sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
+  if (!sortedSecs) {
+    ELFU_WARN("elfu_mScnSortedByOffset: Failed to allocate memory.\n");
+    return NULL;
+  }
+
+  i = 0;
+  elfu_mScnForall(me, subScnsToArray, sortedSecs, &i);
+  assert(i == numSecs);
+
+  qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
+
+  *count = numSecs;
+
+  return sortedSecs;
+}
+
+
+
+/*
+ * Allocation, destruction
+ */
+
+ElfuScn* elfu_mScnAlloc()
+{
+  ElfuScn *ms;
+
+  ms = malloc(sizeof(ElfuScn));
+  if (!ms) {
+    ELFU_WARN("mScnCreate: malloc() failed for ElfuScn.\n");
+    return NULL;
+  }
+
+  memset(ms, 0, sizeof(*ms));
+
+  CIRCLEQ_INIT(&ms->symtab.syms);
+  CIRCLEQ_INIT(&ms->reltab.rels);
+
+  return ms;
+}
diff --git a/src/libelfu/model/symtab.c b/src/libelfu/model/symtab.c
new file mode 100644 (file)
index 0000000..165e00e
--- /dev/null
@@ -0,0 +1,267 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libelfu/libelfu.h>
+
+
+static void* subFindByName(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
+{
+  char *name = (char*)aux1;
+  (void)aux2;
+
+  if (elfu_mScnName(me, ms)) {
+    if (!strcmp(elfu_mScnName(me, ms), name)) {
+      return ms;
+    }
+  }
+
+  /* Continue */
+  return NULL;
+}
+
+/* Hazard a guess where a function may be found in the PLT */
+static GElf_Word pltLookupVal(ElfuElf *me, char *name)
+{
+  ElfuScn *relplt;
+  ElfuScn *plt;
+  ElfuRel *rel;
+  GElf_Word j;
+
+  relplt = elfu_mScnForall(me, subFindByName, ".rel.plt", NULL);
+  if (!relplt) {
+    ELFU_WARN("dynsymLookupVal: Could not find .rel.plt section in destination ELF.\n");
+    return 0;
+  }
+
+  plt = elfu_mScnForall(me, subFindByName, ".plt", NULL);
+  if (!plt) {
+    ELFU_WARN("dynsymLookupVal: Could not find .plt section in destination ELF.\n");
+    return 0;
+  }
+
+
+  /* Look up name. If the j-th entry in .rel.plt has the name we are
+   * looking for, we assume that the (j+1)-th entry in .plt is machine
+   * code to jump to the function.
+   * Your mileage may vary, but it works on my GNU binaries. */
+  assert(relplt->linkptr);
+  j = 0;
+  CIRCLEQ_FOREACH(rel, &relplt->reltab.rels, elem) {
+    GElf_Word i;
+    ElfuSym *sym;
+    char *symname;
+
+    j++;
+
+    /* We only consider runtime relocations for functions.
+     * Technically, these relocations write the functions' addresses
+     * to the GOT, not the PLT, after the dynamic linker has found
+     * them. */
+    if ((me->elfclass == ELFCLASS32 && rel->type != R_386_JMP_SLOT)
+        || (me->elfclass == ELFCLASS64 && rel->type != R_X86_64_JUMP_SLOT)) {
+      continue;
+    }
+
+    /* Get the (rel->sym)-th symbol from the symbol table that
+     * .rel.plt points to. */
+    sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab.syms);
+    for (i = 1; i < rel->sym; i++) {
+      sym = CIRCLEQ_NEXT(sym, elem);
+    }
+
+    symname = ELFU_SYMSTR(relplt->linkptr, sym->name);
+    if (!strcmp(symname, 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
+       * the number of bytes the machine code in a PLT entry take. */
+      GElf_Addr addr = plt->shdr.sh_addr + (16 * j);
+      ELFU_DEBUG("dynsymLookupVal: Guessing symbol '%s' is in destination memory at %x (PLT entry #%u).\n", name, (unsigned)addr, j);
+      return addr;
+    }
+  }
+
+  ELFU_WARN("dynsymLookupVal: Could not find symbol '%s' in destination ELF.\n", name);
+
+  return 0;
+}
+
+
+
+/* Look up a value in the symbol table section *msst which is in *me.
+ * If it is not found there, see if we can find it in *me's PLT. */
+GElf_Word elfu_mSymtabLookupVal(ElfuElf *me, ElfuScn *msst, GElf_Word entry)
+{
+  GElf_Word i;
+  ElfuSym *sym;
+  char *symname;
+
+  assert(me);
+  assert(msst);
+  assert(entry > 0);
+  assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
+
+  sym = CIRCLEQ_FIRST(&msst->symtab.syms);
+  for (i = 1; i < entry; i++) {
+    sym = CIRCLEQ_NEXT(sym, elem);
+  }
+  symname = ELFU_SYMSTR(msst, sym->name);
+
+  switch (sym->type) {
+    case STT_NOTYPE:
+    case STT_OBJECT:
+    case STT_FUNC:
+      if (sym->scnptr) {
+        ElfuScn *newscn = elfu_mScnByOldscn(me, sym->scnptr);
+        assert(newscn);
+        return newscn->shdr.sh_addr + sym->value;
+      } else if (sym->shndx == SHN_UNDEF) {
+        /* Look the symbol up in .rel.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(me, symname);
+      } else if (sym->shndx == SHN_ABS) {
+        return sym->value;
+      } else {
+        ELFU_WARN("symtabLookupVal: Symbol binding COMMON is not supported, using 0.\n");
+        return 0;
+      }
+      break;
+    case STT_SECTION:
+      assert(sym->scnptr);
+      assert(elfu_mScnByOldscn(me, sym->scnptr));
+      return elfu_mScnByOldscn(me, sym->scnptr)->shdr.sh_addr;
+    case STT_FILE:
+      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, symname);
+      return 0;
+  }
+}
+
+
+/* Look up a value in the symbol table section *msst which is in *me. */
+GElf_Word elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name)
+{
+  ElfuSym *sym;
+
+  assert(me);
+  assert(msst);
+  assert(name);
+  assert(strlen(name) > 0);
+  assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
+
+  CIRCLEQ_FOREACH(sym, &msst->symtab.syms, elem) {
+    char *symname = ELFU_SYMSTR(msst, sym->name);
+
+    if (!strcmp(symname, name)) {
+      goto SYMBOL_FOUND;
+    }
+  }
+  return 0;
+
+
+  SYMBOL_FOUND:
+
+  switch (sym->type) {
+    case STT_NOTYPE:
+    case STT_OBJECT:
+    case STT_FUNC:
+      if (sym->scnptr) {
+        GElf_Addr a = sym->value;
+        a += me->ehdr.e_type == ET_REL ? sym->scnptr->shdr.sh_addr : 0;
+        return a;
+      } else if (sym->shndx == SHN_UNDEF) {
+        return 0;
+      } else if (sym->shndx == SHN_ABS) {
+        return sym->value;
+      } else {
+        ELFU_WARN("elfu_mSymtabLookupAddrByName: Symbol binding COMMON is not supported, using 0.\n");
+        return 0;
+      }
+      break;
+    default:
+      return 0;
+  }
+}
+
+
+
+/* Convert symtab from memory model to elfclass specific format */
+void elfu_mSymtabFlatten(ElfuElf *me)
+{
+  ElfuSym *sym;
+  size_t numsyms = 0;
+
+  elfu_mLayoutAuto(me);
+
+  /* Update section indexes and count symbols */
+  CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
+    if (sym->scnptr) {
+      sym->shndx = elfu_mScnIndex(me, sym->scnptr);
+    }
+
+    numsyms++;
+  }
+
+  /* Copy symbols to elfclass-specific format */
+  if (me->elfclass == ELFCLASS32) {
+    size_t newsize = (numsyms + 1) * sizeof(Elf32_Sym);
+    size_t i;
+
+    if (me->symtab->databuf) {
+      free(me->symtab->databuf);
+    }
+    me->symtab->databuf = malloc(newsize);
+    assert(me->symtab->databuf);
+
+    me->symtab->shdr.sh_size = newsize;
+    memset(me->symtab->databuf, 0, newsize);
+
+    i = 1;
+    CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
+      Elf32_Sym *es = ((Elf32_Sym*)me->symtab->databuf) + 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) {
+    size_t newsize = (numsyms + 1) * sizeof(Elf64_Sym);
+    size_t i;
+
+    if (me->symtab->databuf) {
+      free(me->symtab->databuf);
+    }
+    me->symtab->databuf = malloc(newsize);
+    assert(me->symtab->databuf);
+
+    me->symtab->shdr.sh_size = newsize;
+    memset(me->symtab->databuf, 0, newsize);
+
+    i = 1;
+    CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
+      Elf64_Sym *es = ((Elf64_Sym*)me->symtab->databuf) + i;
+
+      es->st_name = sym->name;
+      es->st_value = sym->value;
+      es->st_size = sym->size;
+      es->st_info = ELF64_ST_INFO(sym->bind, sym->type);
+      es->st_other = sym->other;
+      es->st_shndx = sym->shndx;
+
+      i++;
+    }
+  } else {
+    /* Unknown elfclass */
+    assert(0);
+  }
+
+  elfu_mLayoutAuto(me);
+}
index 8f9291999d46cf99b1089508d46a9c62d3c20baa..8b9b0bcea91f9b28b54c396b1f0cbc4b8eb52fc6 100644 (file)
@@ -9,33 +9,27 @@ ElfuScn* elfu_mCloneScn(ElfuScn *ms)
 
   assert(ms);
 
-  newscn = malloc(sizeof(ElfuScn));
+  newscn = elfu_mScnAlloc();
   if (!newscn) {
     ELFU_WARN("elfu_nCloneScn: Could not allocate memory for new ElfuScn.\n");
     return NULL;
   }
 
   newscn->shdr = ms->shdr;
-  newscn->data = ms->data;
-  if (ms->data.d_buf) {
-    void *newbuf = malloc(ms->data.d_size);
+
+  if (ms->databuf) {
+    void *newbuf = malloc(ms->shdr.sh_size);
     if (!newbuf) {
       ELFU_WARN("elfu_nCloneScn: Could not allocate memory for new data buffer.\n");
       free(newscn);
       return NULL;
     }
 
-    memcpy(newbuf, ms->data.d_buf, ms->data.d_size);
-    newscn->data.d_buf = newbuf;
+    memcpy(newbuf, ms->databuf, ms->shdr.sh_size);
+    newscn->databuf = newbuf;
   }
 
-  newscn->linkptr = NULL;
-  newscn->infoptr = NULL;
-
   newscn->oldptr = ms;
 
-  CIRCLEQ_INIT(&ms->symtab.syms);
-  CIRCLEQ_INIT(&ms->reltab.rels);
-
   return newscn;
 }
index 075d94544661f16be7572d3264b1485813a91709..86ac46b57edfe8abfcc1f257e705f1805be60811 100644 (file)
@@ -47,5 +47,5 @@ void elfu_mDetour(ElfuElf *me, GElf_Addr from, GElf_Addr to)
              (unsigned)to);
 
   *(Elf32_Word*)(detourcode + 1) = to - from - 5;
-  memcpy((char*)ms->data.d_buf + scnoffset, detourcode, 5);
+  memcpy(ms->databuf + scnoffset, detourcode, 5);
 }
index dd8b46222b5654b0220b631f491249188d30db5e..9c25e291dc5450729ed6523b0e0e5d08386e8287 100644 (file)
@@ -11,13 +11,13 @@ static void parseSymtab(ElfuElf *me, ElfuScn *ms, ElfuScn**origScnArr)
   size_t i;
 
   assert(ms);
-  assert(ms->data.d_buf);
+  assert(ms->databuf);
   assert(origScnArr);
 
   /* Parse symbols from their elfclass-specific format */
   if (me->elfclass == ELFCLASS32) {
     for (i = 1; (i + 1) * sizeof(Elf32_Sym) <= ms->shdr.sh_size; i++) {
-      Elf32_Sym *cursym = ((Elf32_Sym*)ms->data.d_buf) + i;
+      Elf32_Sym *cursym = ((Elf32_Sym*)ms->databuf) + i;
       ElfuSym *newsym = malloc(sizeof(*sym));
       assert(newsym);
 
@@ -29,13 +29,11 @@ static void parseSymtab(ElfuElf *me, ElfuScn *ms, ElfuScn**origScnArr)
       newsym->other = cursym->st_other;
       newsym->shndx = cursym->st_shndx;
 
-
-
       CIRCLEQ_INSERT_TAIL(&ms->symtab.syms, newsym, elem);
     }
   } else if (me->elfclass == ELFCLASS64) {
     for (i = 1; (i + 1) * sizeof(Elf64_Sym) <= ms->shdr.sh_size; i++) {
-      Elf64_Sym *cursym = ((Elf64_Sym*)ms->data.d_buf) + i;
+      Elf64_Sym *cursym = ((Elf64_Sym*)ms->databuf) + i;
       ElfuSym *newsym = malloc(sizeof(*sym));
       assert(newsym);
 
@@ -47,8 +45,6 @@ static void parseSymtab(ElfuElf *me, ElfuScn *ms, ElfuScn**origScnArr)
       newsym->other = cursym->st_other;
       newsym->shndx = cursym->st_shndx;
 
-
-
       CIRCLEQ_INSERT_TAIL(&ms->symtab.syms, newsym, elem);
     }
   } else {
@@ -77,11 +73,11 @@ static void parseReltab32(ElfuScn *ms)
   size_t i;
 
   assert(ms);
-  assert(ms->data.d_buf);
+  assert(ms->databuf);
 
 
   for (i = 0; (i + 1) * sizeof(Elf32_Rel) <= ms->shdr.sh_size; i++) {
-    Elf32_Rel *currel = &(((Elf32_Rel*)ms->data.d_buf)[i]);
+    Elf32_Rel *currel = &(((Elf32_Rel*)ms->databuf)[i]);
     ElfuRel *rel;
 
     rel = malloc(sizeof(*rel));
@@ -103,11 +99,11 @@ static void parseRelatab64(ElfuScn *ms)
   size_t i;
 
   assert(ms);
-  assert(ms->data.d_buf);
+  assert(ms->databuf);
 
 
   for (i = 0; (i + 1) * sizeof(Elf64_Rela) <= ms->shdr.sh_size; i++) {
-    Elf64_Rela *currel = &(((Elf64_Rela*)ms->data.d_buf)[i]);
+    Elf64_Rela *currel = &(((Elf64_Rela*)ms->databuf)[i]);
     ElfuRel *rel;
 
     rel = malloc(sizeof(*rel));
@@ -210,29 +206,20 @@ static ElfuScn* modelFromSection(Elf_Scn *scn)
 
   assert(scn);
 
-  ms = malloc(sizeof(ElfuScn));
+  ms = elfu_mScnAlloc();
   if (!ms) {
-    ELFU_WARN("modelFromSection: malloc() failed for ElfuScn.\n");
     goto ERROR;
   }
 
-
+  /* Copy SHDR */
   assert(gelf_getshdr(scn, &ms->shdr) == &ms->shdr);
 
-
   /* Copy each data part in source segment */
-  ms->data.d_align = 1;
-  ms->data.d_buf  = NULL;
-  ms->data.d_off  = 0;
-  ms->data.d_type = ELF_T_BYTE;
-  ms->data.d_size = ms->shdr.sh_size;
-  ms->data.d_version = elf_version(EV_NONE);
-  if (ms->shdr.sh_type != SHT_NOBITS
-      && ms->shdr.sh_size > 0) {
+  if (SCNFILESIZE(&ms->shdr) > 0) {
     Elf_Data *data;
 
-    ms->data.d_buf = malloc(ms->shdr.sh_size);
-    if (!ms->data.d_buf) {
+    ms->databuf = malloc(ms->shdr.sh_size);
+    if (!ms->databuf) {
       ELFU_WARN("modelFromSection: malloc() failed for data buffer (%x bytes).\n", (unsigned)ms->shdr.sh_size);
       goto ERROR;
     }
@@ -241,30 +228,20 @@ static ElfuScn* modelFromSection(Elf_Scn *scn)
     data = elf_rawdata(scn, NULL);
     assert(data);
 
-    ms->data.d_align = data->d_align;
-    ms->data.d_type = data->d_type;
-    ms->data.d_version = data->d_version;
+    /* elf_rawdata() always returns ELF_T_BYTE */
+    assert(data->d_type == ELF_T_BYTE);
 
     while (data) {
       if (data->d_off + data->d_size > ms->shdr.sh_size) {
         ELFU_WARN("modelFromSection: libelf delivered a bogus data blob. Skipping\n");
       } else {
-        memcpy((char*)ms->data.d_buf + data->d_off, data->d_buf, data->d_size);
+        memcpy((char*)ms->databuf + data->d_off, data->d_buf, data->d_size);
       }
 
       data = elf_rawdata(scn, data);
     }
   }
 
-  ms->linkptr = NULL;
-  ms->infoptr = NULL;
-
-  ms->oldptr = NULL;
-
-  CIRCLEQ_INIT(&ms->symtab.syms);
-  CIRCLEQ_INIT(&ms->reltab.rels);
-
-
   return ms;
 
   ERROR:
index 8abc766e167e8dea322d8949c3854791ce836bea..65a713df9e19110535e6144277eecbbf8c4d7ad6 100644 (file)
@@ -121,21 +121,15 @@ GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
         if (ms->shdr.sh_offset == endOff) {
           assert(ms->shdr.sh_type == SHT_NOBITS);
           assert(ms->shdr.sh_size == nobitsize);
-          ms->data.d_buf = malloc(ms->shdr.sh_size);
-          memset(ms->data.d_buf, '\0', ms->shdr.sh_size);
-          if (!ms->data.d_buf) {
+          ms->databuf = malloc(ms->shdr.sh_size);
+          memset(ms->databuf, '\0', ms->shdr.sh_size);
+          if (!ms->databuf) {
             ELFU_WARN("mExpandNobits: Could not allocate %u bytes for NOBITS expansion. Data may be inconsistent.\n",
                       (unsigned)ms->shdr.sh_size);
             assert(0);
             goto ERROR;
           }
 
-          ms->data.d_align = 1;
-          ms->data.d_off  = 0;
-          ms->data.d_type = ELF_T_BYTE;
-          ms->data.d_size = ms->shdr.sh_size;
-          ms->data.d_version = elf_version(EV_NONE);
-
           ms->shdr.sh_type = SHT_PROGBITS;
           ms->shdr.sh_addr = endAddr;
         }
diff --git a/src/libelfu/modelops/phdr.c b/src/libelfu/modelops/phdr.c
deleted file mode 100644 (file)
index d26eb77..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <assert.h>
-#include <libelfu/libelfu.h>
-
-
-size_t elfu_mPhdrCount(ElfuElf *me)
-{
-  ElfuPhdr *mp;
-  size_t i = 0;
-
-  assert(me);
-
-  CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
-    i++;
-  }
-
-  return i;
-}
-
-
-
-void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp)
-{
-  ElfuScn *ms;
-  ElfuPhdr *mpc;
-
-  assert(mp);
-  assert(mp->phdr.p_type == PT_LOAD);
-
-  CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) {
-    mpc->phdr.p_offset = mp->phdr.p_offset + (mpc->phdr.p_vaddr - mp->phdr.p_vaddr);
-  }
-
-  CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
-    ms->shdr.sh_offset = mp->phdr.p_offset + (ms->shdr.sh_addr - mp->phdr.p_vaddr);
-  }
-}
index bc909e4c0e7074adeeffd4efc4467877c455d926..8c56d4ff7faa2af178b047598c7c74f46ae8e5db 100644 (file)
@@ -11,19 +11,18 @@ static int appendData(ElfuScn *ms, void *buf, size_t len)
 
   assert(ms);
   assert(ms->shdr.sh_type != SHT_NOBITS);
-  assert(ms->data.d_buf);
+  assert(ms->databuf);
 
-  newbuf = realloc(ms->data.d_buf, ms->shdr.sh_size + len);
+  newbuf = realloc(ms->databuf, ms->shdr.sh_size + len);
   if (!newbuf) {
     ELFU_WARN("appendData: malloc() failed for newbuf.\n");
     return 1;
   }
 
-  ms->data.d_buf = newbuf;
+  ms->databuf = newbuf;
   memcpy(newbuf + ms->shdr.sh_size, buf, len);
   ms->shdr.sh_size += len;
-  ms->data.d_size += len;
-  assert(ms->shdr.sh_size == ms->data.d_size);
+  assert(ms->shdr.sh_size == ms->shdr.sh_size);
 
   return 0;
 }
@@ -45,13 +44,12 @@ static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
     if (newscn->shdr.sh_type == SHT_NOBITS) {
       /* Expand this to SHT_PROGBITS, then insert as such. */
 
-      assert(!newscn->data.d_buf);
+      assert(!newscn->databuf);
 
-      newscn->data.d_buf = malloc(newscn->shdr.sh_size);
-      if (!newscn->data.d_buf) {
+      newscn->databuf = malloc(newscn->shdr.sh_size);
+      if (!newscn->databuf) {
         goto ERROR;
       }
-      newscn->data.d_size = newscn->shdr.sh_size;
       newscn->shdr.sh_type = SHT_PROGBITS;
     }
 
@@ -250,19 +248,18 @@ static void insertSymClone(ElfuElf *me, const ElfuScn *oldmsst, const ElfuSym *o
 
   /* Expand .strtab, append symbol name, link newsym to it */
   newsize = me->symtab->linkptr->shdr.sh_size + strlen(oldsymname) + 1;
-  newbuf = realloc(me->symtab->linkptr->data.d_buf, newsize);
+  newbuf = realloc(me->symtab->linkptr->databuf, newsize);
   if (!newbuf) {
     ELFU_WARN("insertSymClone: realloc() failed for strtab.\n");
     goto ERROR;
   }
 
-  me->symtab->linkptr->data.d_buf = newbuf;
+  me->symtab->linkptr->databuf = newbuf;
 
   newsym->name = me->symtab->linkptr->shdr.sh_size;
 
   strcpy(newbuf + newsym->name, oldsymname);
 
-  me->symtab->linkptr->data.d_size = newsize;
   me->symtab->linkptr->shdr.sh_size = newsize;
 
 
index eefed026c8ad16d3594b9f9bf4693001a6ee3941..2eada0424e8a27e000df13950770a93619d9f234 100644 (file)
@@ -18,8 +18,8 @@ void elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt)
              (unsigned)mstarget->shdr.sh_size);
 
   CIRCLEQ_FOREACH(rel, &msrt->reltab.rels, elem) {
-    Elf32_Word *dest32 = (Elf32_Word*)(((char*)(mstarget->data.d_buf)) + rel->offset);
-    Elf64_Word *dest64 = (Elf64_Word*)(((char*)(mstarget->data.d_buf)) + rel->offset);
+    Elf32_Word *dest32 = (Elf32_Word*)(mstarget->databuf + rel->offset);
+    Elf64_Word *dest64 = (Elf64_Word*)(mstarget->databuf + rel->offset);
 
 
     if (metarget->elfclass == ELFCLASS32) {
diff --git a/src/libelfu/modelops/section.c b/src/libelfu/modelops/section.c
deleted file mode 100644 (file)
index 2675126..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <libelfu/libelfu.h>
-
-
-/* Meta-functions */
-
-void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2)
-{
-  ElfuPhdr *mp;
-  ElfuScn *ms;
-
-  // TODO: Sort PHDRs by offset before interating
-
-  CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
-    if (mp->phdr.p_type != PT_LOAD) {
-      continue;
-    }
-
-    CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
-      void *rv = f(me, ms, aux1, aux2);
-
-      if (rv) {
-        return rv;
-      }
-    }
-  }
-
-  CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
-    void *rv = f(me, ms, aux1, aux2);
-
-    if (rv) {
-      return rv;
-    }
-  }
-
-  return NULL;
-}
-
-
-
-
-/* Counting */
-
-static void* subCounter(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
-  size_t *i = (size_t*)aux1;
-  ElfuScn *otherScn = (ElfuScn*)aux2;
-
-  if (ms == otherScn) {
-    return ms;
-  }
-
-  *i += 1;
-
-  /* Continue */
-  return NULL;
-}
-
-
-size_t elfu_mScnCount(ElfuElf *me)
-{
-  /* NULL section *is not* counted */
-  size_t i = 0;
-
-  assert(me);
-
-  elfu_mScnForall(me, subCounter, &i, NULL);
-
-  return i;
-}
-
-
-/* Returns the index a section would have in the flattened ELF */
-size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms)
-{
-  /* NULL section *is* counted */
-  size_t i = 1;
-
-  assert(me);
-  assert(ms);
-
-  elfu_mScnForall(me, subCounter, &i, ms);
-
-  /* If this assertion is broken then ms is not a section in me. */
-  assert(i <= elfu_mScnCount(me));
-  return i;
-}
-
-
-static void* subOldscn(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
-  ElfuScn *otherScn = (ElfuScn*)aux1;
-  (void)aux2;
-
-  if (ms->oldptr == otherScn) {
-    return ms;
-  }
-
-  /* Continue */
-  return NULL;
-}
-
-/* Returns the section with oldscn == oldscn */
-ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn)
-{
-  assert(me);
-  assert(oldscn);
-
-  return elfu_mScnForall(me, subOldscn, oldscn, NULL);
-}
-
-
-
-
-/* Convenience */
-
-char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
-{
-  assert(me);
-  assert(ms);
-
-  if (!me->shstrtab) {
-    return NULL;
-  }
-
-  if (!me->shstrtab->data.d_buf) {
-    return NULL;
-  }
-
-  return &((char*)me->shstrtab->data.d_buf)[ms->shdr.sh_name];
-}
-
-
-static void* subScnsToArray(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
-  ElfuScn **arr = (ElfuScn**)aux1;
-  size_t *i = (size_t*)aux2;
-
-  arr[(*i)] = ms;
-  *i += 1;
-
-  /* Continue */
-  return NULL;
-}
-
-static int cmpScnOffs(const void *ms1, const void *ms2)
-{
-  ElfuScn *s1;
-  ElfuScn *s2;
-
-  assert(ms1);
-  assert(ms2);
-
-  s1 = *(ElfuScn**)ms1;
-  s2 = *(ElfuScn**)ms2;
-
-  assert(s1);
-  assert(s2);
-
-
-  if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
-    return -1;
-  } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
-    return 0;
-  } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
-    return 1;
-  }
-}
-
-ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
-{
-  size_t numSecs;
-  ElfuScn **sortedSecs;
-  size_t i;
-
-  assert(me);
-
-  /* Sort sections by offset in file */
-  numSecs = elfu_mScnCount(me);
-  sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
-  if (!sortedSecs) {
-    ELFU_WARN("elfu_mScnSortedByOffset: Failed to allocate memory.\n");
-    return NULL;
-  }
-
-  i = 0;
-  elfu_mScnForall(me, subScnsToArray, sortedSecs, &i);
-  assert(i == numSecs);
-
-  qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
-
-  *count = numSecs;
-
-  return sortedSecs;
-}
diff --git a/src/libelfu/modelops/symtab.c b/src/libelfu/modelops/symtab.c
deleted file mode 100644 (file)
index ef8443f..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-
-static void* subFindByName(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
-  char *name = (char*)aux1;
-  (void)aux2;
-
-  if (elfu_mScnName(me, ms)) {
-    if (!strcmp(elfu_mScnName(me, ms), name)) {
-      return ms;
-    }
-  }
-
-  /* Continue */
-  return NULL;
-}
-
-/* Hazard a guess where a function may be found in the PLT */
-static GElf_Word pltLookupVal(ElfuElf *me, char *name)
-{
-  ElfuScn *relplt;
-  ElfuScn *plt;
-  ElfuRel *rel;
-  GElf_Word j;
-
-  relplt = elfu_mScnForall(me, subFindByName, ".rel.plt", NULL);
-  if (!relplt) {
-    ELFU_WARN("dynsymLookupVal: Could not find .rel.plt section in destination ELF.\n");
-    return 0;
-  }
-
-  plt = elfu_mScnForall(me, subFindByName, ".plt", NULL);
-  if (!plt) {
-    ELFU_WARN("dynsymLookupVal: Could not find .plt section in destination ELF.\n");
-    return 0;
-  }
-
-
-  /* Look up name. If the j-th entry in .rel.plt has the name we are
-   * looking for, we assume that the (j+1)-th entry in .plt is machine
-   * code to jump to the function.
-   * Your mileage may vary, but it works on my GNU binaries. */
-  assert(relplt->linkptr);
-  j = 0;
-  CIRCLEQ_FOREACH(rel, &relplt->reltab.rels, elem) {
-    GElf_Word i;
-    ElfuSym *sym;
-    char *symname;
-
-    j++;
-
-    /* We only consider runtime relocations for functions.
-     * Technically, these relocations write the functions' addresses
-     * to the GOT, not the PLT, after the dynamic linker has found
-     * them. */
-    if ((me->elfclass == ELFCLASS32 && rel->type != R_386_JMP_SLOT)
-        || (me->elfclass == ELFCLASS64 && rel->type != R_X86_64_JUMP_SLOT)) {
-      continue;
-    }
-
-    /* Get the (rel->sym)-th symbol from the symbol table that
-     * .rel.plt points to. */
-    sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab.syms);
-    for (i = 1; i < rel->sym; i++) {
-      sym = CIRCLEQ_NEXT(sym, elem);
-    }
-
-    symname = ELFU_SYMSTR(relplt->linkptr, sym->name);
-    if (!strcmp(symname, 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
-       * the number of bytes the machine code in a PLT entry take. */
-      GElf_Addr addr = plt->shdr.sh_addr + (16 * j);
-      ELFU_DEBUG("dynsymLookupVal: Guessing symbol '%s' is in destination memory at %x (PLT entry #%u).\n", name, (unsigned)addr, j);
-      return addr;
-    }
-  }
-
-  ELFU_WARN("dynsymLookupVal: Could not find symbol '%s' in destination ELF.\n", name);
-
-  return 0;
-}
-
-
-
-/* Look up a value in the symbol table section *msst which is in *me.
- * If it is not found there, see if we can find it in *me's PLT. */
-GElf_Word elfu_mSymtabLookupVal(ElfuElf *me, ElfuScn *msst, GElf_Word entry)
-{
-  GElf_Word i;
-  ElfuSym *sym;
-  char *symname;
-
-  assert(me);
-  assert(msst);
-  assert(entry > 0);
-  assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
-
-  sym = CIRCLEQ_FIRST(&msst->symtab.syms);
-  for (i = 1; i < entry; i++) {
-    sym = CIRCLEQ_NEXT(sym, elem);
-  }
-  symname = ELFU_SYMSTR(msst, sym->name);
-
-  switch (sym->type) {
-    case STT_NOTYPE:
-    case STT_OBJECT:
-    case STT_FUNC:
-      if (sym->scnptr) {
-        ElfuScn *newscn = elfu_mScnByOldscn(me, sym->scnptr);
-        assert(newscn);
-        return newscn->shdr.sh_addr + sym->value;
-      } else if (sym->shndx == SHN_UNDEF) {
-        /* Look the symbol up in .rel.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(me, symname);
-      } else if (sym->shndx == SHN_ABS) {
-        return sym->value;
-      } else {
-        ELFU_WARN("symtabLookupVal: Symbol binding COMMON is not supported, using 0.\n");
-        return 0;
-      }
-      break;
-    case STT_SECTION:
-      assert(sym->scnptr);
-      assert(elfu_mScnByOldscn(me, sym->scnptr));
-      return elfu_mScnByOldscn(me, sym->scnptr)->shdr.sh_addr;
-    case STT_FILE:
-      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, symname);
-      return 0;
-  }
-}
-
-
-/* Look up a value in the symbol table section *msst which is in *me. */
-GElf_Word elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name)
-{
-  ElfuSym *sym;
-
-  assert(me);
-  assert(msst);
-  assert(name);
-  assert(strlen(name) > 0);
-  assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
-
-  CIRCLEQ_FOREACH(sym, &msst->symtab.syms, elem) {
-    char *symname = ELFU_SYMSTR(msst, sym->name);
-
-    if (!strcmp(symname, name)) {
-      goto SYMBOL_FOUND;
-    }
-  }
-  return 0;
-
-
-  SYMBOL_FOUND:
-
-  switch (sym->type) {
-    case STT_NOTYPE:
-    case STT_OBJECT:
-    case STT_FUNC:
-      if (sym->scnptr) {
-        GElf_Addr a = sym->value;
-        a += me->ehdr.e_type == ET_REL ? sym->scnptr->shdr.sh_addr : 0;
-        return a;
-      } else if (sym->shndx == SHN_UNDEF) {
-        return 0;
-      } else if (sym->shndx == SHN_ABS) {
-        return sym->value;
-      } else {
-        ELFU_WARN("elfu_mSymtabLookupAddrByName: Symbol binding COMMON is not supported, using 0.\n");
-        return 0;
-      }
-      break;
-    default:
-      return 0;
-  }
-}
-
-
-
-/* Convert symtab from memory model to elfclass specific format */
-void elfu_mSymtabFlatten(ElfuElf *me)
-{
-  ElfuSym *sym;
-  size_t numsyms = 0;
-
-  elfu_mLayoutAuto(me);
-
-  /* Update section indexes and count symbols */
-  CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
-    if (sym->scnptr) {
-      sym->shndx = elfu_mScnIndex(me, sym->scnptr);
-    }
-
-    numsyms++;
-  }
-
-  /* Copy symbols to elfclass-specific format */
-  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) {
-    size_t newsize = (numsyms + 1) * sizeof(Elf64_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) {
-      Elf64_Sym *es = ((Elf64_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 = ELF64_ST_INFO(sym->bind, sym->type);
-      es->st_other = sym->other;
-      es->st_shndx = sym->shndx;
-
-      i++;
-    }
-  } else {
-    /* Unknown elfclass */
-    assert(0);
-  }
-
-  elfu_mLayoutAuto(me);
-}
index 368f12a58fb0baf7ce1b021671826b5fb0108d1b..ff01390b27c1c293a7d19a2f53cc644a03a93eb3 100644 (file)
@@ -59,18 +59,18 @@ static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
 
 
   /* Data */
-  if (ms->data.d_buf) {
+  if (ms->databuf) {
     Elf_Data *dataOut = elf_newdata(scnOut);
     if (!dataOut) {
       ELFU_WARNELF("elf_newdata");
     }
 
-    dataOut->d_align = ms->data.d_align;
-    dataOut->d_buf  = ms->data.d_buf;
-    dataOut->d_off  = ms->data.d_off;
-    dataOut->d_type = ms->data.d_type;
-    dataOut->d_size = ms->data.d_size;
-    dataOut->d_version = ms->data.d_version;
+    dataOut->d_align = 1;
+    dataOut->d_buf  = ms->databuf;
+    dataOut->d_off  = 0;
+    dataOut->d_type = ELF_T_BYTE;
+    dataOut->d_size = ms->shdr.sh_size;
+    dataOut->d_version = elf_version(EV_NONE);
   }
 
   return NULL;