From fb56823e86ceff5e340a691ef2a6d5df81e02fac Mon Sep 17 00:00:00 2001 From: norly Date: Thu, 20 Jun 2013 23:25:09 +0100 Subject: [PATCH] Add Elf/Phdr/Scn alloc/destroy --- include/libelfu/modelops.h | 6 ++++ src/elfucli.c | 8 ++++++ src/libelfu/model/elf.c | 51 +++++++++++++++++++++++++++++++++ src/libelfu/model/phdr.c | 19 ++++++++++++ src/libelfu/model/section.c | 13 +++++++++ src/libelfu/modelops/fromFile.c | 12 ++------ 6 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 src/libelfu/model/elf.c diff --git a/include/libelfu/modelops.h b/include/libelfu/modelops.h index 3dc44d8..afe6b96 100644 --- a/include/libelfu/modelops.h +++ b/include/libelfu/modelops.h @@ -21,6 +21,7 @@ void elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt); size_t elfu_mPhdrCount(ElfuElf *me); void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp); ElfuPhdr* elfu_mPhdrAlloc(); + void elfu_mPhdrDestroy(ElfuPhdr* mp); typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2); @@ -31,6 +32,11 @@ typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *a char* elfu_mScnName(ElfuElf *me, ElfuScn *ms); ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count); ElfuScn* elfu_mScnAlloc(); + void elfu_mScnDestroy(ElfuScn* ms); + + +ElfuElf* elfu_mElfAlloc(); + void elfu_mElfDestroy(ElfuElf* me); GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size, diff --git a/src/elfucli.c b/src/elfucli.c index cd8f0ba..b3ea29f 100644 --- a/src/elfucli.c +++ b/src/elfucli.c @@ -84,6 +84,10 @@ int main(int argc, char **argv) } break; case 'i': + if (me) { + elfu_mElfDestroy(me); + } + printf("Opening input file %s.\n", optarg); openElf(&hIn, optarg, ELF_C_READ); if (!hIn.e) { @@ -200,6 +204,10 @@ int main(int argc, char **argv) EXIT: + if (me) { + elfu_mElfDestroy(me); + } + if (hIn.e) { closeElf(&hIn); } diff --git a/src/libelfu/model/elf.c b/src/libelfu/model/elf.c new file mode 100644 index 0000000..46dc120 --- /dev/null +++ b/src/libelfu/model/elf.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + + +/* + * Allocation, destruction + */ + +ElfuElf* elfu_mElfAlloc() +{ + ElfuElf *me; + + me = malloc(sizeof(ElfuElf)); + if (!me) { + ELFU_WARN("mElfAlloc: malloc() failed for ElfuElf.\n"); + return NULL; + } + + memset(me, 0, sizeof(*me)); + + CIRCLEQ_INIT(&me->phdrList); + CIRCLEQ_INIT(&me->orphanScnList); + + return me; +} + + +void elfu_mElfDestroy(ElfuElf* me) +{ + ElfuPhdr *mp; + ElfuScn *ms; + + assert(me); + + CIRCLEQ_INIT(&me->phdrList); + CIRCLEQ_INIT(&me->orphanScnList); + + CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { + CIRCLEQ_REMOVE(&me->phdrList, mp, elem); + elfu_mPhdrDestroy(mp); + } + + CIRCLEQ_FOREACH(ms, &me->orphanScnList, elem) { + CIRCLEQ_REMOVE(&me->orphanScnList, ms, elem); + elfu_mScnDestroy(ms); + } + + free(me); +} diff --git a/src/libelfu/model/phdr.c b/src/libelfu/model/phdr.c index ce395ec..6896845 100644 --- a/src/libelfu/model/phdr.c +++ b/src/libelfu/model/phdr.c @@ -60,3 +60,22 @@ ElfuPhdr* elfu_mPhdrAlloc() return mp; } + +void elfu_mPhdrDestroy(ElfuPhdr* mp) +{ + ElfuPhdr *mp2; + ElfuScn *ms; + + assert(mp); + + CIRCLEQ_FOREACH(mp2, &mp->childPhdrList, elem) { + // TODO ? + } + + CIRCLEQ_FOREACH(ms, &mp->childScnList, elem) { + CIRCLEQ_REMOVE(&mp->childScnList, ms, elem); + elfu_mScnDestroy(ms); + } + + free(mp); +} diff --git a/src/libelfu/model/section.c b/src/libelfu/model/section.c index c93c5c8..9ef6fd8 100644 --- a/src/libelfu/model/section.c +++ b/src/libelfu/model/section.c @@ -219,3 +219,16 @@ ElfuScn* elfu_mScnAlloc() return ms; } + +void elfu_mScnDestroy(ElfuScn* ms) +{ + assert(ms); + + // TODO: Free symtab/reltab + + if (ms->databuf) { + free(ms->databuf); + } + + free(ms); +} diff --git a/src/libelfu/modelops/fromFile.c b/src/libelfu/modelops/fromFile.c index 9671b5f..e19df7b 100644 --- a/src/libelfu/modelops/fromFile.c +++ b/src/libelfu/modelops/fromFile.c @@ -290,19 +290,11 @@ ElfuElf* elfu_mFromElf(Elf *e) goto ERROR; } - me = malloc(sizeof(ElfuElf)); + me = elfu_mElfAlloc(); if (!me) { - ELFU_WARN("elfu_mFromElf: malloc() failed for ElfuElf.\n"); goto ERROR; } - - /* General stuff */ - CIRCLEQ_INIT(&me->phdrList); - CIRCLEQ_INIT(&me->orphanScnList); - me->shstrtab = NULL; - me->symtab = NULL; - me->elfclass = gelf_getclass(e); assert(me->elfclass != ELFCLASSNONE); assert(gelf_getehdr(e, &me->ehdr) == &me->ehdr); @@ -473,7 +465,7 @@ ElfuElf* elfu_mFromElf(Elf *e) free(secArray); } if (me) { - // TODO: Free data structures + elfu_mElfDestroy(me); } ELFU_WARN("elfu_mFromElf: Failed to load file.\n"); -- 2.30.2