1ebd79076SLisandro Dalcin /*
2ebd79076SLisandro Dalcin Low-level routines for managing dynamic link libraries (DLLs).
3ebd79076SLisandro Dalcin */
4ebd79076SLisandro Dalcin
5*dab73fe7SLisandro Dalcin #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for dlopen() */
6af0996ceSBarry Smith #include <petsc/private/petscimpl.h>
7ebd79076SLisandro Dalcin
8ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
9ebd79076SLisandro Dalcin #include <windows.h>
10184ce1a2SMatthew G. Knepley #endif
11184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLFCN_H)
12ebd79076SLisandro Dalcin #include <dlfcn.h>
13ebd79076SLisandro Dalcin #endif
14ebd79076SLisandro Dalcin
15ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
16ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t;
176ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t;
18ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
19ebd79076SLisandro Dalcin typedef void *dlhandle_t;
206ea75d68SLisandro Dalcin typedef void *dlsymbol_t;
21ebd79076SLisandro Dalcin #else
22ebd79076SLisandro Dalcin typedef void *dlhandle_t;
236ea75d68SLisandro Dalcin typedef void *dlsymbol_t;
24ebd79076SLisandro Dalcin #endif
25ebd79076SLisandro Dalcin
26ebd79076SLisandro Dalcin /*@C
27811af0c4SBarry Smith PetscDLOpen - opens a dynamic library
28b235ab32SBarry Smith
29cc4c1da9SBarry Smith Not Collective, No Fortran Support
30b235ab32SBarry Smith
31b235ab32SBarry Smith Input Parameters:
32b235ab32SBarry Smith + name - name of library
33e4d177b5SBarry Smith - mode - options on how to open library
34b235ab32SBarry Smith
35b235ab32SBarry Smith Output Parameter:
36811af0c4SBarry Smith . handle - opaque pointer to be used with `PetscDLSym()`
37b235ab32SBarry Smith
38b235ab32SBarry Smith Level: developer
39b235ab32SBarry Smith
4021532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`,
4121532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()`
42ebd79076SLisandro Dalcin @*/
PetscDLOpen(const char name[],PetscDLMode mode,PetscDLHandle * handle)43d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLOpen(const char name[], PetscDLMode mode, PetscDLHandle *handle)
44d71ae5a4SJacob Faibussowitsch {
458e049581SJed Brown PETSC_UNUSED int dlflags1, dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
46ebd79076SLisandro Dalcin dlhandle_t dlhandle;
47ebd79076SLisandro Dalcin
48ebd79076SLisandro Dalcin PetscFunctionBegin;
494f572ea9SToby Isaac PetscAssertPointer(name, 1);
504f572ea9SToby Isaac PetscAssertPointer(handle, 3);
51ebd79076SLisandro Dalcin
52be1c6ad7SLisandro Dalcin dlflags1 = 0;
53be1c6ad7SLisandro Dalcin dlflags2 = 0;
545673baf8SLisandro Dalcin dlhandle = (dlhandle_t)0;
55be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle)0;
56ebd79076SLisandro Dalcin
575673baf8SLisandro Dalcin /*
585673baf8SLisandro Dalcin --- LoadLibrary ---
595673baf8SLisandro Dalcin */
60be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
61be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name);
62ebd79076SLisandro Dalcin if (!dlhandle) {
63d0609cedSBarry Smith /* TODO: Seem to need fixing, why not just return with an error with SETERRQ() */
64ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
65ebd79076SLisandro Dalcin DWORD erc;
66b3bb0f5eSLisandro Dalcin char *buff = NULL;
67ebd79076SLisandro Dalcin erc = GetLastError();
689371c9d4SSatish 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);
699371c9d4SSatish 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));
70ebd79076SLisandro Dalcin LocalFree(buff);
713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
72ebd79076SLisandro Dalcin #else
7398921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s", name, "unavailable");
74ebd79076SLisandro Dalcin #endif
75ebd79076SLisandro Dalcin }
765673baf8SLisandro Dalcin
775673baf8SLisandro Dalcin /*
785673baf8SLisandro Dalcin --- dlopen ---
795673baf8SLisandro Dalcin */
80a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
81ebd79076SLisandro Dalcin /*
82ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym()
83ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates
84ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened
85ebd79076SLisandro Dalcin with dlopen()
86ebd79076SLisandro Dalcin */
87be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
88be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY;
89be1c6ad7SLisandro Dalcin #endif
90ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
91a297a907SKarl Rupp if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
92ebd79076SLisandro Dalcin #endif
93ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
94be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL;
95ebd79076SLisandro Dalcin #endif
96b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
97a297a907SKarl Rupp if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
98b3bb0f5eSLisandro Dalcin #endif
99be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
100be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */
101be1c6ad7SLisandro Dalcin #endif
102be1c6ad7SLisandro Dalcin dlhandle = dlopen(name, dlflags1 | dlflags2);
103ebd79076SLisandro Dalcin if (!dlhandle) {
104ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
105ebd79076SLisandro Dalcin const char *errmsg = dlerror();
106ebd79076SLisandro Dalcin #else
107ebd79076SLisandro Dalcin const char *errmsg = "unavailable";
108ebd79076SLisandro Dalcin #endif
10998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n %s\n Error message from dlopen() %s", name, errmsg);
110ebd79076SLisandro Dalcin }
1115673baf8SLisandro Dalcin /*
1125673baf8SLisandro Dalcin --- unimplemented ---
1135673baf8SLisandro Dalcin */
114ebd79076SLisandro Dalcin #else
115e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
116ebd79076SLisandro Dalcin #endif
117ebd79076SLisandro Dalcin
118ebd79076SLisandro Dalcin *handle = (PetscDLHandle)dlhandle;
1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
120ebd79076SLisandro Dalcin }
121ebd79076SLisandro Dalcin
122ebd79076SLisandro Dalcin /*@C
123b235ab32SBarry Smith PetscDLClose - closes a dynamic library
124b235ab32SBarry Smith
125cc4c1da9SBarry Smith Not Collective, No Fortran Support
126b235ab32SBarry Smith
127b235ab32SBarry Smith Input Parameter:
128811af0c4SBarry Smith . handle - the handle for the library obtained with `PetscDLOpen()`
129b235ab32SBarry Smith
130b235ab32SBarry Smith Level: developer
13110699b91SBarry Smith
132db781477SPatrick Sanan .seealso: `PetscDLOpen()`, `PetscDLSym()`, `PetscDLAddr()`
133ebd79076SLisandro Dalcin @*/
PetscDLClose(PetscDLHandle * handle)134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLClose(PetscDLHandle *handle)
135d71ae5a4SJacob Faibussowitsch {
136ebd79076SLisandro Dalcin PetscFunctionBegin;
1374f572ea9SToby Isaac PetscAssertPointer(handle, 1);
138ebd79076SLisandro Dalcin
1395673baf8SLisandro Dalcin /*
1405673baf8SLisandro Dalcin --- FreeLibrary ---
1415673baf8SLisandro Dalcin */
142ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
143be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1448e049581SJed Brown if (FreeLibrary((dlhandle_t)*handle) == 0) {
1455673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
146b3bb0f5eSLisandro Dalcin char *buff = NULL;
147a21658a3SLisandro Dalcin DWORD erc = GetLastError();
1480298fd71SBarry 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);
1493ba16761SJacob Faibussowitsch PetscCall(PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n", buff));
1505673baf8SLisandro Dalcin LocalFree(buff);
1515673baf8SLisandro Dalcin #else
1523ba16761SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n Error message from FreeLibrary() %s", "unavailable");
1535673baf8SLisandro Dalcin #endif
1545673baf8SLisandro Dalcin }
155be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
156ebd79076SLisandro Dalcin
1575673baf8SLisandro Dalcin /*
1585673baf8SLisandro Dalcin --- dclose ---
1595673baf8SLisandro Dalcin */
160ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
161a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
162be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
163be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */
164be1c6ad7SLisandro Dalcin #endif
1658e049581SJed Brown if (dlclose((dlhandle_t)*handle) < 0) {
166ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
167ebd79076SLisandro Dalcin const char *errmsg = dlerror();
168ebd79076SLisandro Dalcin #else
169ebd79076SLisandro Dalcin const char *errmsg = "unavailable";
170ebd79076SLisandro Dalcin #endif
1713ba16761SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n Error message from dlclose() %s", errmsg);
172ebd79076SLisandro Dalcin }
173a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1745673baf8SLisandro Dalcin
1755673baf8SLisandro Dalcin /*
1765673baf8SLisandro Dalcin --- unimplemented ---
1775673baf8SLisandro Dalcin */
178ebd79076SLisandro Dalcin #else
179e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
180ebd79076SLisandro Dalcin #endif
181ebd79076SLisandro Dalcin
1820298fd71SBarry Smith *handle = NULL;
1833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
184ebd79076SLisandro Dalcin }
185ebd79076SLisandro Dalcin
186accbd18bSBarry Smith // clang-format off
187ebd79076SLisandro Dalcin /*@C
188b235ab32SBarry Smith PetscDLSym - finds a symbol in a dynamic library
189b235ab32SBarry Smith
190cc4c1da9SBarry Smith Not Collective, No Fortran Support
191b235ab32SBarry Smith
192b235ab32SBarry Smith Input Parameters:
19321532e8aSBarry Smith + handle - obtained with `PetscDLOpen()` or `NULL`
194b235ab32SBarry Smith - symbol - name of symbol
195b235ab32SBarry Smith
196b235ab32SBarry Smith Output Parameter:
19721532e8aSBarry Smith . value - pointer to the function, `NULL` if not found
198b235ab32SBarry Smith
199b235ab32SBarry Smith Level: developer
200b235ab32SBarry Smith
201811af0c4SBarry Smith Note:
20221532e8aSBarry Smith If handle is `NULL`, the symbol is looked for in the main executable's dynamic symbol table.
2037c62f5d3SDmitry Karpeev In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like
2047c62f5d3SDmitry Karpeev systems this requires platform-specific linker flags.
2057c62f5d3SDmitry Karpeev
20621532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`,
20721532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()`
208ebd79076SLisandro Dalcin @*/
PetscDLSym(PetscDLHandle handle,const char symbol[],void ** value)209d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value)
210d71ae5a4SJacob Faibussowitsch {
211c8025a54SPierre Jolivet dlhandle_t dlhandle;
2126ea75d68SLisandro Dalcin dlsymbol_t dlsymbol;
213ebd79076SLisandro Dalcin
2143ba16761SJacob Faibussowitsch PetscFunctionBegin;
2154f572ea9SToby Isaac PetscAssertPointer(symbol, 2);
2164f572ea9SToby Isaac PetscAssertPointer(value, 3);
217ebd79076SLisandro Dalcin
218be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t)0;
2196ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)0;
220c8025a54SPierre Jolivet *value = NULL;
221ebd79076SLisandro Dalcin
2225673baf8SLisandro Dalcin /*
2235673baf8SLisandro Dalcin --- GetProcAddress ---
2245673baf8SLisandro Dalcin */
225a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
226a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
227e4d177b5SBarry Smith if (handle) dlhandle = (dlhandle_t)handle;
228e4d177b5SBarry Smith else dlhandle = (dlhandle_t)GetCurrentProcess();
2296ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)GetProcAddress(dlhandle, symbol);
230a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
231a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */
232accbd18bSBarry Smith #endif /* PETSC_HAVE_SETLASTERROR */
233a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2345673baf8SLisandro Dalcin
2355673baf8SLisandro Dalcin /*
2365673baf8SLisandro Dalcin --- dlsym ---
2375673baf8SLisandro Dalcin */
238accbd18bSBarry Smith #elif defined(PETSC_HAVE_DLFCN_H) /* PETSC_HAVE_WINDOWS_H */
239a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
240a297a907SKarl Rupp if (handle) dlhandle = (dlhandle_t)handle;
241a297a907SKarl Rupp else {
2425617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN)
2437c62f5d3SDmitry Karpeev /* Attempt to retrieve the main executable's dlhandle. */
2449371c9d4SSatish Balay {
245b8e43d22SPierre Jolivet #if !defined(PETSC_HAVE_RTLD_DEFAULT)
2469371c9d4SSatish Balay int dlflags1 = 0, dlflags2 = 0;
2477c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY)
2487c62f5d3SDmitry Karpeev dlflags1 = RTLD_LAZY;
249accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LAZY */
2507c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW)
2513a7d0413SPierre Jolivet if (!dlflags1) dlflags1 = RTLD_NOW;
252accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_NOW */
2537c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL)
2547c62f5d3SDmitry Karpeev dlflags2 = RTLD_LOCAL;
255accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_LOCAL */
2567c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL)
2573a7d0413SPierre Jolivet if (!dlflags2) dlflags2 = RTLD_GLOBAL;
258accbd18bSBarry Smith #endif /* PETSC_HAVE_RTLD_GLOBAL */
259b8e43d22SPierre Jolivet #endif /* !PETSC_HAVE_RTLD_DEFAULT */
2607c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
261ac530a7eSPierre Jolivet if (!(PETSC_RUNNING_ON_VALGRIND)) dlerror(); /* clear any previous error, valgrind does not like this */
262accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */
263618dc07dSPierre Jolivet #if defined(PETSC_HAVE_RTLD_DEFAULT)
2647d421530SBarry Smith dlhandle = RTLD_DEFAULT;
265d1408c41SPierre Jolivet #else /* PETSC_HAVE_RTLD_DEFAULT */
266accbd18bSBarry Smith /* Attempt to open the main executable as a dynamic library. */
26702c9f0b5SLisandro Dalcin dlhandle = dlopen(NULL, dlflags1 | dlflags2);
2687c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2699371c9d4SSatish Balay {
2709371c9d4SSatish Balay const char *e = (const char *)dlerror();
27100045ab3SPierre Jolivet PetscCheck(!e, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library: error message from dlopen(): '%s'", e);
2727c62f5d3SDmitry Karpeev }
273accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */
274b8e43d22SPierre Jolivet #endif /* !PETSC_HAVE_RTLD_DEFAULT */
2757c62f5d3SDmitry Karpeev }
276accbd18bSBarry Smith #endif /* PETSC_HAVE_DLOPEN */
2774956914eSSatish Balay }
278be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
279be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */
280accbd18bSBarry Smith #endif /* PETSC_HAVE_DLERROR */
2816ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t)dlsym(dlhandle, symbol);
282accbd18bSBarry Smith #else /* PETSC_HAVE_DLSYM */
283e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
284accbd18bSBarry Smith #endif /* PETSC_HAVE_DLSYM */
285accbd18bSBarry Smith #else /* PETSC_HAVE_DLFCN_H */
286accbd18bSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
287accbd18bSBarry Smith #endif /* PETSC_HAVE_WINDOWS_H */
288accbd18bSBarry Smith // clang-format on
289ebd79076SLisandro Dalcin
2906ea75d68SLisandro Dalcin *value = *((void **)&dlsymbol);
291ebd79076SLisandro Dalcin
2922d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
2939566063dSJacob Faibussowitsch if (*value) PetscCall(PetscFPTAdd(*value, symbol));
294accbd18bSBarry Smith #endif /* PETSC_SERIALIZE_FUNCTIONS */
2953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
296ebd79076SLisandro Dalcin }
297184ce1a2SMatthew G. Knepley
298184ce1a2SMatthew G. Knepley /*@C
299184ce1a2SMatthew G. Knepley PetscDLAddr - find the name of a symbol in a dynamic library
300184ce1a2SMatthew G. Knepley
301cc4c1da9SBarry Smith Not Collective, No Fortran Support
302184ce1a2SMatthew G. Knepley
303184ce1a2SMatthew G. Knepley Input Parameters:
30410450e9eSJacob Faibussowitsch . func - pointer to the function, `NULL` if not found
305184ce1a2SMatthew G. Knepley
306184ce1a2SMatthew G. Knepley Output Parameter:
30721532e8aSBarry Smith . name - name of symbol, or `NULL` if name lookup is not supported.
308184ce1a2SMatthew G. Knepley
309184ce1a2SMatthew G. Knepley Level: developer
310184ce1a2SMatthew G. Knepley
311184ce1a2SMatthew G. Knepley Notes:
31204c51a94SMatthew G. Knepley The caller must free the returned name.
313258ec3d2SMatthew G. Knepley
314184ce1a2SMatthew G. Knepley In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like
315184ce1a2SMatthew G. Knepley systems this requires platform-specific linker flags.
31610699b91SBarry Smith
31721532e8aSBarry Smith .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()`, `PetscDLLibrary`, `PetscLoadDynamicLibrary()`, `PetscDLLibraryAppend()`,
31821532e8aSBarry Smith `PetscDLLibraryRetrieve()`, `PetscDLLibraryOpen()`, `PetscDLLibraryClose()`, `PetscDLLibrarySym()`
319184ce1a2SMatthew G. Knepley @*/
PetscDLAddr(PetscVoidFn * func,char * name[])32057d50842SBarry Smith PetscErrorCode PetscDLAddr(PetscVoidFn *func, char *name[])
321d71ae5a4SJacob Faibussowitsch {
322184ce1a2SMatthew G. Knepley PetscFunctionBegin;
3234f572ea9SToby Isaac PetscAssertPointer(name, 2);
324184ce1a2SMatthew G. Knepley *name = NULL;
325e8953f01SSatish Balay #if defined(PETSC_HAVE_DLADDR) && !(defined(__cray__) && defined(__clang__))
326184ce1a2SMatthew G. Knepley dlerror(); /* clear any previous error */
327184ce1a2SMatthew G. Knepley {
328184ce1a2SMatthew G. Knepley Dl_info info;
329184ce1a2SMatthew G. Knepley
3305f80ce2aSJacob Faibussowitsch PetscCheck(dladdr(*(void **)&func, &info), PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
3319566063dSJacob Faibussowitsch PetscCall(PetscDemangleSymbol(info.dli_sname, name));
332184ce1a2SMatthew G. Knepley }
333184ce1a2SMatthew G. Knepley #endif
3343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
335184ce1a2SMatthew G. Knepley }
336