diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | dlfcn/dlfcn.h | 17 | ||||
-rw-r--r-- | elf/dl-support.c | 3 | ||||
-rw-r--r-- | elf/do-lookup.h | 20 | ||||
-rw-r--r-- | elf/rtld.c | 13 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 3 |
6 files changed, 48 insertions, 18 deletions
@@ -1,5 +1,15 @@ 2000-06-07 Ulrich Drepper <drepper@redhat.com> + * dlfcn/dlfcn.h: Pretty print dladdr declaraction. + + * elf/rtld.c (process_envvars): Recognize LD_DYNAMIC_WEAK. + (_dl_dynamic_weak): New variable. + * elf/dl-support.c: Likewise. + * sysdeps/generic/ldsodefs.h: Declare _dl_dynamic_weak. + * elf/do-lookup.h: If we find a weak definition treat it like a + normal symbol unless _dl_dynamic_weak is nonzero. In the latter + case treat it like before. + * elf/dl-addr.c (_dl_addr): Fill in correct information if symbol is in main program. * elf/Versions [ld] (GLIBC_2.2): Export _dl_argv. diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index 4640f7d6c4..d20bffbca2 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -67,15 +67,18 @@ extern void *dlvsym (void *__restrict __handle, extern char *dlerror (void) __THROW; #ifdef __USE_GNU +/* Structure containing information about object searched using + `dladdr'. */ +typedef struct +{ + __const char *dli_fname; /* File name of defining object. */ + void *dli_fbase; /* Load address of that object. */ + __const char *dli_sname; /* Name of nearest symbol. */ + void *dli_saddr; /* Exact value of nearest symbol. */ +} Dl_info; + /* Fill in *INFO with the following information about ADDRESS. Returns 0 iff no shared object's segments contain that address. */ -typedef struct - { - __const char *dli_fname; /* File name of defining object. */ - void *dli_fbase; /* Load address of that object. */ - __const char *dli_sname; /* Name of nearest symbol. */ - void *dli_saddr; /* Exact value of nearest symbol. */ - } Dl_info; extern int dladdr (const void *__address, Dl_info *__info) __THROW; #endif diff --git a/elf/dl-support.c b/elf/dl-support.c index 68973cc5c1..4006d960dd 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -42,6 +42,7 @@ int _dl_debug_versions; int _dl_debug_reloc; int _dl_debug_files; int _dl_lazy; +int _dl_dynamic_weak; /* If nonzero print warnings about problematic situations. */ int _dl_verbose; @@ -107,6 +108,8 @@ non_dynamic_init (void) _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; + _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; + #ifdef DL_PLATFORM_INIT DL_PLATFORM_INIT; #endif diff --git a/elf/do-lookup.h b/elf/do-lookup.h index 873e95322c..ffc98ab624 100644 --- a/elf/do-lookup.h +++ b/elf/do-lookup.h @@ -157,19 +157,23 @@ FCT (const char *undef_name, struct link_map *undef_map, found_it: switch (ELFW(ST_BIND) (sym->st_info)) { + case STB_WEAK: + /* Weak definition. Use this value if we don't find another. */ + if (__builtin_expect (_dl_dynamic_weak, 0)) + { + if (! result->s) + { + result->s = sym; + result->m = map; + } + break; + } + /* FALLTHROUGH */ case STB_GLOBAL: /* Global definition. Just what we need. */ result->s = sym; result->m = map; return 1; - case STB_WEAK: - /* Weak definition. Use this value if we don't find another. */ - if (! result->s) - { - result->s = sym; - result->m = map; - } - break; default: /* Local symbols are ignored. */ break; diff --git a/elf/rtld.c b/elf/rtld.c index f358700466..6bf1dba089 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -87,6 +87,7 @@ const char *_dl_profile; const char *_dl_profile_output; struct link_map *_dl_profile_map; int _dl_lazy; +int _dl_dynamic_weak; int _dl_debug_libs; int _dl_debug_impcalls; int _dl_debug_bindings; @@ -1393,6 +1394,13 @@ process_envvars (enum mode *modep, int *lazyp) break; case 12: + /* The library search path. */ + if (memcmp (&envline[3], "LIBRARY_PATH", 12) == 0) + { + library_path = &envline[16]; + break; + } + /* Where to place the profiling data file. */ if (memcmp (&envline[3], "DEBUG_OUTPUT", 12) == 0) { @@ -1400,9 +1408,8 @@ process_envvars (enum mode *modep, int *lazyp) break; } - /* The library search path. */ - if (memcmp (&envline[3], "LIBRARY_PATH", 12) == 0) - library_path = &envline[16]; + if (memcmp (&envline[3], "DYNAMIC_WEAK", 12) == 0) + _dl_dynamic_weak = 1; break; case 14: diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 4fc1578a95..e01aed12a3 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -189,6 +189,9 @@ extern int _dl_debug_fd; /* Names of shared object for which the RPATH should be ignored. */ extern const char *_dl_inhibit_rpath; +/* Nonzero if references should be treated as weak during runtime linking. */ +extern int _dl_dynamic_weak; + /* OS-dependent function to open the zero-fill device. */ extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ |