xref: /petsc/src/sys/dll/dlimpl.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
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
33*811af0c4SBarry 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:
42*811af0c4SBarry 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 @*/
489371c9d4SSatish Balay PetscErrorCode PetscDLOpen(const char name[], PetscDLMode mode, PetscDLHandle *handle) {
498e049581SJed Brown   PETSC_UNUSED int dlflags1, dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
50ebd79076SLisandro Dalcin   dlhandle_t       dlhandle;
51ebd79076SLisandro Dalcin 
52ebd79076SLisandro Dalcin   PetscFunctionBegin;
53ebd79076SLisandro Dalcin   PetscValidCharPointer(name, 1);
54ebd79076SLisandro Dalcin   PetscValidPointer(handle, 3);
55ebd79076SLisandro Dalcin 
56be1c6ad7SLisandro Dalcin   dlflags1 = 0;
57be1c6ad7SLisandro Dalcin   dlflags2 = 0;
585673baf8SLisandro Dalcin   dlhandle = (dlhandle_t)0;
59be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle)0;
60ebd79076SLisandro Dalcin 
615673baf8SLisandro Dalcin   /*
625673baf8SLisandro Dalcin      --- LoadLibrary ---
635673baf8SLisandro Dalcin   */
64be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
65be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
66ebd79076SLisandro Dalcin   if (!dlhandle) {
67d0609cedSBarry Smith     /* TODO: Seem to need fixing, why not just return with an error with SETERRQ() */
68ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
69ebd79076SLisandro Dalcin     DWORD erc;
70b3bb0f5eSLisandro Dalcin     char *buff = NULL;
71ebd79076SLisandro Dalcin     erc        = GetLastError();
729371c9d4SSatish 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);
739371c9d4SSatish 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));
74ebd79076SLisandro Dalcin     LocalFree(buff);
7563a3b9bcSJacob Faibussowitsch     PetscFunctionReturn(0);
76ebd79076SLisandro Dalcin #else
7798921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s", name, "unavailable");
78ebd79076SLisandro Dalcin #endif
79ebd79076SLisandro Dalcin   }
805673baf8SLisandro Dalcin 
815673baf8SLisandro Dalcin   /*
825673baf8SLisandro Dalcin      --- dlopen ---
835673baf8SLisandro Dalcin   */
84a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
85ebd79076SLisandro Dalcin   /*
86ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
87ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
88ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
89ebd79076SLisandro Dalcin      with dlopen()
90ebd79076SLisandro Dalcin   */
91be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
92be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
93be1c6ad7SLisandro Dalcin #endif
94ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
95a297a907SKarl Rupp   if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
96ebd79076SLisandro Dalcin #endif
97ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
98be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
99ebd79076SLisandro Dalcin #endif
100b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
101a297a907SKarl Rupp   if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
102b3bb0f5eSLisandro Dalcin #endif
103be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
104be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
105be1c6ad7SLisandro Dalcin #endif
106be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name, dlflags1 | dlflags2);
107ebd79076SLisandro Dalcin   if (!dlhandle) {
108ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
109ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
110ebd79076SLisandro Dalcin #else
111ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
112ebd79076SLisandro Dalcin #endif
11398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s", name, errmsg);
114ebd79076SLisandro Dalcin   }
1155673baf8SLisandro Dalcin   /*
1165673baf8SLisandro Dalcin      --- unimplemented ---
1175673baf8SLisandro Dalcin   */
118ebd79076SLisandro Dalcin #else
119e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
120ebd79076SLisandro Dalcin #endif
121ebd79076SLisandro Dalcin 
122ebd79076SLisandro Dalcin   *handle = (PetscDLHandle)dlhandle;
123ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
124ebd79076SLisandro Dalcin }
125ebd79076SLisandro Dalcin 
126ebd79076SLisandro Dalcin /*@C
127b235ab32SBarry Smith    PetscDLClose -  closes a dynamic library
128b235ab32SBarry Smith 
129b235ab32SBarry Smith    Not Collective
130b235ab32SBarry Smith 
131b235ab32SBarry Smith   Input Parameter:
132*811af0c4SBarry Smith .   handle - the handle for the library obtained with `PetscDLOpen()`
133b235ab32SBarry Smith 
134b235ab32SBarry Smith   Level: developer
13510699b91SBarry Smith 
136db781477SPatrick Sanan .seealso: `PetscDLOpen()`, `PetscDLSym()`, `PetscDLAddr()`
137ebd79076SLisandro Dalcin @*/
1389371c9d4SSatish Balay PetscErrorCode PetscDLClose(PetscDLHandle *handle) {
139ebd79076SLisandro Dalcin   PetscFunctionBegin;
140ebd79076SLisandro Dalcin   PetscValidPointer(handle, 1);
141ebd79076SLisandro Dalcin 
1425673baf8SLisandro Dalcin   /*
1435673baf8SLisandro Dalcin      --- FreeLibrary ---
1445673baf8SLisandro Dalcin   */
145ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
146be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1478e049581SJed Brown   if (FreeLibrary((dlhandle_t)*handle) == 0) {
1485673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
149b3bb0f5eSLisandro Dalcin     char *buff = NULL;
150a21658a3SLisandro Dalcin     DWORD erc  = GetLastError();
1510298fd71SBarry 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);
1525673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n", buff);
1535673baf8SLisandro Dalcin     LocalFree(buff);
1545673baf8SLisandro Dalcin #else
1555673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n", "unavailable");
1565673baf8SLisandro Dalcin #endif
1575673baf8SLisandro Dalcin   }
158be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
159ebd79076SLisandro Dalcin 
1605673baf8SLisandro Dalcin   /*
1615673baf8SLisandro Dalcin      --- dclose ---
1625673baf8SLisandro Dalcin   */
163ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
164a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
165be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
166be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
167be1c6ad7SLisandro Dalcin #endif
1688e049581SJed Brown   if (dlclose((dlhandle_t)*handle) < 0) {
169ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
170ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
171ebd79076SLisandro Dalcin #else
172ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
173ebd79076SLisandro Dalcin #endif
1745673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
175ebd79076SLisandro Dalcin   }
176a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1775673baf8SLisandro Dalcin 
1785673baf8SLisandro Dalcin   /*
1795673baf8SLisandro Dalcin      --- unimplemented ---
1805673baf8SLisandro Dalcin   */
181ebd79076SLisandro Dalcin #else
182e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
183ebd79076SLisandro Dalcin #endif
184ebd79076SLisandro Dalcin 
1850298fd71SBarry Smith   *handle = NULL;
186ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
187ebd79076SLisandro Dalcin }
188ebd79076SLisandro Dalcin 
189ebd79076SLisandro Dalcin /*@C
190b235ab32SBarry Smith    PetscDLSym - finds a symbol in a dynamic library
191b235ab32SBarry Smith 
192b235ab32SBarry Smith    Not Collective
193b235ab32SBarry Smith 
194b235ab32SBarry Smith    Input Parameters:
195*811af0c4SBarry Smith +   handle - obtained with `PetscDLOpen()` or NULL
196b235ab32SBarry Smith -   symbol - name of symbol
197b235ab32SBarry Smith 
198b235ab32SBarry Smith    Output Parameter:
1990298fd71SBarry Smith .   value - pointer to the function, NULL if not found
200b235ab32SBarry Smith 
201b235ab32SBarry Smith    Level: developer
202b235ab32SBarry Smith 
203*811af0c4SBarry Smith   Note:
2040298fd71SBarry Smith    If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
2057c62f5d3SDmitry Karpeev    In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
2067c62f5d3SDmitry Karpeev    systems this requires platform-specific linker flags.
2077c62f5d3SDmitry Karpeev 
208db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()`
209ebd79076SLisandro Dalcin @*/
2109371c9d4SSatish Balay PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value) {
2118e049581SJed Brown   PETSC_UNUSED dlhandle_t dlhandle;
2126ea75d68SLisandro Dalcin   dlsymbol_t              dlsymbol;
213ebd79076SLisandro Dalcin 
214ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol, 2);
215ebd79076SLisandro Dalcin   PetscValidPointer(value, 3);
216ebd79076SLisandro Dalcin 
217be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t)0;
2186ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t)0;
219a21658a3SLisandro Dalcin   *value   = (void *)0;
220ebd79076SLisandro Dalcin 
2215673baf8SLisandro Dalcin   /*
2225673baf8SLisandro Dalcin      --- GetProcAddress ---
2235673baf8SLisandro Dalcin   */
224a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
225a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
226e4d177b5SBarry Smith   if (handle) dlhandle = (dlhandle_t)handle;
227e4d177b5SBarry Smith   else dlhandle = (dlhandle_t)GetCurrentProcess();
2286ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t)GetProcAddress(dlhandle, symbol);
229a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
230a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
231a21658a3SLisandro Dalcin #endif
232a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2335673baf8SLisandro Dalcin 
2345673baf8SLisandro Dalcin   /*
2355673baf8SLisandro Dalcin      --- dlsym ---
2365673baf8SLisandro Dalcin   */
237ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
238a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
239a297a907SKarl Rupp   if (handle) dlhandle = (dlhandle_t)handle;
240a297a907SKarl Rupp   else {
2417c62f5d3SDmitry Karpeev 
2425617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN)
2437c62f5d3SDmitry Karpeev     /* Attempt to retrieve the main executable's dlhandle. */
2449371c9d4SSatish Balay     {
2459371c9d4SSatish Balay       int dlflags1 = 0, dlflags2 = 0;
2467c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY)
2477c62f5d3SDmitry Karpeev       dlflags1 = RTLD_LAZY;
2487c62f5d3SDmitry Karpeev #endif
2497c62f5d3SDmitry Karpeev       if (!dlflags1) {
2507c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW)
2517c62f5d3SDmitry Karpeev         dlflags1 = RTLD_NOW;
2527c62f5d3SDmitry Karpeev #endif
2537c62f5d3SDmitry Karpeev       }
2547c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL)
2557c62f5d3SDmitry Karpeev       dlflags2 = RTLD_LOCAL;
2567c62f5d3SDmitry Karpeev #endif
2577c62f5d3SDmitry Karpeev       if (!dlflags2) {
2587c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL)
2597c62f5d3SDmitry Karpeev         dlflags2 = RTLD_GLOBAL;
2607c62f5d3SDmitry Karpeev #endif
2617c62f5d3SDmitry Karpeev       }
2627c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2639371c9d4SSatish Balay       if (!(PETSC_RUNNING_ON_VALGRIND)) { dlerror(); /* clear any previous error; valgrind does not like this */ }
2647bb14e67SBarry Smith #endif
2657c62f5d3SDmitry Karpeev       /* Attempt to open the main executable as a dynamic library. */
2667d421530SBarry Smith #if defined(PETSC_HAVE_RTDL_DEFAULT)
2677d421530SBarry Smith       dlhandle = RTLD_DEFAULT;
2687d421530SBarry Smith #else
26902c9f0b5SLisandro Dalcin       dlhandle = dlopen(NULL, dlflags1 | dlflags2);
2707c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2719371c9d4SSatish Balay       {
2729371c9d4SSatish Balay         const char *e = (const char *)dlerror();
27328b400f6SJacob 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);
2747c62f5d3SDmitry Karpeev       }
2757c62f5d3SDmitry Karpeev #endif
2767d421530SBarry Smith #endif
277be1c6ad7SLisandro Dalcin     }
278be1c6ad7SLisandro Dalcin #endif
279aa2d57e9SJed Brown #endif /* PETSC_HAVE_DLOPEN && PETSC_HAVE_DYNAMIC_LIBRARIES */
2804956914eSSatish Balay   }
281be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
282be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
283be1c6ad7SLisandro Dalcin #endif
2846ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t)dlsym(dlhandle, symbol);
2855673baf8SLisandro Dalcin   /*
2865673baf8SLisandro Dalcin      --- unimplemented ---
2875673baf8SLisandro Dalcin   */
288ebd79076SLisandro Dalcin #else
289e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
290ebd79076SLisandro Dalcin #endif
291ebd79076SLisandro Dalcin 
2926ea75d68SLisandro Dalcin   *value = *((void **)&dlsymbol);
293ebd79076SLisandro Dalcin 
2942d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
2959566063dSJacob Faibussowitsch   if (*value) PetscCall(PetscFPTAdd(*value, symbol));
2962d53ad75SBarry Smith #endif
2972d53ad75SBarry Smith   return (0);
298ebd79076SLisandro Dalcin }
299184ce1a2SMatthew G. Knepley 
300184ce1a2SMatthew G. Knepley /*@C
301184ce1a2SMatthew G. Knepley   PetscDLAddr - find the name of a symbol in a dynamic library
302184ce1a2SMatthew G. Knepley 
303184ce1a2SMatthew G. Knepley   Not Collective
304184ce1a2SMatthew G. Knepley 
305184ce1a2SMatthew G. Knepley   Input Parameters:
306*811af0c4SBarry Smith + handle - obtained with `PetscDLOpen()` or NULL
307184ce1a2SMatthew G. Knepley - func   - pointer to the function, NULL if not found
308184ce1a2SMatthew G. Knepley 
309184ce1a2SMatthew G. Knepley   Output Parameter:
31004c51a94SMatthew G. Knepley . name   - name of symbol, or NULL if name lookup is not supported.
311184ce1a2SMatthew G. Knepley 
312184ce1a2SMatthew G. Knepley   Level: developer
313184ce1a2SMatthew G. Knepley 
314184ce1a2SMatthew G. Knepley   Notes:
31504c51a94SMatthew G. Knepley   The caller must free the returned name.
316258ec3d2SMatthew G. Knepley 
317184ce1a2SMatthew G. Knepley   In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
318184ce1a2SMatthew G. Knepley   systems this requires platform-specific linker flags.
31910699b91SBarry Smith 
320db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()`
321184ce1a2SMatthew G. Knepley @*/
3229371c9d4SSatish Balay PetscErrorCode PetscDLAddr(void (*func)(void), char **name) {
323184ce1a2SMatthew G. Knepley   PetscFunctionBegin;
324dadcf809SJacob Faibussowitsch   PetscValidPointer(name, 2);
325184ce1a2SMatthew G. Knepley   *name = NULL;
3266f5d4113SSatish Balay #if defined(PETSC_HAVE_DLADDR) && defined(__USE_GNU)
327184ce1a2SMatthew G. Knepley   dlerror(); /* clear any previous error */
328184ce1a2SMatthew G. Knepley   {
329184ce1a2SMatthew G. Knepley     Dl_info info;
330184ce1a2SMatthew G. Knepley 
3315f80ce2aSJacob Faibussowitsch     PetscCheck(dladdr(*(void **)&func, &info), PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
332258ec3d2SMatthew G. Knepley #ifdef PETSC_HAVE_CXX
3339566063dSJacob Faibussowitsch     PetscCall(PetscDemangleSymbol(info.dli_sname, name));
334258ec3d2SMatthew G. Knepley #else
3359566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(info.dli_sname, name));
336258ec3d2SMatthew G. Knepley #endif
337184ce1a2SMatthew G. Knepley   }
338184ce1a2SMatthew G. Knepley #endif
339184ce1a2SMatthew G. Knepley   PetscFunctionReturn(0);
340184ce1a2SMatthew G. Knepley }
341