5f7b84
commit 2a764c6ee848dfe92cb2921ed3b14085f15d9e79
5f7b84
Author: Florian Weimer <fweimer@redhat.com>
5f7b84
Date:   Thu Oct 31 13:23:06 2019 +0100
5f7b84
5f7b84
    Enhance _dl_catch_exception to allow disabling exception handling
5f7b84
    
5f7b84
    In some cases, it is necessary to introduce noexcept regions
5f7b84
    where raised dynamic loader exceptions (e.g., from lazy binding)
5f7b84
    are fatal, despite being nested in a code region with an active
5f7b84
    exception handler.  This change enhances _dl_catch_exception with
5f7b84
    to provide such a capability.  The existing function is reused,
5f7b84
    so that it is not necessary to introduce yet another function with
5f7b84
    a similar purpose.
5f7b84
    
5f7b84
    Change-Id: Iec1bf642ff95a349fdde8040e9baf851ac7b8904
5f7b84
5f7b84
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
5f7b84
index d5f418ab1848f0c4..9cb002ccfed2c7b4 100644
5f7b84
--- a/elf/dl-error-skeleton.c
5f7b84
+++ b/elf/dl-error-skeleton.c
5f7b84
@@ -173,6 +173,18 @@ int
5f7b84
 _dl_catch_exception (struct dl_exception *exception,
5f7b84
 		     void (*operate) (void *), void *args)
5f7b84
 {
5f7b84
+  /* If exception is NULL, temporarily disable exception handling.
5f7b84
+     Exceptions during operate (args) are fatal.  */
5f7b84
+  if (exception == NULL)
5f7b84
+    {
5f7b84
+      struct catch *const old = catch_hook;
5f7b84
+      catch_hook = NULL;
5f7b84
+      operate (args);
5f7b84
+      /* If we get here, the operation was successful.  */
5f7b84
+      catch_hook = old;
5f7b84
+      return 0;
5f7b84
+    }
5f7b84
+
5f7b84
   /* We need not handle `receiver' since setting a `catch' is handled
5f7b84
      before it.  */
5f7b84
 
5f7b84
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
5f7b84
index 95dc87519b80e0ec..cc2484033fe0d902 100644
5f7b84
--- a/sysdeps/generic/ldsodefs.h
5f7b84
+++ b/sysdeps/generic/ldsodefs.h
5f7b84
@@ -852,7 +852,9 @@ libc_hidden_proto (_dl_catch_error)
5f7b84
 
5f7b84
 /* Call OPERATE (ARGS).  If no error occurs, set *EXCEPTION to zero.
5f7b84
    Otherwise, store a copy of the raised exception in *EXCEPTION,
5f7b84
-   which has to be freed by _dl_exception_free.  */
5f7b84
+   which has to be freed by _dl_exception_free.  As a special case, if
5f7b84
+   EXCEPTION is null, call OPERATE (ARGS) with exception handling
5f7b84
+   disabled (so that exceptions are fatal).  */
5f7b84
 int _dl_catch_exception (struct dl_exception *exception,
5f7b84
 			 void (*operate) (void *), void *args);
5f7b84
 libc_hidden_proto (_dl_catch_exception)