https://github.com/xingxue-ibm created 
https://github.com/llvm/llvm-project/pull/112436

`__xlcxx_personality_v0` is the personality routine in `libc++abi` for the EH 
of applications generated by the legacy IBM C++ compiler. Since the EH info 
generated by the legacy compiler does not provide the location of the 
personality routine, this routine is directly referenced as the handler for 
legacy EH in the unwinder. The symbol is resolved dynamically using `dlopen()` 
to avoid a hard dependency of `libunwind` on `libc++abi` for cases such as 
non-C++ applications. The weak definition  `__xlcxx_personality_v0` was 
originally intended to bypass `dlopen()` if the C++ application generated by 
the legacy compiler is statically linked with the new LLVM C++ compiler. 
Unfortunately this causes problems with runtime linking for Clang compiled code 
using the unwinder but does not link with `libc++abi`.

On the other hand, the C++ runtime libraries shipped for AIX are actually 
stripped and statically linking is not supported. So, we can fix the problem by 
removing the `__xlcxx_personality_v0` weak definition. Besides, `dlopen()` 
would work whether it is static or dynamic linking.


>From edabcb3b43800c3e12a55325a786600064ccde10 Mon Sep 17 00:00:00 2001
From: Xing Xue <xing...@outlook.com>
Date: Tue, 15 Oct 2024 16:21:29 -0400
Subject: [PATCH] Remove weak definition "__xlcxx_personality_v0".

---
 libunwind/src/UnwindCursor.hpp | 52 ++++++++++++++--------------------
 1 file changed, 22 insertions(+), 30 deletions(-)

diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index ce6dced535e781..8869be5236b1e6 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -2033,7 +2033,6 @@ typedef _Unwind_Reason_Code __xlcxx_personality_v0_t(int, 
_Unwind_Action,
                                                      uint64_t,
                                                      _Unwind_Exception *,
                                                      struct _Unwind_Context *);
-__attribute__((__weak__)) __xlcxx_personality_v0_t __xlcxx_personality_v0;
 }
 
 static __xlcxx_personality_v0_t *xlcPersonalityV0;
@@ -2126,42 +2125,35 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, 
R &registers) {
     // function __xlcxx_personality_v0(), which is the personality for the 
state
     // table and is exported from libc++abi, is directly assigned as the
     // handler here. When a legacy XLC++ frame is encountered, the symbol
-    // is resolved dynamically using dlopen() to avoid hard dependency from
-    // libunwind on libc++abi.
+    // is resolved dynamically using dlopen() to avoid a hard dependency of
+    // libunwind on libc++abi in cases such as non-C++ applications.
 
     // Resolve the function pointer to the state table personality if it has
-    // not already.
+    // not already done.
     if (xlcPersonalityV0 == NULL) {
       xlcPersonalityV0InitLock.lock();
       if (xlcPersonalityV0 == NULL) {
-        // If libc++abi is statically linked in, symbol __xlcxx_personality_v0
-        // has been resolved at the link time.
-        xlcPersonalityV0 = &__xlcxx_personality_v0;
+        // Resolve __xlcxx_personality_v0 using dlopen().
+        const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
+        void *libHandle;
+        // The AIX dlopen() sets errno to 0 when it is successful, which
+        // clobbers the value of errno from the user code. This is an AIX
+        // bug because according to POSIX it should not set errno to 0. To
+        // workaround before AIX fixes the bug, errno is saved and restored.
+        int saveErrno = errno;
+        libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
+        if (libHandle == NULL) {
+          _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
+                                     errno);
+          assert(0 && "dlopen() failed");
+        }
+        xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
+            dlsym(libHandle, "__xlcxx_personality_v0"));
         if (xlcPersonalityV0 == NULL) {
-          // libc++abi is dynamically linked. Resolve __xlcxx_personality_v0
-          // using dlopen().
-          const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
-          void *libHandle;
-          // The AIX dlopen() sets errno to 0 when it is successful, which
-          // clobbers the value of errno from the user code. This is an AIX
-          // bug because according to POSIX it should not set errno to 0. To
-          // workaround before AIX fixes the bug, errno is saved and restored.
-          int saveErrno = errno;
-          libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
-          if (libHandle == NULL) {
-            _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
-                                       errno);
-            assert(0 && "dlopen() failed");
-          }
-          xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
-              dlsym(libHandle, "__xlcxx_personality_v0"));
-          if (xlcPersonalityV0 == NULL) {
-            _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", 
errno);
-            assert(0 && "dlsym() failed");
-          }
-          dlclose(libHandle);
-          errno = saveErrno;
+          _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", errno);
+          assert(0 && "dlsym() failed");
         }
+        errno = saveErrno;
       }
       xlcPersonalityV0InitLock.unlock();
     }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to