aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-08-10 13:40:22 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-08-10 16:54:57 +0200
commit2449ae7b2da24c9940962304a3e44bc80e389265 (patch)
treec2cfdcfc3a90731d2da26dda79984eda95e9079e /sysdeps
parentf87cc2bfba9b844da48a63441c6099342b1551c7 (diff)
downloadglibc-2449ae7b2da24c9940962304a3e44bc80e389265.zip
glibc-2449ae7b2da24c9940962304a3e44bc80e389265.tar.gz
glibc-2449ae7b2da24c9940962304a3e44bc80e389265.tar.bz2
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')
-rw-r--r--sysdeps/generic/ldsodefs.h107
-rw-r--r--sysdeps/generic/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/arm/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/hppa/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/i386/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/ia64/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/nios2/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/s390/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/sh/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data2
-rw-r--r--sysdeps/x86_64/localplt.data2
19 files changed, 122 insertions, 21 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4508365..1c0b9cb 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 81c741b..2d5c66a 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 bb18ff9..a60053b 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 1f0e3b4..c69eb04 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 19d3299..7bd541c 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 db9e24b..3279c0a 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 8ea4333..f6f20a5 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 fd2b98c..3820e2a 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 1a2acfd..c70d6ea 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 ca476be..8ca2389 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 b0d6dca..4430a58 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 5000631..e822e0a 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 1c20d2f..fead931 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 6f8ed25..c120933 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 5000631..e822e0a 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 f1f5eff..2753547 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 2f6ff3c..1668f40 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 912bd1a..b881b90 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 a1840cf..c27a02b 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