From d6b5d570a3255d8dc80e07c3674594574cd98fe7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 31 Jan 2002 03:41:25 +0000 Subject: Update. 2002-01-30 Ulrich Drepper * Versions.def [ld]: Add GLIBC_2.3. * elf/dl-addr.c: Move global variables for SHARED code in struct _rtld_global. Export this struct, remove all exports for the signal variables. * elf/dl-close.c: Likewise. * elf/dl-conflict.c: Likewise. * elf/dl-debug.c: Likewise. * elf/dl-deps.c: Likewise. * elf/dl-dst.h: Likewise. * elf/dl-error.c: Likewise. * elf/dl-fini.c: Likewise. * elf/dl-init.c: Likewise. * elf/dl-iteratephdr.c: Likewise. * elf/dl-libc.c: Likewise. * elf/dl-load.c: Likewise. * elf/dl-lookup.c: Likewise. * elf/dl-minimal.c: Likewise. * elf/dl-object.c: Likewise. * elf/dl-open.c: Likewise. * elf/dl-profile.c: Likewise. * elf/dl-profstub.c: Likewise. * elf/dl-reloc.c: Likewise. * elf/dl-runtime.c: Likewise. * elf/dl-support.c: Likewise. * elf/dl-sym.c: Likewise. * elf/dl-version.c: Likewise. * elf/do-lookup.h: Likewise. * elf/do-rel.h: Likewise. * elf/dynamic-link.h: Likewise. * elf/rtld.c: Likewise. * sysdeps/generic/dl-cache.c: Likewise. * sysdeps/generic/dl-sysdep.c: Likewise. * sysdeps/generic/ldsodefs.h: Likewise. * sysdeps/generic/libc-start.c: Likewise. * sysdeps/i386/dl-machine.h: Likewise. * sysdeps/ia64/dl-fptr.c: Likewise. * sysdeps/ia64/dl-machine.h: Likewise. * sysdeps/unix/sysv/linux/dl-librecon.h: Likewise. * sysdeps/unix/sysv/linux/dl-origin.c: Likewise. * sysdeps/unix/sysv/linux/dl-osinfo.h: Likewise. * sysdeps/unix/sysv/linux/getclktck.c: Likewise. * sysdeps/unix/sysv/linux/getpagesize.c: Likewise. * sysdeps/unix/sysv/linux/i386/dl-librecon.h: Likewise. * sysdeps/unix/sysv/linux/ia64/dl-static.c: Likewise. * sysdeps/unix/sysv/linux/ia64/getpagesize.c: Likewise. * malloc/thread-m.h: Spinlock definitions for x86/x86_64. --- ChangeLog | 49 +++++ Versions.def | 1 + elf/Versions | 27 ++- elf/dl-addr.c | 4 +- elf/dl-close.c | 32 +-- elf/dl-conflict.c | 27 +-- elf/dl-debug.c | 4 +- elf/dl-deps.c | 20 +- elf/dl-dst.h | 4 +- elf/dl-error.c | 2 +- elf/dl-fini.c | 20 +- elf/dl-init.c | 15 +- elf/dl-iteratephdr.c | 4 +- elf/dl-libc.c | 8 +- elf/dl-load.c | 98 ++++----- elf/dl-lookup.c | 33 ++- elf/dl-minimal.c | 9 +- elf/dl-object.c | 12 +- elf/dl-open.c | 52 +++-- elf/dl-profile.c | 23 ++- elf/dl-profstub.c | 6 +- elf/dl-reloc.c | 18 +- elf/dl-runtime.c | 6 +- elf/dl-support.c | 29 ++- elf/dl-sym.c | 26 +-- elf/dl-version.c | 17 +- elf/do-lookup.h | 4 +- elf/do-rel.h | 8 +- elf/dynamic-link.h | 7 +- elf/rtld.c | 320 ++++++++++++++--------------- malloc/thread-m.h | 61 +++++- sysdeps/generic/dl-cache.c | 17 +- sysdeps/generic/dl-sysdep.c | 29 +-- sysdeps/generic/ldsodefs.h | 168 +++++++++------ sysdeps/generic/libc-start.c | 6 +- sysdeps/i386/dl-machine.h | 18 +- sysdeps/ia64/dl-fptr.c | 5 +- sysdeps/ia64/dl-machine.h | 8 +- sysdeps/unix/sysv/linux/dl-librecon.h | 2 +- sysdeps/unix/sysv/linux/dl-origin.c | 9 +- sysdeps/unix/sysv/linux/dl-osinfo.h | 4 +- sysdeps/unix/sysv/linux/getclktck.c | 8 +- sysdeps/unix/sysv/linux/getpagesize.c | 10 +- sysdeps/unix/sysv/linux/i386/dl-librecon.h | 12 +- sysdeps/unix/sysv/linux/ia64/dl-static.c | 4 +- sysdeps/unix/sysv/linux/ia64/getpagesize.c | 7 +- 46 files changed, 680 insertions(+), 573 deletions(-) diff --git a/ChangeLog b/ChangeLog index e99d50a971..7edb033730 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +2002-01-30 Ulrich Drepper + + * Versions.def [ld]: Add GLIBC_2.3. + * elf/dl-addr.c: Move global variables for SHARED code in struct + _rtld_global. Export this struct, remove all exports for the + signal variables. + * elf/dl-close.c: Likewise. + * elf/dl-conflict.c: Likewise. + * elf/dl-debug.c: Likewise. + * elf/dl-deps.c: Likewise. + * elf/dl-dst.h: Likewise. + * elf/dl-error.c: Likewise. + * elf/dl-fini.c: Likewise. + * elf/dl-init.c: Likewise. + * elf/dl-iteratephdr.c: Likewise. + * elf/dl-libc.c: Likewise. + * elf/dl-load.c: Likewise. + * elf/dl-lookup.c: Likewise. + * elf/dl-minimal.c: Likewise. + * elf/dl-object.c: Likewise. + * elf/dl-open.c: Likewise. + * elf/dl-profile.c: Likewise. + * elf/dl-profstub.c: Likewise. + * elf/dl-reloc.c: Likewise. + * elf/dl-runtime.c: Likewise. + * elf/dl-support.c: Likewise. + * elf/dl-sym.c: Likewise. + * elf/dl-version.c: Likewise. + * elf/do-lookup.h: Likewise. + * elf/do-rel.h: Likewise. + * elf/dynamic-link.h: Likewise. + * elf/rtld.c: Likewise. + * sysdeps/generic/dl-cache.c: Likewise. + * sysdeps/generic/dl-sysdep.c: Likewise. + * sysdeps/generic/ldsodefs.h: Likewise. + * sysdeps/generic/libc-start.c: Likewise. + * sysdeps/i386/dl-machine.h: Likewise. + * sysdeps/ia64/dl-fptr.c: Likewise. + * sysdeps/ia64/dl-machine.h: Likewise. + * sysdeps/unix/sysv/linux/dl-librecon.h: Likewise. + * sysdeps/unix/sysv/linux/dl-origin.c: Likewise. + * sysdeps/unix/sysv/linux/dl-osinfo.h: Likewise. + * sysdeps/unix/sysv/linux/getclktck.c: Likewise. + * sysdeps/unix/sysv/linux/getpagesize.c: Likewise. + * sysdeps/unix/sysv/linux/i386/dl-librecon.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/dl-static.c: Likewise. + * sysdeps/unix/sysv/linux/ia64/getpagesize.c: Likewise. + 2002-01-29 Ulrich Drepper * sysdeps/ia64/dl-lookupcfg.h (DL_AUTO_FUNCTION_ADDRESS): Add cast @@ -33,6 +81,7 @@ * malloc/malloc.c: Rewrite, adapted from Doug Lea's malloc-2.7.0.c. * malloc/malloc.h: Likewise. + * malloc/thread-m.h: Spinlock definitions for x86/x86_64. * malloc/arena.c: New file. * malloc/hooks.c: New file. * malloc/tst-mallocstate.c: New file. diff --git a/Versions.def b/Versions.def index a5829cf98c..e89a34cf90 100644 --- a/Versions.def +++ b/Versions.def @@ -97,6 +97,7 @@ ld { GLIBC_2.2 GLIBC_2.2.1 GLIBC_2.2.3 + GLIBC_2.3 } libthread_db { GLIBC_2.1.3 diff --git a/elf/Versions b/elf/Versions index 0c3480450f..5c8da22843 100644 --- a/elf/Versions +++ b/elf/Versions @@ -35,12 +35,12 @@ ld { # Those are in the dynamic linker, but used by libc.so. __libc_enable_secure; _dl_catch_error; _dl_check_all_versions; - _dl_debug_initialize; _dl_debug_state; _dl_default_scope; - _dl_global_scope_end; _dl_lookup_symbol; + _dl_debug_initialize; _dl_debug_state; + _dl_lookup_symbol; _dl_map_object; _dl_map_object_deps; _dl_object_relocation_scope; _dl_relocate_object; _dl_signal_error; _dl_starting_up; _dl_sysdep_start; _r_debug; - _dl_global_scope; _dl_lookup_symbol_skip; + _dl_lookup_symbol_skip; _dl_lookup_versioned_symbol; _dl_lookup_versioned_symbol_skip; # Function from libc.so which must be shared with libc. @@ -48,31 +48,28 @@ ld { } GLIBC_2.1 { # global variables - _dl_profile; _dl_profile_map; _dl_profile_output; _dl_start_profile; - _dl_loaded; _dl_main_searchlist; _dl_fpu_control; _dl_initial_searchlist; - _dl_global_scope_alloc; __libc_stack_end; + _dl_fpu_control; __libc_stack_end; # functions used in other libraries - _dl_mcount; _dl_unload_cache; + _dl_start_profile; _dl_mcount; _dl_unload_cache; } GLIBC_2.1.1 { # global variables - _dl_lazy; _dl_origin_path; _dl_platformlen; + _dl_lazy; # functions used in other libraries _dl_dst_count; _dl_dst_substitute; } GLIBC_2.2 { - _dl_init; _dl_load_lock; _dl_argv; _dl_nloaded; _dl_check_map_versions; - - # this is defined in ld.so and overridden by libc - _dl_init_first; + _dl_init; _dl_load_lock; _dl_argv; _dl_check_map_versions; # variables used elsewhere - _dl_out_of_memory; _dl_all_dirs; _dl_init_all_dirs; - _dl_clktck; _dl_pagesize; + _dl_out_of_memory; } GLIBC_2.2.3 { - _dl_debug_mask; _dl_debug_printf; + _dl_debug_printf; + } + GLIBC_2.3 { + _rtld_global; } } diff --git a/elf/dl-addr.c b/elf/dl-addr.c index ebb62858e6..59f1a430b5 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -1,5 +1,5 @@ /* Locate the shared object symbol nearest a given address. - Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1996-2000, 2001, 2002 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 @@ -34,7 +34,7 @@ _dl_addr (const void *address, Dl_info *info) /* Find the highest-addressed object that ADDRESS is not below. */ match = NULL; - for (l = _dl_loaded; l; l = l->l_next) + for (l = GL(dl_loaded); l; l = l->l_next) if (addr >= l->l_map_start && addr < l->l_map_end) { /* We know ADDRESS lies within L if in any shared object. diff --git a/elf/dl-close.c b/elf/dl-close.c index de4b91ac03..cece96b7fb 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -1,5 +1,5 @@ /* Close a shared object opened by `_dl_open'. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2002 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 @@ -63,7 +63,7 @@ _dl_close (void *_map) if (map->l_opencount > 1 || map->l_type != lt_loaded) { /* There are still references to this object. Do nothing more. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf ("\nclosing file=%s; opencount == %u\n", map->l_name, map->l_opencount); @@ -125,7 +125,7 @@ _dl_close (void *_map) && imap->l_init_called) { /* When debugging print a message first. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ncalling fini: %s\n\n", imap->l_name); /* Call its termination function. */ @@ -192,18 +192,18 @@ _dl_close (void *_map) if (__builtin_expect (imap->l_global, 0)) { /* This object is in the global scope list. Remove it. */ - unsigned int cnt = _dl_main_searchlist->r_nlist; + unsigned int cnt = GL(dl_main_searchlist)->r_nlist; do --cnt; - while (_dl_main_searchlist->r_list[cnt] != imap); + while (GL(dl_main_searchlist)->r_list[cnt] != imap); /* The object was already correctly registered. */ - while (++cnt < _dl_main_searchlist->r_nlist) - _dl_main_searchlist->r_list[cnt - 1] - = _dl_main_searchlist->r_list[cnt]; + while (++cnt < GL(dl_main_searchlist)->r_nlist) + GL(dl_main_searchlist)->r_list[cnt - 1] + = GL(dl_main_searchlist)->r_list[cnt]; - --_dl_main_searchlist->r_nlist; + --GL(dl_main_searchlist)->r_nlist; } /* We can unmap all the maps at once. We determined the @@ -221,9 +221,9 @@ _dl_close (void *_map) if (imap->l_prev != NULL) imap->l_prev->l_next = imap->l_next; else - _dl_loaded = imap->l_next; + GL(dl_loaded) = imap->l_next; #endif - --_dl_nloaded; + --GL(dl_nloaded); if (imap->l_next) imap->l_next->l_prev = imap->l_prev; @@ -305,17 +305,17 @@ _dl_close (void *_map) static void free_mem (void) { - if (__builtin_expect (_dl_global_scope_alloc, 0) != 0 - && _dl_main_searchlist->r_nlist == _dl_initial_searchlist.r_nlist) + if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0 + && GL(dl_main_searchlist)->r_nlist == GL(dl_initial_searchlist).r_nlist) { /* All object dynamically loaded by the program are unloaded. Free the memory allocated for the global scope variable. */ - struct link_map **old = _dl_main_searchlist->r_list; + struct link_map **old = GL(dl_main_searchlist)->r_list; /* Put the old map in. */ - _dl_main_searchlist->r_list = _dl_initial_searchlist.r_list; + GL(dl_main_searchlist)->r_list = GL(dl_initial_searchlist).r_list; /* Signal that the original map is used. */ - _dl_global_scope_alloc = 0; + GL(dl_global_scope_alloc) = 0; /* Now free the old map. */ free (old); diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c index 0f863ac893..3e88e54021 100644 --- a/elf/dl-conflict.c +++ b/elf/dl-conflict.c @@ -1,5 +1,5 @@ /* Resolve conflicts against already prelinked libraries. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2001. @@ -28,13 +28,12 @@ #include #include "dynamic-link.h" -extern unsigned long int _dl_num_cache_relocations; /* in dl-lookup.c */ void _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, ElfW(Rela) *conflictend) { - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_RELOC, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_RELOC, 0)) _dl_printf ("\nconflict processing: %s\n", l->l_name[0] ? l->l_name : _dl_argv[0]); @@ -45,25 +44,21 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ #define RESOLVE_MAP(ref, version, flags) (*ref = NULL, 0) #define RESOLVE(ref, version, flags) (*ref = NULL, 0) -#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ -do \ - { \ - while ((resolve_conflict_map->l_map_end \ - < (ElfW(Addr))(r_offset)) \ - || (resolve_conflict_map->l_map_start \ - > (ElfW(Addr))(r_offset))) \ - resolve_conflict_map \ - = resolve_conflict_map->l_next; \ - (map) = resolve_conflict_map; \ +#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ + do { \ + while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \ + || (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \ + resolve_conflict_map = resolve_conflict_map->l_next; \ + \ + (map) = resolve_conflict_map; \ } while (0) struct link_map *resolve_conflict_map __attribute__ ((__unused__)) - = _dl_loaded; - + = GL(dl_loaded); #include "dynamic-link.h" - _dl_num_cache_relocations += conflictend - conflict; + GL(dl_num_cache_relocations) += conflictend - conflict; for (; conflict < conflictend; ++conflict) elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset); diff --git a/elf/dl-debug.c b/elf/dl-debug.c index 5a51b53357..4e8197227e 100644 --- a/elf/dl-debug.c +++ b/elf/dl-debug.c @@ -1,5 +1,5 @@ /* Communicate dynamic linker state to the debugger at runtime. - Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1998, 2000, 2002 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 @@ -39,7 +39,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase) /* Tell the debugger where to find the map of loaded objects. */ _r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; _r_debug.r_ldbase = ldbase; - _r_debug.r_map = _dl_loaded; + _r_debug.r_map = GL(dl_loaded); _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state; } diff --git a/elf/dl-deps.c b/elf/dl-deps.c index af39de1023..368ad2d557 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -1,5 +1,5 @@ /* Load the dependencies of a mapped object. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2002 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 @@ -39,12 +39,6 @@ #define FILTERTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ + DT_EXTRATAGIDX (DT_FILTER)) -/* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ -size_t _dl_global_scope_alloc; - -extern size_t _dl_platformlen; /* When loading auxiliary objects we must ignore errors. It's ok if an object is missing. */ @@ -131,7 +125,7 @@ empty dynamics string token substitution")); \ else \ { \ /* This is for DT_AUXILIARY. */ \ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) \ + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) \ _dl_debug_printf ("cannot load auxiliary `%s' because of" \ "empty dynamic string token " \ "substitution\n", __str); \ @@ -294,7 +288,8 @@ _dl_map_object_deps (struct link_map *map, int err; /* Say that we are about to load an auxiliary library. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, + 0)) _dl_debug_printf ("load auxiliary object=%s" " requested by file=%s\n", name, l->l_name[0] @@ -320,7 +315,8 @@ _dl_map_object_deps (struct link_map *map, int err; /* Say that we are about to load an auxiliary library. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, + 0)) _dl_debug_printf ("load filtered object=%s" " requested by file=%s\n", name, l->l_name[0] @@ -507,8 +503,8 @@ _dl_map_object_deps (struct link_map *map, runp->map->l_reserved = 0; } - if (__builtin_expect(_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0 - && map == _dl_loaded) + if (__builtin_expect(GL(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 + && map == GL(dl_loaded)) { /* If we are to compute conflicts, we have to build local scope for each library, not just the ultimate loader. */ diff --git a/elf/dl-dst.h b/elf/dl-dst.h index 2ebd4d9636..af4a94a3b3 100644 --- a/elf/dl-dst.h +++ b/elf/dl-dst.h @@ -1,5 +1,5 @@ /* Handling of dynamic sring tokens. - Copyright (C) 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2002 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 @@ -57,7 +57,7 @@ extern size_t _dl_dst_count (const char *name, int is_path); else \ origin_len = (l)->l_origin == (char *) -1 ? 0 : strlen ((l)->l_origin); \ \ - __len + cnt * (MAX (origin_len, _dl_platformlen) - 7); }) + __len + cnt * (MAX (origin_len, GL(dl_platformlen)) - 7); }) /* Find origin of the executable. */ extern const char *_dl_get_origin (void); diff --git a/elf/dl-error.c b/elf/dl-error.c index be9a84361c..922de5caeb 100644 --- a/elf/dl-error.c +++ b/elf/dl-error.c @@ -1,5 +1,5 @@ /* Error handling for runtime dynamic linker. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 diff --git a/elf/dl-fini.c b/elf/dl-fini.c index fc4f4b68a6..e8533a471c 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -1,5 +1,5 @@ /* Call the termination functions of loaded shared objects. - Copyright (C) 1995,96,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,98,99,2000,2001,2002 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 @@ -47,15 +47,15 @@ _dl_fini (void) struct link_map **maps; /* XXX Could it be (in static binaries) that there is no object loaded? */ - assert (_dl_nloaded > 0); + assert (GL(dl_nloaded) > 0); /* Now we can allocate an array to hold all the pointers and copy the pointers in. */ - maps = (struct link_map **) alloca (_dl_nloaded + maps = (struct link_map **) alloca (GL(dl_nloaded) * sizeof (struct link_map *)); - for (l = _dl_loaded, i = 0; l != NULL; l = l->l_next) + for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next) { - assert (i < _dl_nloaded); + assert (i < GL(dl_nloaded)); maps[i++] = l; @@ -63,10 +63,10 @@ _dl_fini (void) from underneath us. */ ++l->l_opencount; } - assert (i == _dl_nloaded); + assert (i == GL(dl_nloaded)); /* Now we have to do the sorting. */ - for (l = _dl_loaded->l_next; l != NULL; l = l->l_next) + for (l = GL(dl_loaded)->l_next; l != NULL; l = l->l_next) { unsigned int j; unsigned int k; @@ -77,7 +77,7 @@ _dl_fini (void) /* Find all object for which the current one is a dependency and move the found object (if necessary) in front. */ - for (k = j + 1; k < _dl_nloaded; ++k) + for (k = j + 1; k < GL(dl_nloaded); ++k) { struct link_map **runp; @@ -128,7 +128,7 @@ _dl_fini (void) /* `maps' now contains the objects in the right order. Now call the destructors. We have to process this array from the front. */ - for (i = 0; i < _dl_nloaded; ++i) + for (i = 0; i < GL(dl_nloaded); ++i) { l = maps[i]; @@ -146,7 +146,7 @@ _dl_fini (void) continue; /* When debugging print a message first. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ncalling fini: %s\n\n", l->l_name[0] ? l->l_name : _dl_argv[0]); diff --git a/elf/dl-init.c b/elf/dl-init.c index 5448b03c33..700efc58e5 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -1,5 +1,5 @@ /* Return the next shared object initializer function not yet run. - Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1998-2001, 2002 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 @@ -27,9 +27,6 @@ typedef void (*init_t) (int, char **, char **); /* Flag, nonzero during startup phase. */ extern int _dl_starting_up; -/* The object to be initialized first. */ -extern struct link_map *_dl_initfirst; - static void call_init (struct link_map *l, int argc, char **argv, char **env) @@ -53,7 +50,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env) return; /* Print a debug message if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ncalling init: %s\n\n", l->l_name[0] ? l->l_name : _dl_argv[0]); @@ -95,10 +92,10 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) struct r_debug *r; unsigned int i; - if (__builtin_expect (_dl_initfirst != NULL, 0)) + if (__builtin_expect (GL(dl_initfirst) != NULL, 0)) { - call_init (_dl_initfirst, argc, argv, env); - _dl_initfirst = NULL; + call_init (GL(dl_initfirst), argc, argv, env); + GL(dl_initfirst) = NULL; } /* Don't do anything if there is no preinit array. */ @@ -108,7 +105,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) ElfW(Addr) *addrs; unsigned int cnt; - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ncalling preinit: %s\n\n", main_map->l_name[0] ? main_map->l_name : _dl_argv[0]); diff --git a/elf/dl-iteratephdr.c b/elf/dl-iteratephdr.c index ff11ce5bff..e2a5d2a753 100644 --- a/elf/dl-iteratephdr.c +++ b/elf/dl-iteratephdr.c @@ -1,5 +1,5 @@ /* Get loaded objects program headers. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2001. @@ -34,7 +34,7 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, /* Make sure we are alone. */ __libc_lock_lock_recursive (_dl_load_lock); - for (l = _dl_loaded; l != NULL; l = l->l_next) + for (l = GL(dl_loaded); l != NULL; l = l->l_next) { /* Skip the dynamic linker. */ if (l->l_phdr == NULL) diff --git a/elf/dl-libc.c b/elf/dl-libc.c index c83448df77..bb32f697e1 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -1,5 +1,5 @@ /* Handle loading and unloading shared objects for internal libc purposes. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Zack Weinberg , 1999. @@ -129,8 +129,8 @@ free_mem (void) struct r_search_path_elem *d; /* Remove all search directories. */ - d = _dl_all_dirs; - while (d != _dl_init_all_dirs) + d = GL(dl_all_dirs); + while (d != GL(dl_init_all_dirs)) { struct r_search_path_elem *old = d; d = d->next; @@ -138,7 +138,7 @@ free_mem (void) } /* Remove all additional names added to the objects. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) + for (l = GL(dl_loaded); l != NULL; l = l->l_next) { struct libname_list *lnp = l->l_libname->next; diff --git a/elf/dl-load.c b/elf/dl-load.c index b66e7fee1d..cd568d2261 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -111,18 +111,6 @@ struct filebuf char buf[1024]; }; -size_t _dl_pagesize; - -unsigned int _dl_osversion; - -int _dl_clktck; - -extern const char *_dl_platform; -extern size_t _dl_platformlen; - -/* The object to be initialized first. */ -struct link_map *_dl_initfirst; - /* This is the decomposed LD_LIBRARY_PATH search path. */ static struct r_search_path_struct env_path_list; @@ -240,7 +228,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, repl = l->l_origin; else if ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, 0)) != 0) - repl = _dl_platform; + repl = GL(dl_platform); if (repl != NULL && repl != (const char *) -1) { @@ -344,12 +332,6 @@ add_name_to_object (struct link_map *l, const char *name) lastp->next = newname; } -/* All known directories in sorted order. */ -struct r_search_path_elem *_dl_all_dirs; - -/* All directories after startup. */ -struct r_search_path_elem *_dl_init_all_dirs; - /* Standard search directories. */ static struct r_search_path_struct rtld_search_dirs; @@ -413,7 +395,7 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, } /* See if this directory is already known. */ - for (dirp = _dl_all_dirs; dirp != NULL; dirp = dirp->next) + for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next) if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0) break; @@ -460,13 +442,13 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, dirp->what = what; if (__builtin_expect (where != NULL, 1)) dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1 - + ncapstr * sizeof (enum r_dir_status), + + (ncapstr * sizeof (enum r_dir_status)), where, where_len); else dirp->where = NULL; - dirp->next = _dl_all_dirs; - _dl_all_dirs = dirp; + dirp->next = GL(dl_all_dirs); + GL(dl_all_dirs) = dirp; /* Put it in the result array. */ result[nelems++] = dirp; @@ -496,13 +478,14 @@ decompose_rpath (struct r_search_path_struct *sps, /* First see whether we must forget the RUNPATH and RPATH from this object. */ - if (__builtin_expect (_dl_inhibit_rpath != NULL, 0) && !__libc_enable_secure) + if (__builtin_expect (GL(dl_inhibit_rpath) != NULL, 0) + && !__libc_enable_secure) { - const char *found = strstr (_dl_inhibit_rpath, where); + const char *found = strstr (GL(dl_inhibit_rpath), where); if (found != NULL) { size_t len = strlen (where); - if ((found == _dl_inhibit_rpath || found[-1] == ':') + if ((found == GL(dl_inhibit_rpath) || found[-1] == ':') && (found[len] == '\0' || found[len] == ':')) { /* This object is on the list of objects for which the @@ -579,7 +562,7 @@ _dl_init_paths (const char *llp) directories addressed by the LD_LIBRARY_PATH environment variable. */ /* Get the capabilities. */ - capstr = _dl_important_hwcaps (_dl_platform, _dl_platformlen, + capstr = _dl_important_hwcaps (GL(dl_platform), GL(dl_platformlen), &ncapstr, &max_capstrlen); /* First set up the rest of the default search directory entries. */ @@ -606,7 +589,7 @@ _dl_init_paths (const char *llp) } rtld_search_dirs.malloced = 0; - pelem = _dl_all_dirs = rtld_search_dirs.dirs[0]; + pelem = GL(dl_all_dirs) = rtld_search_dirs.dirs[0]; strp = system_dirs; idx = 0; @@ -639,7 +622,7 @@ _dl_init_paths (const char *llp) #ifdef SHARED /* This points to the map of the main object. */ - l = _dl_loaded; + l = GL(dl_loaded); if (l != NULL) { assert (l->l_type != lt_loaded); @@ -715,7 +698,7 @@ _dl_init_paths (const char *llp) env_path_list.dirs = (void *) -1; /* Remember the last search directory added at startup. */ - _dl_init_all_dirs = _dl_all_dirs; + GL(dl_init_all_dirs) = GL(dl_all_dirs); } @@ -746,11 +729,11 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, #ifndef SHARED if (l->l_prev == NULL) /* No other module loaded. */ - _dl_loaded = NULL; + GL(dl_loaded) = NULL; else #endif l->l_prev->l_next = NULL; - --_dl_nloaded; + --GL(dl_nloaded); free (l); } free (realname); @@ -791,7 +774,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, } /* Look again to see if the real name matched another already loaded. */ - for (l = _dl_loaded; l; l = l->l_next) + for (l = GL(dl_loaded); l; l = l->l_next) if (l->l_ino == st.st_ino && l->l_dev == st.st_dev) { /* The object is already loaded. @@ -812,7 +795,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, return NULL; /* Print debugging message. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf ("file=%s; generating link map\n", name); /* This is the ELF header. We read it in `open_verify'. */ @@ -892,7 +875,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, case PT_LOAD: /* A load command tells us to map in part of the file. We record the load commands and process them all later. */ - if ((ph->p_align & (_dl_pagesize - 1)) != 0) + if ((ph->p_align & (GL(dl_pagesize) - 1)) != 0) { errstring = N_("ELF load command alignment not page-aligned"); goto call_lose; @@ -907,8 +890,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, { struct loadcmd *c = &loadcmds[nloadcmds++]; c->mapstart = ph->p_vaddr & ~(ph->p_align - 1); - c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); + c->mapend = ((ph->p_vaddr + ph->p_filesz + GL(dl_pagesize) - 1) + & ~(GL(dl_pagesize) - 1)); c->dataend = ph->p_vaddr + ph->p_filesz; c->allocend = ph->p_vaddr + ph->p_memsz; c->mapoff = ph->p_offset & ~(ph->p_align - 1); @@ -1023,7 +1006,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, zero = l->l_addr + c->dataend; zeroend = l->l_addr + c->allocend; - zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1); + zeropage = ((zero + GL(dl_pagesize) - 1) + & ~(GL(dl_pagesize) - 1)); if (zeroend < zeropage) /* All the extra data is in the last page of the segment. @@ -1036,8 +1020,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, if ((c->prot & PROT_WRITE) == 0) { /* Dag nab it. */ - if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), - _dl_pagesize, c->prot|PROT_WRITE) < 0) + if (__mprotect ((caddr_t) (zero & ~(GL(dl_pagesize) - 1)), + GL(dl_pagesize), c->prot|PROT_WRITE) < 0) { errstring = N_("cannot change memory protections"); goto call_lose_errno; @@ -1045,8 +1029,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, } memset ((void *) zero, '\0', zeropage - zero); if ((c->prot & PROT_WRITE) == 0) - __mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), - _dl_pagesize, c->prot); + __mprotect ((caddr_t) (zero & ~(GL(dl_pagesize) - 1)), + GL(dl_pagesize), c->prot); } if (zeroend > zeropage) @@ -1110,7 +1094,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, l->l_entry += l->l_addr; - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf (" dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n" " entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n", (int) sizeof (void *) * 2, (unsigned long int) l->l_ld, @@ -1176,7 +1160,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, /* Remember whether this object must be initialized first. */ if (l->l_flags_1 & DF_1_INITFIRST) - _dl_initfirst = l; + GL(dl_initfirst) = l; /* Finally the file information. */ l->l_dev = st.st_dev; @@ -1397,7 +1381,7 @@ open_verify (const char *name, struct filebuf *fbp) + (abi_note[6] & 0xff) * 256 + (abi_note[7] & 0xff); if (abi_note[4] != __ABI_TAG_OS - || (_dl_osversion && _dl_osversion < osversion)) + || (GL(dl_osversion) && GL(dl_osversion) < osversion)) { close_and_out: __close (fd); @@ -1442,7 +1426,7 @@ open_path (const char *name, size_t namelen, int preloaded, /* If we are debugging the search for libraries print the path now if it hasn't happened now. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0) && current_what != this_dir->what) { current_what = this_dir->what; @@ -1457,13 +1441,13 @@ open_path (const char *name, size_t namelen, int preloaded, continue; buflen = - ((char *) __mempcpy (__mempcpy (edp, - capstr[cnt].str, capstr[cnt].len), + ((char *) __mempcpy (__mempcpy (edp, capstr[cnt].str, + capstr[cnt].len), name, namelen) - buf); /* Print name we try if this is wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf (" trying file=%s\n", buf); fd = open_verify (buf, fbp); @@ -1566,7 +1550,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, struct filebuf fb; /* Look for this name among those already loaded. */ - for (l = _dl_loaded; l; l = l->l_next) + for (l = GL(dl_loaded); l; l = l->l_next) { /* If the requested name matches the soname of a loaded object, use that object. Elide this check for names that have not @@ -1596,7 +1580,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, } /* Display information if we are debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0) && loader != NULL) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0) && loader != NULL) _dl_debug_printf ("\nfile=%s; needed by %s\n", name, loader->l_name[0] ? loader->l_name : _dl_argv[0]); @@ -1606,7 +1590,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, size_t namelen = strlen (name) + 1; - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf ("find library=%s; searching\n", name); fd = -1; @@ -1644,7 +1628,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, /* If dynamically linked, try the DT_RPATH of the executable itself. */ - l = _dl_loaded; + l = GL(dl_loaded); if (fd == -1 && l && l->l_type != lt_loaded && l != loader && l->l_rpath_dirs.dirs != (void *) -1) fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, @@ -1698,7 +1682,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if (cached != NULL) { #ifdef SHARED - l = loader ?: _dl_loaded; + l = loader ?: GL(dl_loaded); #else l = loader; #endif @@ -1748,14 +1732,14 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, /* Finally, try the default path. */ if (fd == -1 - && ((l = loader ?: _dl_loaded) == NULL + && ((l = loader ?: GL(dl_loaded)) == NULL || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) && rtld_search_dirs.dirs != (void *) -1) fd = open_path (name, namelen, preloaded, &rtld_search_dirs, &realname, &fb); /* Add another newline when we a tracing the library loading. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf ("\n"); } else @@ -1777,7 +1761,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if (__builtin_expect (fd, 0) == -1) { if (trace_mode - && __builtin_expect (_dl_debug_mask & DL_DEBUG_PRELINK, 0) == 0) + && __builtin_expect (GL(dl_debug_mask) & DL_DEBUG_PRELINK, 0) == 0) { /* We haven't found an appropriate library. But since we are only interested in the list of libraries this isn't diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index ae8df270e9..f10ff4739d 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -59,12 +59,11 @@ struct sym_val result; \ }) -#ifdef SHARED /* Statistics function. */ -unsigned long int _dl_num_relocations; -# define bump_num_relocation() ++_dl_num_relocations +#ifdef SHARED +# define bump_num_relocations() ++GL(dl_num_relocations) #else -# define bump_num_relocation() ((void) 0) +# define bump_num_relocations() ((void) 0) #endif @@ -122,7 +121,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map) reference is still available. There is a brief period in which the object could have been removed since we found the definition. */ - runp = _dl_loaded; + runp = GL(dl_loaded); while (runp != NULL && runp != map) runp = runp->l_next; @@ -168,7 +167,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map) ++(*list)->l_opencount; /* Display information if we are debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf ("\ \nfile=%s; needed by %s (relocation dependency)\n\n", map->l_name[0] ? map->l_name : _dl_argv[0], @@ -281,7 +280,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, } } - if (__builtin_expect (_dl_debug_mask + if (__builtin_expect (GL(dl_debug_mask) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope, ¤t_value, NULL, type_class, protected); @@ -352,7 +351,7 @@ _dl_lookup_symbol_skip (const char *undef_name, } } - if (__builtin_expect (_dl_debug_mask + if (__builtin_expect (GL(dl_debug_mask) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope, ¤t_value, NULL, 0, protected); @@ -471,7 +470,7 @@ _dl_lookup_versioned_symbol (const char *undef_name, } } - if (__builtin_expect (_dl_debug_mask + if (__builtin_expect (GL(dl_debug_mask) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope, ¤t_value, version, type_class, protected); @@ -557,7 +556,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name, } } - if (__builtin_expect (_dl_debug_mask + if (__builtin_expect (GL(dl_debug_mask) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope, ¤t_value, version, 0, protected); @@ -596,7 +595,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, { const char *reference_name = undef_map->l_name; - if (_dl_debug_mask & DL_DEBUG_BINDINGS) + if (GL(dl_debug_mask) & DL_DEBUG_BINDINGS) { _dl_debug_printf ("binding file %s to %s: %s symbol `%s'", (reference_name[0] @@ -610,14 +609,14 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, _dl_debug_printf_c ("\n"); } #ifdef SHARED - if (_dl_debug_mask & DL_DEBUG_PRELINK) + if (GL(dl_debug_mask) & DL_DEBUG_PRELINK) { int conflict = 0; struct sym_val val = { NULL, NULL }; - if ((_dl_trace_prelink_map == NULL - || _dl_trace_prelink_map == _dl_loaded) - && undef_map != _dl_loaded) + if ((GL(dl_trace_prelink_map) == NULL + || GL(dl_trace_prelink_map) == GL(dl_loaded)) + && undef_map != GL(dl_loaded)) { const unsigned long int hash = _dl_elf_hash (undef_name); @@ -634,8 +633,8 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map, } if (conflict - || _dl_trace_prelink_map == undef_map - || _dl_trace_prelink_map == NULL) + || GL(dl_trace_prelink_map) == undef_map + || GL(dl_trace_prelink_map) == NULL) { _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ", conflict ? "conflict" : "lookup", diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c index b72faa0aa7..12e9d69ff7 100644 --- a/elf/dl-minimal.c +++ b/elf/dl-minimal.c @@ -1,5 +1,5 @@ /* Minimal replacements for basic facilities used in the dynamic linker. - Copyright (C) 1995,96,97,98,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,2000,2001,2002 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 @@ -60,8 +60,9 @@ malloc (size_t n) /* Consume any unused space in the last page of our data segment. */ extern int _end; alloc_ptr = &_end; - alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); + alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + + GL(dl_pagesize) - 1) + & ~(GL(dl_pagesize) - 1)); } /* Make sure the allocation pointer is ideally aligned. */ @@ -72,7 +73,7 @@ malloc (size_t n) { /* Insufficient space left; allocate another page. */ caddr_t page; - size_t nup = (n + _dl_pagesize - 1) & ~(_dl_pagesize - 1); + size_t nup = (n + GL(dl_pagesize) - 1) & ~(GL(dl_pagesize) - 1); page = __mmap (0, nup, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); assert (page != MAP_FAILED); diff --git a/elf/dl-object.c b/elf/dl-object.c index eee9deb3d2..0488e3230c 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -1,5 +1,5 @@ /* Storage management for the chain of loaded shared objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 @@ -64,9 +64,9 @@ _dl_new_object (char *realname, const char *libname, int type, /* Counter for the scopes we have to handle. */ idx = 0; - if (_dl_loaded != NULL) + if (GL(dl_loaded) != NULL) { - l = _dl_loaded; + l = GL(dl_loaded); while (l->l_next != NULL) l = l->l_next; new->l_prev = l; @@ -74,11 +74,11 @@ _dl_new_object (char *realname, const char *libname, int type, l->l_next = new; /* Add the global scope. */ - new->l_scope[idx++] = &_dl_loaded->l_searchlist; + new->l_scope[idx++] = &GL(dl_loaded)->l_searchlist; } else - _dl_loaded = new; - ++_dl_nloaded; + GL(dl_loaded) = new; + ++GL(dl_nloaded); /* If we have no loader the new object acts as it. */ if (loader == NULL) diff --git a/elf/dl-open.c b/elf/dl-open.c index c061cdeb0e..2f82e4cf40 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1,5 +1,5 @@ /* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2002 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 @@ -50,16 +50,12 @@ extern char **__libc_argv; extern char **__environ; -extern int _dl_lazy; /* Do we do lazy relocations? */ - /* Undefine the following for debugging. */ /* #define SCOPE_DEBUG 1 */ #ifdef SCOPE_DEBUG static void show_scope (struct link_map *new); #endif -extern size_t _dl_platformlen; - /* We must be carefull not to leave us in an inconsistent state. Thus we catch any error and re-raise it after cleaning up. */ @@ -98,15 +94,15 @@ add_to_global (struct link_map *new) in an realloc() call. Therefore we allocate a completely new array the first time we have to add something to the locale scope. */ - if (_dl_global_scope_alloc == 0) + if (GL(dl_global_scope_alloc) == 0) { /* This is the first dynamic object given global scope. */ - _dl_global_scope_alloc = _dl_main_searchlist->r_nlist + to_add + 8; + GL(dl_global_scope_alloc) = GL(dl_main_searchlist)->r_nlist + to_add + 8; new_global = (struct link_map **) - malloc (_dl_global_scope_alloc * sizeof (struct link_map *)); + malloc (GL(dl_global_scope_alloc) * sizeof (struct link_map *)); if (new_global == NULL) { - _dl_global_scope_alloc = 0; + GL(dl_global_scope_alloc) = 0; nomem: _dl_signal_error (ENOMEM, new->l_libname->name, NULL, N_("cannot extend global scope")); @@ -114,24 +110,25 @@ add_to_global (struct link_map *new) } /* Copy over the old entries. */ - memcpy (new_global, _dl_main_searchlist->r_list, - (_dl_main_searchlist->r_nlist * sizeof (struct link_map *))); + memcpy (new_global, GL(dl_main_searchlist)->r_list, + (GL(dl_main_searchlist)->r_nlist * sizeof (struct link_map *))); - _dl_main_searchlist->r_list = new_global; + GL(dl_main_searchlist)->r_list = new_global; } - else if (_dl_main_searchlist->r_nlist + to_add > _dl_global_scope_alloc) + else if (GL(dl_main_searchlist)->r_nlist + to_add + > GL(dl_global_scope_alloc)) { /* We have to extend the existing array of link maps in the main map. */ new_global = (struct link_map **) - realloc (_dl_main_searchlist->r_list, - ((_dl_global_scope_alloc + to_add + 8) + realloc (GL(dl_main_searchlist)->r_list, + ((GL(dl_global_scope_alloc) + to_add + 8) * sizeof (struct link_map *))); if (new_global == NULL) goto nomem; - _dl_global_scope_alloc += to_add + 8; - _dl_main_searchlist->r_list = new_global; + GL(dl_global_scope_alloc) += to_add + 8; + GL(dl_main_searchlist)->r_list = new_global; } /* Now add the new entries. */ @@ -142,8 +139,9 @@ add_to_global (struct link_map *new) if (map->l_global == 0) { map->l_global = 1; - _dl_main_searchlist->r_list[_dl_main_searchlist->r_nlist] = map; - ++_dl_main_searchlist->r_nlist; + GL(dl_main_searchlist)->r_list[GL(dl_main_searchlist)->r_nlist] + = map; + ++GL(dl_main_searchlist)->r_nlist; } } @@ -180,7 +178,7 @@ dl_open_worker (void *a) /* We have to find out from which object the caller is calling. */ call_map = NULL; - for (l = _dl_loaded; l; l = l->l_next) + for (l = GL(dl_loaded); l; l = l->l_next) if (caller >= (const void *) l->l_map_start && caller < (const void *) l->l_map_end) { @@ -192,7 +190,7 @@ dl_open_worker (void *a) if (call_map == NULL) /* In this case we assume this is the main application. */ - call_map = _dl_loaded; + call_map = GL(dl_loaded); /* Determine how much space we need. We have to allocate the memory locally. */ @@ -233,7 +231,7 @@ dl_open_worker (void *a) if (new->l_searchlist.r_list != NULL) { /* Let the user know about the opencount. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf ("opening file=%s; opencount == %u\n\n", new->l_name, new->l_opencount); @@ -274,20 +272,20 @@ dl_open_worker (void *a) if (! l->l_relocated) { #ifdef SHARED - if (_dl_profile != NULL) + if (GL(dl_profile) != NULL) { /* If this here is the shared object which we want to profile make sure the profile is started. We can find out whether this is necessary or not by observing the `_dl_profile_map' variable. If was NULL but is not NULL afterwars we must start the profiling. */ - struct link_map *old_profile_map = _dl_profile_map; + struct link_map *old_profile_map = GL(dl_profile_map); _dl_relocate_object (l, l->l_scope, 1, 1); - if (old_profile_map == NULL && _dl_profile_map != NULL) + if (old_profile_map == NULL && GL(dl_profile_map) != NULL) /* We must prepare the profiling. */ - _dl_start_profile (_dl_profile_map, _dl_profile_output); + _dl_start_profile (GL(dl_profile_map), GL(dl_profile_output)); } else #endif @@ -382,7 +380,7 @@ dl_open_worker (void *a) __libc_multiple_libcs = 1; /* Let the user know about the opencount. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0)) _dl_debug_printf ("opening file=%s; opencount == %u\n\n", new->l_name, new->l_opencount); } diff --git a/elf/dl-profile.c b/elf/dl-profile.c index 9f16a9359e..6abdb1b76d 100644 --- a/elf/dl-profile.c +++ b/elf/dl-profile.c @@ -1,5 +1,5 @@ /* Profiling of shared libraries. - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1997,1998,1999,2000,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. Based on the BSD mcount implementation. @@ -196,9 +196,9 @@ _dl_start_profile (struct link_map *map, const char *output_dir) for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph) if (ph->p_type == PT_LOAD && (ph->p_flags & PF_X)) { - ElfW(Addr) start = (ph->p_vaddr & ~(_dl_pagesize - 1)); - ElfW(Addr) end = ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); + ElfW(Addr) start = (ph->p_vaddr & ~(GL(dl_pagesize) - 1)); + ElfW(Addr) end = ((ph->p_vaddr + ph->p_memsz + GL(dl_pagesize) - 1) + & ~(GL(dl_pagesize) - 1)); if (start < mapstart) mapstart = start; @@ -250,11 +250,11 @@ _dl_start_profile (struct link_map *map, const char *output_dir) /* First determine the output name. We write in the directory OUTPUT_DIR and the name is composed from the shared objects soname (or the file name) and the ending ".profile". */ - filename = (char *) alloca (strlen (output_dir) + 1 + strlen (_dl_profile) + filename = (char *) alloca (strlen (output_dir) + 1 + strlen (GL(dl_profile)) + sizeof ".profile"); cp = __stpcpy (filename, output_dir); *cp++ = '/'; - __stpcpy (__stpcpy (cp, _dl_profile), ".profile"); + __stpcpy (__stpcpy (cp, GL(dl_profile)), ".profile"); #ifdef O_NOFOLLOW # define EXTRA_FLAGS | O_NOFOLLOW @@ -287,11 +287,11 @@ _dl_start_profile (struct link_map *map, const char *output_dir) if (st.st_size == 0) { /* We have to create the file. */ - char buf[_dl_pagesize]; + char buf[GL(dl_pagesize)]; - memset (buf, '\0', _dl_pagesize); + memset (buf, '\0', GL(dl_pagesize)); - if (__lseek (fd, expected_size & ~(_dl_pagesize - 1), SEEK_SET) == -1) + if (__lseek (fd, expected_size & ~(GL(dl_pagesize) - 1), SEEK_SET) == -1) { char buf[400]; int errnum; @@ -304,7 +304,8 @@ _dl_start_profile (struct link_map *map, const char *output_dir) } if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size - & (_dl_pagesize - 1)))) + & (GL(dl_pagesize) + - 1)))) < 0) goto cannot_create; } @@ -317,7 +318,7 @@ _dl_start_profile (struct link_map *map, const char *output_dir) __munmap ((void *) addr, expected_size); _dl_error_printf ("%s: file is no correct profile data file for `%s'\n", - filename, _dl_profile); + filename, GL(dl_profile)); return; } diff --git a/elf/dl-profstub.c b/elf/dl-profstub.c index 4ca39b5b80..45fb4e987c 100644 --- a/elf/dl-profstub.c +++ b/elf/dl-profstub.c @@ -1,5 +1,5 @@ /* Helper definitions for profiling of shared libraries. - Copyright (C) 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -24,7 +24,7 @@ /* This is the map for the shared object we profile. It is defined here only because we test for this value being NULL or not. */ -extern struct link_map *_dl_profile_map; +//Xextern struct link_map *_dl_profile_map; void @@ -37,6 +37,6 @@ _dl_mcount_wrapper (void *selfpc) void _dl_mcount_wrapper_check (void *selfpc) { - if (_dl_profile_map != NULL) + if (GL(dl_profile_map) != NULL) _dl_mcount ((ElfW(Addr)) RETURN_ADDRESS (0), (ElfW(Addr)) selfpc); } diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index bfab6a2bda..a3ee153b84 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -27,10 +27,9 @@ #include #include "dynamic-link.h" -#ifdef SHARED /* Statistics function. */ -unsigned long int _dl_num_cache_relocations; -# define bump_num_cache_relocations() ++_dl_num_cache_relocations +#ifdef SHARED +# define bump_num_cache_relocations() ++GL(dl_num_cache_relocations) #else # define bump_num_cache_relocations() ((void) 0) #endif @@ -59,9 +58,10 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) lazy = 0; - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_RELOC, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_RELOC, 0)) _dl_printf ("\nrelocation processing: %s%s\n", - l->l_name[0] ? l->l_name : _dl_argv[0], lazy ? " (lazy)" : ""); + l->l_name[0] ? l->l_name : _dl_argv[0], + lazy ? " (lazy)" : ""); /* DT_TEXTREL is now in level 2 and might phase out at some time. But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make @@ -77,10 +77,10 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], struct textrels *newp; newp = (struct textrels *) alloca (sizeof (*newp)); - newp->len = (((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)) - - (ph->p_vaddr & ~(_dl_pagesize - 1))); - newp->start = ((ph->p_vaddr & ~(_dl_pagesize - 1)) + newp->len = (((ph->p_vaddr + ph->p_memsz + GL(dl_pagesize) - 1) + & ~(GL(dl_pagesize) - 1)) + - (ph->p_vaddr & ~(GL(dl_pagesize) - 1))); + newp->start = ((ph->p_vaddr & ~(GL(dl_pagesize) - 1)) + (caddr_t) l->l_addr); if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0) diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 27d99fcc66..44af537ab7 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -1,5 +1,5 @@ /* On-demand PLT fixup for shared objects. - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001, 2002 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 @@ -118,7 +118,7 @@ fixup ( value = elf_machine_plt_value (l, reloc, value); /* Finally, fix up the plt itself. */ - if (__builtin_expect (_dl_bind_not, 0)) + if (__builtin_expect (GL(dl_bind_not), 0)) return value; return elf_machine_fixup_plt (l, result, reloc, rel_addr, value); @@ -210,7 +210,7 @@ profile_fixup ( value = elf_machine_plt_value (l, reloc, value); /* Store the result for later runs. */ - if (__builtin_expect (! _dl_bind_not, 1)) + if (__builtin_expect (! GL(dl_bind_not), 1)) *resultp = value; } diff --git a/elf/dl-support.c b/elf/dl-support.c index 1332e8a89f..0efbcc4cb6 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -1,5 +1,5 @@ /* Support for dynamic linking code in static libc. - Copyright (C) 1996, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2002 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 @@ -52,9 +52,6 @@ int _dl_dynamic_weak = 1; /* If nonzero print warnings about problematic situations. */ int _dl_verbose; -/* Structure to store information about search paths. */ -struct r_search_path *_dl_search_paths; - /* We never do profiling. */ const char *_dl_profile; @@ -104,6 +101,24 @@ int _dl_starting_up = 1; hp_timing_t _dl_cpuclock_offset; #endif +/* This is zero at program start to signal that the global scope map is + allocated by rtld. Later it keeps the size of the map. It might be + reset if in _dl_close if the last global object is removed. */ +size_t _dl_global_scope_alloc; + +size_t _dl_pagesize; + +unsigned int _dl_osversion; + +/* All known directories in sorted order. */ +struct r_search_path_elem *_dl_all_dirs; + +/* All directories after startup. */ +struct r_search_path_elem *_dl_init_all_dirs; + +/* The object to be initialized first. */ +struct link_map *_dl_initfirst; + /* During the program run we must not modify the global data of loaded shared object simultanously in two threads. Therefore we protect `_dl_open' and `_dl_close' in dl-close.c. @@ -115,7 +130,7 @@ __libc_lock_define_initialized_recursive (, _dl_load_lock) #ifdef HAVE_AUX_VECTOR -extern int _dl_clktck; +int _dl_clktck; void internal_function @@ -125,10 +140,10 @@ _dl_aux_init (ElfW(auxv_t) *av) switch (av->a_type) { case AT_PAGESZ: - _dl_pagesize = av->a_un.a_val; + GL(dl_pagesize) = av->a_un.a_val; break; case AT_CLKTCK: - _dl_clktck = av->a_un.a_val; + GL(dl_clktck) = av->a_un.a_val; break; } } diff --git a/elf/dl-sym.c b/elf/dl-sym.c index 85d084f7f7..b0db159aa6 100644 --- a/elf/dl-sym.c +++ b/elf/dl-sym.c @@ -1,5 +1,5 @@ /* Look up a symbol in a shared object loaded by `dlopen'. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002 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 @@ -37,10 +37,10 @@ _dl_sym (void *handle, const char *name, void *who) /* If the address is not recognized the call comes from the main program (we hope). */ - match = _dl_loaded; + match = GL(dl_loaded); /* Find the highest-addressed object that CALLER is not below. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) + for (l = GL(dl_loaded); l != NULL; l = l->l_next) if (caller >= l->l_map_start && caller < l->l_map_end) { /* There must be exactly one DSO for the range of the virtual @@ -64,11 +64,11 @@ _dl_sym (void *handle, const char *name, void *who) } else { - if (__builtin_expect (match == _dl_loaded, 0)) + if (__builtin_expect (match == GL(dl_loaded), 0)) { - if (! _dl_loaded - || caller < _dl_loaded->l_map_start - || caller >= _dl_loaded->l_map_end) + if (! GL(dl_loaded) + || caller < GL(dl_loaded)->l_map_start + || caller >= GL(dl_loaded)->l_map_end) _dl_signal_error (0, NULL, NULL, N_("\ RTLD_NEXT used in code not dynamically loaded")); } @@ -108,10 +108,10 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who) /* If the address is not recognized the call comes from the main program (we hope). */ - match = _dl_loaded; + match = GL(dl_loaded); /* Find the highest-addressed object that CALLER is not below. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) + for (l = GL(dl_loaded); l != NULL; l = l->l_next) if (caller >= l->l_map_start && caller < l->l_map_end) { /* There must be exactly one DSO for the range of the virtual @@ -126,11 +126,11 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who) &vers, 0, 0); else if (handle == RTLD_NEXT) { - if (__builtin_expect (match == _dl_loaded, 0)) + if (__builtin_expect (match == GL(dl_loaded), 0)) { - if (! _dl_loaded - || caller < _dl_loaded->l_map_start - || caller >= _dl_loaded->l_map_end) + if (! GL(dl_loaded) + || caller < GL(dl_loaded)->l_map_start + || caller >= GL(dl_loaded)->l_map_end) _dl_signal_error (0, NULL, NULL, N_("\ RTLD_NEXT used in code not dynamically loaded")); } diff --git a/elf/dl-version.c b/elf/dl-version.c index 6715bc1547..7edb8ec359 100644 --- a/elf/dl-version.c +++ b/elf/dl-version.c @@ -1,5 +1,5 @@ /* Handle symbol and library versioning. - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1997,1998,1999,2000,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -58,7 +58,7 @@ find_needed (const char *name, struct link_map *map) struct link_map *tmap; unsigned int n; - for (tmap = _dl_loaded; tmap != NULL; tmap = tmap->l_next) + for (tmap = GL(dl_loaded); tmap != NULL; tmap = tmap->l_next) if (_dl_name_match_p (name, tmap)) return tmap; @@ -86,11 +86,11 @@ match_symbol (const char *name, ElfW(Word) hash, const char *string, int result = 0; /* Display information about what we are doing while debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_VERSIONS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_VERSIONS, 0)) _dl_debug_printf ("\ checking for version `%s' in file %s required by file %s\n", - string, map->l_name[0] ? map->l_name : _dl_argv[0], - name); + string, map->l_name[0] + ? map->l_name : _dl_argv[0], name); if (__builtin_expect (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL, 0)) { @@ -166,8 +166,8 @@ no version information available (required by ", name, ")"); name, ")"); result = 1; call_cerror: - _dl_signal_cerror (0, map->l_name[0] ? map->l_name : _dl_argv[0], NULL, - errstring); + _dl_signal_cerror (0, map->l_name[0] ? map->l_name : _dl_argv[0], + NULL, errstring); return result; } @@ -214,7 +214,8 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) &buf[sizeof (buf) - 1], 10, 0), " of Verneed record\n"); call_error: - _dl_signal_error (errval, (*map->l_name ? map->l_name : _dl_argv[0]), + _dl_signal_error (errval, (*map->l_name + ? map->l_name : _dl_argv[0]), NULL, errstring); } diff --git a/elf/do-lookup.h b/elf/do-lookup.h index b9364b95d1..65f7b02a20 100644 --- a/elf/do-lookup.h +++ b/elf/do-lookup.h @@ -1,5 +1,5 @@ /* Look up a symbol in the loaded objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 @@ -60,7 +60,7 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref, continue; /* Print some debugging info if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_SYMBOLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0)) _dl_debug_printf ("symbol=%s; lookup in file=%s\n", undef_name, map->l_name[0] ? map->l_name : _dl_argv[0]); diff --git a/elf/do-rel.h b/elf/do-rel.h index d08f655815..3968937093 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -1,5 +1,5 @@ /* Do relocations for ELF dynamic linking. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 @@ -79,8 +79,10 @@ elf_dynamic_do_rel (struct link_map *map, RTLD_BOOTSTRAP) because rtld.c contains the common defn for _dl_rtld_map, which is incompatible with a weak decl in the same file. */ - weak_extern (_dl_rtld_map); - if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +# ifndef SHARED + weak_extern (GL(dl_rtld_map)); +# endif + if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */ # ifndef DO_RELA /* Rela platforms get the offset from r_addend and this must be copied in the relocation address. Therefore we can skip diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index bbfd301231..8792b8e4b6 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -1,5 +1,5 @@ /* Inline functions for dynamic linking. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 @@ -26,11 +26,6 @@ #endif -/* Global read-only variable defined in rtld.c which is nonzero if we - shall give more warning messages. */ -extern int _dl_verbose __attribute__ ((unused)); - - /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ static inline void __attribute__ ((unused)) diff --git a/elf/rtld.c b/elf/rtld.c index 45b15fd8f2..050d7fae8a 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -58,17 +58,7 @@ static void process_envvars (enum mode *modep); int _dl_argc; char **_dl_argv; unsigned int _dl_skip_args; /* Nonzero if we were run directly. */ -int _dl_verbose; -const char *_dl_platform; -size_t _dl_platformlen; -unsigned long _dl_hwcap; fpu_control_t _dl_fpu_control = _FPU_DEFAULT; -struct r_search_path *_dl_search_paths; -const char *_dl_profile; -const char *_dl_profile_output; -struct link_map *_dl_profile_map; -const char *_dl_trace_prelink; -struct link_map *_dl_trace_prelink_map; int _dl_lazy = 1; /* XXX I know about at least one case where we depend on the old weak behavior (it has to do with librt). Until we get DSO groups implemented @@ -78,23 +68,6 @@ int _dl_dynamic_weak; #else int _dl_dynamic_weak = 1; #endif -int _dl_debug_mask; -const char *_dl_inhibit_rpath; /* RPATH values which should be - ignored. */ -const char *_dl_origin_path; -int _dl_bind_not; - -/* This is a pointer to the map for the main object and through it to - all loaded objects. */ -struct link_map *_dl_loaded; -/* Number of object in the _dl_loaded list. */ -unsigned int _dl_nloaded; -/* Pointer to the l_searchlist element of the link map of the main object. */ -struct r_scope_elem *_dl_main_searchlist; -/* Copy of the content of `_dl_main_searchlist'. */ -struct r_scope_elem _dl_initial_searchlist; -/* Array which is used when looking up in the global scope. */ -struct r_scope_elem *_dl_global_scope[2]; /* During the program run we must not modify the global data of loaded shared object simultanously in two threads. Therefore we @@ -114,14 +87,17 @@ __libc_lock_define_initialized_recursive (, _dl_load_lock) never be called. */ int _dl_starting_up; +/* This is the structure which defines all variables global to ld.so + (except those which cannot be added for some reason). */ +struct rtld_global _rtld_global; + static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum, ElfW(Addr) *user_entry); -struct link_map _dl_rtld_map; -struct libname_list _dl_rtld_libname; -struct libname_list _dl_rtld_libname2; +static struct libname_list _dl_rtld_libname; +static struct libname_list _dl_rtld_libname2; /* We expect less than a second for relocation. */ #ifdef HP_SMALL_TIMING_AVAIL @@ -135,8 +111,6 @@ static hp_timing_t rtld_total_time; static hp_timing_t relocate_time; static hp_timing_t load_time; #endif -extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */ -extern unsigned long int _dl_num_cache_relocations; /* in dl-reloc.c */ static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p, hp_timing_t start_time); @@ -217,7 +191,7 @@ _dl_start (void *arg) # define ELF_MACHINE_START_ADDRESS(map, start) (start) #endif - return ELF_MACHINE_START_ADDRESS (_dl_loaded, entry); + return ELF_MACHINE_START_ADDRESS (GL(dl_loaded), entry); } } @@ -253,15 +227,15 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p, } /* Transfer data about ourselves to the permanent link_map structure. */ - _dl_rtld_map.l_addr = bootstrap_map_p->l_addr; - _dl_rtld_map.l_ld = bootstrap_map_p->l_ld; - _dl_rtld_map.l_opencount = 1; - memcpy (_dl_rtld_map.l_info, bootstrap_map_p->l_info, - sizeof _dl_rtld_map.l_info); - _dl_setup_hash (&_dl_rtld_map); - _dl_rtld_map.l_mach = bootstrap_map_p->l_mach; - _dl_rtld_map.l_map_start = (ElfW(Addr)) _begin; - _dl_rtld_map.l_map_end = (ElfW(Addr)) _end; + GL(dl_rtld_map).l_addr = bootstrap_map_p->l_addr; + GL(dl_rtld_map).l_ld = bootstrap_map_p->l_ld; + GL(dl_rtld_map).l_opencount = 1; + memcpy (GL(dl_rtld_map).l_info, bootstrap_map_p->l_info, + sizeof GL(dl_rtld_map).l_info); + _dl_setup_hash (&GL(dl_rtld_map)); + GL(dl_rtld_map).l_mach = bootstrap_map_p->l_mach; + GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin; + GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; /* Call the OS-dependent function to set up life so we can do things like file access. It will call `dl_main' (below) to do all the real work @@ -281,7 +255,7 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p, } #endif - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_STATISTICS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_STATISTICS, 0)) print_statistics (); return *start_addr; @@ -334,7 +308,7 @@ static void version_check_doit (void *a) { struct version_check_args *args = (struct version_check_args *) a; - if (_dl_check_all_versions (_dl_loaded, 1, args->dotrace) && args->doexit) + if (_dl_check_all_versions (GL(dl_loaded), 1, args->dotrace) && args->doexit) /* We cannot start the application. Abort now. */ _exit (1); } @@ -343,11 +317,11 @@ version_check_doit (void *a) static inline struct link_map * find_needed (const char *name) { - unsigned int n = _dl_loaded->l_searchlist.r_nlist; + unsigned int n = GL(dl_loaded)->l_searchlist.r_nlist; while (n-- > 0) - if (_dl_name_match_p (name, _dl_loaded->l_searchlist.r_list[n])) - return _dl_loaded->l_searchlist.r_list[n]; + if (_dl_name_match_p (name, GL(dl_loaded)->l_searchlist.r_list[n])) + return GL(dl_loaded)->l_searchlist.r_list[n]; /* Should never happen. */ return NULL; @@ -438,7 +412,7 @@ dl_main (const ElfW(Phdr) *phdr, rtld_is_main = 1; /* Note the place where the dynamic linker actually came from. */ - _dl_rtld_map.l_name = _dl_argv[0]; + GL(dl_rtld_map).l_name = _dl_argv[0]; while (_dl_argc > 1) if (! strcmp (_dl_argv[1], "--list")) @@ -468,7 +442,7 @@ dl_main (const ElfW(Phdr) *phdr, } else if (! strcmp (_dl_argv[1], "--inhibit-rpath") && _dl_argc > 2) { - _dl_inhibit_rpath = _dl_argv[2]; + GL(dl_inhibit_rpath) = _dl_argv[2]; _dl_skip_args += 2; _dl_argc -= 2; @@ -534,25 +508,25 @@ of this helper program; chances are you did not intend to run this program.\n\ HP_TIMING_DIFF (load_time, start, stop); } - phdr = _dl_loaded->l_phdr; - phnum = _dl_loaded->l_phnum; + phdr = GL(dl_loaded)->l_phdr; + phnum = GL(dl_loaded)->l_phnum; /* We overwrite here a pointer to a malloc()ed string. But since the malloc() implementation used at this point is the dummy implementations which has no real free() function it does not makes sense to free the old string first. */ - _dl_loaded->l_name = (char *) ""; - *user_entry = _dl_loaded->l_entry; + GL(dl_loaded)->l_name = (char *) ""; + *user_entry = GL(dl_loaded)->l_entry; } else { /* Create a link_map for the executable itself. This will be what dlopen on "" returns. */ _dl_new_object ((char *) "", "", lt_executable, NULL); - if (_dl_loaded == NULL) + if (GL(dl_loaded) == NULL) _dl_fatal_printf ("cannot allocate memory for link map\n"); - _dl_loaded->l_phdr = phdr; - _dl_loaded->l_phnum = phnum; - _dl_loaded->l_entry = *user_entry; + GL(dl_loaded)->l_phdr = phdr; + GL(dl_loaded)->l_phnum = phnum; + GL(dl_loaded)->l_entry = *user_entry; /* At this point we are in a bit of trouble. We would have to fill in the values for l_dev and l_ino. But in general we @@ -573,11 +547,11 @@ of this helper program; chances are you did not intend to run this program.\n\ information for the program. */ } - _dl_loaded->l_map_end = 0; + GL(dl_loaded)->l_map_end = 0; /* Perhaps the executable has no PT_LOAD header entries at all. */ - _dl_loaded->l_map_start = ~0; + GL(dl_loaded)->l_map_start = ~0; /* We opened the file, account for it. */ - ++_dl_loaded->l_opencount; + ++GL(dl_loaded)->l_opencount; /* Scan the program header table for the dynamic section. */ for (ph = phdr; ph < &phdr[phnum]; ++ph) @@ -585,12 +559,12 @@ of this helper program; chances are you did not intend to run this program.\n\ { case PT_PHDR: /* Find out the load address. */ - _dl_loaded->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; + GL(dl_loaded)->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; break; case PT_DYNAMIC: /* This tells us where to find the dynamic section, which tells us everything we need to do. */ - _dl_loaded->l_ld = (void *) _dl_loaded->l_addr + ph->p_vaddr; + GL(dl_loaded)->l_ld = (void *) GL(dl_loaded)->l_addr + ph->p_vaddr; break; case PT_INTERP: /* This "interpreter segment" was used by the program loader to @@ -599,17 +573,17 @@ of this helper program; chances are you did not intend to run this program.\n\ dlopen call or DT_NEEDED entry, for something that wants to link against the dynamic linker as a shared library, will know that the shared object is already loaded. */ - _dl_rtld_libname.name = ((const char *) _dl_loaded->l_addr + _dl_rtld_libname.name = ((const char *) GL(dl_loaded)->l_addr + ph->p_vaddr); /* _dl_rtld_libname.next = NULL; Already zero. */ - _dl_rtld_map.l_libname = &_dl_rtld_libname; + GL(dl_rtld_map).l_libname = &_dl_rtld_libname; /* Ordinarilly, we would get additional names for the loader from our DT_SONAME. This can't happen if we were actually linked as a static executable (detect this case when we have no DYNAMIC). If so, assume the filename component of the interpreter path to be our SONAME, and add it to our name list. */ - if (_dl_rtld_map.l_ld == NULL) + if (GL(dl_rtld_map).l_ld == NULL) { char *p = strrchr (_dl_rtld_libname.name, '/'); if (p) @@ -628,37 +602,38 @@ of this helper program; chances are you did not intend to run this program.\n\ ElfW(Addr) allocend; /* Remember where the main program starts in memory. */ - mapstart = _dl_loaded->l_addr + (ph->p_vaddr & ~(ph->p_align - 1)); - if (_dl_loaded->l_map_start > mapstart) - _dl_loaded->l_map_start = mapstart; + mapstart = (GL(dl_loaded)->l_addr + + (ph->p_vaddr & ~(ph->p_align - 1))); + if (GL(dl_loaded)->l_map_start > mapstart) + GL(dl_loaded)->l_map_start = mapstart; /* Also where it ends. */ - allocend = _dl_loaded->l_addr + ph->p_vaddr + ph->p_memsz; - if (_dl_loaded->l_map_end < allocend) - _dl_loaded->l_map_end = allocend; + allocend = GL(dl_loaded)->l_addr + ph->p_vaddr + ph->p_memsz; + if (GL(dl_loaded)->l_map_end < allocend) + GL(dl_loaded)->l_map_end = allocend; } break; } - if (! _dl_loaded->l_map_end) - _dl_loaded->l_map_end = ~0; - if (! _dl_rtld_map.l_libname && _dl_rtld_map.l_name) + if (! GL(dl_loaded)->l_map_end) + GL(dl_loaded)->l_map_end = ~0; + if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name) { /* We were invoked directly, so the program might not have a PT_INTERP. */ - _dl_rtld_libname.name = _dl_rtld_map.l_name; + _dl_rtld_libname.name = GL(dl_rtld_map).l_name; /* _dl_rtld_libname.next = NULL; Alread zero. */ - _dl_rtld_map.l_libname = &_dl_rtld_libname; + GL(dl_rtld_map).l_libname = &_dl_rtld_libname; } else - assert (_dl_rtld_map.l_libname); /* How else did we get here? */ + assert (GL(dl_rtld_map).l_libname); /* How else did we get here? */ if (! rtld_is_main) { /* Extract the contents of the dynamic section for easy access. */ - elf_get_dynamic_info (_dl_loaded); - if (_dl_loaded->l_info[DT_HASH]) + elf_get_dynamic_info (GL(dl_loaded)); + if (GL(dl_loaded)->l_info[DT_HASH]) /* Set up our cache of pointers into the hash table. */ - _dl_setup_hash (_dl_loaded); + _dl_setup_hash (GL(dl_loaded)); } if (__builtin_expect (mode, normal) == verify) @@ -667,7 +642,7 @@ of this helper program; chances are you did not intend to run this program.\n\ executable using us as the program interpreter. Exit with an error if we were not able to load the binary or no interpreter is specified (i.e., this is no dynamically linked binary. */ - if (_dl_loaded->l_ld == NULL) + if (GL(dl_loaded)->l_ld == NULL) _exit (1); /* We allow here some platform specific code. */ @@ -684,15 +659,15 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Put the link_map for ourselves on the chain so it can be found by name. Note that at this point the global chain of link maps contains - exactly one element, which is pointed to by _dl_loaded. */ - if (! _dl_rtld_map.l_name) + exactly one element, which is pointed to by dl_loaded. */ + if (! GL(dl_rtld_map).l_name) /* If not invoked directly, the dynamic linker shared object file was found by the PT_INTERP name. */ - _dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname->name; - _dl_rtld_map.l_type = lt_library; - _dl_loaded->l_next = &_dl_rtld_map; - _dl_rtld_map.l_prev = _dl_loaded; - ++_dl_nloaded; + GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name; + GL(dl_rtld_map).l_type = lt_library; + GL(dl_loaded)->l_next = &GL(dl_rtld_map); + GL(dl_rtld_map).l_prev = GL(dl_loaded); + ++GL(dl_nloaded); /* We have two ways to specify objects to preload: via environment variable and via the file /etc/ld.so.preload. The latter can also @@ -717,7 +692,7 @@ of this helper program; chances are you did not intend to run this program.\n\ && (__builtin_expect (! __libc_enable_secure, 1) || strchr (p, '/') == NULL)) { - struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1, + struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1, lt_library, 0, 0); if (++new_map->l_opencount == 1) /* It is no duplicate. */ @@ -785,7 +760,7 @@ of this helper program; chances are you did not intend to run this program.\n\ while ((p = strsep (&runp, ": \t\n")) != NULL) if (p[0] != '\0') { - struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1, + struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1, lt_library, 0, 0); if (++new_map->l_opencount == 1) /* It is no duplicate. */ @@ -796,7 +771,7 @@ of this helper program; chances are you did not intend to run this program.\n\ if (problem != NULL) { char *p = strndupa (problem, file_size - (problem - file)); - struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1, + struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1, lt_library, 0, 0); if (++new_map->l_opencount == 1) /* It is no duplicate. */ @@ -816,7 +791,7 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Set up PRELOADS with a vector of the preloaded libraries. */ struct link_map *l; preloads = __alloca (npreloads * sizeof preloads[0]); - l = _dl_rtld_map.l_next; /* End of the chain before preloads. */ + l = GL(dl_rtld_map).l_next; /* End of the chain before preloads. */ i = 0; do { @@ -830,18 +805,18 @@ of this helper program; chances are you did not intend to run this program.\n\ specified some libraries to load, these are inserted before the actual dependencies in the executable's searchlist for symbol resolution. */ HP_TIMING_NOW (start); - _dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace); + _dl_map_object_deps (GL(dl_loaded), preloads, npreloads, mode == trace); HP_TIMING_NOW (stop); HP_TIMING_DIFF (diff, start, stop); HP_TIMING_ACCUM_NT (load_time, diff); /* Mark all objects as being in the global scope and set the open counter. */ - for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; ) + for (i = GL(dl_loaded)->l_searchlist.r_nlist; i > 0; ) { --i; - _dl_loaded->l_searchlist.r_list[i]->l_global = 1; - ++_dl_loaded->l_searchlist.r_list[i]->l_opencount; + GL(dl_loaded)->l_searchlist.r_list[i]->l_global = 1; + ++GL(dl_loaded)->l_searchlist.r_list[i]->l_opencount; } #ifndef MAP_ANON @@ -851,38 +826,38 @@ of this helper program; chances are you did not intend to run this program.\n\ #endif /* Remove _dl_rtld_map from the chain. */ - _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next; - if (_dl_rtld_map.l_next) - _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev; + GL(dl_rtld_map).l_prev->l_next = GL(dl_rtld_map).l_next; + if (GL(dl_rtld_map).l_next) + GL(dl_rtld_map).l_next->l_prev = GL(dl_rtld_map).l_prev; - if (__builtin_expect (_dl_rtld_map.l_opencount > 1, 1)) + if (__builtin_expect (GL(dl_rtld_map).l_opencount > 1, 1)) { /* Some DT_NEEDED entry referred to the interpreter object itself, so put it back in the list of visible objects. We insert it into the chain in symbol search order because gdb uses the chain's order as its symbol search order. */ i = 1; - while (_dl_loaded->l_searchlist.r_list[i] != &_dl_rtld_map) + while (GL(dl_loaded)->l_searchlist.r_list[i] != &GL(dl_rtld_map)) ++i; - _dl_rtld_map.l_prev = _dl_loaded->l_searchlist.r_list[i - 1]; + GL(dl_rtld_map).l_prev = GL(dl_loaded)->l_searchlist.r_list[i - 1]; if (__builtin_expect (mode, normal) == normal) - _dl_rtld_map.l_next = (i + 1 < _dl_loaded->l_searchlist.r_nlist - ? _dl_loaded->l_searchlist.r_list[i + 1] - : NULL); + GL(dl_rtld_map).l_next = (i + 1 < GL(dl_loaded)->l_searchlist.r_nlist + ? GL(dl_loaded)->l_searchlist.r_list[i + 1] + : NULL); else /* In trace mode there might be an invisible object (which we could not find) after the previous one in the search list. In this case it doesn't matter much where we put the interpreter object, so we just initialize the list pointer so that the assertion below holds. */ - _dl_rtld_map.l_next = _dl_rtld_map.l_prev->l_next; + GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; - assert (_dl_rtld_map.l_prev->l_next == _dl_rtld_map.l_next); - _dl_rtld_map.l_prev->l_next = &_dl_rtld_map; - if (_dl_rtld_map.l_next) + assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); + GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); + if (GL(dl_rtld_map).l_next) { - assert (_dl_rtld_map.l_next->l_prev == _dl_rtld_map.l_prev); - _dl_rtld_map.l_next->l_prev = &_dl_rtld_map; + assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); + GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); } } @@ -901,15 +876,15 @@ of this helper program; chances are you did not intend to run this program.\n\ important that we do this before real relocation, because the functions we call below for output may no longer work properly after relocation. */ - if (! _dl_loaded->l_info[DT_NEEDED]) + if (! GL(dl_loaded)->l_info[DT_NEEDED]) _dl_printf ("\tstatically linked\n"); else { struct link_map *l; - if (_dl_debug_mask & DL_DEBUG_PRELINK) + if (GL(dl_debug_mask) & DL_DEBUG_PRELINK) { - struct r_scope_elem *scope = &_dl_loaded->l_searchlist; + struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist; for (i = 0; i < scope->r_nlist; i++) { @@ -919,8 +894,8 @@ of this helper program; chances are you did not intend to run this program.\n\ _dl_printf ("\t%s => not found\n", l->l_libname->name); continue; } - if (_dl_name_match_p (_dl_trace_prelink, l)) - _dl_trace_prelink_map = l; + if (_dl_name_match_p (GL(dl_trace_prelink), l)) + GL(dl_trace_prelink_map) = l; _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)\n", l->l_libname->name[0] ? l->l_libname->name : _dl_argv[0] ?: "
", @@ -934,7 +909,7 @@ of this helper program; chances are you did not intend to run this program.\n\ } else { - for (l = _dl_loaded->l_next; l; l = l->l_next) + for (l = GL(dl_loaded)->l_next; l; l = l->l_next) if (l->l_faked) /* The library was not found. */ _dl_printf ("\t%s => not found\n", l->l_libname->name); @@ -952,8 +927,8 @@ of this helper program; chances are you did not intend to run this program.\n\ ElfW(Addr) loadbase; lookup_t result; - result = _dl_lookup_symbol (_dl_argv[i], _dl_loaded, - &ref, _dl_loaded->l_scope, + result = _dl_lookup_symbol (_dl_argv[i], GL(dl_loaded), + &ref, GL(dl_loaded)->l_scope, ELF_RTYPE_CLASS_PLT, 1); loadbase = LOOKUP_VALUE_ADDRESS (result); @@ -966,7 +941,7 @@ of this helper program; chances are you did not intend to run this program.\n\ else { /* If LD_WARN is set warn about undefined symbols. */ - if (_dl_lazy >= 0 && _dl_verbose) + if (_dl_lazy >= 0 && GL(dl_verbose)) { /* We have to do symbol dependency testing. */ struct relocate_args args; @@ -974,12 +949,12 @@ of this helper program; chances are you did not intend to run this program.\n\ args.lazy = _dl_lazy; - l = _dl_loaded; + l = GL(dl_loaded); while (l->l_next) l = l->l_next; do { - if (l != &_dl_rtld_map && ! l->l_faked) + if (l != &GL(dl_rtld_map) && ! l->l_faked) { args.l = l; _dl_receive_error (print_unresolved, relocate_doit, @@ -988,9 +963,10 @@ of this helper program; chances are you did not intend to run this program.\n\ l = l->l_prev; } while (l); - if ((_dl_debug_mask & DL_DEBUG_PRELINK) - && _dl_rtld_map.l_opencount > 1) - _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0); + if ((GL(dl_debug_mask) & DL_DEBUG_PRELINK) + && GL(dl_rtld_map).l_opencount > 1) + _dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope, + 0, 0); } #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) @@ -999,9 +975,9 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Print more information. This means here, print information about the versions needed. */ int first = 1; - struct link_map *map = _dl_loaded; + struct link_map *map = GL(dl_loaded); - for (map = _dl_loaded; map != NULL; map = map->l_next) + for (map = GL(dl_loaded); map != NULL; map = map->l_next) { const char *strtab; ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG]; @@ -1069,28 +1045,28 @@ of this helper program; chances are you did not intend to run this program.\n\ _exit (0); } - if (_dl_loaded->l_info [ADDRIDX (DT_GNU_LIBLIST)] - && ! __builtin_expect (_dl_profile != NULL, 0)) + if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)] + && ! __builtin_expect (GL(dl_profile) != NULL, 0)) { ElfW(Lib) *liblist, *liblistend; struct link_map **r_list, **r_listend, *l; const char *strtab = (const void *) - D_PTR (_dl_loaded, l_info[DT_STRTAB]); + D_PTR (GL(dl_loaded), l_info[DT_STRTAB]); - assert (_dl_loaded->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL); + assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL); liblist = (ElfW(Lib) *) - _dl_loaded->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; + GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; liblistend = (ElfW(Lib) *) ((char *) liblist - + _dl_loaded->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); - r_list = _dl_loaded->l_searchlist.r_list; - r_listend = r_list + _dl_loaded->l_searchlist.r_nlist; + + GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); + r_list = GL(dl_loaded)->l_searchlist.r_list; + r_listend = r_list + GL(dl_loaded)->l_searchlist.r_nlist; for (; r_list < r_listend && liblist < liblistend; r_list++) { l = *r_list; - if (l == _dl_loaded) + if (l == GL(dl_loaded)) continue; /* If the library is not mapped where it should, fail. */ @@ -1118,13 +1094,13 @@ of this helper program; chances are you did not intend to run this program.\n\ if (r_list == r_listend && liblist == liblistend) prelinked = 1; - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_printf ("\nprelink checking: %s\n", prelinked ? "ok" : "failed"); } if (prelinked) { - if (_dl_loaded->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) + if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) { ElfW(Rela) *conflict, *conflictend; #ifndef HP_TIMING_NONAVAIL @@ -1133,13 +1109,13 @@ of this helper program; chances are you did not intend to run this program.\n\ #endif HP_TIMING_NOW (start); - assert (_dl_loaded->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); + assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); conflict = (ElfW(Rela) *) - _dl_loaded->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; + GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; conflictend = (ElfW(Rela) *) ((char *) conflict - + _dl_loaded->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); - _dl_resolve_conflicts (_dl_loaded, conflict, conflictend); + + GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); + _dl_resolve_conflicts (GL(dl_loaded), conflict, conflictend); HP_TIMING_NOW (stop); HP_TIMING_DIFF (relocate_time, start, stop); } @@ -1158,7 +1134,7 @@ of this helper program; chances are you did not intend to run this program.\n\ know that because it is self-contained). */ struct link_map *l; - int consider_profiling = _dl_profile != NULL; + int consider_profiling = GL(dl_profile) != NULL; #ifndef HP_TIMING_NONAVAIL hp_timing_t start; hp_timing_t stop; @@ -1168,7 +1144,7 @@ of this helper program; chances are you did not intend to run this program.\n\ /* If we are profiling we also must do lazy reloaction. */ _dl_lazy |= consider_profiling; - l = _dl_loaded; + l = GL(dl_loaded); while (l->l_next) l = l->l_next; @@ -1186,7 +1162,7 @@ of this helper program; chances are you did not intend to run this program.\n\ lnp = lnp->next; } - if (l != &_dl_rtld_map) + if (l != &GL(dl_rtld_map)) _dl_relocate_object (l, l->l_scope, _dl_lazy, consider_profiling); l = l->l_prev; @@ -1207,16 +1183,16 @@ of this helper program; chances are you did not intend to run this program.\n\ this has to go here because the calls it makes should use the rtld versions of the functions (particularly calloc()), but it needs to have _dl_profile_map set up by the relocator. */ - if (__builtin_expect (_dl_profile_map != NULL, 0)) + if (__builtin_expect (GL(dl_profile_map) != NULL, 0)) /* We must prepare the profiling. */ - _dl_start_profile (_dl_profile_map, _dl_profile_output); + _dl_start_profile (GL(dl_profile_map), GL(dl_profile_output)); - if (_dl_rtld_map.l_opencount > 1) + if (GL(dl_rtld_map).l_opencount > 1) { /* There was an explicit ref to the dynamic linker as a shared lib. Re-relocate ourselves with user-controlled symbol definitions. */ HP_TIMING_NOW (start); - _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0); + _dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope, 0, 0); HP_TIMING_NOW (stop); HP_TIMING_DIFF (add, start, stop); HP_TIMING_ACCUM_NT (relocate_time, add); @@ -1224,26 +1200,26 @@ of this helper program; chances are you did not intend to run this program.\n\ } /* Now set up the variable which helps the assembler startup code. */ - _dl_main_searchlist = &_dl_loaded->l_searchlist; - _dl_global_scope[0] = &_dl_loaded->l_searchlist; + GL(dl_main_searchlist) = &GL(dl_loaded)->l_searchlist; + GL(dl_global_scope)[0] = &GL(dl_loaded)->l_searchlist; /* Save the information about the original global scope list since we need it in the memory handling later. */ - _dl_initial_searchlist = *_dl_main_searchlist; + GL(dl_initial_searchlist) = *GL(dl_main_searchlist); { /* Initialize _r_debug. */ - struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr); + struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr); struct link_map *l; - l = _dl_loaded; + l = GL(dl_loaded); #ifdef ELF_MACHINE_DEBUG_SETUP /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */ ELF_MACHINE_DEBUG_SETUP (l, r); - ELF_MACHINE_DEBUG_SETUP (&_dl_rtld_map, r); + ELF_MACHINE_DEBUG_SETUP (&GL(dl_rtld_map), r); #else @@ -1254,8 +1230,8 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Fill in the pointer in the dynamic linker's own dynamic section, in case you run gdb on the dynamic linker directly. */ - if (_dl_rtld_map.l_info[DT_DEBUG]) - _dl_rtld_map.l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r; + if (GL(dl_rtld_map).l_info[DT_DEBUG]) + GL(dl_rtld_map).l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r; #endif @@ -1350,7 +1326,7 @@ process_dl_debug (const char *dl_debug) if (strncmp (dl_debug, debopts[cnt].name, len) == 0 && debopts[cnt].name[len] == '\0') { - _dl_debug_mask |= debopts[cnt].mask; + GL(dl_debug_mask) |= debopts[cnt].mask; break; } @@ -1367,7 +1343,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy); } while (*(dl_debug += len) != '\0'); - if (_dl_debug_mask & DL_DEBUG_HELP) + if (GL(dl_debug_mask) & DL_DEBUG_HELP) { size_t cnt; @@ -1391,6 +1367,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n"); all the entries. */ extern char **_environ; + static void process_envvars (enum mode *modep) { @@ -1400,7 +1377,8 @@ process_envvars (enum mode *modep) char *debug_output = NULL; /* This is the default place for profiling data file. */ - _dl_profile_output = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; + GL(dl_profile_output) = &"/var/tmp\0/var/profile"[__libc_enable_secure + ? 9 : 0]; while ((envline = _dl_next_ld_env_entry (&runp)) != NULL) { @@ -1417,7 +1395,7 @@ process_envvars (enum mode *modep) case 4: /* Warning level, verbose or not. */ if (memcmp (envline, "WARN", 4) == 0) - _dl_verbose = envline[5] != '\0'; + GL(dl_verbose) = envline[5] != '\0'; break; case 5: @@ -1443,7 +1421,7 @@ process_envvars (enum mode *modep) /* Which shared object shall be profiled. */ if (memcmp (envline, "PROFILE", 7) == 0 && envline[8] != '\0') - _dl_profile = &envline[8]; + GL(dl_profile) = &envline[8]; break; case 8: @@ -1454,7 +1432,7 @@ process_envvars (enum mode *modep) break; } if (memcmp (envline, "BIND_NOT", 8) == 0) - _dl_bind_not = envline[9] != '\0'; + GL(dl_bind_not) = envline[9] != '\0'; break; case 9: @@ -1467,14 +1445,14 @@ process_envvars (enum mode *modep) case 10: /* Mask for the important hardware capabilities. */ if (memcmp (envline, "HWCAP_MASK", 10) == 0) - _dl_hwcap_mask = __strtoul_internal (&envline[11], NULL, 0, 0); + GL(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, 0, 0); break; case 11: /* Path where the binary is found. */ if (!__libc_enable_secure && memcmp (envline, "ORIGIN_PATH", 11) == 0) - _dl_origin_path = &envline[12]; + GL(dl_origin_path) = &envline[12]; break; case 12: @@ -1501,7 +1479,7 @@ process_envvars (enum mode *modep) if (!__libc_enable_secure && memcmp (envline, "PROFILE_OUTPUT", 14) == 0 && envline[15] != '\0') - _dl_profile_output = &envline[15]; + GL(dl_profile_output) = &envline[15]; break; case 16: @@ -1509,9 +1487,9 @@ process_envvars (enum mode *modep) if (memcmp (envline, "TRACE_PRELINKING", 16) == 0) { mode = trace; - _dl_verbose = 1; - _dl_debug_mask |= DL_DEBUG_PRELINK; - _dl_trace_prelink = &envline[17]; + GL(dl_verbose) = 1; + GL(dl_debug_mask) |= DL_DEBUG_PRELINK; + GL(dl_trace_prelink) = &envline[17]; } break; @@ -1624,9 +1602,9 @@ print_statistics (void) } #endif _dl_debug_printf (" number of relocations: %lu\n", - _dl_num_relocations); + GL(dl_num_relocations)); _dl_debug_printf (" number of relocations from cache: %lu\n", - _dl_num_cache_relocations); + GL(dl_num_cache_relocations)); #ifndef HP_TIMING_NONAVAIL /* Time spend while loading the object and the dependencies. */ diff --git a/malloc/thread-m.h b/malloc/thread-m.h index 145730c8c3..9cbfb497b8 100644 --- a/malloc/thread-m.h +++ b/malloc/thread-m.h @@ -1,8 +1,8 @@ /* Basic platform-independent macro definitions for mutexes and thread-specific data. - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Wolfram Gloger , 1996. + Contributed by Wolfram Gloger , 2001. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -117,6 +117,61 @@ __libc_tsd_define (, MALLOC) /* declaration/common definition */ typedef pthread_t thread_id; /* mutex */ +#if (defined __i386__ || defined __x86_64__) && defined __GNUC__ && \ + !defined USE_NO_SPINLOCKS + +#include + +/* Use fast inline spinlocks. */ +typedef struct { + volatile unsigned int lock; + int pad0_; +} mutex_t; + +#define MUTEX_INITIALIZER { 0 } +#define mutex_init(m) ((m)->lock = 0) +static inline int mutex_lock(mutex_t *m) { + int cnt = 0, r; + struct timespec tm; + + for(;;) { + __asm__ __volatile__ + ("xchgl %0, %1" + : "=r"(r), "=m"(m->lock) + : "0"(1), "m"(m->lock) + : "memory"); + if(!r) + return 0; + if(cnt < 50) { + sched_yield(); + cnt++; + } else { + tm.tv_sec = 0; + tm.tv_nsec = 2000001; + nanosleep(&tm, NULL); + cnt = 0; + } + } +} +static inline int mutex_trylock(mutex_t *m) { + int r; + + __asm__ __volatile__ + ("xchgl %0, %1" + : "=r"(r), "=m"(m->lock) + : "0"(1), "m"(m->lock) + : "memory"); + return r; +} +static inline int mutex_unlock(mutex_t *m) { + m->lock = 0; + __asm __volatile ("" : "=m" (m->lock) : "0" (m->lock)); + return 0; +} + +#else + +/* Normal pthread mutex. */ typedef pthread_mutex_t mutex_t; #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER @@ -125,6 +180,8 @@ typedef pthread_mutex_t mutex_t; #define mutex_trylock(m) pthread_mutex_trylock(m) #define mutex_unlock(m) pthread_mutex_unlock(m) +#endif /* (__i386__ || __x86_64__) && __GNUC__ && !USE_NO_SPINLOCKS */ + /* thread specific data */ #if defined(__sgi) || defined(USE_TSD_DATA_HACK) diff --git a/sysdeps/generic/dl-cache.c b/sysdeps/generic/dl-cache.c index 6ed26a3b7b..7ba00e46f7 100644 --- a/sysdeps/generic/dl-cache.c +++ b/sysdeps/generic/dl-cache.c @@ -1,5 +1,5 @@ /* Support for reading /etc/ld.so.cache files written by Linux ldconfig. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1996,1997,1998,1999,2000,2001,2002 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 @@ -26,8 +26,6 @@ #include -extern const char *_dl_platform; - #ifndef _DL_PLATFORMS_COUNT # define _DL_PLATFORMS_COUNT 0 #endif @@ -154,7 +152,7 @@ _dl_load_cache_lookup (const char *name) const char *best; /* Print a message if the loading of libs is traced. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE); if (cache == NULL) @@ -213,7 +211,9 @@ _dl_load_cache_lookup (const char *name) /* This file ends in static libraries where we don't have a hwcap. */ unsigned long int *hwcap; uint64_t platform; +#ifndef SHARED weak_extern (_dl_hwcap); +#endif /* This is where the strings start. */ cache_data = (const char *) cache_new; @@ -221,14 +221,15 @@ _dl_load_cache_lookup (const char *name) /* Now we can compute how large the string table is. */ cache_data_size = (const char *) cache + cachesize - cache_data; - hwcap = &_dl_hwcap; - platform = _dl_string_platform (_dl_platform); + hwcap = &GL(dl_hwcap); + platform = _dl_string_platform (GL(dl_platform)); if (platform != -1) platform = 1ULL << platform; /* Only accept hwcap if it's for the right platform. */ #define HWCAP_CHECK \ - if (_dl_osversion && cache_new->libs[middle].osversion > _dl_osversion) \ + if (GL(dl_osversion) \ + && cache_new->libs[middle].osversion > GL(dl_osversion)) \ continue; \ if (_DL_PLATFORMS_COUNT && platform != -1 \ && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0 \ @@ -253,7 +254,7 @@ _dl_load_cache_lookup (const char *name) } /* Print our result if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) && best != NULL) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0) && best != NULL) _dl_debug_printf (" trying file=%s\n", best); return best; diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c index 8d182be9e9..2954b3309f 100644 --- a/sysdeps/generic/dl-sysdep.c +++ b/sysdeps/generic/dl-sysdep.c @@ -1,5 +1,5 @@ /* Operating system support for run-time dynamic linker. Generic Unix version. - Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000, 2001, 2002 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 @@ -38,14 +38,7 @@ #include #include -extern int _dl_argc; -extern char **_dl_argv; extern char **_environ; -extern size_t _dl_pagesize; -extern int _dl_clktck; -extern const char *_dl_platform; -extern unsigned long int _dl_hwcap; -extern size_t _dl_platformlen; extern fpu_control_t _dl_fpu_control; extern void _end; @@ -61,7 +54,7 @@ int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion /* This variable contains the lowest stack address ever used. */ void *__libc_stack_end; static ElfW(auxv_t) *_dl_auxv; -unsigned long int _dl_hwcap_mask = HWCAP_IMPORTANT; +//Xunsigned long int _dl_hwcap_mask = HWCAP_IMPORTANT; #if HP_TIMING_AVAIL hp_timing_t _dl_cpuclock_offset; #endif @@ -109,7 +102,7 @@ _dl_sysdep_start (void **start_argptr, _dl_auxv); user_entry = (ElfW(Addr)) ENTRY_POINT; - _dl_platform = NULL; /* Default to nothing known about the platform. */ + GL(dl_platform) = NULL; /* Default to nothing known about the platform. */ for (av = _dl_auxv; av->a_type != AT_NULL; set_seen (av++)) switch (av->a_type) @@ -121,7 +114,7 @@ _dl_sysdep_start (void **start_argptr, phnum = av->a_un.a_val; break; case AT_PAGESZ: - _dl_pagesize = av->a_un.a_val; + GL(dl_pagesize) = av->a_un.a_val; break; case AT_ENTRY: user_entry = av->a_un.a_val; @@ -144,13 +137,13 @@ _dl_sysdep_start (void **start_argptr, egid = av->a_un.a_val; break; case AT_PLATFORM: - _dl_platform = av->a_un.a_ptr; + GL(dl_platform) = av->a_un.a_ptr; break; case AT_HWCAP: - _dl_hwcap = av->a_un.a_val; + GL(dl_hwcap) = av->a_un.a_val; break; case AT_CLKTCK: - _dl_clktck = av->a_un.a_val; + GL(dl_clktck) = av->a_un.a_val; break; case AT_FPUCW: _dl_fpu_control = av->a_un.a_val; @@ -188,8 +181,8 @@ _dl_sysdep_start (void **start_argptr, #endif /* Determine the length of the platform name. */ - if (_dl_platform != NULL) - _dl_platformlen = strlen (_dl_platform); + if (GL(dl_platform) != NULL) + GL(dl_platformlen) = strlen (GL(dl_platform)); if (__sbrk (0) == &_end) /* The dynamic linker was run as a program, and so the initial break @@ -197,7 +190,7 @@ _dl_sysdep_start (void **start_argptr, will consume the rest of this page, so tell the kernel to move the break up that far. When the user program examines its break, it will see this new value and not clobber our data. */ - __sbrk (_dl_pagesize - ((&_end - (void *) 0) & (_dl_pagesize - 1))); + __sbrk (GL(dl_pagesize) - ((&_end - (void *) 0) & (GL(dl_pagesize) - 1))); /* If this is a SUID program we make sure that FDs 0, 1, and 2 are allocated. If necessary we are doing it ourself. If it is not @@ -288,7 +281,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, size_t *max_capstrlen) { /* Determine how many important bits are set. */ - unsigned long int masked = _dl_hwcap & _dl_hwcap_mask; + unsigned long int masked = GL(dl_hwcap) & GL(dl_hwcap_mask); size_t cnt = platform != NULL; size_t n, m; size_t total; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 837d32d0ca..52303327c0 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000, 2001, 2002 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 @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -189,29 +190,35 @@ typedef void (*receiver_fct) (int, const char *, const char *); user interface to run-time dynamic linking. */ -/* Parameters passed to the dynamic linker. */ -extern char **_dl_argv; - -/* Cached value of `getpagesize ()'. */ -extern size_t _dl_pagesize; - -/* OS version. */ -extern unsigned int _dl_osversion; - -/* File descriptor referring to the zero-fill device. */ -extern int _dl_zerofd; - -/* Name of the shared object to be profiled (if any). */ -extern const char *_dl_profile; -/* Map of shared object to be profiled. */ -extern struct link_map *_dl_profile_map; -/* Filename of the output file. */ -extern const char *_dl_profile_output; -/* Map of shared object to be prelink traced. */ -extern struct link_map *_dl_trace_prelink_map; - -/* If nonzero the appropriate debug information is printed. */ -extern int _dl_debug_mask; +#ifndef SHARED +# define EXTERN extern +# define GL(name) _##name +#else +# define EXTERN +# define GL(name) _rtld_global._##name +struct rtld_global +{ +#endif + /* Don't change the order of the following elements. 'dl_loaded' + must remain the first element. Forever. */ + + /* And a pointer to the map for the main map. */ + EXTERN struct link_map *_dl_loaded; + /* Number of object in the _dl_loaded list. */ + EXTERN unsigned int _dl_nloaded; + /* Array representing global scope. */ + EXTERN struct r_scope_elem *_dl_global_scope[2]; + /* Direct pointer to the searchlist of the main object. */ + EXTERN struct r_scope_elem *_dl_main_searchlist; + /* Copy of the content of `_dl_main_searchlist'. */ + EXTERN struct r_scope_elem _dl_initial_searchlist; + /* This is zero at program start to signal that the global scope map is + allocated by rtld. Later it keeps the size of the map. It might be + reset if in _dl_close if the last global object is removed. */ + EXTERN size_t _dl_global_scope_alloc; + + /* If nonzero the appropriate debug information is printed. */ + EXTERN int _dl_debug_mask; #define DL_DEBUG_LIBS (1 << 0) #define DL_DEBUG_IMPCALLS (1 << 1) #define DL_DEBUG_BINDINGS (1 << 2) @@ -224,33 +231,94 @@ extern int _dl_debug_mask; #define DL_DEBUG_HELP (1 << 8) #define DL_DEBUG_PRELINK (1 << 9) -/* Expect cache ID. */ -extern int _dl_correct_cache_id; + /* Cached value of `getpagesize ()'. */ + EXTERN size_t _dl_pagesize; -/* Mask for hardware capabilities that are available. */ -extern unsigned long int _dl_hwcap; + /* OS version. */ + EXTERN unsigned int _dl_osversion; + /* Platform name. */ + EXTERN const char *_dl_platform; + EXTERN size_t _dl_platformlen; -/* Mask for important hardware capabilities we honour. */ -extern unsigned long int _dl_hwcap_mask; +#ifndef MAP_ANON + /* File descriptor referring to the zero-fill device. */ + EXTERN int _dl_zerofd; +#endif -/* File descriptor to write debug messages to. */ -extern int _dl_debug_fd; + /* CLK_TCK as reported by the kernel. */ + EXTERN int _dl_clktck; -/* Names of shared object for which the RPATH should be ignored. */ -extern const char *_dl_inhibit_rpath; + /* If nonzero print warnings messages. */ + EXTERN int _dl_verbose; -/* Nonzero if references should be treated as weak during runtime linking. */ -extern int _dl_dynamic_weak; + /* Nonzero if runtime lookups should not update the .got/.plt. */ + EXTERN int _dl_bind_not; + + /* The object to be initialized first. */ + EXTERN struct link_map *_dl_initfirst; + + /* Name of the shared object to be profiled (if any). */ + EXTERN const char *_dl_profile; + /* Map of shared object to be profiled. */ + EXTERN struct link_map *_dl_profile_map; + /* Filename of the output file. */ + EXTERN const char *_dl_profile_output; + /* Map of shared object to be prelink traced. */ + EXTERN struct link_map *_dl_trace_prelink_map; + /* Name of the object we want to trace the prelinking. */ + EXTERN const char *_dl_trace_prelink; + + /* Expect cache ID. */ + EXTERN int _dl_correct_cache_id; + + /* Counters for the number of relocations performed. */ + EXTERN unsigned long int _dl_num_relocations; + EXTERN unsigned long int _dl_num_cache_relocations; + + /* Mask for hardware capabilities that are available. */ + EXTERN unsigned long int _dl_hwcap; + + /* Mask for important hardware capabilities we honour. */ + EXTERN unsigned long int _dl_hwcap_mask; + + /* Names of shared object for which the RPATH should be ignored. */ + EXTERN const char *_dl_inhibit_rpath; + + /* Location of the binary. */ + EXTERN const char *_dl_origin_path; + + /* List of search directories. */ + EXTERN struct r_search_path_elem *_dl_all_dirs; + EXTERN struct r_search_path_elem *_dl_init_all_dirs; + + /* Structure describing the dynamic linker itself. */ + EXTERN struct link_map _dl_rtld_map; +#ifdef SHARED +}; +extern struct rtld_global _rtld_global; +#endif +#undef EXTERN + +/* Parameters passed to the dynamic linker. */ +extern int _dl_argc; +extern char **_dl_argv; + +/* Do we do lazy relocations? */ +extern int _dl_lazy; /* The array with message we print as a last resort. */ extern const char _dl_out_of_memory[]; -/* Nonzero if runtime lookups should not update the .got/.plt. */ -extern int _dl_bind_not; +/* File descriptor to write debug messages to. */ +extern int _dl_debug_fd; + +/* Nonzero if references should be treated as weak during runtime + linking. + + XXX Once we can set the default for this variable to zero move it + into _rtld_global. */ +extern int _dl_dynamic_weak; -/* List of search directories. */ -extern struct r_search_path_elem *_dl_all_dirs; -extern struct r_search_path_elem *_dl_init_all_dirs; /* OS-dependent function to open the zero-fill device. */ extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ @@ -400,24 +468,6 @@ extern lookup_t _dl_lookup_versioned_symbol_skip (const char *undef, extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) internal_function; - -/* Structure describing the dynamic linker itself. */ -extern struct link_map _dl_rtld_map; -/* And a pointer to the map for the main map. */ -extern struct link_map *_dl_loaded; -/* Number of object in the _dl_loaded list. */ -extern unsigned int _dl_nloaded; -/* Array representing global scope. */ -extern struct r_scope_elem *_dl_global_scope[2]; -/* Direct pointer to the searchlist of the main object. */ -extern struct r_scope_elem *_dl_main_searchlist; -/* Copy of the content of `_dl_main_searchlist'. */ -extern struct r_scope_elem _dl_initial_searchlist; -/* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ -extern size_t _dl_global_scope_alloc; - /* Allocate a `struct link_map' for a new object being loaded, and enter it into the _dl_main_map list. */ extern struct link_map *_dl_new_object (char *realname, const char *libname, diff --git a/sysdeps/generic/libc-start.c b/sysdeps/generic/libc-start.c index 71aef46731..4d1748614e 100644 --- a/sysdeps/generic/libc-start.c +++ b/sysdeps/generic/libc-start.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2001, 2002 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 @@ -115,14 +115,14 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), /* Call the initializer of the program, if any. */ #ifdef SHARED - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ninitialize program: %s\n\n", argv[0]); #endif if (init) (*init) (); #ifdef SHARED - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) + if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]); #endif diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index b86f11724b..338dbfbdbe 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. i386 version. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 @@ -94,7 +94,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { l->l_mach.plt = got[1] + l->l_addr; l->l_mach.gotplt = (Elf32_Addr) &got[3]; - } + } got[1] = (Elf32_Addr) l; /* Identify this shared object. */ /* The got[2] entry contains the address of a function which gets @@ -107,10 +107,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { got[2] = (Elf32_Addr) &_dl_runtime_profile; - if (_dl_name_match_p (_dl_profile, l)) + if (_dl_name_match_p (GL(dl_profile), l)) /* This is the object we are looking for. Say that we really want profiling and the timers are started. */ - _dl_profile_map = l; + GL(dl_profile_map) = l; } else /* This function will get called to fix up the GOT entry indicated by @@ -237,7 +237,7 @@ _dl_start_user:\n\ " RTLD_START_SPECIAL_INIT "\n\ # Load the parameters again.\n\ # (eax, edx, ecx, *--esp) = (_dl_loaded, argc, argv, envp)\n\ - movl _dl_loaded@GOT(%ebx), %esi\n\ + movl _rtld_global@GOT(%ebx), %esi\n\ leal 8(%esp,%edx,4), %eax\n\ leal 4(%esp), %ecx\n\ pushl %eax\n\ @@ -274,14 +274,12 @@ _dl_start_user:\n\ _dl_sysdep_start. */ #define DL_PLATFORM_INIT dl_platform_init () -extern const char *_dl_platform; - static inline void __attribute__ ((unused)) dl_platform_init (void) { - if (_dl_platform != NULL && *_dl_platform == '\0') + if (GL(dl_platform) != NULL && *GL(dl_platform) == '\0') /* Avoid an empty string which would disturb us. */ - _dl_platform = NULL; + GL(dl_platform) = NULL; } static inline Elf32_Addr @@ -372,7 +370,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, break; if (__builtin_expect (sym->st_size > refsym->st_size, 0) || (__builtin_expect (sym->st_size < refsym->st_size, 0) - && _dl_verbose)) + && GL(dl_verbose))) { const char *strtab; diff --git a/sysdeps/ia64/dl-fptr.c b/sysdeps/ia64/dl-fptr.c index 6916635281..dd8eb9d391 100644 --- a/sysdeps/ia64/dl-fptr.c +++ b/sysdeps/ia64/dl-fptr.c @@ -101,7 +101,7 @@ local = static struct ia64_fdesc * new_fdesc_table (struct local *l) { - size_t size = l->npages * _dl_pagesize; + size_t size = l->npages * GL(dl_pagesize); struct ia64_fdesc_table *new_table; struct ia64_fdesc *fdesc; @@ -174,7 +174,8 @@ make_fptr_table (struct link_map *map) symbol section is to assume that the string table follows right afterwards... */ len = ((strtab - (char *) symtab) / map->l_info[DT_SYMENT]->d_un.d_val); - size = ((len * sizeof (fptr_table[0]) + _dl_pagesize - 1) & -_dl_pagesize); + size = ((len * sizeof (fptr_table[0]) + GL(dl_pagesize) - 1) + & -GL(dl_pagesize)); /* XXX We don't support here in the moment systems without MAP_ANON. There probably are none for IA-64. In case this is proven wrong we will have to open /dev/null here and use the file descriptor diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h index 2af418c122..b81cf29ebd 100644 --- a/sysdeps/ia64/dl-machine.h +++ b/sysdeps/ia64/dl-machine.h @@ -145,11 +145,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) doit = (Elf64_Addr) ((struct ia64_fdesc *) &_dl_runtime_resolve)->ip; else { - if (_dl_name_match_p (_dl_profile, l)) + if (_dl_name_match_p (GL(dl_profile), l)) { /* This is the object we are looking for. Say that we really want profiling and the timers are started. */ - _dl_profile_map = l; + GL(dl_profile_map) = l; } doit = (Elf64_Addr) ((struct ia64_fdesc *) &_dl_runtime_profile)->ip; } @@ -381,7 +381,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) " { .mmi\n" \ " mov out3 = r11\n" \ " sub r17 = r17, r3 /* Substract _dl_skip_args. */\n" \ -" addl out0 = @ltoff(_dl_loaded), gp\n" \ +" addl out0 = @ltoff(_rtld_global), gp\n" \ " }\n" \ "1: /* Copy env. */\n" \ " { .mfi\n" \ @@ -528,7 +528,7 @@ elf_machine_rela (struct link_map *map, value = *reloc_addr; # if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC /* Already done in dynamic linker. */ - if (map != &_dl_rtld_map) + if (map != &GL(dl_rtld_map)) # endif value += map->l_addr; } diff --git a/sysdeps/unix/sysv/linux/dl-librecon.h b/sysdeps/unix/sysv/linux/dl-librecon.h index 5c34d00edb..d98afcb8a8 100644 --- a/sysdeps/unix/sysv/linux/dl-librecon.h +++ b/sysdeps/unix/sysv/linux/dl-librecon.h @@ -42,7 +42,7 @@ break; \ } \ if (osversion) \ - _dl_osversion = osversion; \ + GL(dl_osversion) = osversion; \ break; \ } diff --git a/sysdeps/unix/sysv/linux/dl-origin.c b/sysdeps/unix/sysv/linux/dl-origin.c index 9149a0a4de..90add58ef5 100644 --- a/sysdeps/unix/sysv/linux/dl-origin.c +++ b/sysdeps/unix/sysv/linux/dl-origin.c @@ -1,5 +1,5 @@ /* Find path of executable. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -29,7 +29,6 @@ /* On Linux >= 2.1 systems which have the dcache implementation we can get the path of the application from the /proc/self/exe symlink. Try this first and fall back on the generic method if necessary. */ -extern const char *_dl_origin_path; const char * _dl_get_origin (void) @@ -55,15 +54,15 @@ _dl_get_origin (void) result = (char *) -1; /* We use the environment variable LD_ORIGIN_PATH. If it is set make a copy and strip out trailing slashes. */ - if (_dl_origin_path != NULL) + if (GL(dl_origin_path) != NULL) { - size_t len = strlen (_dl_origin_path); + size_t len = strlen (GL(dl_origin_path)); result = malloc (len + 1); if (result == NULL) result = (char *) -1; else { - char *cp = __mempcpy (result, _dl_origin_path, len); + char *cp = __mempcpy (result, GL(dl_origin_path), len); while (cp > result + 1 && cp[-1] == '/') --cp; *cp = '\0'; diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h index 4976b3126d..1510b5b8c7 100644 --- a/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/sysdeps/unix/sysv/linux/dl-osinfo.h @@ -1,5 +1,5 @@ /* Operating system specific code for generic dynamic loader functions. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002 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 @@ -103,6 +103,6 @@ dl_fatal (const char *str) /* Not sufficent. */ \ FATAL ("FATAL: kernel too old\n"); \ \ - _dl_osversion = version; \ + GL(dl_osversion) = version; \ } \ } while (0) diff --git a/sysdeps/unix/sysv/linux/getclktck.c b/sysdeps/unix/sysv/linux/getclktck.c index 57deaa3727..dc8ec9b50b 100644 --- a/sysdeps/unix/sysv/linux/getclktck.c +++ b/sysdeps/unix/sysv/linux/getclktck.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002 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 @@ -18,6 +18,8 @@ #include +#include + #ifndef SYSTEM_CLK_TCK # define SYSTEM_CLK_TCK 100 #endif @@ -26,7 +28,5 @@ int __getclktck () { - extern int _dl_clktck; /* Defined in dl-load.c. */ - - return _dl_clktck ?: SYSTEM_CLK_TCK; + return GL(dl_clktck) ?: SYSTEM_CLK_TCK; } diff --git a/sysdeps/unix/sysv/linux/getpagesize.c b/sysdeps/unix/sysv/linux/getpagesize.c index a1796e8714..f030abc61b 100644 --- a/sysdeps/unix/sysv/linux/getpagesize.c +++ b/sysdeps/unix/sysv/linux/getpagesize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,1992,1995,1996,1997,2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1992,1995-1997,2000,2002 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 @@ -19,14 +19,14 @@ #include #include +#include + /* Return the system page size. */ int __getpagesize () { - extern size_t _dl_pagesize; - - if (_dl_pagesize != 0) - return _dl_pagesize; + if (GL(dl_pagesize) != 0) + return GL(dl_pagesize); #ifdef EXEC_PAGESIZE return EXEC_PAGESIZE; diff --git a/sysdeps/unix/sysv/linux/i386/dl-librecon.h b/sysdeps/unix/sysv/linux/i386/dl-librecon.h index 3e39a32e69..e01631146a 100644 --- a/sysdeps/unix/sysv/linux/i386/dl-librecon.h +++ b/sysdeps/unix/sysv/linux/i386/dl-librecon.h @@ -1,5 +1,5 @@ /* Optional code to distinguish library flavours. - Copyright (C) 1998, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -27,15 +27,15 @@ /* We have to find out whether the binary is linked against \ libc 5 or glibc. We do this by looking at all the DT_NEEDED \ entries. If one is libc.so.5 this is a libc 5 linked binary. */ \ - if (_dl_loaded->l_info[DT_NEEDED]) \ + if (GL(dl_loaded)->l_info[DT_NEEDED]) \ { \ /* We have dependencies. */ \ const ElfW(Dyn) *d; \ const char *strtab; \ \ - strtab = (const char *) D_PTR (_dl_loaded, l_info[DT_STRTAB]); \ + strtab = (const char *) D_PTR (GL(dl_loaded), l_info[DT_STRTAB]); \ \ - for (d = _dl_loaded->l_ld; d->d_tag != DT_NULL; ++d) \ + for (d = GL(dl_loaded)->l_ld; d->d_tag != DT_NULL; ++d) \ if (d->d_tag == DT_NEEDED \ && strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0) \ break; \ @@ -67,14 +67,14 @@ break; \ } \ if (osversion) \ - _dl_osversion = osversion; \ + GL(dl_osversion) = osversion; \ break; \ } \ \ case 15: \ if (memcmp (envline, "LIBRARY_VERSION", 15) == 0) \ { \ - _dl_correct_cache_id = envline[16] == '5' ? 2 : 3; \ + GL(dl_correct_cache_id) = envline[16] == '5' ? 2 : 3; \ break; \ } diff --git a/sysdeps/unix/sysv/linux/ia64/dl-static.c b/sysdeps/unix/sysv/linux/ia64/dl-static.c index 8be9d58b01..f74353e725 100644 --- a/sysdeps/unix/sysv/linux/ia64/dl-static.c +++ b/sysdeps/unix/sysv/linux/ia64/dl-static.c @@ -33,8 +33,8 @@ _dl_var_init (void *array[]) DL_CLKTCK }; - _dl_pagesize = *((size_t *) array[DL_PAGESIZE]); - _dl_clktck = *((int *) array[DL_CLKTCK]); + GL(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); + GL(dl_clktck) = *((int *) array[DL_CLKTCK]); } #else diff --git a/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/sysdeps/unix/sysv/linux/ia64/getpagesize.c index 67d0a3a5c2..0f1f8e13ed 100644 --- a/sysdeps/unix/sysv/linux/ia64/getpagesize.c +++ b/sysdeps/unix/sysv/linux/ia64/getpagesize.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -28,13 +29,11 @@ determine the page size to ensure proper alignment for calls such as mmap and friends. --davidm 99/11/30 */ -extern size_t _dl_pagesize; - int __getpagesize () { - assert (_dl_pagesize != 0); - return _dl_pagesize; + assert (GL(dl_pagesize) != 0); + return GL(dl_pagesize); } weak_alias (__getpagesize, getpagesize) -- cgit 1.4.1