Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 21 additions & 30 deletions libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -2126,42 +2125,34 @@ 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();
}
Expand Down
Loading