diff options
Diffstat (limited to 'sysdeps/generic/ldsodefs.h')
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 369 |
1 files changed, 241 insertions, 128 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 2733ac8268..95dc87519b 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-2016 Free Software Foundation, Inc. + Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -66,14 +66,21 @@ __BEGIN_DECLS /* Result of the lookup functions and how to retrieve the base address. */ typedef struct link_map *lookup_t; #define LOOKUP_VALUE(map) map -#define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0) +#define LOOKUP_VALUE_ADDRESS(map, set) ((set) || (map) ? (map)->l_addr : 0) + +/* Calculate the address of symbol REF using the base address from map MAP, + if non-NULL. Don't check for NULL map if MAP_SET is TRUE. */ +#define SYMBOL_ADDRESS(map, ref, map_set) \ + ((ref) == NULL ? 0 \ + : (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0 \ + : LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value) /* On some architectures a pointer to a function is not just a pointer to the actual code of the function but rather an architecture specific descriptor. */ #ifndef ELF_FUNCTION_PTR_IS_SPECIAL # define DL_SYMBOL_ADDRESS(map, ref) \ - (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value) + (void *) SYMBOL_ADDRESS (map, ref, false) # define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr)) # define DL_CALL_DT_INIT(map, start, argc, argv, env) \ ((init_t) (start)) (argc, argv, env) @@ -88,6 +95,19 @@ typedef struct link_map *lookup_t; || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size) \ && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value)) +/* According to the ELF gABI no STV_HIDDEN or STV_INTERNAL symbols are + expected to be present in dynamic symbol tables as they should have + been either removed or converted to STB_LOCAL binding by the static + linker. However some GNU binutils versions produce such symbols in + some cases. To prevent such symbols present in a buggy binary from + preempting global symbols we filter them out with this predicate. */ +static __always_inline bool +dl_symbol_visibility_binds_local_p (const ElfW(Sym) *sym) +{ + return (ELFW(ST_VISIBILITY) (sym->st_other) == STV_HIDDEN + || ELFW(ST_VISIBILITY) (sym->st_other) == STV_INTERNAL); +} + /* Unmap a loaded object, called by _dl_close (). */ #ifndef DL_UNMAP_IS_SPECIAL # define DL_UNMAP(map) _dl_unmap_segments (map) @@ -235,11 +255,14 @@ struct audit_ifaces /* Test whether given NAME matches any of the names of the given object. */ extern int _dl_name_match_p (const char *__name, const struct link_map *__map) - internal_function attribute_hidden; + attribute_hidden; /* Compute next higher prime number. */ extern unsigned long int _dl_higher_prime_number (unsigned long int n) - internal_function attribute_hidden; + attribute_hidden; + +/* A stripped down strtoul-like implementation. */ +uint64_t _dl_strtoul (const char *, char **) attribute_hidden; /* Function used as argument for `_dl_receive_error' function. The arguments are the error code, error string, and the objname the @@ -344,10 +367,6 @@ struct rtld_global /* List of search directories. */ EXTERN struct r_search_path_elem *_dl_all_dirs; -#ifdef _LIBC_REENTRANT - EXTERN void **(*_dl_error_catch_tsd) (void) __attribute__ ((const)); -#endif - /* Structure describing the dynamic linker itself. We need to reserve memory for the data the audit libraries need. */ EXTERN struct link_map _dl_rtld_map; @@ -361,10 +380,17 @@ struct rtld_global EXTERN void (*_dl_rtld_unlock_recursive) (void *); #endif + /* Get architecture specific definitions. */ +#define PROCINFO_DECL +#ifndef PROCINFO_CLASS +# define PROCINFO_CLASS EXTERN +#endif +#include <dl-procruntime.c> + /* If loading a shared object requires that we make the stack executable when it was not, we do it by calling this function. It returns an errno code or zero on success. */ - EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function; + EXTERN int (*_dl_make_stack_executable_hook) (void **); /* Prevailing state of the stack, PF_X indicating it's executable. */ EXTERN ElfW(Word) _dl_stack_flags; @@ -416,6 +442,9 @@ struct rtld_global size_t count; void *list[50]; } *_dl_scope_free_list; +#if !THREAD_GSCOPE_IN_TCB + EXTERN int _dl_thread_gscope_count; +#endif #ifdef SHARED }; # define __rtld_global_attribute__ @@ -506,17 +535,17 @@ struct rtld_global_ro /* Mask for hardware capabilities that are available. */ EXTERN uint64_t _dl_hwcap; +#if !HAVE_TUNABLES /* Mask for important hardware capabilities we honour. */ EXTERN uint64_t _dl_hwcap_mask; +#endif +#ifdef HAVE_AUX_VECTOR /* Pointer to the auxv list supplied to the program at startup. */ EXTERN ElfW(auxv_t) *_dl_auxv; +#endif /* Get architecture specific definitions. */ -#define PROCINFO_DECL -#ifndef PROCINFO_CLASS -# define PROCINFO_CLASS EXTERN -#endif #include <dl-procinfo.c> /* Names of shared object for which the RPATH should be ignored. */ @@ -539,7 +568,11 @@ struct rtld_global_ro /* Map of shared object to be prelink traced. */ EXTERN struct link_map *_dl_trace_prelink_map; - /* All search directories defined at startup. */ + /* All search directories defined at startup. This is assigned a + non-NULL pointer by the ld.so startup code (after initialization + to NULL), so this can also serve as an indicator whether a copy + of ld.so is initialized and active. See the rtld_active function + below. */ EXTERN struct r_search_path_elem *_dl_init_all_dirs; #ifdef NEED_DL_SYSINFO @@ -568,19 +601,11 @@ struct rtld_global_ro PLT relocations in libc.so. */ void (*_dl_debug_printf) (const char *, ...) __attribute__ ((__format__ (__printf__, 1, 2))); - int (internal_function *_dl_catch_error) (const char **, const char **, - bool *, void (*) (void *), void *); - void (internal_function *_dl_signal_error) (int, const char *, const char *, - const char *); void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc); - lookup_t (internal_function *_dl_lookup_symbol_x) (const char *, - struct link_map *, - const ElfW(Sym) **, - struct r_scope_elem *[], - const struct r_found_version *, - int, int, - struct link_map *); - int (*_dl_check_caller) (const void *, enum allowmask); + lookup_t (*_dl_lookup_symbol_x) (const char *, struct link_map *, + const ElfW(Sym) **, struct r_scope_elem *[], + const struct r_found_version *, int, int, + struct link_map *); void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]); void (*_dl_close) (void *map); @@ -617,16 +642,9 @@ extern const ElfW(Phdr) *_dl_phdr; extern size_t _dl_phnum; #endif -#if IS_IN (rtld) -/* This is the initial value of GL(dl_error_catch_tsd). - A non-TLS libpthread will change it. */ -extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const)) - attribute_hidden; -#endif - /* This is the initial value of GL(dl_make_stack_executable_hook). A threads library can change it. */ -extern int _dl_make_stack_executable (void **stack_endp) internal_function; +extern int _dl_make_stack_executable (void **stack_endp); rtld_hidden_proto (_dl_make_stack_executable) /* Variable pointing to the end of the stack (or close to it). This value @@ -690,9 +708,20 @@ extern void _dl_debug_printf_c (const char *fmt, ...) /* Write a message on the specified descriptor FD. The parameters are interpreted as for a `printf' call. */ +#if IS_IN (rtld) || !defined (SHARED) extern void _dl_dprintf (int fd, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))) attribute_hidden; +#else +__attribute__ ((always_inline, __format__ (__printf__, 2, 3))) +static inline void +_dl_dprintf (int fd, const char *fmt, ...) +{ + /* Use local declaration to avoid includign <stdio.h>. */ + extern int __dprintf(int fd, const char *format, ...) attribute_hidden; + __dprintf (fd, fmt, __builtin_va_arg_pack ()); +} +#endif /* Write a message on the specified descriptor standard output. The parameters are interpreted as for a `printf' call. */ @@ -715,41 +744,118 @@ extern void _dl_dprintf (int fd, const char *fmt, ...) while (1) -/* This function is called by all the internal dynamic linker functions - when they encounter an error. ERRCODE is either an `errno' code or - zero; OBJECT is the name of the problematical shared object, or null if - it is a general problem; ERRSTRING is a string describing the specific - problem. */ +/* An exception raised by the _dl_signal_error function family and + caught by _dl_catch_error function family. Exceptions themselves + are copied as part of the raise operation, but the strings are + not. */ +struct dl_exception +{ + const char *objname; + const char *errstring; + + /* This buffer typically stores both objname and errstring + above. */ + char *message_buffer; +}; + +/* Creates a new exception. This calls malloc; if allocation fails, + dummy values are inserted. OBJECT is the name of the problematical + shared object, or null if its a general problem. ERRSTRING is a + string describing the specific problem. */ +void _dl_exception_create (struct dl_exception *, const char *object, + const char *errstring) + __attribute__ ((nonnull (1, 3))); +rtld_hidden_proto (_dl_exception_create) + +/* Like _dl_exception_create, but create errstring from a format + string FMT. Currently, only "%s" and "%%" are supported as format + directives. */ +void _dl_exception_create_format (struct dl_exception *, const char *objname, + const char *fmt, ...) + __attribute__ ((nonnull (1, 3), format (printf, 3, 4))); +rtld_hidden_proto (_dl_exception_create_format) + +/* Deallocate the exception, freeing allocated buffers (if + possible). */ +void _dl_exception_free (struct dl_exception *) + __attribute__ ((nonnull (1))); +rtld_hidden_proto (_dl_exception_free) + +/* This function is called by all the internal dynamic linker + functions when they encounter an error. ERRCODE is either an + `errno' code or zero; it specifies the return value of + _dl_catch_error. OCCASION is included in the error message if the + process is terminated immediately. */ +void _dl_signal_exception (int errcode, struct dl_exception *, + const char *occasion) + __attribute__ ((__noreturn__)); +libc_hidden_proto (_dl_signal_exception) + +/* Like _dl_signal_exception, but creates the exception first. */ extern void _dl_signal_error (int errcode, const char *object, - const char *occurred, const char *errstring) - internal_function __attribute__ ((__noreturn__)) attribute_hidden; + const char *occasion, const char *errstring) + __attribute__ ((__noreturn__)); +libc_hidden_proto (_dl_signal_error) + +/* Like _dl_signal_exception, but may return when called in the + context of _dl_receive_error. This is only used during ld.so + bootstrap. In static and profiled builds, this is equivalent to + _dl_signal_exception. */ +#if IS_IN (rtld) +extern void _dl_signal_cexception (int errcode, struct dl_exception *, + const char *occasion) attribute_hidden; +#else +__attribute__ ((always_inline)) +static inline void +_dl_signal_cexception (int errcode, struct dl_exception *exception, + const char *occasion) +{ + _dl_signal_exception (errcode, exception, occasion); +} +#endif -/* Like _dl_signal_error, but may return when called in the context of - _dl_receive_error. */ +/* See _dl_signal_cexception above. */ +#if IS_IN (rtld) extern void _dl_signal_cerror (int errcode, const char *object, - const char *occation, const char *errstring) - internal_function attribute_hidden; + const char *occasion, const char *errstring) + attribute_hidden; +#else +__attribute__ ((always_inline)) +static inline void +_dl_signal_cerror (int errcode, const char *object, + const char *occasion, const char *errstring) +{ + _dl_signal_error (errcode, object, occasion, errstring); +} +#endif /* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike `_dl_catch_error' the operation is resumed after the OPERATE function returns. ARGS is passed as argument to OPERATE. */ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), - void *args) - internal_function attribute_hidden; - -/* Call OPERATE, catching errors from `dl_signal_error'. If there is no - error, *ERRSTRING is set to null. If there is an error, *ERRSTRING is - set to a string constructed from the strings passed to _dl_signal_error, - and the error code passed is the return value and *OBJNAME is set to - the object name which experienced the problems. ERRSTRING if nonzero - points to a malloc'ed string which the caller has to free after use. - ARGS is passed as argument to OPERATE. MALLOCEDP is set to true only - if the returned string is allocated using the libc's malloc. */ + void *args) attribute_hidden; + +/* Call OPERATE, catching errors from `_dl_signal_error' and related + functions. If there is no error, *ERRSTRING is set to null. If + there is an error, *ERRSTRING is set to a string constructed from + the strings passed to _dl_signal_error, and the error code passed + is the return value and *OBJNAME is set to the object name which + experienced the problems. ERRSTRING if nonzero points to a + malloc'ed string which the caller has to free after use. ARGS is + passed as argument to OPERATE. MALLOCEDP is set to true only if + the returned string is allocated using the libc's malloc. */ extern int _dl_catch_error (const char **objname, const char **errstring, bool *mallocedp, void (*operate) (void *), - void *args) - internal_function attribute_hidden; + void *args); +libc_hidden_proto (_dl_catch_error) + +/* Call OPERATE (ARGS). If no error occurs, set *EXCEPTION to zero. + Otherwise, store a copy of the raised exception in *EXCEPTION, + which has to be freed by _dl_exception_free. */ +int _dl_catch_exception (struct dl_exception *exception, + void (*operate) (void *), void *args); +libc_hidden_proto (_dl_catch_exception) /* Open the shared object NAME and map in its segments. LOADER's DT_RPATH is used in searching for NAME. @@ -757,8 +863,7 @@ extern int _dl_catch_error (const char **objname, const char **errstring, extern struct link_map *_dl_map_object (struct link_map *loader, const char *name, int type, int trace_mode, int mode, - Lmid_t nsid) - internal_function attribute_hidden; + Lmid_t nsid) attribute_hidden; /* Call _dl_map_object on the dependencies of MAP, and set up MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously @@ -768,11 +873,10 @@ extern void _dl_map_object_deps (struct link_map *map, struct link_map **preloads, unsigned int npreloads, int trace_mode, int open_mode) - internal_function attribute_hidden; + attribute_hidden; /* Cache the locations of MAP's hash table. */ -extern void _dl_setup_hash (struct link_map *map) - internal_function attribute_hidden; +extern void _dl_setup_hash (struct link_map *map) attribute_hidden; /* Collect the directories in the search path for LOADER's dependencies. @@ -781,8 +885,7 @@ extern void _dl_setup_hash (struct link_map *map) by a previous call with COUNTING set, and SI must point to SI->dls_size bytes to be used in filling in the result. */ extern void _dl_rtld_di_serinfo (struct link_map *loader, - Dl_serinfo *si, bool counting) - internal_function; + Dl_serinfo *si, bool counting); /* Search loaded objects' symbol tables for a definition of the symbol @@ -813,22 +916,18 @@ extern lookup_t _dl_lookup_symbol_x (const char *undef, const struct r_found_version *version, int type_class, int flags, struct link_map *skip_map) - internal_function attribute_hidden; - + attribute_hidden; -/* Look up symbol NAME in MAP's scope and return its run-time address. */ -extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) - internal_function; /* Add the new link_map NEW to the end of the namespace list. */ extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) - internal_function attribute_hidden; + attribute_hidden; /* Allocate a `struct link_map' for a new object being loaded. */ extern struct link_map *_dl_new_object (char *realname, const char *libname, int type, struct link_map *loader, int mode, Lmid_t nsid) - internal_function attribute_hidden; + attribute_hidden; /* Relocate the given object (if it hasn't already been). SCOPE is passed to _dl_lookup_symbol in symbol lookups. @@ -839,15 +938,14 @@ extern void _dl_relocate_object (struct link_map *map, attribute_hidden; /* Protect PT_GNU_RELRO area. */ -extern void _dl_protect_relro (struct link_map *map) - internal_function attribute_hidden; +extern void _dl_protect_relro (struct link_map *map) attribute_hidden; /* Call _dl_signal_error with a message about an unhandled reloc type. TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value. PLT is nonzero if this was a PLT reloc; it just affects the message. */ extern void _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) - internal_function attribute_hidden __attribute__ ((__noreturn__)); + attribute_hidden __attribute__ ((__noreturn__)); /* Resolve conflicts if prelinking. */ extern void _dl_resolve_conflicts (struct link_map *l, @@ -858,28 +956,25 @@ extern void _dl_resolve_conflicts (struct link_map *l, /* Check the version dependencies of all objects available through MAP. If VERBOSE print some more diagnostics. */ extern int _dl_check_all_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function attribute_hidden; + int trace_mode) attribute_hidden; /* Check the version dependencies for MAP. If VERBOSE print some more diagnostics. */ extern int _dl_check_map_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function attribute_hidden; + int trace_mode) attribute_hidden; /* Initialize the object in SCOPE by calling the constructors with ARGC, ARGV, and ENV as the parameters. */ extern void _dl_init (struct link_map *main_map, int argc, char **argv, - char **env) internal_function attribute_hidden; + char **env) attribute_hidden; /* Call the finalizer functions of all shared objects whose initializer functions have completed. */ -extern void _dl_fini (void) internal_function; +extern void _dl_fini (void) attribute_hidden; /* Sort array MAPS according to dependencies of the contained objects. */ -extern void _dl_sort_fini (struct link_map **maps, size_t nmaps, char *used, - Lmid_t ns) - internal_function attribute_hidden; +extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, + char *used, bool for_fini) attribute_hidden; /* The dynamic linker calls this function before and having changing any shared object mappings. The `r_state' member of `struct r_debug' @@ -892,15 +987,14 @@ rtld_hidden_proto (_dl_debug_state) argument is the run-time load address of the dynamic linker, to be put in the `r_ldbase' member. Returns the address of the structure. */ extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns) - internal_function attribute_hidden; + attribute_hidden; /* Initialize the basic data structure for the search paths. */ -extern void _dl_init_paths (const char *library_path) - internal_function attribute_hidden; +extern void _dl_init_paths (const char *library_path) attribute_hidden; /* Gather the information needed to install the profiling tables and start the timers. */ -extern void _dl_start_profile (void) internal_function attribute_hidden; +extern void _dl_start_profile (void) attribute_hidden; /* The actual functions used to keep book on the calls. */ extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc); @@ -912,25 +1006,22 @@ rtld_hidden_proto (_dl_mcount) extern void _dl_mcount_wrapper (void *selfpc); /* Show the members of the auxiliary array passed up from the kernel. */ -extern void _dl_show_auxv (void) - internal_function attribute_hidden; +extern void _dl_show_auxv (void) attribute_hidden; /* Return all environment variables starting with `LD_', one after the other. */ -extern char *_dl_next_ld_env_entry (char ***position) - internal_function attribute_hidden; +extern char *_dl_next_ld_env_entry (char ***position) attribute_hidden; /* Return an array with the names of the important hardware capabilities. */ extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform, size_t paltform_len, size_t *sz, size_t *max_capstrlen) - internal_function attribute_hidden; + attribute_hidden; /* Look up NAME in ld.so.cache and return the file name stored there, or null if none is found. Caller must free returned string. */ -extern char *_dl_load_cache_lookup (const char *name) - internal_function attribute_hidden; +extern char *_dl_load_cache_lookup (const char *name) attribute_hidden; /* If the system does not support MAP_COPY we cannot leave the file open all the time since this would create problems when the file is replaced. @@ -942,8 +1033,7 @@ extern void _dl_unload_cache (void) attribute_hidden; most convenient manner available. *SIZEP gets the size of the file. On error MAP_FAILED is returned. */ extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep, - int prot) - internal_function attribute_hidden; + int prot) attribute_hidden; /* System-specific function to do initial startup for the dynamic linker. After this, file access calls and getenv must work. This is responsible @@ -956,45 +1046,57 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, ElfW(auxv_t) *auxv)) attribute_hidden; -extern void _dl_sysdep_start_cleanup (void) - internal_function attribute_hidden; +extern void _dl_sysdep_start_cleanup (void) attribute_hidden; /* Determine next available module ID. */ -extern size_t _dl_next_tls_modid (void) internal_function attribute_hidden; +extern size_t _dl_next_tls_modid (void) attribute_hidden; /* Count the modules with TLS segments. */ -extern size_t _dl_count_modids (void) internal_function attribute_hidden; +extern size_t _dl_count_modids (void) attribute_hidden; /* Calculate offset of the TLS blocks in the static TLS block. */ -extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden; +extern void _dl_determine_tlsoffset (void) attribute_hidden; + +#ifndef SHARED +/* Set up the TCB for statically linked applications. This is called + early during startup because we always use TLS (for errno and the + stack protector, among other things). */ +void __libc_setup_tls (void); + +# if ENABLE_STATIC_PIE +/* Relocate static executable with PIE. */ +extern void _dl_relocate_static_pie (void) attribute_hidden; + +/* Get a pointer to _dl_main_map. */ +extern struct link_map * _dl_get_dl_main_map (void) + __attribute__ ((visibility ("hidden"))); +# else +# define _dl_relocate_static_pie() +# endif +#endif -/* Set up the data structures for TLS, when they were not set up at startup. - Returns nonzero on malloc failure. - This is called from _dl_map_object_from_fd or by libpthread. */ -extern int _dl_tls_setup (void) internal_function; -rtld_hidden_proto (_dl_tls_setup) +/* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ +void __pthread_initialize_minimal (void) weak_function; /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */ -extern void *_dl_allocate_tls (void *mem) internal_function; +extern void *_dl_allocate_tls (void *mem); rtld_hidden_proto (_dl_allocate_tls) /* Get size and alignment requirements of the static TLS block. */ -extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp) - internal_function; +extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp); -extern void _dl_allocate_static_tls (struct link_map *map) - internal_function attribute_hidden; +extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden; /* These are internal entry points to the two halves of _dl_allocate_tls, only used within rtld.c itself at startup time. */ -extern void *_dl_allocate_tls_storage (void) - internal_function attribute_hidden; -extern void *_dl_allocate_tls_init (void *) internal_function; +extern void *_dl_allocate_tls_storage (void) attribute_hidden; +extern void *_dl_allocate_tls_init (void *); rtld_hidden_proto (_dl_allocate_tls_init) /* Deallocate memory allocated with _dl_allocate_tls. */ -extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function; +extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb); rtld_hidden_proto (_dl_deallocate_tls) extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden; @@ -1003,15 +1105,11 @@ extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden; extern const char *_dl_get_origin (void) attribute_hidden; /* Count DSTs. */ -extern size_t _dl_dst_count (const char *name, int is_path) attribute_hidden; +extern size_t _dl_dst_count (const char *name) attribute_hidden; /* Substitute DST values. */ extern char *_dl_dst_substitute (struct link_map *l, const char *name, - char *result, int is_path) attribute_hidden; - -/* Check validity of the caller. */ -extern int _dl_check_caller (const void *caller, enum allowmask mask) - attribute_hidden; + char *result) attribute_hidden; /* Open the shared object NAME, relocate it, and run its initializer if it hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If @@ -1038,22 +1136,37 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid) extern void *_dl_tls_get_addr_soft (struct link_map *l) attribute_hidden; extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) - internal_function attribute_hidden; + attribute_hidden; /* Show show of an object. */ extern void _dl_show_scope (struct link_map *new, int from) attribute_hidden; -extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr) - internal_function; +extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr); rtld_hidden_proto (_dl_find_dso_for_object) /* Initialization which is normally done by the dynamic linker. */ -extern void _dl_non_dynamic_init (void) internal_function; +extern void _dl_non_dynamic_init (void) + attribute_hidden; /* Used by static binaries to check the auxiliary vector. */ -extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function; +extern void _dl_aux_init (ElfW(auxv_t) *av) + attribute_hidden; +/* Return true if the ld.so copy in this namespace is actually active + and working. If false, the dl_open/dlfcn hooks have to be used to + call into the outer dynamic linker (which happens after static + dlopen). */ +#ifdef SHARED +static inline bool +rtld_active (void) +{ + /* The default-initialized variable does not have a non-zero + dl_init_all_dirs member, so this allows us to recognize an + initialized and active ld.so copy. */ + return GLRO(dl_init_all_dirs) != NULL; +} +#endif __END_DECLS |