I Thomas, I tested backtrace example on my sh4 arch and fix the problem of address resolution of static function. Follow the output I got executing the test:
# ./prog 3 backtrace() returned 7 addresses ./prog(myfunc3+0x1e) [0x40082a] ./prog [0x40090c] ./prog(myfunc+0x30) [0x400948] ./prog(myfunc+0x26) [0x40093e] ./prog(myfunc+0x26) [0x40093e] ./prog(main+0x5a) [0x4009b2] /lib/libc.so.0(__uClibc_main+0x21e) [0x295ce466] The following patch (against the uclibc master branch) fix it in the dladdr function. Could you try on your arch? Regards, Filippo Arcidiacono >From a386894ad712d4b4a712d0ec3df950495ad5b53f Mon Sep 17 00:00:00 2001 From: Filippo Arcidiacono <[email protected]> Date: Fri, 6 May 2011 16:49:28 +0200 Subject: [PATCH] libdl: fix symbol resolution of static functions in dladdr Fix dladdr to correctly resolve static function so backtrace_symbols print only the function address. Signed-off-by: Filippo Arcidiacono <[email protected]> --- ldso/include/dl-defs.h | 8 ++++++++ ldso/libdl/libdl.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index be0a81d..9b2f028 100644 --- a/ldso/include/dl-defs.h +++ b/ldso/include/dl-defs.h @@ -179,6 +179,14 @@ typedef struct { #define DL_LOOKUP_ADDRESS(ADDRESS) (ADDRESS) #endif +/* On some architectures dladdr can't use st_size of all symbols this way. */ +#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ + ((ADDR) >= (L)->loadaddr + (SYM)->st_value \ + && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0) \ + && (ADDR) == (L)->loadaddr + (SYM)->st_value) \ + || (ADDR) < (L)->loadaddr + (SYM)->st_value + (SYM)->st_size) \ + && ((MATCHSYM) == NULL || MATCHSYM < (L)->loadaddr + (SYM)->st_value)) + /* Use this macro to convert a pointer to a function's entry point to * a pointer to function. The pointer is assumed to have already been * relocated. LOADADDR is passed because it may contain additional diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 68cd579..2454cc7 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -1067,7 +1067,10 @@ int dladdr(const void *__address, Dl_info * __info) ElfW(Addr) symbol_addr; symbol_addr = (ElfW(Addr)) DL_RELOC_ADDR(pelf->loadaddr, symtab[si].st_value); - if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) { + if ((symtab[si].st_shndx != SHN_UNDEF || + symtab[si].st_value != 0) && + ELF_ST_TYPE(symtab[si].st_info) != STT_TLS && + DL_ADDR_SYM_MATCH(pelf, &symtab[si], sa, __address)) { sa = symbol_addr; sn = si; sf = 1; -- 1.5.5.6 _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
