diff options
| author | Matt Fischer <matt.fischer@garmin.com> | 2009-12-31 12:17:40 -0600 |
|---|---|---|
| committer | Garmin Android technology group <android@garmin.com> | 2010-03-17 16:11:37 -0500 |
| commit | e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5 (patch) | |
| tree | e5448ec45187a37dbade76fcf10115f91135a8bd /linker/linker.c | |
| parent | ede2e75f4942293342dfb8dfd4751369600ed8f1 (diff) | |
| download | bionic-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.c | 34 |
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) { |
