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 35cc4c1da9SBarry Smith Not Collective, No Fortran Support 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 4621532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 4721532e8aSBarry 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; 554f572ea9SToby Isaac PetscAssertPointer(name, 1); 564f572ea9SToby Isaac PetscAssertPointer(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 131cc4c1da9SBarry Smith Not Collective, No Fortran Support 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; 1434f572ea9SToby Isaac PetscAssertPointer(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 193ebd79076SLisandro Dalcin /*@C 194b235ab32SBarry Smith PetscDLSym - finds a symbol in a dynamic library 195b235ab32SBarry Smith 196cc4c1da9SBarry Smith Not Collective, No Fortran Support 197b235ab32SBarry Smith 198b235ab32SBarry Smith Input Parameters: 19921532e8aSBarry Smith + handle - obtained with `PetscDLOpen()` or `NULL` 200b235ab32SBarry Smith - symbol - name of symbol 201b235ab32SBarry Smith 202b235ab32SBarry Smith Output Parameter: 20321532e8aSBarry Smith . value - pointer to the function, `NULL` if not found 204b235ab32SBarry Smith 205b235ab32SBarry Smith Level: developer 206b235ab32SBarry Smith 207811af0c4SBarry Smith Note: 20821532e8aSBarry 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 21221532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 21321532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()` 214ebd79076SLisandro Dalcin @*/ 215d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value) 216d71ae5a4SJacob Faibussowitsch { 217c8025a54SPierre Jolivet dlhandle_t dlhandle; 2186ea75d68SLisandro Dalcin dlsymbol_t dlsymbol; 219ebd79076SLisandro Dalcin 2203ba16761SJacob Faibussowitsch PetscFunctionBegin; 2214f572ea9SToby Isaac PetscAssertPointer(symbol, 2); 2224f572ea9SToby Isaac PetscAssertPointer(value, 3); 223ebd79076SLisandro Dalcin 224be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t)0; 2256ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)0; 226c8025a54SPierre Jolivet *value = NULL; 227ebd79076SLisandro Dalcin 2285673baf8SLisandro Dalcin /* 2295673baf8SLisandro Dalcin --- GetProcAddress --- 2305673baf8SLisandro Dalcin */ 231a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 232a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 233e4d177b5SBarry Smith if (handle) dlhandle = (dlhandle_t)handle; 234e4d177b5SBarry Smith else dlhandle = (dlhandle_t)GetCurrentProcess(); 2356ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)GetProcAddress(dlhandle, symbol); 236a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 237a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 238accbd18bSBarry Smith #endif /* PETSC_HAVE_SETLASTERROR */ 239a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2405673baf8SLisandro Dalcin 2415673baf8SLisandro Dalcin /* 2425673baf8SLisandro Dalcin --- dlsym --- 2435673baf8SLisandro Dalcin */ 244accbd18bSBarry Smith #elif defined(PETSC_HAVE_DLFCN_H) /* PETSC_HAVE_WINDOWS_H */ 245a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 246a297a907SKarl Rupp if (handle) dlhandle = (dlhandle_t)handle; 247a297a907SKarl Rupp else { 2485617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN) 2497c62f5d3SDmitry Karpeev /* Attempt to retrieve the main executable's dlhandle. */ 2509371c9d4SSatish Balay { 251b8e43d22SPierre Jolivet #if !defined(PETSC_HAVE_RTLD_DEFAULT) 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) 2573a7d0413SPierre Jolivet if (!dlflags1) dlflags1 = RTLD_NOW; 258accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_NOW */ 2597c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL) 2607c62f5d3SDmitry Karpeev dlflags2 = RTLD_LOCAL; 261accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LOCAL */ 2627c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL) 2633a7d0413SPierre Jolivet if (!dlflags2) dlflags2 = RTLD_GLOBAL; 264accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_GLOBAL */ 265b8e43d22SPierre Jolivet #endif /* !PETSC_HAVE_RTLD_DEFAULT */ 2667c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 267ac530a7eSPierre Jolivet if (!(PETSC_RUNNING_ON_VALGRIND)) dlerror(); /* clear any previous error, valgrind does not like this */ 268accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 269618dc07dSPierre Jolivet #if defined(PETSC_HAVE_RTLD_DEFAULT) 2707d421530SBarry Smith dlhandle = RTLD_DEFAULT; 271d1408c41SPierre 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(); 27700045ab3SPierre Jolivet PetscCheck(!e, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library: error message from dlopen(): '%s'", e); 2787c62f5d3SDmitry Karpeev } 279accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */ 280b8e43d22SPierre 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 */ 3013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 307cc4c1da9SBarry Smith Not Collective, No Fortran Support 308184ce1a2SMatthew G. Knepley 309184ce1a2SMatthew G. Knepley Input Parameters: 31010450e9eSJacob Faibussowitsch . func - pointer to the function, `NULL` if not found 311184ce1a2SMatthew G. Knepley 312184ce1a2SMatthew G. Knepley Output Parameter: 31321532e8aSBarry Smith . name - name of symbol, or `NULL` if name lookup is not supported. 314184ce1a2SMatthew G. Knepley 315184ce1a2SMatthew G. Knepley Level: developer 316184ce1a2SMatthew G. Knepley 317184ce1a2SMatthew G. Knepley Notes: 31804c51a94SMatthew G. Knepley The caller must free the returned name. 319258ec3d2SMatthew G. Knepley 320184ce1a2SMatthew G. Knepley In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 321184ce1a2SMatthew G. Knepley systems this requires platform-specific linker flags. 32210699b91SBarry Smith 32321532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`, 32421532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()` 325184ce1a2SMatthew G. Knepley @*/ 326*57d50842SBarry Smith PetscErrorCode PetscDLAddr(PetscVoidFn *func, char *name[]) 327d71ae5a4SJacob Faibussowitsch { 328184ce1a2SMatthew G. Knepley PetscFunctionBegin; 3294f572ea9SToby Isaac PetscAssertPointer(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 3443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 345184ce1a2SMatthew G. Knepley } 346