1*dab73fe7SLisandro Dalcin #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for and RTLD_* */ 2*dab73fe7SLisandro Dalcin #include <petsc/private/petscimpl.h> 3*dab73fe7SLisandro Dalcin 4*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_DLFCN_H) 5*dab73fe7SLisandro Dalcin #include <dlfcn.h> 6*dab73fe7SLisandro Dalcin #endif 7*dab73fe7SLisandro Dalcin 8*dab73fe7SLisandro Dalcin #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H) 9*dab73fe7SLisandro Dalcin #include <cxxabi.h> 10*dab73fe7SLisandro Dalcin #endif 11*dab73fe7SLisandro Dalcin 12*dab73fe7SLisandro Dalcin PetscErrorCode PetscDemangleSymbol(const char mangledName[], char **name) 13*dab73fe7SLisandro Dalcin { 14*dab73fe7SLisandro Dalcin char *(*cxa_demangle)(const char *, char *, size_t *, int *) = PETSC_NULLPTR; 15*dab73fe7SLisandro Dalcin char *newname; 16*dab73fe7SLisandro Dalcin int status; 17*dab73fe7SLisandro Dalcin 18*dab73fe7SLisandro Dalcin PetscFunctionBegin; 19*dab73fe7SLisandro Dalcin if (mangledName) PetscAssertPointer(mangledName, 1); 20*dab73fe7SLisandro Dalcin PetscAssertPointer(name, 2); 21*dab73fe7SLisandro Dalcin 22*dab73fe7SLisandro Dalcin *name = PETSC_NULLPTR; 23*dab73fe7SLisandro Dalcin if (!mangledName) PetscFunctionReturn(PETSC_SUCCESS); 24*dab73fe7SLisandro Dalcin 25*dab73fe7SLisandro Dalcin #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H) 26*dab73fe7SLisandro Dalcin cxa_demangle = __cxxabiv1::__cxa_demangle; 27*dab73fe7SLisandro Dalcin #endif 28*dab73fe7SLisandro Dalcin 29*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 30*dab73fe7SLisandro Dalcin if (!cxa_demangle) { 31*dab73fe7SLisandro Dalcin void *symbol = PETSC_NULLPTR; 32*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_DEFAULT) 33*dab73fe7SLisandro Dalcin symbol = dlsym(RTLD_DEFAULT, "__cxa_demangle"); 34*dab73fe7SLisandro Dalcin #endif 35*dab73fe7SLisandro Dalcin if (!symbol) { 36*dab73fe7SLisandro Dalcin int mode = 0; 37*dab73fe7SLisandro Dalcin void *handle = PETSC_NULLPTR; 38*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 39*dab73fe7SLisandro Dalcin mode |= RTLD_LAZY; 40*dab73fe7SLisandro Dalcin #endif 41*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 42*dab73fe7SLisandro Dalcin mode |= RTLD_LOCAL; 43*dab73fe7SLisandro Dalcin #endif 44*dab73fe7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOLOAD) 45*dab73fe7SLisandro Dalcin mode |= RTLD_NOLOAD; 46*dab73fe7SLisandro Dalcin #endif 47*dab73fe7SLisandro Dalcin #ifdef __APPLE__ 48*dab73fe7SLisandro Dalcin if (!handle) handle = dlopen("libc++.1.dylib", mode); 49*dab73fe7SLisandro Dalcin #else 50*dab73fe7SLisandro Dalcin if (!handle) handle = dlopen("libstdc++.so.6", mode); 51*dab73fe7SLisandro Dalcin #endif 52*dab73fe7SLisandro Dalcin if (handle) { 53*dab73fe7SLisandro Dalcin symbol = dlsym(handle, "__cxa_demangle"); 54*dab73fe7SLisandro Dalcin dlclose(handle); 55*dab73fe7SLisandro Dalcin } 56*dab73fe7SLisandro Dalcin } 57*dab73fe7SLisandro Dalcin *(void **)(&cxa_demangle) = symbol; 58*dab73fe7SLisandro Dalcin } 59*dab73fe7SLisandro Dalcin #endif 60*dab73fe7SLisandro Dalcin 61*dab73fe7SLisandro Dalcin if (!cxa_demangle) { 62*dab73fe7SLisandro Dalcin PetscCall(PetscStrallocpy(mangledName, name)); 63*dab73fe7SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 64*dab73fe7SLisandro Dalcin } 65*dab73fe7SLisandro Dalcin 66*dab73fe7SLisandro Dalcin newname = cxa_demangle(mangledName, PETSC_NULLPTR, PETSC_NULLPTR, &status); 67*dab73fe7SLisandro Dalcin if (status) { 68*dab73fe7SLisandro Dalcin PetscCheck(status != -1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate memory for symbol %s", mangledName); 69*dab73fe7SLisandro Dalcin PetscCheck(status == -2, PETSC_COMM_SELF, PETSC_ERR_LIB, "Demangling failed for symbol %s", mangledName); 70*dab73fe7SLisandro Dalcin /* Mangled name is not a valid name under the C++ ABI mangling rules */ 71*dab73fe7SLisandro Dalcin PetscCall(PetscStrallocpy(mangledName, name)); 72*dab73fe7SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 73*dab73fe7SLisandro Dalcin } 74*dab73fe7SLisandro Dalcin PetscCall(PetscStrallocpy(newname, name)); 75*dab73fe7SLisandro Dalcin free(newname); 76*dab73fe7SLisandro Dalcin PetscFunctionReturn(PETSC_SUCCESS); 77*dab73fe7SLisandro Dalcin } 78