I tried a simple test using dladdr() on Solaris 10 / SPARC (but caveats: GCC 3.4, direct 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 that you can correctly resolve nm output, so the possibilities seem limited ... are you sure that the return address is output or correctly passed to your recognizer function? You probably use the GCC built-in for this? I tested __builtin_return_address(0) and it also works great for me. If you use the built-in GCC consoles, will you call __builtin_extract_return_address() (see above on the page for details, explicitly mentions SPARC)? Can you post your code?
Can you stretch a bit to "reprogram your own binary / shared object files"? If so, libelf may be a way forward. This is exactly what some of the utilities you mentioned use, for example nm : http://cr.opensolaris.org/~devnull/6515400/usr/src/cmd/sgs/nm/common/nm.c.html
This introductory article from sun.com may be helpful (warning: 10 year article).
This is not as nice as doing internal introspection, and it is strange that dladdr(3C) does not work: (
Alternative intermediate: did you try the RTLD_DL_SYMENT flag on dladdr1(3C) (and then, perhaps, borrowed from nm.c , as indicated above on the returned ELF element)?