I have tried a simple test using dladdr()
on Solaris 10/SPARC (but caveats: GCC 3.4, straight C), and this works fine for me:
#include <dlfcn.h>
#include <stdio.h>
void print_name(char *name, void *addr);
void print_name_by_dladdr(void *addr);
int main(int argc, const char *argv[])
{
print_name("main", (void *)&main);
print_name("print_name", (void *)&print_name);
print_name("printf", (void *)&printf);
return 0;
}
void print_name(char *name, void *addr)
{
(void)printf("Getting name of function %s() at 0x%x\n", name, addr);
print_name_by_dladdr(addr);
}
void print_name_by_dladdr(void *addr)
{
Dl_info dli;
if(!dladdr(addr, &dli)) {
perror("dladdr()");
exit(1);
}
(void)printf(" %s\n", dli.dli_sname);
}
Output:
Getting name of function main() at 0x10714
main
Getting name of function print_name() at 0x10778
print_name
Getting name of function printf() at 0x209b8
_PROCEDURE_LINKAGE_TABLE_
This also works correctly if I write (for example)
print_name("main", (void *)&main + 4);
You say you can resolve correctly against the output of nm
so possibilities seem limited... are you certain that the return address is being derived or passed correctly to your resolver function? I guess you are using the GCC builtins for this? I have tested __builtin_return_address(0)
and this also works fine for me. If you are using the GCC builtins, did you call __builtin_extract_return_address()
(see above page for details, mentions SPARC explicitly)? Can you post your code?
Can you stretch slightly to "process re-reading it's own binary/shared object files"? If so then libelf may be a way forwards. This is exactly what some of those utilities you mention are using, eg nm
: http://cr.opensolaris.org/~devnull/6515400/usr/src/cmd/sgs/nm/common/nm.c.html
This introductory article from sun.com might be of use (warning: article is 10 years old).
This isn't as nice as doing native introspection and it's odd that dladdr(3C)
doesn't work :(
Alternative intermediate: have you tried the RTLD_DL_SYMENT
flag to dladdr1(3C)
(and then perhaps borrow from nm.c
as above on the returned ELF sym)?