diff options
author | Florian Weimer <fweimer@redhat.com> | 2017-08-10 13:40:22 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2017-08-10 16:54:57 +0200 |
commit | 2449ae7b2da24c9940962304a3e44bc80e389265 (patch) | |
tree | c2cfdcfc3a90731d2da26dda79984eda95e9079e /sysdeps | |
parent | f87cc2bfba9b844da48a63441c6099342b1551c7 (diff) | |
download | glibc-2449ae7b2da24c9940962304a3e44bc80e389265.tar.gz |
ld.so: Introduce struct dl_exception
This commit separates allocating and raising exceptions. This
simplifies catching and re-raising them because it is no longer
necessary to make a temporary, on-stack copy of the exception message.
Diffstat (limited to 'sysdeps')
19 files changed, 122 insertions, 21 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 4508365871..1c0b9cb32e 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -732,31 +732,88 @@ _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) + const char *occasion, const char *errstring) 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. This is only used during ld.so bootstrap. In - static and profiled builds, this is equivalent to - _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 + +/* 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) + const char *occasion, 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) + const char *occasion, const char *errstring) { - _dl_signal_error (errcode, object, occation, errstring); + _dl_signal_error (errcode, object, occasion, errstring); } #endif @@ -768,20 +825,28 @@ 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. */ +/* 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; 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. If the object is already opened, returns its existing map. */ diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data index 81c741b038..2d5c66ae28 100644 --- a/sysdeps/generic/localplt.data +++ b/sysdeps/generic/localplt.data @@ -16,3 +16,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data index bb18ff9bb2..a60053b914 100644 --- a/sysdeps/unix/sysv/linux/aarch64/localplt.data +++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data @@ -18,3 +18,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data index 1f0e3b494e..c69eb04ce5 100644 --- a/sysdeps/unix/sysv/linux/alpha/localplt.data +++ b/sysdeps/unix/sysv/linux/alpha/localplt.data @@ -35,3 +35,5 @@ 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 +ld.so: _dl_signal_exception + RELA R_ALPHA_GLOB_DAT +ld.so: _dl_catch_exception + RELA R_ALPHA_GLOB_DAT diff --git a/sysdeps/unix/sysv/linux/arm/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data index 19d3299d98..7bd541c28a 100644 --- a/sysdeps/unix/sysv/linux/arm/localplt.data +++ b/sysdeps/unix/sysv/linux/arm/localplt.data @@ -17,3 +17,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data index db9e24b090..3279c0af05 100644 --- a/sysdeps/unix/sysv/linux/hppa/localplt.data +++ b/sysdeps/unix/sysv/linux/hppa/localplt.data @@ -21,3 +21,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data index 8ea4333846..f6f20a5d15 100644 --- a/sysdeps/unix/sysv/linux/i386/localplt.data +++ b/sysdeps/unix/sysv/linux/i386/localplt.data @@ -16,3 +16,5 @@ 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 +ld.so: _dl_signal_exception + REL R_386_GLOB_DAT +ld.so: _dl_catch_exception + REL R_386_GLOB_DAT diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data index fd2b98c8b6..3820e2a4e6 100644 --- a/sysdeps/unix/sysv/linux/ia64/localplt.data +++ b/sysdeps/unix/sysv/linux/ia64/localplt.data @@ -15,3 +15,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/m68k/localplt.data b/sysdeps/unix/sysv/linux/m68k/localplt.data index 1a2acfdb93..c70d6ea301 100644 --- a/sysdeps/unix/sysv/linux/m68k/localplt.data +++ b/sysdeps/unix/sysv/linux/m68k/localplt.data @@ -15,3 +15,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/microblaze/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data index ca476bedd8..8ca23897df 100644 --- a/sysdeps/unix/sysv/linux/microblaze/localplt.data +++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data @@ -16,3 +16,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data index b0d6dcae55..4430a5891e 100644 --- a/sysdeps/unix/sysv/linux/nios2/localplt.data +++ b/sysdeps/unix/sysv/linux/nios2/localplt.data @@ -36,3 +36,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data index 50006317c7..e822e0a480 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data @@ -14,3 +14,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data index 1c20d2f2b4..fead931d4e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data @@ -44,3 +44,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data index 6f8ed25922..c1209336d2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data @@ -13,3 +13,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/s390/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data index 50006317c7..e822e0a480 100644 --- a/sysdeps/unix/sysv/linux/s390/localplt.data +++ b/sysdeps/unix/sysv/linux/s390/localplt.data @@ -14,3 +14,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/sh/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data index f1f5effc24..2753547d97 100644 --- a/sysdeps/unix/sysv/linux/sh/localplt.data +++ b/sysdeps/unix/sysv/linux/sh/localplt.data @@ -19,3 +19,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data index 2f6ff3c3a6..1668f4017e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data @@ -26,3 +26,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data index 912bd1a16e..b881b9096d 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data @@ -27,3 +27,5 @@ 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 +ld.so: _dl_signal_exception +ld.so: _dl_catch_exception diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data index a1840cff31..c27a02b66a 100644 --- a/sysdeps/x86_64/localplt.data +++ b/sysdeps/x86_64/localplt.data @@ -18,3 +18,5 @@ 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 +ld.so: _dl_signal_exception + RELA R_X86_64_GLOB_DAT +ld.so: _dl_catch_exception + RELA R_X86_64_GLOB_DAT |