From e68a6c6cc16279c72e270daae0548ea7c0f11c6e Mon Sep 17 00:00:00 2001 From: norly Date: Thu, 20 Jun 2013 23:47:01 +0100 Subject: [PATCH] LOAD PHDRs at top level, others as children. mPhdrForall(). The reference binaries had to be updated as PHDRs are now reordered. --- include/libelfu/modelops.h | 2 + src/libelfu/model/phdr.c | 51 ++++++++++++++++-- src/libelfu/modelops/fromFile.c | 2 + src/libelfu/modelops/toFile.c | 37 ++++++------- tests/reference/putsmain32-cloned | Bin 6104 -> 6104 bytes .../putsmain32-with-puts-alternative32 | Bin 18696 -> 18696 bytes 6 files changed, 66 insertions(+), 26 deletions(-) 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 58328b4f0cc4bbe596d38b57e00fbf0e4d754c32..973ea9c01bdb771776c0a2dfcddf8cc804f79e49 100755 GIT binary patch delta 23 fcmcbie?xzQ$;1+ci6#ycuQ*Jc;;>nS@rW1zd*2DE delta 23 fcmcbie?xzQ$;1$ci6#mYuQ*Jc;;>nS@rW1zdOrz? diff --git a/tests/reference/putsmain32-with-puts-alternative32 b/tests/reference/putsmain32-with-puts-alternative32 index 953ddad817253b60089f9767dd21e825a416099d..c820ef55851e56e8e9e9dc17e7cc2fcbed99103d 100755 GIT binary patch delta 25 hcmeB}#Mm*3ae~Rj5`~E-4im39Oq}AdS%mS6I{<=d3Nioy delta 25 hcmeB}#Mm*3ae~Rj5Qm8-3KOq5Oq}AdS%mS6I{<*m3K9SS -- 2.30.2