diff options
author | Maciej W. Rozycki <macro@codesourcery.com> | 2013-06-28 16:20:26 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@codesourcery.com> | 2013-06-28 16:22:20 +0100 |
commit | f91f1c0fb89056995f1c9c6a06c361efdf5139e7 (patch) | |
tree | 67db98c499e8dbd72bc5b49e654706d375384c0f /elf/dl-support.c | |
parent | ed0257f7d3378ec4a72e297f0dcba5159f2dd138 (diff) | |
download | glibc-f91f1c0fb89056995f1c9c6a06c361efdf5139e7.tar glibc-f91f1c0fb89056995f1c9c6a06c361efdf5139e7.tar.gz glibc-f91f1c0fb89056995f1c9c6a06c361efdf5139e7.tar.bz2 glibc-f91f1c0fb89056995f1c9c6a06c361efdf5139e7.zip |
[BZ #15022] Correct global-scope dlopen issues in static executables.
This change creates a link map in static executables to serve as the
global search list for dlopen. It fixes a problem with the inability
to access the global symbol object and a crash on an attempt to map a
DSO into the global scope. Some code that has become dead after the
addition of this link map is removed too and test cases are provided.
Diffstat (limited to 'elf/dl-support.c')
-rw-r--r-- | elf/dl-support.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/elf/dl-support.c b/elf/dl-support.c index b3ab9560ad..76752f33f3 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -70,17 +70,52 @@ const char *_dl_origin_path; /* Nonzero if runtime lookup should not update the .got/.plt. */ int _dl_bind_not; +/* A dummy link map for the executable, used by dlopen to access the global + scope. We don't export any symbols ourselves, so this can be minimal. */ +static struct link_map _dl_main_map = + { + .l_name = (char *) "", + .l_real = &_dl_main_map, + .l_ns = LM_ID_BASE, + .l_libname = &(struct libname_list) { .name = "", .dont_free = 1 }, + .l_searchlist = + { + .r_list = &(struct link_map *) { &_dl_main_map }, + .r_nlist = 1, + }, + .l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } }, + .l_type = lt_executable, + .l_scope_mem = { &_dl_main_map.l_searchlist }, + .l_scope_max = (sizeof (_dl_main_map.l_scope_mem) + / sizeof (_dl_main_map.l_scope_mem[0])), + .l_scope = _dl_main_map.l_scope_mem, + .l_local_scope = { &_dl_main_map.l_searchlist }, + .l_used = 1, + .l_tls_offset = NO_TLS_OFFSET, + .l_serial = 1, + }; + /* Namespace information. */ -struct link_namespaces _dl_ns[DL_NNS]; -size_t _dl_nns; +struct link_namespaces _dl_ns[DL_NNS] = + { + [LM_ID_BASE] = + { + ._ns_loaded = &_dl_main_map, + ._ns_nloaded = 1, + ._ns_main_searchlist = &_dl_main_map.l_searchlist, + } + }; +size_t _dl_nns = 1; /* Incremented whenever something may have been added to dl_loaded. */ -unsigned long long _dl_load_adds; +unsigned long long _dl_load_adds = 1; -/* Fake scope. In dynamically linked binaries this is the scope of the - main application but here we don't have something like this. So - create a fake scope containing nothing. */ -struct r_scope_elem _dl_initial_searchlist; +/* Fake scope of the main application. */ +struct r_scope_elem _dl_initial_searchlist = + { + .r_list = &(struct link_map *) { &_dl_main_map }, + .r_nlist = 1, + }; #ifndef HAVE_INLINED_SYSCALLS /* Nonzero during startup. */ @@ -265,6 +300,8 @@ void internal_function _dl_non_dynamic_init (void) { + _dl_main_map.l_origin = _dl_get_origin (); + if (HP_TIMING_AVAIL) HP_TIMING_NOW (_dl_cpuclock_offset); |