From: norly Date: Thu, 20 Jun 2013 22:47:01 +0000 (+0100) Subject: LOAD PHDRs at top level, others as children. mPhdrForall(). X-Git-Url: https://git.enpas.org/?p=centaur.git;a=commitdiff_plain;h=e68a6c6cc16279c72e270daae0548ea7c0f11c6e LOAD PHDRs at top level, others as children. mPhdrForall(). The reference binaries had to be updated as PHDRs are now reordered. --- diff --git a/include/libelfu/modelops.h b/include/libelfu/modelops.h index afe6b96..e5702f7 100644 --- a/include/libelfu/modelops.h +++ b/include/libelfu/modelops.h @@ -18,6 +18,8 @@ void elfu_mSymtabFlatten(ElfuElf *me); void elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt); +typedef void* (PhdrHandlerFunc)(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2); + void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2); size_t elfu_mPhdrCount(ElfuElf *me); void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp); ElfuPhdr* elfu_mPhdrAlloc(); diff --git a/src/libelfu/model/phdr.c b/src/libelfu/model/phdr.c index 6896845..1159fbb 100644 --- a/src/libelfu/model/phdr.c +++ b/src/libelfu/model/phdr.c @@ -4,22 +4,62 @@ #include -size_t elfu_mPhdrCount(ElfuElf *me) +/* Meta-functions */ + +void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2) { ElfuPhdr *mp; + + CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { + ElfuPhdr *mp2; + void *rv = f(me, mp, aux1, aux2); + if (rv) { + return rv; + } + + CIRCLEQ_FOREACH(mp2, &mp->childPhdrList, elemChildPhdr) { + void *rv = f(me, mp2, aux1, aux2); + if (rv) { + return rv; + } + } + } + + return NULL; +} + + + + +/* Counting */ + +static void* subCounter(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) +{ + size_t *i = (size_t*)aux1; + (void)aux2; + + *i += 1; + + /* Continue */ + return NULL; +} + + +size_t elfu_mPhdrCount(ElfuElf *me) +{ size_t i = 0; assert(me); - CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { - i++; - } + elfu_mPhdrForall(me, subCounter, &i, NULL); return i; } +/* Layout update */ + void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp) { ElfuScn *ms; @@ -69,7 +109,8 @@ void elfu_mPhdrDestroy(ElfuPhdr* mp) assert(mp); CIRCLEQ_FOREACH(mp2, &mp->childPhdrList, elem) { - // TODO ? + CIRCLEQ_REMOVE(&mp->childPhdrList, mp2, elem); + elfu_mPhdrDestroy(mp2); } CIRCLEQ_FOREACH(ms, &mp->childScnList, elem) { diff --git a/src/libelfu/modelops/fromFile.c b/src/libelfu/modelops/fromFile.c index e19df7b..c4e8c45 100644 --- a/src/libelfu/modelops/fromFile.c +++ b/src/libelfu/modelops/fromFile.c @@ -340,6 +340,8 @@ ElfuElf* elfu_mFromElf(Elf *e) if (mp->phdr.p_vaddr <= mp2->phdr.p_vaddr && OFFS_END(mp2->phdr.p_vaddr, mp2->phdr.p_memsz) <= OFFS_END(mp->phdr.p_vaddr, mp->phdr.p_memsz)) { + /* Remove from the main list so only LOADs remain there */ + CIRCLEQ_REMOVE(&me->phdrList, mp2, elem); CIRCLEQ_INSERT_TAIL(&mp->childPhdrList, mp2, elemChildPhdr); } } diff --git a/src/libelfu/modelops/toFile.c b/src/libelfu/modelops/toFile.c index ff01390..b42bc08 100644 --- a/src/libelfu/modelops/toFile.c +++ b/src/libelfu/modelops/toFile.c @@ -4,34 +4,22 @@ #include -static void modelToPhdrs(ElfuElf *me, Elf *e) +static void* modelToPhdr(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) { - ElfuPhdr *mp; - size_t i; + size_t *i = (size_t*)aux1; + Elf *e = (Elf*)aux2; - /* Count PHDRs */ - i = 0; - CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { - i++; + if (!gelf_update_phdr (e, *i, &mp->phdr)) { + ELFU_WARNELF("gelf_update_phdr"); } - if (!gelf_newphdr(e, i)) { - ELFU_WARNELF("gelf_newphdr"); - } - - /* Copy PHDRs */ - i = 0; - CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { - if (!gelf_update_phdr (e, i, &mp->phdr)) { - ELFU_WARNELF("gelf_update_phdr"); - } + *i += 1; - i++; - } + /* Continue */ + return NULL; } - static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2) { Elf_Scn *scnOut; @@ -82,6 +70,8 @@ static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2) void elfu_mToElf(ElfuElf *me, Elf *e) { + size_t i = 0; + if (me->symtab) { elfu_mSymtabFlatten(me); } @@ -114,8 +104,13 @@ void elfu_mToElf(ElfuElf *me, Elf *e) /* PHDRs */ - modelToPhdrs(me, e); + if (!gelf_newphdr(e, elfu_mPhdrCount(me))) { + ELFU_WARNELF("gelf_newphdr"); + } + + elfu_mPhdrForall(me, modelToPhdr, &i, e); + /* Done */ elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY); } diff --git a/tests/reference/putsmain32-cloned b/tests/reference/putsmain32-cloned index 58328b4..973ea9c 100755 Binary files a/tests/reference/putsmain32-cloned and b/tests/reference/putsmain32-cloned differ diff --git a/tests/reference/putsmain32-with-puts-alternative32 b/tests/reference/putsmain32-with-puts-alternative32 index 953ddad..c820ef5 100755 Binary files a/tests/reference/putsmain32-with-puts-alternative32 and b/tests/reference/putsmain32-with-puts-alternative32 differ