diff options
author | norly <ny-git@enpas.org> | 2013-06-20 23:47:01 +0100 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2013-06-21 00:42:22 +0100 |
commit | e68a6c6cc16279c72e270daae0548ea7c0f11c6e (patch) | |
tree | 1bb268b01d557bf64744c1a0794acea2fad9286b | |
parent | fb56823e86ceff5e340a691ef2a6d5df81e02fac (diff) |
LOAD PHDRs at top level, others as children. mPhdrForall().
The reference binaries had to be updated as PHDRs are now reordered.
-rw-r--r-- | include/libelfu/modelops.h | 2 | ||||
-rw-r--r-- | src/libelfu/model/phdr.c | 51 | ||||
-rw-r--r-- | src/libelfu/modelops/fromFile.c | 2 | ||||
-rw-r--r-- | src/libelfu/modelops/toFile.c | 37 | ||||
-rwxr-xr-x | tests/reference/putsmain32-cloned | bin | 6104 -> 6104 bytes | |||
-rwxr-xr-x | tests/reference/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 <libelfu/libelfu.h> -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 <libelfu/libelfu.h> -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 Binary files differindex 58328b4..973ea9c 100755 --- a/tests/reference/putsmain32-cloned +++ b/tests/reference/putsmain32-cloned diff --git a/tests/reference/putsmain32-with-puts-alternative32 b/tests/reference/putsmain32-with-puts-alternative32 Binary files differindex 953ddad..c820ef5 100755 --- a/tests/reference/putsmain32-with-puts-alternative32 +++ b/tests/reference/putsmain32-with-puts-alternative32 |