/* Structure to describe a single list of scope elements. The lookup functions get passed an array of pointers to such structures. */ structr_scope_elem { /* Array of maps for the scope. */ structlink_map **r_list; /* Number of entries in the scope. */ unsignedint r_nlist; };
structlink_map { // ... /* Size of array allocated for 'l_scope'. */ size_t l_scope_max; /* This is an array defining the lookup scope for this link map. There are initially at most three different scope lists. */ structr_scope_elem **l_scope; // ... };
/* Storage management for the chain of loaded shared objects. Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */
// Add the new link_map `new` to the end of the namespace list. void _dl_add_to_namespace_list(struct link_map* new, Lmid_t nsid) { _dl_debug_printf( "\nadding object %s to 0x%x as global scope with namespace id %u\n\n", strlen(new->l_name) == 0 ? "<empty libname>" : new->l_name, GL(dl_ns)[nsid]._ns_loaded, nsid);
if (GL(dl_ns)[nsid]._ns_loaded != NULL) { structlink_map* l = GL(dl_ns)[nsid]._ns_loaded; while (l->l_next != NULL) l = l->l_next; new->l_prev = l; new->l_next = NULL; l->l_next = new; } else { GL(dl_ns)[nsid]._ns_loaded = new; } ++GL(dl_ns)[nsid]._ns_nloaded; new->l_serial = GL(dl_load_adds); ++GL(dl_load_adds); }
// Counter for the scopes we have to handle. int idx = 0; if (GL(dl_ns)[nsid]._ns_loaded != NULL) { // Add the global scope. new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist; _dl_debug_printf("\nassigning l_searchlist (0x%x) of 0x%x as global scope " "to l_scope[%u] of object %s\n\n", &GL(dl_ns)[nsid]._ns_loaded->l_searchlist, GL(dl_ns)[nsid]._ns_loaded, idx - 1, strlen(libname) == 0 ? "<empty libname>" : libname); }
# make LD_DEBUG=all ./main 2>&1 | grep "creating object" 2313: creating object of <empty libname> with namespace id 0 2313: creating object of <empty libname> with namespace id 0 2313: creating object of libe.so with namespace id 0 2313: creating object of libc.so.6 with namespace id 0 2313: creating object of libb.so with namespace id 0 2313: creating object of liba.so with namespace id 0
各个动态链接库都使用了 id 为 0 的 namespace 。
Scope
1 2 3 4 5 6 7
# LD_DEBUG=all ./main 2>&1 | grep -E "creating main map |assigning" 2390: creating main map at: 0x57cde190 2390: assigning l_searchlist (0x57cde450) of 0x57cde190 as global scope to l_scope[0] of object <empty libname> 2390: assigning l_searchlist (0x57cde450) of 0x57cde190 as global scope to l_scope[0] of object libe.so 2390: assigning l_searchlist (0x57cde450) of 0x57cde190 as global scope to l_scope[0] of object libc.so.6 2390: assigning l_searchlist (0x57cde450) of 0x57cde190 as global scope to l_scope[0] of object libb.so 2390: assigning l_searchlist (0x57cde450) of 0x57cde190 as global scope to l_scope[0] of object liba.so