From feb8656ebe8c24137b179e1fc347c4fd3bf4bcd4 Mon Sep 17 00:00:00 2001 From: norly Date: Sun, 10 Feb 2013 00:36:16 +0000 Subject: First memory model of an ELF file --- src/model/fromFile.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/model/fromFile.c (limited to 'src/model') diff --git a/src/model/fromFile.c b/src/model/fromFile.c new file mode 100644 index 0000000..f349335 --- /dev/null +++ b/src/model/fromFile.c @@ -0,0 +1,152 @@ +#include +#include + +#include +#include + +#include + + +ElfuPhdr* elfu_modelFromPhdr(GElf_Phdr *phdr) +{ + ElfuPhdr *mp; + + mp = malloc(sizeof(ElfuPhdr)); + if (!mp) { + return NULL; + } + + mp->phdr = *phdr; + + return mp; +} + + +ElfuScn* elfu_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)); + goto out; + } + + + + /* Copy each data part in source segment */ + data = elf_rawdata(scn, NULL); + while (data) { + ElfuData *md; + + md = malloc(sizeof(ElfuData)); + if (!md) { + goto out; + } + + md->data = *data; + + CIRCLEQ_INSERT_TAIL(&ms->dataList, md, elem); + + data = elf_rawdata(scn, data); + } + + return ms; + + out: + // FIXME + return NULL; +} + + + + +ElfuElf* elfu_modelFromElf(Elf *e) +{ + ElfuElf *me; + + me = malloc(sizeof(ElfuElf)); + if (!me) { + return NULL; + } + + CIRCLEQ_INIT(&me->scnList); + CIRCLEQ_INIT(&me->phdrList); + + /* + * General stuff + */ + me->elfclass = gelf_getclass(e); + if (me->elfclass == ELFCLASSNONE) { + fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1)); + } + + if (!gelf_getehdr(e, &me->ehdr)) { + fprintf(stderr, "gelf_getehdr() failed: %s\n", elf_errmsg(-1)); + goto out; + } + + + /* + * Sections + */ + Elf_Scn *scn; + + scn = elf_getscn(e, 1); + while (scn) { + ElfuScn *ms = elfu_modelFromSection(scn); + + if (ms) { + CIRCLEQ_INSERT_TAIL(&me->scnList, ms, elem); + } else { + goto out; + } + + scn = elf_nextscn(e, scn); + } + + + + /* + * Segments + */ + size_t i, n; + + if (elf_getphdrnum(e, &n)) { + fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1)); + } + + for (i = 0; i < n; i++) { + GElf_Phdr phdr; + ElfuPhdr *mp; + + if (gelf_getphdr(e, i, &phdr) != &phdr) { + fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1)); + break; + } + + mp = elfu_modelFromPhdr(&phdr); + + if (mp) { + CIRCLEQ_INSERT_TAIL(&me->phdrList, mp, elem); + } else { + goto out; + } + } + + + + return me; + + out: + // FIXME + return NULL; +} -- cgit v1.2.3