From 974d3140577ac740c8db2f1ad9635c4ba591361e Mon Sep 17 00:00:00 2001 From: Filippo Arcidiacono Date: Fri, 6 May 2011 16:49:28 +0200 Subject: libdl: fix local symbol's address handling in dladdr Fix dladdr to correctly handle local function's address so backtrace_symbols print only the function address for these function, instead of showing the name of nearest one. Indeed the dladdr walk through the hash table to find the nearest symbol, that doesn't contain local symbols. Signed-off-by: Filippo Arcidiacono Signed-off-by: Carmelo Amoroso --- ldso/libdl/libdl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'ldso/libdl') diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 68cd5797e..b80495e71 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -1067,7 +1067,11 @@ 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(symbol_addr, &symtab[si], sa, + (ElfW(Addr)) __address)) { sa = symbol_addr; sn = si; sf = 1; @@ -1083,7 +1087,11 @@ 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(symbol_addr, &symtab[si], sa, + (ElfW(Addr)) __address)) { sa = symbol_addr; sn = si; sf = 1; -- cgit v1.2.3 From bfbab32be6d74de0717c7f5fbdd90edfd2839169 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 10 May 2011 21:22:25 +0200 Subject: ldso: commentary typo fix Signed-off-by: Bernhard Reutner-Fischer --- ldso/libdl/libdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ldso/libdl') diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index b80495e71..52c77b00a 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -672,7 +672,7 @@ void *dlsym(void *vhandle, const char *name) #if defined(USE_TLS) && USE_TLS && defined SHARED if (sym_ref.tpnt) { /* The found symbol is a thread-local storage variable. - Return the address for to the current thread. */ + Return its address for the current thread. */ ret = _dl_tls_symaddr ((struct link_map *)sym_ref.tpnt, (Elf32_Addr)ret); } #endif -- cgit v1.2.3 From 6b76a7129903ab3726ec0217349b526262bec3ac Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 14 Jun 2011 16:48:51 +0200 Subject: libdl: search for ELF_RTYPE_CLASS_DLSYM in dlsym() On FDPIC platforms, functions are passed by function descriptor, not by pointers. If you don't specify ELF_RTYPE_CLASS_DLSYM when calling _dl_find_hash() the return value from dlsym() will be a pointer not a function descriptor, crashing the program. The bug was introduced when TLS support was added in 534661b91c98492995274c364c8177c45efc63db Closes bug#3433 Signed-off-by: Bernhard Reutner-Fischer --- ldso/libdl/libdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ldso/libdl') diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 52c77b00a..f59889c99 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -667,7 +667,7 @@ void *dlsym(void *vhandle, const char *name) tpnt = NULL; if (handle == _dl_symbol_tables) tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */ - ret = _dl_find_hash(name2, handle, tpnt, 0, &sym_ref); + ret = _dl_find_hash(name2, handle, tpnt, ELF_RTYPE_CLASS_DLSYM, &sym_ref); #if defined(USE_TLS) && USE_TLS && defined SHARED if (sym_ref.tpnt) { -- cgit v1.2.3