From 9e78f6f6e7134a5f299cc8de77370218f8019237 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 30 Nov 2016 15:59:57 +0100 Subject: Implement _dl_catch_error, _dl_signal_error in libc.so [BZ #16628] This change moves the main implementation of _dl_catch_error, _dl_signal_error to libc.so, where TLS variables can be used directly. This removes a writable function pointer from the rtld_global variable. For use during initial relocation, minimal implementations of these functions are provided in ld.so. These are eventually interposed by the libc.so implementations. This is implemented by compiling elf/dl-error-skeleton.c twice, via elf/dl-error.c and elf/dl-error-minimal.c. As a side effect of this change, the static version of dl-error.c no longer includes support for the _dl_signal_cerror/_dl_receive_error mechanism because it is only used in ld.so. --- sysdeps/generic/ldsodefs.h | 46 +++++++++++++--------- sysdeps/generic/localplt.data | 3 ++ sysdeps/unix/sysv/linux/aarch64/localplt.data | 3 ++ sysdeps/unix/sysv/linux/alpha/localplt.data | 3 ++ sysdeps/unix/sysv/linux/arm/localplt.data | 3 ++ sysdeps/unix/sysv/linux/hppa/localplt.data | 3 ++ sysdeps/unix/sysv/linux/i386/localplt.data | 3 ++ sysdeps/unix/sysv/linux/ia64/localplt.data | 3 ++ sysdeps/unix/sysv/linux/m68k/localplt.data | 3 ++ sysdeps/unix/sysv/linux/microblaze/localplt.data | 3 ++ sysdeps/unix/sysv/linux/nios2/localplt.data | 3 ++ .../sysv/linux/powerpc/powerpc32/fpu/localplt.data | 3 ++ .../linux/powerpc/powerpc32/nofpu/localplt.data | 3 ++ .../sysv/linux/powerpc/powerpc64/localplt.data | 3 ++ sysdeps/unix/sysv/linux/s390/localplt.data | 3 ++ sysdeps/unix/sysv/linux/sh/localplt.data | 3 ++ .../unix/sysv/linux/sparc/sparc32/localplt.data | 3 ++ .../unix/sysv/linux/sparc/sparc64/localplt.data | 3 ++ sysdeps/x86_64/localplt.data | 3 ++ 19 files changed, 82 insertions(+), 18 deletions(-) (limited to 'sysdeps') diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index f68fdf4501..288f5fe32e 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -357,10 +357,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; @@ -583,10 +579,6 @@ 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 *, @@ -632,13 +624,6 @@ 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; @@ -705,9 +690,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 . */ + 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. */ @@ -737,13 +733,26 @@ extern void _dl_dprintf (int fd, const char *fmt, ...) problem. */ extern void _dl_signal_error (int errcode, const char *object, const char *occurred, const char *errstring) - internal_function __attribute__ ((__noreturn__)) attribute_hidden; + internal_function __attribute__ ((__noreturn__)); +libc_hidden_proto (_dl_signal_error) /* Like _dl_signal_error, but may return when called in the context of - _dl_receive_error. */ + _dl_receive_error. This is only used during ld.so bootstrap. In + static and profiled builds, this is equivalent to + _dl_signal_error. */ +#if IS_IN (rtld) extern void _dl_signal_cerror (int errcode, const char *object, const char *occation, const char *errstring) internal_function attribute_hidden; +#else +__attribute__ ((always_inline)) +static inline void +_dl_signal_cerror (int errcode, const char *object, + const char *occation, const char *errstring) +{ + _dl_signal_error (errcode, object, occation, errstring); +} +#endif /* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike `_dl_catch_error' the operation is resumed after the OPERATE @@ -764,7 +773,8 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), extern int _dl_catch_error (const char **objname, const char **errstring, bool *mallocedp, void (*operate) (void *), void *args) - internal_function attribute_hidden; + internal_function; +libc_hidden_proto (_dl_catch_error) /* Open the shared object NAME and map in its segments. LOADER's DT_RPATH is used in searching for NAME. diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data index 1a40cf9841..5cf53a4c21 100644 --- a/sysdeps/generic/localplt.data +++ b/sysdeps/generic/localplt.data @@ -15,3 +15,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data index d7d673454f..e431f368e3 100644 --- a/sysdeps/unix/sysv/linux/aarch64/localplt.data +++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data @@ -16,3 +16,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data index 351596cf57..298439365f 100644 --- a/sysdeps/unix/sysv/linux/alpha/localplt.data +++ b/sysdeps/unix/sysv/linux/alpha/localplt.data @@ -33,3 +33,6 @@ ld.so: malloc + RELA R_ALPHA_GLOB_DAT ld.so: calloc + RELA R_ALPHA_GLOB_DAT ld.so: realloc + RELA R_ALPHA_GLOB_DAT ld.so: free + RELA R_ALPHA_GLOB_DAT +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error + RELA R_ALPHA_GLOB_DAT +ld.so: _dl_catch_error + RELA R_ALPHA_GLOB_DAT diff --git a/sysdeps/unix/sysv/linux/arm/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data index 4301703553..a5ccd7fa58 100644 --- a/sysdeps/unix/sysv/linux/arm/localplt.data +++ b/sysdeps/unix/sysv/linux/arm/localplt.data @@ -16,3 +16,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data index 2a25ebce46..fea8c9cbf6 100644 --- a/sysdeps/unix/sysv/linux/hppa/localplt.data +++ b/sysdeps/unix/sysv/linux/hppa/localplt.data @@ -21,3 +21,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data index 4ce8447673..48bcc42a67 100644 --- a/sysdeps/unix/sysv/linux/i386/localplt.data +++ b/sysdeps/unix/sysv/linux/i386/localplt.data @@ -15,3 +15,6 @@ ld.so: malloc + REL R_386_GLOB_DAT ld.so: calloc + REL R_386_GLOB_DAT ld.so: realloc + REL R_386_GLOB_DAT ld.so: free + REL R_386_GLOB_DAT +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error + REL R_386_GLOB_DAT +ld.so: _dl_catch_error + REL R_386_GLOB_DAT diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data index b628ca4dfc..df63530b6c 100644 --- a/sysdeps/unix/sysv/linux/ia64/localplt.data +++ b/sysdeps/unix/sysv/linux/ia64/localplt.data @@ -14,3 +14,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/m68k/localplt.data b/sysdeps/unix/sysv/linux/m68k/localplt.data index 88124c4460..abfbd34f41 100644 --- a/sysdeps/unix/sysv/linux/m68k/localplt.data +++ b/sysdeps/unix/sysv/linux/m68k/localplt.data @@ -14,3 +14,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/microblaze/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data index 176d61818e..697fdd0186 100644 --- a/sysdeps/unix/sysv/linux/microblaze/localplt.data +++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data @@ -15,3 +15,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data index 6cf93cc2af..a7d774dcf8 100644 --- a/sysdeps/unix/sysv/linux/nios2/localplt.data +++ b/sysdeps/unix/sysv/linux/nios2/localplt.data @@ -35,3 +35,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data index b25abf8006..4ef5bf4a7f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data @@ -13,3 +13,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data index 8c4e65d123..c9194264dd 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data @@ -43,3 +43,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data index 49d5de6019..2d434726cc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data @@ -12,3 +12,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/s390/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data index 122641312c..bd1adddb1f 100644 --- a/sysdeps/unix/sysv/linux/s390/localplt.data +++ b/sysdeps/unix/sysv/linux/s390/localplt.data @@ -20,3 +20,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/sh/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data index 57f31c579a..e6fb930cf7 100644 --- a/sysdeps/unix/sysv/linux/sh/localplt.data +++ b/sysdeps/unix/sysv/linux/sh/localplt.data @@ -18,3 +18,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data index a208adff31..d5b5895a5c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data @@ -24,3 +24,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data index 2323551f63..edceab57c3 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data @@ -26,3 +26,6 @@ ld.so: malloc ld.so: calloc ld.so: realloc ld.so: free +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error +ld.so: _dl_catch_error diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data index f168b143ff..28096f893e 100644 --- a/sysdeps/x86_64/localplt.data +++ b/sysdeps/x86_64/localplt.data @@ -17,3 +17,6 @@ ld.so: malloc + RELA R_X86_64_GLOB_DAT ld.so: calloc + RELA R_X86_64_GLOB_DAT ld.so: realloc + RELA R_X86_64_GLOB_DAT ld.so: free + RELA R_X86_64_GLOB_DAT +# The TLS-enabled version of these functions is interposed from libc.so. +ld.so: _dl_signal_error + RELA R_X86_64_GLOB_DAT +ld.so: _dl_catch_error + RELA R_X86_64_GLOB_DAT -- cgit 1.4.1