summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'ldso')
-rw-r--r--ldso/include/dl-defs.h8
-rw-r--r--ldso/ldso/arm/dl-startup.h1
-rw-r--r--ldso/ldso/dl-elf.c3
-rw-r--r--ldso/ldso/dl-tls.c2
-rw-r--r--ldso/ldso/x86_64/dl-startup.h3
-rw-r--r--ldso/libdl/libdl.c16
6 files changed, 28 insertions, 5 deletions
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h
index d387c0bb9..11edc4dfc 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/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 <features.h>
+#include <bits/arm_asm.h>
#if !defined(__thumb__)
__asm__(
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 9e1415b83..5cf50d4ed 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -718,6 +718,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
}
}
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);
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);
}
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 83dfd0898..4ecd1c55e 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -706,12 +706,12 @@ 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->dyn->symbol_scope, tpnt, 0, &sym_ref);
+ ret = _dl_find_hash(name2, &handle->dyn->symbol_scope, tpnt, ELF_RTYPE_CLASS_DLSYM, &sym_ref);
#if defined(USE_TLS) && USE_TLS && defined SHARED
if (sym_ref.sym && (ELF_ST_TYPE(sym_ref.sym->st_info) == STT_TLS) && (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
@@ -1118,7 +1118,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;
@@ -1134,7 +1138,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;