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 46*21532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 47*21532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()` 48ebd79076SLisandro Dalcin @*/ 49d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLOpen(const char name[], PetscDLMode mode, PetscDLHandle *handle) 50d71ae5a4SJacob Faibussowitsch { 518e049581SJed Brown PETSC_UNUSED int dlflags1, dlflags2; /* There are some preprocessor paths where these variables are set, but not used */ 52ebd79076SLisandro Dalcin dlhandle_t dlhandle; 53ebd79076SLisandro Dalcin 54ebd79076SLisandro Dalcin PetscFunctionBegin; 55ebd79076SLisandro Dalcin PetscValidCharPointer(name, 1); 56ebd79076SLisandro Dalcin PetscValidPointer(handle, 3); 57ebd79076SLisandro Dalcin 58be1c6ad7SLisandro Dalcin dlflags1 = 0; 59be1c6ad7SLisandro Dalcin dlflags2 = 0; 605673baf8SLisandro Dalcin dlhandle = (dlhandle_t)0; 61be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle)0; 62ebd79076SLisandro Dalcin 635673baf8SLisandro Dalcin /* 645673baf8SLisandro Dalcin --- LoadLibrary --- 655673baf8SLisandro Dalcin */ 66be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 67be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 68ebd79076SLisandro Dalcin if (!dlhandle) { 69d0609cedSBarry Smith /* TODO: Seem to need fixing, why not just return with an error with SETERRQ() */ 70ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 71ebd79076SLisandro Dalcin DWORD erc; 72b3bb0f5eSLisandro Dalcin char *buff = NULL; 73ebd79076SLisandro Dalcin erc = GetLastError(); 749371c9d4SSatish 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); 759371c9d4SSatish 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)); 76ebd79076SLisandro Dalcin LocalFree(buff); 773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78ebd79076SLisandro Dalcin #else 7998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s", name, "unavailable"); 80ebd79076SLisandro Dalcin #endif 81ebd79076SLisandro Dalcin } 825673baf8SLisandro Dalcin 835673baf8SLisandro Dalcin /* 845673baf8SLisandro Dalcin --- dlopen --- 855673baf8SLisandro Dalcin */ 86a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 87ebd79076SLisandro Dalcin /* 88ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 89ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 90ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 91ebd79076SLisandro Dalcin with dlopen() 92ebd79076SLisandro Dalcin */ 93be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 94be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 95be1c6ad7SLisandro Dalcin #endif 96ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 97a297a907SKarl Rupp if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW; 98ebd79076SLisandro Dalcin #endif 99ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 100be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 101ebd79076SLisandro Dalcin #endif 102b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 103a297a907SKarl Rupp if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL; 104b3bb0f5eSLisandro Dalcin #endif 105be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 106be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 107be1c6ad7SLisandro Dalcin #endif 108be1c6ad7SLisandro Dalcin dlhandle = dlopen(name, dlflags1 | dlflags2); 109ebd79076SLisandro Dalcin if (!dlhandle) { 110ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 111ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 112ebd79076SLisandro Dalcin #else 113ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 114ebd79076SLisandro Dalcin #endif 11598921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from dlopen() %s", name, errmsg); 116ebd79076SLisandro Dalcin } 1175673baf8SLisandro Dalcin /* 1185673baf8SLisandro Dalcin --- unimplemented --- 1195673baf8SLisandro Dalcin */ 120ebd79076SLisandro Dalcin #else 121e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 122ebd79076SLisandro Dalcin #endif 123ebd79076SLisandro Dalcin 124ebd79076SLisandro Dalcin *handle = (PetscDLHandle)dlhandle; 1253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 126ebd79076SLisandro Dalcin } 127ebd79076SLisandro Dalcin 128ebd79076SLisandro Dalcin /*@C 129b235ab32SBarry Smith PetscDLClose - closes a dynamic library 130b235ab32SBarry Smith 131b235ab32SBarry Smith Not Collective 132b235ab32SBarry Smith 133b235ab32SBarry Smith Input Parameter: 134811af0c4SBarry Smith . handle - the handle for the library obtained with `PetscDLOpen()` 135b235ab32SBarry Smith 136b235ab32SBarry Smith Level: developer 13710699b91SBarry Smith 138db781477SPatrick Sanan .seealso: `PetscDLOpen()`, `PetscDLSym()`, `PetscDLAddr()` 139ebd79076SLisandro Dalcin @*/ 140d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLClose(PetscDLHandle *handle) 141d71ae5a4SJacob Faibussowitsch { 142ebd79076SLisandro Dalcin PetscFunctionBegin; 143ebd79076SLisandro Dalcin PetscValidPointer(handle, 1); 144ebd79076SLisandro Dalcin 1455673baf8SLisandro Dalcin /* 1465673baf8SLisandro Dalcin --- FreeLibrary --- 1475673baf8SLisandro Dalcin */ 148ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 149be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1508e049581SJed Brown if (FreeLibrary((dlhandle_t)*handle) == 0) { 1515673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 152b3bb0f5eSLisandro Dalcin char *buff = NULL; 153a21658a3SLisandro Dalcin DWORD erc = GetLastError(); 1540298fd71SBarry 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); 1553ba16761SJacob Faibussowitsch PetscCall(PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n", buff)); 1565673baf8SLisandro Dalcin LocalFree(buff); 1575673baf8SLisandro Dalcin #else 1583ba16761SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n Error message from FreeLibrary() %s", "unavailable"); 1595673baf8SLisandro Dalcin #endif 1605673baf8SLisandro Dalcin } 161be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 162ebd79076SLisandro Dalcin 1635673baf8SLisandro Dalcin /* 1645673baf8SLisandro Dalcin --- dclose --- 1655673baf8SLisandro Dalcin */ 166ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 167a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE) 168be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 169be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 170be1c6ad7SLisandro Dalcin #endif 1718e049581SJed Brown if (dlclose((dlhandle_t)*handle) < 0) { 172ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 173ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 174ebd79076SLisandro Dalcin #else 175ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 176ebd79076SLisandro Dalcin #endif 1773ba16761SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n Error message from dlclose() %s", errmsg); 178ebd79076SLisandro Dalcin } 179a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */ 1805673baf8SLisandro Dalcin 1815673baf8SLisandro Dalcin /* 1825673baf8SLisandro Dalcin --- unimplemented --- 1835673baf8SLisandro Dalcin */ 184ebd79076SLisandro Dalcin #else 185e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 186ebd79076SLisandro Dalcin #endif 187ebd79076SLisandro Dalcin 1880298fd71SBarry Smith *handle = NULL; 1893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190ebd79076SLisandro Dalcin } 191ebd79076SLisandro Dalcin 192accbd18bSBarry Smith // clang-format off 193accbd18bSBarry Smith 194ebd79076SLisandro Dalcin /*@C 195b235ab32SBarry Smith PetscDLSym - finds a symbol in a dynamic library 196b235ab32SBarry Smith 197b235ab32SBarry Smith Not Collective 198b235ab32SBarry Smith 199b235ab32SBarry Smith Input Parameters: 200*21532e8aSBarry Smith + handle - obtained with `PetscDLOpen()` or `NULL` 201b235ab32SBarry Smith - symbol - name of symbol 202b235ab32SBarry Smith 203b235ab32SBarry Smith Output Parameter: 204*21532e8aSBarry Smith . value - pointer to the function, `NULL` if not found 205b235ab32SBarry Smith 206b235ab32SBarry Smith Level: developer 207b235ab32SBarry Smith 208811af0c4SBarry Smith Note: 209*21532e8aSBarry Smith If handle is `NULL`, the symbol is looked for in the main executable's dynamic symbol table. 2107c62f5d3SDmitry Karpeev In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 2117c62f5d3SDmitry Karpeev systems this requires platform-specific linker flags. 2127c62f5d3SDmitry Karpeev 213*21532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 214*21532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()` 215ebd79076SLisandro Dalcin @*/ 216d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value) 217d71ae5a4SJacob Faibussowitsch { 2188e049581SJed Brown PETSC_UNUSED dlhandle_t dlhandle; 2196ea75d68SLisandro Dalcin dlsymbol_t dlsymbol; 220ebd79076SLisandro Dalcin 2213ba16761SJacob Faibussowitsch PetscFunctionBegin; 222ebd79076SLisandro Dalcin PetscValidCharPointer(symbol, 2); 223ebd79076SLisandro Dalcin PetscValidPointer(value, 3); 224ebd79076SLisandro Dalcin 225be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t)0; 2266ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)0; 227a21658a3SLisandro Dalcin *value = (void *)0; 228ebd79076SLisandro Dalcin 2295673baf8SLisandro Dalcin /* 2305673baf8SLisandro Dalcin --- GetProcAddress --- 2315673baf8SLisandro Dalcin */ 232a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 233a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 234e4d177b5SBarry Smith if (handle) dlhandle = (dlhandle_t)handle; 235e4d177b5SBarry Smith else dlhandle = (dlhandle_t)GetCurrentProcess(); 2366ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)GetProcAddress(dlhandle, symbol); 237a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 238a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 239accbd18bSBarry Smith #endif /* PETSC_HAVE_SETLASTERROR */ 240a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2415673baf8SLisandro Dalcin 2425673baf8SLisandro Dalcin /* 2435673baf8SLisandro Dalcin --- dlsym --- 2445673baf8SLisandro Dalcin */ 245accbd18bSBarry Smith #elif defined(PETSC_HAVE_DLFCN_H) /* PETSC_HAVE_WINDOWS_H */ 246a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 247a297a907SKarl Rupp if (handle) dlhandle = (dlhandle_t)handle; 248a297a907SKarl Rupp else { 2495617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN) 2507c62f5d3SDmitry Karpeev /* Attempt to retrieve the main executable's dlhandle. */ 2519371c9d4SSatish Balay { 2529371c9d4SSatish Balay int dlflags1 = 0, dlflags2 = 0; 2537c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY) 2547c62f5d3SDmitry Karpeev dlflags1 = RTLD_LAZY; 255accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LAZY */ 2567c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW) 257accbd18bSBarry Smith if (!dlflags1) { 2587c62f5d3SDmitry Karpeev dlflags1 = RTLD_NOW; 2597c62f5d3SDmitry Karpeev } 260accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_NOW */ 2617c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL) 2627c62f5d3SDmitry Karpeev dlflags2 = RTLD_LOCAL; 263accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LOCAL */ 2647c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL) 265accbd18bSBarry Smith if (!dlflags2) { 2667c62f5d3SDmitry Karpeev dlflags2 = RTLD_GLOBAL; 2677c62f5d3SDmitry Karpeev } 268accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_GLOBAL */ 2697c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 2709371c9d4SSatish Balay if (!(PETSC_RUNNING_ON_VALGRIND)) { dlerror(); /* clear any previous error; valgrind does not like this */ } 271accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 272618dc07dSPierre Jolivet #if defined(PETSC_HAVE_RTLD_DEFAULT) 2737d421530SBarry Smith dlhandle = RTLD_DEFAULT; 274d1408c41SPierre Jolivet #else /* PETSC_HAVE_RTLD_DEFAULT */ 275accbd18bSBarry Smith /* Attempt to open the main executable as a dynamic library. */ 27602c9f0b5SLisandro Dalcin dlhandle = dlopen(NULL, dlflags1 | dlflags2); 2777c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 2789371c9d4SSatish Balay { 2799371c9d4SSatish Balay const char *e = (const char *)dlerror(); 28028b400f6SJacob 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); 2817c62f5d3SDmitry Karpeev } 282accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 283d1408c41SPierre Jolivet #endif /* PETSC_HAVE_RTLD_DEFAULT */ 2847c62f5d3SDmitry Karpeev } 285accbd18bSBarry Smith #endif /* PETSC_HAVE_DLOPEN */ 2864956914eSSatish Balay } 287be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 288be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 289accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 2906ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)dlsym(dlhandle, symbol); 291accbd18bSBarry Smith #else /* PETSC_HAVE_DLSYM */ 292e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 293accbd18bSBarry Smith #endif /* PETSC_HAVE_DLSYM */ 294accbd18bSBarry Smith #else /* PETSC_HAVE_DLFCN_H */ 295accbd18bSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 296accbd18bSBarry Smith #endif /* PETSC_HAVE_WINDOWS_H */ 297accbd18bSBarry Smith // clang-format on 298ebd79076SLisandro Dalcin 2996ea75d68SLisandro Dalcin *value = *((void **)&dlsymbol); 300ebd79076SLisandro Dalcin 3012d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 3029566063dSJacob Faibussowitsch if (*value) PetscCall(PetscFPTAdd(*value, symbol)); 303accbd18bSBarry Smith #endif /* PETSC_SERIALIZE_FUNCTIONS */ 3043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 305ebd79076SLisandro Dalcin } 306184ce1a2SMatthew G. Knepley 307184ce1a2SMatthew G. Knepley /*@C 308184ce1a2SMatthew G. Knepley PetscDLAddr - find the name of a symbol in a dynamic library 309184ce1a2SMatthew G. Knepley 310184ce1a2SMatthew G. Knepley Not Collective 311184ce1a2SMatthew G. Knepley 312184ce1a2SMatthew G. Knepley Input Parameters: 313*21532e8aSBarry Smith + handle - obtained with `PetscDLOpen()` or `NULL` 314*21532e8aSBarry Smith - func - pointer to the function, `NULL` if not found 315184ce1a2SMatthew G. Knepley 316184ce1a2SMatthew G. Knepley Output Parameter: 317*21532e8aSBarry Smith . name - name of symbol, or `NULL` if name lookup is not supported. 318184ce1a2SMatthew G. Knepley 319184ce1a2SMatthew G. Knepley Level: developer 320184ce1a2SMatthew G. Knepley 321184ce1a2SMatthew G. Knepley Notes: 32204c51a94SMatthew G. Knepley The caller must free the returned name. 323258ec3d2SMatthew G. Knepley 324184ce1a2SMatthew G. Knepley In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 325184ce1a2SMatthew G. Knepley systems this requires platform-specific linker flags. 32610699b91SBarry Smith 327*21532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 328*21532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()` 329184ce1a2SMatthew G. Knepley @*/ 330d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLAddr(void (*func)(void), char **name) 331d71ae5a4SJacob Faibussowitsch { 332184ce1a2SMatthew G. Knepley PetscFunctionBegin; 333dadcf809SJacob Faibussowitsch PetscValidPointer(name, 2); 334184ce1a2SMatthew G. Knepley *name = NULL; 335e8953f01SSatish Balay #if defined(PETSC_HAVE_DLADDR) && !(defined(__cray__) && defined(__clang__)) 336184ce1a2SMatthew G. Knepley dlerror(); /* clear any previous error */ 337184ce1a2SMatthew G. Knepley { 338184ce1a2SMatthew G. Knepley Dl_info info; 339184ce1a2SMatthew G. Knepley 3405f80ce2aSJacob Faibussowitsch PetscCheck(dladdr(*(void **)&func, &info), PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror()); 341258ec3d2SMatthew G. Knepley #ifdef PETSC_HAVE_CXX 3429566063dSJacob Faibussowitsch PetscCall(PetscDemangleSymbol(info.dli_sname, name)); 343258ec3d2SMatthew G. Knepley #else 3449566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(info.dli_sname, name)); 345258ec3d2SMatthew G. Knepley #endif 346184ce1a2SMatthew G. Knepley } 347184ce1a2SMatthew G. Knepley #endif 3483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 349184ce1a2SMatthew G. Knepley } 350