1ebd79076SLisandro Dalcin /* 2ebd79076SLisandro Dalcin Low-level routines for managing dynamic link libraries (DLLs). 3ebd79076SLisandro Dalcin */ 4ebd79076SLisandro Dalcin 5184ce1a2SMatthew G. Knepley #include <petscconf.h> 6184ce1a2SMatthew G. Knepley #if defined(PETSC__GNU_SOURCE) 7184ce1a2SMatthew G. Knepley #if !defined(_GNU_SOURCE) 8184ce1a2SMatthew G. Knepley #define _GNU_SOURCE 1 9184ce1a2SMatthew G. Knepley #endif 10184ce1a2SMatthew G. Knepley #endif 11184ce1a2SMatthew G. Knepley 12af0996ceSBarry Smith #include <petsc/private/petscimpl.h> 13ebd79076SLisandro Dalcin 14ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 15ebd79076SLisandro Dalcin #include <windows.h> 16184ce1a2SMatthew G. Knepley #endif 17184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLFCN_H) 18ebd79076SLisandro Dalcin #include <dlfcn.h> 19ebd79076SLisandro Dalcin #endif 20ebd79076SLisandro Dalcin 21ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 22ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t; 236ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t; 24ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 25ebd79076SLisandro Dalcin typedef void *dlhandle_t; 266ea75d68SLisandro Dalcin typedef void *dlsymbol_t; 27ebd79076SLisandro Dalcin #else 28ebd79076SLisandro Dalcin typedef void *dlhandle_t; 296ea75d68SLisandro Dalcin typedef void *dlsymbol_t; 30ebd79076SLisandro Dalcin #endif 31ebd79076SLisandro Dalcin 32ebd79076SLisandro Dalcin /*@C 33811af0c4SBarry Smith PetscDLOpen - opens a dynamic library 34b235ab32SBarry Smith 35b235ab32SBarry Smith Not Collective 36b235ab32SBarry Smith 37b235ab32SBarry Smith Input Parameters: 38b235ab32SBarry Smith + name - name of library 39e4d177b5SBarry Smith - mode - options on how to open library 40b235ab32SBarry Smith 41b235ab32SBarry Smith Output Parameter: 42811af0c4SBarry Smith . handle - opaque pointer to be used with `PetscDLSym()` 43b235ab32SBarry Smith 44b235ab32SBarry Smith Level: developer 45b235ab32SBarry Smith 46db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLAddr()` 47ebd79076SLisandro Dalcin @*/ 48d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLOpen(const char name[], PetscDLMode mode, PetscDLHandle *handle) 49d71ae5a4SJacob Faibussowitsch { 508e049581SJed Brown PETSC_UNUSED int dlflags1, dlflags2; /* There are some preprocessor paths where these variables are set, but not used */ 51ebd79076SLisandro Dalcin dlhandle_t dlhandle; 52ebd79076SLisandro Dalcin 53ebd79076SLisandro Dalcin PetscFunctionBegin; 54ebd79076SLisandro Dalcin PetscValidCharPointer(name, 1); 55ebd79076SLisandro Dalcin PetscValidPointer(handle, 3); 56ebd79076SLisandro Dalcin 57be1c6ad7SLisandro Dalcin dlflags1 = 0; 58be1c6ad7SLisandro Dalcin dlflags2 = 0; 595673baf8SLisandro Dalcin dlhandle = (dlhandle_t)0; 60be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle)0; 61ebd79076SLisandro Dalcin 625673baf8SLisandro Dalcin /* 635673baf8SLisandro Dalcin --- LoadLibrary --- 645673baf8SLisandro Dalcin */ 65be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 66be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 67ebd79076SLisandro Dalcin if (!dlhandle) { 68d0609cedSBarry Smith /* TODO: Seem to need fixing, why not just return with an error with SETERRQ() */ 69ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 70ebd79076SLisandro Dalcin DWORD erc; 71b3bb0f5eSLisandro Dalcin char *buff = NULL; 72ebd79076SLisandro Dalcin erc = GetLastError(); 739371c9d4SSatish Balay FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, erc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buff, 0, NULL); 749371c9d4SSatish Balay PetscCall(PetscError(PETSC_COMM_SELF, __LINE__, PETSC_FUNCTION_NAME, __FILE__, PETSC_ERR_FILE_OPEN, PETSC_ERROR_REPEAT, "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n", name, buff)); 75ebd79076SLisandro Dalcin LocalFree(buff); 7663a3b9bcSJacob Faibussowitsch PetscFunctionReturn(0); 77ebd79076SLisandro Dalcin #else 7898921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s", name, "unavailable"); 79ebd79076SLisandro Dalcin #endif 80ebd79076SLisandro Dalcin } 815673baf8SLisandro Dalcin 825673baf8SLisandro Dalcin /* 835673baf8SLisandro Dalcin --- dlopen --- 845673baf8SLisandro Dalcin */ 85a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 86ebd79076SLisandro Dalcin /* 87ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 88ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 89ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 90ebd79076SLisandro Dalcin with dlopen() 91ebd79076SLisandro Dalcin */ 92be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 93be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 94be1c6ad7SLisandro Dalcin #endif 95ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 96a297a907SKarl Rupp if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW; 97ebd79076SLisandro Dalcin #endif 98ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 99be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 100ebd79076SLisandro Dalcin #endif 101b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 102a297a907SKarl Rupp if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL; 103b3bb0f5eSLisandro Dalcin #endif 104be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 105be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 106be1c6ad7SLisandro Dalcin #endif 107be1c6ad7SLisandro Dalcin dlhandle = dlopen(name, dlflags1 | dlflags2); 108ebd79076SLisandro Dalcin if (!dlhandle) { 109ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 110ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 111ebd79076SLisandro Dalcin #else 112ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 113ebd79076SLisandro Dalcin #endif 11498921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from dlopen() %s", name, errmsg); 115ebd79076SLisandro Dalcin } 1165673baf8SLisandro Dalcin /* 1175673baf8SLisandro Dalcin --- unimplemented --- 1185673baf8SLisandro Dalcin */ 119ebd79076SLisandro Dalcin #else 120e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 121ebd79076SLisandro Dalcin #endif 122ebd79076SLisandro Dalcin 123ebd79076SLisandro Dalcin *handle = (PetscDLHandle)dlhandle; 124ebd79076SLisandro Dalcin PetscFunctionReturn(0); 125ebd79076SLisandro Dalcin } 126ebd79076SLisandro Dalcin 127ebd79076SLisandro Dalcin /*@C 128b235ab32SBarry Smith PetscDLClose - closes a dynamic library 129b235ab32SBarry Smith 130b235ab32SBarry Smith Not Collective 131b235ab32SBarry Smith 132b235ab32SBarry Smith Input Parameter: 133811af0c4SBarry Smith . handle - the handle for the library obtained with `PetscDLOpen()` 134b235ab32SBarry Smith 135b235ab32SBarry Smith Level: developer 13610699b91SBarry Smith 137db781477SPatrick Sanan .seealso: `PetscDLOpen()`, `PetscDLSym()`, `PetscDLAddr()` 138ebd79076SLisandro Dalcin @*/ 139d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLClose(PetscDLHandle *handle) 140d71ae5a4SJacob Faibussowitsch { 141ebd79076SLisandro Dalcin PetscFunctionBegin; 142ebd79076SLisandro Dalcin PetscValidPointer(handle, 1); 143ebd79076SLisandro Dalcin 1445673baf8SLisandro Dalcin /* 1455673baf8SLisandro Dalcin --- FreeLibrary --- 1465673baf8SLisandro Dalcin */ 147ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 148be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1498e049581SJed Brown if (FreeLibrary((dlhandle_t)*handle) == 0) { 1505673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 151b3bb0f5eSLisandro Dalcin char *buff = NULL; 152a21658a3SLisandro Dalcin DWORD erc = GetLastError(); 1530298fd71SBarry Smith FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, erc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buff, 0, NULL); 1545673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n", buff); 1555673baf8SLisandro Dalcin LocalFree(buff); 1565673baf8SLisandro Dalcin #else 1575673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n", "unavailable"); 1585673baf8SLisandro Dalcin #endif 1595673baf8SLisandro Dalcin } 160be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 161ebd79076SLisandro Dalcin 1625673baf8SLisandro Dalcin /* 1635673baf8SLisandro Dalcin --- dclose --- 1645673baf8SLisandro Dalcin */ 165ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 166a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE) 167be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 168be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 169be1c6ad7SLisandro Dalcin #endif 1708e049581SJed Brown if (dlclose((dlhandle_t)*handle) < 0) { 171ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 172ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 173ebd79076SLisandro Dalcin #else 174ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 175ebd79076SLisandro Dalcin #endif 1765673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 177ebd79076SLisandro Dalcin } 178a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */ 1795673baf8SLisandro Dalcin 1805673baf8SLisandro Dalcin /* 1815673baf8SLisandro Dalcin --- unimplemented --- 1825673baf8SLisandro Dalcin */ 183ebd79076SLisandro Dalcin #else 184e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 185ebd79076SLisandro Dalcin #endif 186ebd79076SLisandro Dalcin 1870298fd71SBarry Smith *handle = NULL; 188ebd79076SLisandro Dalcin PetscFunctionReturn(0); 189ebd79076SLisandro Dalcin } 190ebd79076SLisandro Dalcin 191accbd18bSBarry Smith // clang-format off 192accbd18bSBarry Smith 193ebd79076SLisandro Dalcin /*@C 194b235ab32SBarry Smith PetscDLSym - finds a symbol in a dynamic library 195b235ab32SBarry Smith 196b235ab32SBarry Smith Not Collective 197b235ab32SBarry Smith 198b235ab32SBarry Smith Input Parameters: 199811af0c4SBarry Smith + handle - obtained with `PetscDLOpen()` or NULL 200b235ab32SBarry Smith - symbol - name of symbol 201b235ab32SBarry Smith 202b235ab32SBarry Smith Output Parameter: 2030298fd71SBarry Smith . value - pointer to the function, NULL if not found 204b235ab32SBarry Smith 205b235ab32SBarry Smith Level: developer 206b235ab32SBarry Smith 207811af0c4SBarry Smith Note: 2080298fd71SBarry Smith If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table. 2097c62f5d3SDmitry Karpeev In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 2107c62f5d3SDmitry Karpeev systems this requires platform-specific linker flags. 2117c62f5d3SDmitry Karpeev 212db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()` 213ebd79076SLisandro Dalcin @*/ 214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value) 215d71ae5a4SJacob Faibussowitsch { 2168e049581SJed Brown PETSC_UNUSED dlhandle_t dlhandle; 2176ea75d68SLisandro Dalcin dlsymbol_t dlsymbol; 218ebd79076SLisandro Dalcin 219ebd79076SLisandro Dalcin PetscValidCharPointer(symbol, 2); 220ebd79076SLisandro Dalcin PetscValidPointer(value, 3); 221ebd79076SLisandro Dalcin 222be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t)0; 2236ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)0; 224a21658a3SLisandro Dalcin *value = (void *)0; 225ebd79076SLisandro Dalcin 2265673baf8SLisandro Dalcin /* 2275673baf8SLisandro Dalcin --- GetProcAddress --- 2285673baf8SLisandro Dalcin */ 229a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 230a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 231e4d177b5SBarry Smith if (handle) dlhandle = (dlhandle_t)handle; 232e4d177b5SBarry Smith else dlhandle = (dlhandle_t)GetCurrentProcess(); 2336ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)GetProcAddress(dlhandle, symbol); 234a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 235a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 236accbd18bSBarry Smith #endif /* PETSC_HAVE_SETLASTERROR */ 237a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2385673baf8SLisandro Dalcin 2395673baf8SLisandro Dalcin /* 2405673baf8SLisandro Dalcin --- dlsym --- 2415673baf8SLisandro Dalcin */ 242accbd18bSBarry Smith #elif defined(PETSC_HAVE_DLFCN_H) /* PETSC_HAVE_WINDOWS_H */ 243a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 244a297a907SKarl Rupp if (handle) dlhandle = (dlhandle_t)handle; 245a297a907SKarl Rupp else { 2465617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN) 2477c62f5d3SDmitry Karpeev /* Attempt to retrieve the main executable's dlhandle. */ 2489371c9d4SSatish Balay { 2499371c9d4SSatish Balay int dlflags1 = 0, dlflags2 = 0; 2507c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY) 2517c62f5d3SDmitry Karpeev dlflags1 = RTLD_LAZY; 252accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LAZY */ 2537c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW) 254accbd18bSBarry Smith if (!dlflags1) { 2557c62f5d3SDmitry Karpeev dlflags1 = RTLD_NOW; 2567c62f5d3SDmitry Karpeev } 257accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_NOW */ 2587c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL) 2597c62f5d3SDmitry Karpeev dlflags2 = RTLD_LOCAL; 260accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LOCAL */ 2617c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL) 262accbd18bSBarry Smith if (!dlflags2) { 2637c62f5d3SDmitry Karpeev dlflags2 = RTLD_GLOBAL; 2647c62f5d3SDmitry Karpeev } 265accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_GLOBAL */ 2667c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 2679371c9d4SSatish Balay if (!(PETSC_RUNNING_ON_VALGRIND)) { dlerror(); /* clear any previous error; valgrind does not like this */ } 268accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 2697d421530SBarry Smith #if defined(PETSC_HAVE_RTDL_DEFAULT) 2707d421530SBarry Smith dlhandle = RTLD_DEFAULT; 271*d1408c41SPierre Jolivet #else /* PETSC_HAVE_RTLD_DEFAULT */ 272accbd18bSBarry Smith /* Attempt to open the main executable as a dynamic library. */ 27302c9f0b5SLisandro Dalcin dlhandle = dlopen(NULL, dlflags1 | dlflags2); 2747c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 2759371c9d4SSatish Balay { 2769371c9d4SSatish Balay const char *e = (const char *)dlerror(); 27728b400f6SJacob Faibussowitsch PetscCheck(!e, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library:\n Error message from dlopen(): '%s'", e); 2787c62f5d3SDmitry Karpeev } 279accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 280*d1408c41SPierre Jolivet #endif /* PETSC_HAVE_RTLD_DEFAULT */ 2817c62f5d3SDmitry Karpeev } 282accbd18bSBarry Smith #endif /* PETSC_HAVE_DLOPEN */ 2834956914eSSatish Balay } 284be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 285be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 286accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 2876ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)dlsym(dlhandle, symbol); 288accbd18bSBarry Smith #else /* PETSC_HAVE_DLSYM */ 289e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 290accbd18bSBarry Smith #endif /* PETSC_HAVE_DLSYM */ 291accbd18bSBarry Smith #else /* PETSC_HAVE_DLFCN_H */ 292accbd18bSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 293accbd18bSBarry Smith #endif /* PETSC_HAVE_WINDOWS_H */ 294accbd18bSBarry Smith // clang-format on 295ebd79076SLisandro Dalcin 2966ea75d68SLisandro Dalcin *value = *((void **)&dlsymbol); 297ebd79076SLisandro Dalcin 2982d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 2999566063dSJacob Faibussowitsch if (*value) PetscCall(PetscFPTAdd(*value, symbol)); 300accbd18bSBarry Smith #endif /* PETSC_SERIALIZE_FUNCTIONS */ 3012d53ad75SBarry Smith return (0); 302ebd79076SLisandro Dalcin } 303184ce1a2SMatthew G. Knepley 304184ce1a2SMatthew G. Knepley /*@C 305184ce1a2SMatthew G. Knepley PetscDLAddr - find the name of a symbol in a dynamic library 306184ce1a2SMatthew G. Knepley 307184ce1a2SMatthew G. Knepley Not Collective 308184ce1a2SMatthew G. Knepley 309184ce1a2SMatthew G. Knepley Input Parameters: 310811af0c4SBarry Smith + handle - obtained with `PetscDLOpen()` or NULL 311184ce1a2SMatthew G. Knepley - func - pointer to the function, NULL if not found 312184ce1a2SMatthew G. Knepley 313184ce1a2SMatthew G. Knepley Output Parameter: 31404c51a94SMatthew G. Knepley . name - name of symbol, or NULL if name lookup is not supported. 315184ce1a2SMatthew G. Knepley 316184ce1a2SMatthew G. Knepley Level: developer 317184ce1a2SMatthew G. Knepley 318184ce1a2SMatthew G. Knepley Notes: 31904c51a94SMatthew G. Knepley The caller must free the returned name. 320258ec3d2SMatthew G. Knepley 321184ce1a2SMatthew G. Knepley In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 322184ce1a2SMatthew G. Knepley systems this requires platform-specific linker flags. 32310699b91SBarry Smith 324db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()` 325184ce1a2SMatthew G. Knepley @*/ 326d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLAddr(void (*func)(void), char **name) 327d71ae5a4SJacob Faibussowitsch { 328184ce1a2SMatthew G. Knepley PetscFunctionBegin; 329dadcf809SJacob Faibussowitsch PetscValidPointer(name, 2); 330184ce1a2SMatthew G. Knepley *name = NULL; 331e8953f01SSatish Balay #if defined(PETSC_HAVE_DLADDR) && !(defined(__cray__) && defined(__clang__)) 332184ce1a2SMatthew G. Knepley dlerror(); /* clear any previous error */ 333184ce1a2SMatthew G. Knepley { 334184ce1a2SMatthew G. Knepley Dl_info info; 335184ce1a2SMatthew G. Knepley 3365f80ce2aSJacob Faibussowitsch PetscCheck(dladdr(*(void **)&func, &info), PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror()); 337258ec3d2SMatthew G. Knepley #ifdef PETSC_HAVE_CXX 3389566063dSJacob Faibussowitsch PetscCall(PetscDemangleSymbol(info.dli_sname, name)); 339258ec3d2SMatthew G. Knepley #else 3409566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(info.dli_sname, name)); 341258ec3d2SMatthew G. Knepley #endif 342184ce1a2SMatthew G. Knepley } 343184ce1a2SMatthew G. Knepley #endif 344184ce1a2SMatthew G. Knepley PetscFunctionReturn(0); 345184ce1a2SMatthew G. Knepley } 346