xref: /petsc/src/sys/dll/demangle.c (revision a28344a5144139f565b3604164979954db19997e)
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 
PetscDemangleSymbol(const char mangledName[],char ** name)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