diff options
author | norly <ny-git@enpas.org> | 2013-02-10 00:36:16 +0000 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2013-02-11 01:24:36 +0000 |
commit | feb8656ebe8c24137b179e1fc347c4fd3bf4bcd4 (patch) | |
tree | c64080870ae87ce1c42a7c52878f7278173ade80 /src | |
parent | d9eb4398773cbda1dc185f4cf7b1b0e4cb9fb135 (diff) |
First memory model of an ELF file
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 14 | ||||
-rw-r--r-- | src/model/fromFile.c | 152 | ||||
-rw-r--r-- | src/options.c | 4 |
3 files changed, 170 insertions, 0 deletions
@@ -5,6 +5,8 @@ #include <libelf.h> #include <gelf.h> +#include <libelfu/libelfu.h> + #include "elfhandle.h" #include "options.h" #include "printing.h" @@ -57,6 +59,18 @@ int main(int argc, char **argv) } + /* Generate a memory model of the file */ + if (opts.model) { + ElfuElf *me; + + me = elfu_modelFromElf(hIn.e); + + if (me) { + printf("Model successfully loaded.\n"); + } + } + + EXIT: if (hOut.e) { 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 <stdio.h> +#include <stdlib.h> + +#include <libelf.h> +#include <gelf.h> + +#include <libelfu/libelfu.h> + + +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; +} diff --git a/src/options.c b/src/options.c index 014a1f2..42637f0 100644 --- a/src/options.c +++ b/src/options.c @@ -34,6 +34,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv) {"print-header", 0, 0, 10001}, {"print-segments", 0, 0, 10002}, {"print-sections", 0, 0, 10003}, + {"model", 0, 0, 10004}, {NULL, 0, NULL, 0} }; @@ -55,6 +56,9 @@ void parseOptions(CLIOpts *opts, int argc, char **argv) case 10003: opts->printSections = 1; break; + case 10004: + opts->model = 1; + break; case '?': default: goto USAGE; |