diff options
author | norly <ny-git@enpas.org> | 2013-06-22 01:00:38 +0100 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2013-06-22 01:00:38 +0100 |
commit | 2affa1e1f0c64a2ca4d7a69761932b070c1bdc52 (patch) | |
tree | c44be25b1666c70cb4afc5a0b07b8a2f7745685d | |
parent | 8e6a1501ab9d8020950bc1883d14d14dd76fdb5f (diff) |
PHDR: find by addr/offset
-rw-r--r-- | include/libelfu/modelops.h | 2 | ||||
-rw-r--r-- | src/libelfu/model/phdr.c | 46 |
2 files changed, 47 insertions, 1 deletions
diff --git a/include/libelfu/modelops.h b/include/libelfu/modelops.h index 3a5d7ea..c6d5c30 100644 --- a/include/libelfu/modelops.h +++ b/include/libelfu/modelops.h @@ -21,6 +21,8 @@ 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); +ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr); +ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset); 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 1159fbb..d175362 100644 --- a/src/libelfu/model/phdr.c +++ b/src/libelfu/model/phdr.c @@ -44,7 +44,6 @@ static void* subCounter(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) return NULL; } - size_t elfu_mPhdrCount(ElfuElf *me) { size_t i = 0; @@ -58,6 +57,51 @@ size_t elfu_mPhdrCount(ElfuElf *me) + +/* Finding */ + +static void* subFindLoadByAddr(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) +{ + GElf_Addr addr = *(GElf_Addr*)aux1; + (void)aux2; + + if (mp->phdr.p_type == PT_LOAD + && FULLY_OVERLAPPING(mp->phdr.p_vaddr, mp->phdr.p_memsz, addr, 1)) { + return mp; + } + + /* Continue */ + return NULL; +} + +ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr) +{ + return elfu_mPhdrForall(me, subFindLoadByAddr, &addr, NULL); +} + + +static void* subFindLoadByOffset(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2) +{ + GElf_Off offset = *(GElf_Off*)aux1; + (void)aux2; + + if (mp->phdr.p_type == PT_LOAD + && FULLY_OVERLAPPING(mp->phdr.p_offset, mp->phdr.p_filesz, offset, 1)) { + return mp; + } + + /* Continue */ + return NULL; +} + +ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset) +{ + return elfu_mPhdrForall(me, subFindLoadByOffset, &offset, NULL); +} + + + + /* Layout update */ void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp) |