Copy section contents into newly allocated buffers
authornorly <ny-git@enpas.org>
Thu, 21 Mar 2013 00:41:08 +0000 (00:41 +0000)
committernorly <ny-git@enpas.org>
Thu, 21 Mar 2013 00:41:08 +0000 (00:41 +0000)
include/libelfu/modeltypes.h
src/model/fromFile.c
src/model/section-name.c
src/model/toFile.c

index 18f66717cc77f9954aaa3f5a3fcc9ea742f3302d..33a68a3d66ea27420579b4efbbd44e3bac1a2df8 100644 (file)
@@ -6,17 +6,11 @@
 #include <elf.h>
 #include <gelf.h>
 
-typedef struct ElfuData {
-  Elf_Data data;
-
-  CIRCLEQ_ENTRY(ElfuData) elem;
-} ElfuData;
-
 
 typedef struct ElfuScn {
   GElf_Shdr shdr;
 
-  CIRCLEQ_HEAD(DataList, ElfuData) dataList;
+  Elf_Data data;
 
   CIRCLEQ_ENTRY(ElfuScn) elem;
 } ElfuScn;
index dedbfa0c000e2518cf7e6c490227aa9e4bf72cb6..da57ad7cf15170e76a7f0b4a950f45e23bfa294f 100644 (file)
@@ -1,5 +1,7 @@
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <libelf.h>
 #include <gelf.h>
@@ -24,15 +26,13 @@ static ElfuPhdr* modelFromPhdr(GElf_Phdr *phdr)
 static ElfuScn* modelFromSection(Elf_Scn *scn)
 {
   ElfuScn *ms;
-  Elf_Data *data;
+
 
   ms = malloc(sizeof(ElfuScn));
   if (!ms) {
     return NULL;
   }
 
-  CIRCLEQ_INIT(&ms->dataList);
-
 
   if (gelf_getshdr(scn, &ms->shdr) != &ms->shdr) {
     fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
@@ -40,24 +40,44 @@ static ElfuScn* modelFromSection(Elf_Scn *scn)
   }
 
 
-
   /* Copy each data part in source segment */
-  data = elf_rawdata(scn, NULL);
-  while (data) {
-    ElfuData *md;
-
-    md = malloc(sizeof(ElfuData));
-    if (!md) {
+  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 > 1) {
+    Elf_Data *data;
+
+    ms->data.d_buf = malloc(ms->shdr.sh_size);
+    if (!ms->data.d_buf) {
+      fprintf(stderr, "modelFromSection: Could not allocate data buffer (%jx bytes).\n", ms->shdr.sh_size);
       goto out;
     }
 
-    md->data = *data;
+    /* A non-empty section should contain at least on data block. */
+    data = elf_rawdata(scn, NULL);
+
+    assert(data);
 
-    CIRCLEQ_INSERT_TAIL(&ms->dataList, md, elem);
+    ms->data.d_align = data->d_align;
+    ms->data.d_type = data->d_type;
+    ms->data.d_version = data->d_version;
 
-    data = elf_rawdata(scn, data);
+    while (data) {
+      if (data->d_off + data->d_size > ms->shdr.sh_size) {
+        fprintf(stderr, "modelFromSection: libelf delivered a bogus data blob. Skipping\n");
+      } else {
+        memcpy(ms->data.d_buf + data->d_off, data->d_buf, data->d_size);
+      }
+
+      data = elf_rawdata(scn, data);
+    }
   }
 
+
   return ms;
 
   out:
index 2ecd5f0a07b00c66defa054da717873759c575ee..fe3144801a1614c62cbd71a169ca489c0ab2ae4b 100644 (file)
@@ -15,11 +15,9 @@ char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
     return NULL;
   }
 
-  if (CIRCLEQ_EMPTY(&me->shstrtab->dataList)) {
+  if (!me->shstrtab->data.d_buf) {
     return NULL;
   }
 
-  /* Don't take multiple data parts into account. */
-  ElfuData *md = me->shstrtab->dataList.cqh_first;
-  return &((char*)md->data.d_buf)[ms->shdr.sh_name];
+  return &((char*)me->shstrtab->data.d_buf)[ms->shdr.sh_name];
 }
index 0bfbd004468a6ef3f28cc8663f74d0a7ebd81a27..3b0ae62500d1535b47b04ec160c5663fef887cc5 100644 (file)
@@ -52,19 +52,18 @@ static void modelToSection(ElfuScn *ms, Elf *e)
 
 
   /* Data */
-  ElfuData *md;
-  CIRCLEQ_FOREACH(md, &ms->dataList, elem) {
+  if (ms->data.d_buf) {
     Elf_Data *dataOut = elf_newdata(scnOut);
     if (!dataOut) {
       fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1));
     }
 
-    dataOut->d_align = md->data.d_align;
-    dataOut->d_buf  = md->data.d_buf;
-    dataOut->d_off  = md->data.d_off;
-    dataOut->d_type = md->data.d_type;
-    dataOut->d_size = md->data.d_size;
-    dataOut->d_version = md->data.d_version;
+    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;
   }
 }