summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-22 01:00:38 +0100
committernorly <ny-git@enpas.org>2013-06-22 01:00:38 +0100
commit2affa1e1f0c64a2ca4d7a69761932b070c1bdc52 (patch)
treec44be25b1666c70cb4afc5a0b07b8a2f7745685d
parent8e6a1501ab9d8020950bc1883d14d14dd76fdb5f (diff)
PHDR: find by addr/offset
-rw-r--r--include/libelfu/modelops.h2
-rw-r--r--src/libelfu/model/phdr.c46
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)