xref: /petsc/src/sys/dll/dlimpl.c (revision a28344a5144139f565b3604164979954db19997e)
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