[PATCH 4/4] libgcc: Use _dl_find_eh_frame in _Unwind_Find_FDE
Florian Weimer
fweimer@redhat.com
Wed Nov 3 16:28:55 GMT 2021
libgcc/ChangeLog
* unwind-dw2-fde-dip.c (USE_DL_FIND_EH_FRAME)
(DL_FIND_EH_FRAME_CONDITION): New macros.
[__GLIBC__ && !DL_FIND_EH_FRAME_DBASE] (_dl_find_eh_frame):
Declare weak function.
(_Unwind_Find_FDE): Call _dl_find_eh_frame if available.
---
libgcc/unwind-dw2-fde-dip.c | 50 +++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
index 272c0ec46c0..b5b4a23dc56 100644
--- a/libgcc/unwind-dw2-fde-dip.c
+++ b/libgcc/unwind-dw2-fde-dip.c
@@ -129,6 +129,30 @@ unw_eh_callback_data_dbase (const struct unw_eh_callback_data *data
#endif
}
+#ifdef DL_FIND_EH_FRAME_DBASE
+#if DL_FIND_EH_FRAME_DBASE != NEED_DBASE_MEMBER
+#error "DL_FIND_EH_FRAME_DBASE != NEED_DBASE_MEMBER"
+#endif
+#define USE_DL_FIND_EH_FRAME 1
+#define DL_FIND_EH_FRAME_CONDITION 1
+#endif
+
+/* Fallback declaration for old glibc headers. DL_FIND_EH_FRAME_DBASE is used
+ as a proxy to determine if <dlfcn.h> declares _dl_find_eh_frame. */
+#if defined __GLIBC__ && !defined DL_FIND_EH_FRAME_DBASE
+#if NEED_DBASE_MEMBER
+void *_dl_find_eh_frame (void *__pc, void **__dbase) __attribute__ ((weak));
+#else
+void *_dl_find_eh_frame (void *__pc) __attribute__ ((weak));
+#endif
+#define USE_DL_FIND_EH_FRAME 1
+#define DL_FIND_EH_FRAME_CONDITION (_dl_find_eh_frame != NULL)
+#endif
+
+#ifndef USE_DL_FIND_EH_FRAME
+#define USE_DL_FIND_EH_FRAME 0
+#endif
+
struct unw_eh_frame_hdr
{
unsigned char version;
@@ -501,6 +525,32 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
if (ret != NULL)
return ret;
+#if USE_DL_FIND_EH_FRAME
+ if (DL_FIND_EH_FRAME_CONDITION)
+ {
+ void *dbase;
+ void *eh_frame;
+#if NEED_DBASE_MEMBER
+ eh_frame = _dl_find_eh_frame (pc, &dbase);
+#else
+ dbase = NULL;
+ eh_frame = _dl_find_eh_frame (pc);
+#endif
+ if (eh_frame == NULL)
+ return NULL;
+
+ struct find_fde_tail_result result
+ = find_fde_tail ((_Unwind_Ptr) pc, eh_frame, (_Unwind_Ptr) dbase);
+ if (result.entry != NULL)
+ {
+ bases->tbase = NULL;
+ bases->dbase = (void *) dbase;
+ bases->func = result.func;
+ }
+ return result.entry;
+ }
+#endif
+
data.pc = (_Unwind_Ptr) pc;
#if NEED_DBASE_MEMBER
data.dbase = NULL;
--
2.31.1
More information about the Libc-alpha
mailing list