summaryrefslogtreecommitdiffstats
path: root/linker/linker.c
diff options
context:
space:
mode:
authorMatt Fischer <matt.fischer@garmin.com>2009-12-31 12:17:40 -0600
committerGarmin Android technology group <android@garmin.com>2010-03-17 16:11:37 -0500
commite2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5 (patch)
treee5448ec45187a37dbade76fcf10115f91135a8bd /linker/linker.c
parentede2e75f4942293342dfb8dfd4751369600ed8f1 (diff)
downloadbionic-e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5.zip
bionic-e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5.tar.gz
bionic-e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5.tar.bz2
Added support for dladdr()
dladdr() is a GNU extension function, which allows the caller to retrieve symbol information for a specified memory address. It is useful for things like generating backtrace information at runtime. Change-Id: I3a1def1a6c9c666d93e1e97b7d260dfa5b9b79a9
Diffstat (limited to 'linker/linker.c')
-rw-r--r--linker/linker.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/linker/linker.c b/linker/linker.c
index 6d57cbc..f5294d9 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -538,6 +538,40 @@ Elf32_Sym *lookup(const char *name, soinfo **found)
return 0;
}
+soinfo *find_containing_library(void *addr)
+{
+ soinfo *si;
+
+ for(si = solist; si != NULL; si = si->next)
+ {
+ if((unsigned)addr >= si->base && (unsigned)addr - si->base < si->size) {
+ return si;
+ }
+ }
+
+ return NULL;
+}
+
+Elf32_Sym *find_containing_symbol(void *addr, soinfo *si)
+{
+ unsigned int i;
+ unsigned soaddr = (unsigned)addr - si->base;
+
+ /* Search the library's symbol table for any defined symbol which
+ * contains this address */
+ for(i=0; i<si->nchain; i++) {
+ Elf32_Sym *sym = &si->symtab[i];
+
+ if(sym->st_shndx != SHN_UNDEF &&
+ soaddr >= sym->st_value &&
+ soaddr < sym->st_value + sym->st_size) {
+ return sym;
+ }
+ }
+
+ return NULL;
+}
+
#if 0
static void dump(soinfo *si)
{