diff options
author | norly <ny-git@enpas.org> | 2013-03-21 00:41:08 +0000 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2013-03-21 00:41:08 +0000 |
commit | e2b6e201992b9e4d458dd469d286db3dca46e75f (patch) | |
tree | e0ae6d46df0f55d5179ab6ee21eadb1fecdd46d4 /src/model/fromFile.c | |
parent | 20d33931a158fe6236092964120aaec793321a4c (diff) |
Copy section contents into newly allocated buffers
Diffstat (limited to 'src/model/fromFile.c')
-rw-r--r-- | src/model/fromFile.c | 46 |
1 files changed, 33 insertions, 13 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: |