diff --git a/elf/Makefile b/elf/Makefile index 73229952ca..32d9fdc221 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -2765,6 +2765,8 @@ $(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o $(LINK.o) -shared -o $@ $(LDFLAGS.so) $(dt-relr-ldflag) $< $(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so +LDLIBS-tst-unwind-ctor += $(libunwind) +LDFLAGS-tst-unwind-ctor-lib.so = -Wl,--unresolved-symbols=ignore-all CFLAGS-tst-unwind-main.c += -funwind-tables -DUSE_PTHREADS=0 diff --git a/misc/unwind-link.c b/misc/unwind-link.c index 6019dacf66..c5c1a3ea69 100644 --- a/misc/unwind-link.c +++ b/misc/unwind-link.c @@ -37,6 +37,12 @@ static void *global_libgcc_handle; may depend on unwinding. */ __libc_lock_define (static, lock); +#ifndef HAVE_CC_WITH_LIBUNWIND +# define UNWIND_SONAME LIBGCC_S_SO +#else +# define UNWIND_SONAME LIBUNWIND_SO +#endif + struct unwind_link * __libc_unwind_link_get (void) { @@ -48,7 +54,7 @@ __libc_unwind_link_get (void) /* Initialize a copy of the data, so that we do not need about unlocking in case the dynamic loader somehow triggers unwinding. */ - void *local_libgcc_handle = __libc_dlopen (LIBGCC_S_SO); + void *local_libgcc_handle = __libc_dlopen (UNWIND_SONAME); if (local_libgcc_handle == NULL) { __libc_lock_unlock (lock); @@ -72,8 +78,19 @@ __libc_unwind_link_get (void) local.ptr___frame_state_for = __libc_dlsym (local_libgcc_handle, "__frame_state_for"); #endif +#ifndef HAVE_CC_WITH_LIBUNWIND local.ptr_personality = __libc_dlsym (local_libgcc_handle, "__gcc_personality_v0"); +#else + local.ptr__Unwind_GetLanguageSpecificData + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetLanguageSpecificData"); + local.ptr__Unwind_SetGR + = __libc_dlsym (local_libgcc_handle, "_Unwind_SetGR"); + local.ptr__Unwind_SetIP + = __libc_dlsym (local_libgcc_handle, "_Unwind_SetIP"); + local.ptr__Unwind_GetRegionStart + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetRegionStart"); +#endif UNWIND_LINK_EXTRA_INIT /* If a symbol is missing, libgcc_s has somehow been corrupted. */ @@ -84,7 +101,15 @@ __libc_unwind_link_get (void) assert (local.ptr__Unwind_GetIP != NULL); #endif assert (local.ptr__Unwind_Resume != NULL); +#ifndef HAVE_CC_WITH_LIBUNWIND assert (local.ptr_personality != NULL); +#else + assert (local.ptr__Unwind_GetLanguageSpecificData != NULL); + assert (local.ptr__Unwind_SetGR != NULL); + assert (local.ptr__Unwind_GetIP != NULL); + assert (local.ptr__Unwind_SetIP != NULL); + assert (local.ptr__Unwind_GetRegionStart != NULL); +#endif PTR_MANGLE (local.ptr__Unwind_Backtrace); PTR_MANGLE (local.ptr__Unwind_ForcedUnwind); @@ -96,7 +121,14 @@ __libc_unwind_link_get (void) #if UNWIND_LINK_FRAME_STATE_FOR PTR_MANGLE (local.ptr___frame_state_for); #endif +#ifndef HAVE_CC_WITH_LIBUNWIND PTR_MANGLE (local.ptr_personality); +#else + PTR_MANGLE (local.ptr__Unwind_GetLanguageSpecificData); + PTR_MANGLE (local.ptr__Unwind_SetGR); + PTR_MANGLE (local.ptr__Unwind_SetIP); + PTR_MANGLE (local.ptr__Unwind_GetRegionStart); +#endif __libc_lock_lock (lock); if (atomic_load_relaxed (&global_libgcc_handle) != NULL) diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 9150411271..5a5a637d7c 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -87,7 +87,7 @@ __pthread_cancel (pthread_t th) { struct unwind_link *unwind_link = __libc_unwind_link_get (); if (unwind_link == NULL) - __libc_fatal (LIBGCC_S_SO + __libc_fatal (UNWIND_SONAME " must be installed for pthread_cancel to work\n"); } #endif diff --git a/nptl/pthread_exit.c b/nptl/pthread_exit.c index 4c15171992..1ed5ed52c4 100644 --- a/nptl/pthread_exit.c +++ b/nptl/pthread_exit.c @@ -28,7 +28,7 @@ __pthread_exit (void *value) { struct unwind_link *unwind_link = __libc_unwind_link_get (); if (unwind_link == NULL) - __libc_fatal (LIBGCC_S_SO + __libc_fatal (UNWIND_SONAME " must be installed for pthread_exit to work\n"); } #endif diff --git a/shlib-versions b/shlib-versions index b1fd0a5eab..32093228c4 100644 --- a/shlib-versions +++ b/shlib-versions @@ -68,3 +68,5 @@ libmvec=1 # The malloc debug library libc_malloc_debug=0 + +libunwind=1 diff --git a/sysdeps/generic/unwind-link.h b/sysdeps/generic/unwind-link.h index 1150cda219..ea39e525d2 100644 --- a/sysdeps/generic/unwind-link.h +++ b/sysdeps/generic/unwind-link.h @@ -34,6 +34,12 @@ unwind_arch_adjustment (void *prev, void *addr) # include # include +# ifndef HAVE_CC_WITH_LIBUNWIND +# define UNWIND_SONAME LIBGCC_S_SO +# else +# define UNWIND_SONAME LIBUNWIND_SO +# endif + # if UNWIND_LINK_FRAME_STATE_FOR struct frame_state; # endif @@ -50,7 +56,14 @@ struct unwind_link #if UNWIND_LINK_FRAME_STATE_FOR struct frame_state *(*ptr___frame_state_for) (void *, struct frame_state *); #endif +#ifndef HAVE_CC_WITH_LIBUNWIND _Unwind_Reason_Code (*ptr_personality) PERSONALITY_PROTO; +#else + __typeof (_Unwind_GetLanguageSpecificData) *ptr__Unwind_GetLanguageSpecificData; + __typeof (_Unwind_SetGR) *ptr__Unwind_SetGR; + __typeof (_Unwind_SetIP) *ptr__Unwind_SetIP; + __typeof (_Unwind_GetRegionStart) *ptr__Unwind_GetRegionStart; +#endif UNWIND_LINK_EXTRA_FIELDS }; diff --git a/sysdeps/generic/unwind-resume.c b/sysdeps/generic/unwind-resume.c index de176a1f72..18c40501bb 100644 --- a/sysdeps/generic/unwind-resume.c +++ b/sysdeps/generic/unwind-resume.c @@ -38,11 +38,43 @@ _Unwind_Resume (struct _Unwind_Exception *exc) } #endif +#ifndef HAVE_CC_WITH_LIBUNWIND _Unwind_Reason_Code __gcc_personality_v0 PERSONALITY_PROTO { return UNWIND_LINK_PTR (link (), personality) PERSONALITY_ARGS; } +#else +void * +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) +{ + return UNWIND_LINK_PTR (link (), _Unwind_GetLanguageSpecificData) (context); +} + +void +_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) +{ + UNWIND_LINK_PTR (link (), _Unwind_SetGR) (context, index, val); +} + +_Unwind_Ptr +_Unwind_GetIP (struct _Unwind_Context *context) +{ + return UNWIND_LINK_PTR (link (), _Unwind_GetIP) (context); +} + +void +_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) +{ + UNWIND_LINK_PTR (link (), _Unwind_SetIP) (context, val); +} + +_Unwind_Ptr +_Unwind_GetRegionStart (struct _Unwind_Context *context) +{ + return UNWIND_LINK_PTR (link (), _Unwind_GetRegionStart) (context); +} +#endif _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,