summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/model')
-rw-r--r--src/model/fromFile.c46
-rw-r--r--src/model/section-name.c6
-rw-r--r--src/model/toFile.c15
3 files changed, 42 insertions, 25 deletions
diff --git a/src/model/fromFile.c b/src/model/fromFile.c
index dedbfa0..da57ad7 100644
--- a/src/model/fromFile.c
+++ b/src/model/fromFile.c
@@ -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:
diff --git a/src/model/section-name.c b/src/model/section-name.c
index 2ecd5f0..fe31448 100644
--- a/src/model/section-name.c
+++ b/src/model/section-name.c
@@ -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];
}
diff --git a/src/model/toFile.c b/src/model/toFile.c
index 0bfbd00..3b0ae62 100644
--- a/src/model/toFile.c
+++ b/src/model/toFile.c
@@ -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;
}
}