From: norly Date: Sat, 22 Jun 2013 00:26:45 +0000 (+0100) Subject: PHDR: Find lowest/highest addr/offs X-Git-Url: https://git.enpas.org/?p=centaur.git;a=commitdiff_plain;h=605d8a0c062b080d984fe6f3634c1511c6b6f2e8 PHDR: Find lowest/highest addr/offs --- diff --git a/include/libelfu/modelops.h b/include/libelfu/modelops.h index c6d5c30..c0a5851 100644 --- a/include/libelfu/modelops.h +++ b/include/libelfu/modelops.h @@ -23,6 +23,11 @@ typedef void* (PhdrHandlerFunc)(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux size_t elfu_mPhdrCount(ElfuElf *me); ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr); ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset); + void elfu_mPhdrLoadLowestHighest(ElfuElf *me, + ElfuPhdr **lowestAddr, + ElfuPhdr **highestAddr, + ElfuPhdr **lowestOffs, + ElfuPhdr **highestOffsEnd); void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp); ElfuPhdr* elfu_mPhdrAlloc(); void elfu_mPhdrDestroy(ElfuPhdr* mp); diff --git a/src/libelfu/model/phdr.c b/src/libelfu/model/phdr.c index d175362..9889f39 100644 --- a/src/libelfu/model/phdr.c +++ b/src/libelfu/model/phdr.c @@ -58,7 +58,7 @@ size_t elfu_mPhdrCount(ElfuElf *me) -/* Finding */ +/* Finding by exact address/offset */ static void* subFindLoadByAddr(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) { @@ -102,6 +102,53 @@ ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset) +/* Find lowest/highest address/offset */ + +void elfu_mPhdrLoadLowestHighest(ElfuElf *me, + ElfuPhdr **lowestAddr, ElfuPhdr **highestAddr, + ElfuPhdr **lowestOffs, ElfuPhdr **highestOffsEnd) +{ + ElfuPhdr *mp; + + assert(me); + assert(lowestAddr); + assert(highestAddr); + assert(lowestOffs); + assert(highestOffsEnd); + + *lowestAddr = NULL; + *highestAddr = NULL; + *lowestOffs = NULL; + *highestOffsEnd = NULL; + + /* Find first and last LOAD PHDRs. + * Don't compare p_memsz - segments don't overlap in memory. */ + CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { + if (mp->phdr.p_type != PT_LOAD) { + continue; + } + if (!*lowestAddr || mp->phdr.p_vaddr < (*lowestAddr)->phdr.p_vaddr) { + *lowestAddr = mp; + } + if (!*highestAddr || mp->phdr.p_vaddr > (*highestAddr)->phdr.p_vaddr) { + *highestAddr = mp; + } + if (!*lowestOffs || mp->phdr.p_offset < (*lowestOffs)->phdr.p_offset) { + *lowestOffs = mp; + } + if (!*highestOffsEnd + || (OFFS_END(mp->phdr.p_offset, + mp->phdr.p_filesz) + > OFFS_END((*highestOffsEnd)->phdr.p_offset, + (*highestOffsEnd)->phdr.p_filesz))) { + *highestOffsEnd = mp; + } + } +} + + + + /* Layout update */ void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp)