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