diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2013-05-23 23:37:00 +0200 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2013-05-23 23:37:00 +0200 |
commit | f9e888643115b4b2f28853ebd1733f4410fb8839 (patch) | |
tree | 58c69f6cef623679080e8933b6c79880bfbd7cb8 /elf/dl-open.c | |
parent | d78eef6ebc008f784f501ce208bef12c6eafda27 (diff) | |
parent | b934acf0e93c5a220551ed6e686bb9d45a24a8cc (diff) |
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'elf/dl-open.c')
-rw-r--r-- | elf/dl-open.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index 385a6c1f35..201d95d1be 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -28,7 +28,6 @@ #include <sys/param.h> #include <bits/libc-lock.h> #include <ldsodefs.h> -#include <bp-sym.h> #include <caller.h> #include <sysdep-cancel.h> #include <tls.h> @@ -43,7 +42,7 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, ElfW(Word) phnum, ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv)); -weak_extern (BP_SYM (_dl_sysdep_start)) +weak_extern (_dl_sysdep_start) extern int __libc_multiple_libcs; /* Defined in init-first.c. */ @@ -166,6 +165,29 @@ add_to_global (struct link_map *new) return 0; } +/* Search link maps in all namespaces for the DSO that containes the object at + address ADDR. Returns the pointer to the link map of the matching DSO, or + NULL if a match is not found. */ +struct link_map * +internal_function +_dl_find_dso_for_object (const ElfW(Addr) addr) +{ + struct link_map *l; + + /* Find the highest-addressed object that ADDR is not below. */ + for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) + for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) + if (addr >= l->l_map_start && addr < l->l_map_end + && (l->l_contiguous + || _dl_addr_inside_object (l, (ElfW(Addr)) addr))) + { + assert (ns == l->l_ns); + return l; + } + return NULL; +} +rtld_hidden_def (_dl_find_dso_for_object); + static void dl_open_worker (void *a) { @@ -195,20 +217,11 @@ dl_open_worker (void *a) call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; #endif - struct link_map *l; - for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns) - for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) - if (caller_dlopen >= (const void *) l->l_map_start - && caller_dlopen < (const void *) l->l_map_end - && (l->l_contiguous - || _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen))) - { - assert (ns == l->l_ns); - call_map = l; - goto found_caller; - } + struct link_map *l = _dl_find_dso_for_object ((ElfW(Addr)) caller_dlopen); + + if (l) + call_map = l; - found_caller: if (args->nsid == __LM_ID_CALLER) { #ifndef SHARED |