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/include/dl-defs.h | 8 ++++++++ ldso/libdl/libdl.c | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'ldso') diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index be0a81da3..88ff81593 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(SYM_ADDR, SYM, MATCHSYM, ADDR) \ + ((ADDR) >= (SYM_ADDR) \ + && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0) \ + && (ADDR) == (SYM_ADDR)) \ + || (ADDR) < (SYM_ADDR) + (SYM)->st_size) \ + && (!(MATCHSYM) || MATCHSYM < (SYM_ADDR))) + /* 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 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') 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 08c36f4c11f5ffdcd1656802257ea472df8339e7 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Wed, 11 May 2011 20:29:59 +0200 Subject: x86_64: add TODO for R_X86_64_RELATIVE Signed-off-by: Bernhard Reutner-Fischer --- ldso/ldso/x86_64/dl-startup.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ldso') diff --git a/ldso/ldso/x86_64/dl-startup.h b/ldso/ldso/x86_64/dl-startup.h index 7e05846dd..b2ea93db7 100644 --- a/ldso/ldso/x86_64/dl-startup.h +++ b/ldso/ldso/x86_64/dl-startup.h @@ -58,6 +58,9 @@ void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr, case R_X86_64_TPOFF64: *reloc_addr = sym->st_value + rpnt->r_addend - symbol_addr; break; +/*TODO: case R_X86_64_RELATIVE: + *reloc_addr = load_addr + rpnt->r_addend; + break; */ default: _dl_exit(1); } -- cgit v1.2.3 From 8514218c136c9a21a5ed4f123d2c49f21ef86947 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 26 May 2011 18:15:06 +0200 Subject: Correct a bug when remapping textrel segments on nommu From: Alan Davis On C6X, when trying to execute a program that has a textrel DSO, it fails to load. The telltale line in the LD_DEBUG output is: _dl_get_ready_to_run:779: file=''; needed by './a.out' The corresponding DT_NEEDED entry has 'libc.so.0', but here the filename is empty. This is what is happening in _dl_elf_shared_library(): First, map all segments according to their permissions. Text gets initially mapped read-only. Then, parse the dynamic information. The dynamic table is in RW but some of the tags may point to RO. For example, DT_NEEDED points to a string in .dynstr which is in RO. These pointers get computed according to the loadmap from the original mapping. Then, in response to a DT_TEXTREL tag, the RO segment gets remapped, thereby invaliding anything that points to it, in particular certain dynamic tags such as DT_NEEDED. The following patch re-parses the dynamic info after the remapping so as to re-compute any invalid pointers. Signed-off-by: Alan Davis Signed-off-by: Bernd Schmidt --- ldso/ldso/dl-elf.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ldso') diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 7b5d75146..09b3aaf01 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -714,6 +714,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, DL_UPDATE_LOADADDR_HDR(lib_loadaddr, new_addr + (ppnt->p_vaddr & ADDR_ALIGN), ppnt); + /* This has invalidated all pointers into the previously readonly segment. + Update any them to point into the remapped segment. */ + _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr); #endif } } -- cgit v1.2.3 From 3862c65a05983b2b18cb7884a124a905828f7a18 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Sun, 9 Jan 2011 01:45:08 +0100 Subject: ARM: #include where __USE_BX__ is used The check for __USE_BX__ will be available in bits/arm_asm.h, so the latter must be included wherever the former is used. Signed-off-by: "Yann E. MORIN" Cc: Khem Raj Cc: Bernhard Reutner-Fischer Cc: Carmelo AMOROSO Signed-off-by: Khem Raj --- ldso/ldso/arm/dl-startup.h | 1 + 1 file changed, 1 insertion(+) (limited to 'ldso') diff --git a/ldso/ldso/arm/dl-startup.h b/ldso/ldso/arm/dl-startup.h index a95389d98..2dfdaffda 100644 --- a/ldso/ldso/arm/dl-startup.h +++ b/ldso/ldso/arm/dl-startup.h @@ -7,6 +7,7 @@ */ #include +#include #if !defined(__thumb__) __asm__( -- 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') 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 From c2eaaf39dc68e5d2acc4fbae95d815c85dd5a4fb Mon Sep 17 00:00:00 2001 From: Carmelo Amoroso Date: Mon, 13 Jun 2011 19:58:22 +0200 Subject: ldso_tls: fix compiler warning due to missing cast Fix compiler warning (as below) due to missign cast In file included from ldso/ldso/ldso.c:42:0: ldso/ldso/dl-tls.c: In function 'init_tls': ldso/ldso/dl-tls.c:1028:24: error: initialization makes pointer from integer without a cast Signed-off-by: Carmelo Amoroso --- ldso/ldso/dl-tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ldso') diff --git a/ldso/ldso/dl-tls.c b/ldso/ldso/dl-tls.c index 43dd5a00a..362efbbec 100644 --- a/ldso/ldso/dl-tls.c +++ b/ldso/ldso/dl-tls.c @@ -1025,7 +1025,7 @@ init_tls (void) /* And finally install it for the main thread. If ld.so itself uses TLS we know the thread pointer was initialized earlier. */ - const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD); + const char *lossage = (char *)TLS_INIT_TP (tcbp, USE___THREAD); if(__builtin_expect (lossage != NULL, 0)) { _dl_debug_early("cannot set up thread-local storage: %s\n", lossage); _dl_exit(30); -- cgit v1.2.3