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
PetscDemangleSymbol(const char mangledName[],char ** name)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