Actual source code: demangle.c

  1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for and RTLD_* */
  2: #include <petsc/private/petscimpl.h>

  4: #if defined(PETSC_HAVE_DLFCN_H)
  5:   #include <dlfcn.h>
  6: #endif

  8: #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H)
  9:   #include <cxxabi.h>
 10: #endif

 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;

 18:   PetscFunctionBegin;
 19:   if (mangledName) PetscAssertPointer(mangledName, 1);
 20:   PetscAssertPointer(name, 2);

 22:   *name = PETSC_NULLPTR;
 23:   if (!mangledName) PetscFunctionReturn(PETSC_SUCCESS);

 25: #if defined(__cplusplus) && defined(PETSC_HAVE_CXXABI_H)
 26:   cxa_demangle = __cxxabiv1::__cxa_demangle;
 27: #endif

 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

 61:   if (!cxa_demangle) {
 62:     PetscCall(PetscStrallocpy(mangledName, name));
 63:     PetscFunctionReturn(PETSC_SUCCESS);
 64:   }

 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: }