From e2b6e201992b9e4d458dd469d286db3dca46e75f Mon Sep 17 00:00:00 2001 From: norly Date: Thu, 21 Mar 2013 00:41:08 +0000 Subject: [PATCH] Copy section contents into newly allocated buffers --- include/libelfu/modeltypes.h | 8 +------ src/model/fromFile.c | 46 ++++++++++++++++++++++++++---------- src/model/section-name.c | 6 ++--- src/model/toFile.c | 15 ++++++------ 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/include/libelfu/modeltypes.h b/include/libelfu/modeltypes.h index 18f6671..33a68a3 100644 --- a/include/libelfu/modeltypes.h +++ b/include/libelfu/modeltypes.h @@ -6,17 +6,11 @@ #include #include -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; 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 #include #include +#include #include #include #include @@ -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; } } -- 2.30.2