xref: /petsc/src/sys/dll/dlimpl.c (revision 184ce1a26a4ca5e28a51e07ddf3fb9be1d04a31d)
17d0a6c19SBarry Smith 
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
6*184ce1a2SMatthew G. Knepley #include <petscconf.h>
7*184ce1a2SMatthew G. Knepley #if defined(PETSC__GNU_SOURCE)
8*184ce1a2SMatthew G. Knepley   #if !defined(_GNU_SOURCE)
9*184ce1a2SMatthew G. Knepley     #define _GNU_SOURCE 1
10*184ce1a2SMatthew G. Knepley   #endif
11*184ce1a2SMatthew G. Knepley #endif
12*184ce1a2SMatthew G. Knepley 
13af0996ceSBarry Smith #include <petsc/private/petscimpl.h>
14022afb99SBarry Smith #include <petscvalgrind.h>
15ebd79076SLisandro Dalcin 
16ebd79076SLisandro Dalcin /* XXX Should be done better !!!*/
17be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
18ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
19ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
20ebd79076SLisandro Dalcin #endif
21ebd79076SLisandro Dalcin 
22ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
23ebd79076SLisandro Dalcin #include <windows.h>
24*184ce1a2SMatthew G. Knepley #endif
25*184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLFCN_H)
26ebd79076SLisandro Dalcin #include <dlfcn.h>
27ebd79076SLisandro Dalcin #endif
28ebd79076SLisandro Dalcin 
29ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
30ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t;
316ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t;
32ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
33ebd79076SLisandro Dalcin typedef void* dlhandle_t;
346ea75d68SLisandro Dalcin typedef void* dlsymbol_t;
35ebd79076SLisandro Dalcin #else
36ebd79076SLisandro Dalcin typedef void* dlhandle_t;
376ea75d68SLisandro Dalcin typedef void* dlsymbol_t;
38ebd79076SLisandro Dalcin #endif
39ebd79076SLisandro Dalcin 
40ebd79076SLisandro Dalcin /*@C
41b235ab32SBarry Smith    PetscDLOpen - opens dynamic library
42b235ab32SBarry Smith 
43b235ab32SBarry Smith    Not Collective
44b235ab32SBarry Smith 
45b235ab32SBarry Smith    Input Parameters:
46b235ab32SBarry Smith +    name - name of library
47e4d177b5SBarry Smith -    mode - options on how to open library
48b235ab32SBarry Smith 
49b235ab32SBarry Smith    Output Parameter:
50b235ab32SBarry Smith .    handle
51b235ab32SBarry Smith 
52b235ab32SBarry Smith    Level: developer
53b235ab32SBarry Smith 
54ebd79076SLisandro Dalcin @*/
55e4d177b5SBarry Smith PetscErrorCode  PetscDLOpen(const char name[],PetscDLMode mode,PetscDLHandle *handle)
56ebd79076SLisandro Dalcin {
578e049581SJed Brown   PETSC_UNUSED int dlflags1,dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
58ebd79076SLisandro Dalcin   dlhandle_t       dlhandle;
59ebd79076SLisandro Dalcin 
60ebd79076SLisandro Dalcin   PetscFunctionBegin;
61ebd79076SLisandro Dalcin   PetscValidCharPointer(name,1);
62ebd79076SLisandro Dalcin   PetscValidPointer(handle,3);
63ebd79076SLisandro Dalcin 
64be1c6ad7SLisandro Dalcin   dlflags1 = 0;
65be1c6ad7SLisandro Dalcin   dlflags2 = 0;
665673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
67be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle) 0;
68ebd79076SLisandro Dalcin 
695673baf8SLisandro Dalcin   /*
705673baf8SLisandro Dalcin      --- LoadLibrary ---
715673baf8SLisandro Dalcin   */
72be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
73be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
74ebd79076SLisandro Dalcin   if (!dlhandle) {
75ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
76ebd79076SLisandro Dalcin     PetscErrorCode ierr;
77ebd79076SLisandro Dalcin     DWORD          erc;
78b3bb0f5eSLisandro Dalcin     char           *buff = NULL;
79ebd79076SLisandro Dalcin     erc = GetLastError();
80ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
810298fd71SBarry Smith                   NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
82fbfcfee5SBarry Smith     ierr = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_ERR_FILE_OPEN,PETSC_ERROR_REPEAT,
83be1c6ad7SLisandro Dalcin                       "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
84ebd79076SLisandro Dalcin     LocalFree(buff);
85ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
86ebd79076SLisandro Dalcin #else
87e32f2f54SBarry Smith     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
88ebd79076SLisandro Dalcin #endif
89ebd79076SLisandro Dalcin   }
905673baf8SLisandro Dalcin 
915673baf8SLisandro Dalcin   /*
925673baf8SLisandro Dalcin      --- dlopen ---
935673baf8SLisandro Dalcin   */
94a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
95ebd79076SLisandro Dalcin   /*
96ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
97ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
98ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
99ebd79076SLisandro Dalcin      with dlopen()
100ebd79076SLisandro Dalcin   */
101be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
102be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
103be1c6ad7SLisandro Dalcin #endif
104ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
105a297a907SKarl Rupp   if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
106ebd79076SLisandro Dalcin #endif
107ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
108be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
109ebd79076SLisandro Dalcin #endif
110b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
111a297a907SKarl Rupp   if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
112b3bb0f5eSLisandro Dalcin #endif
113be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
114be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
115be1c6ad7SLisandro Dalcin #endif
116be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name,dlflags1|dlflags2);
117ebd79076SLisandro Dalcin   if (!dlhandle) {
118ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
119ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
120ebd79076SLisandro Dalcin #else
121ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
122ebd79076SLisandro Dalcin #endif
123be015529SBarry Smith     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n",name,errmsg);
124ebd79076SLisandro Dalcin   }
1255673baf8SLisandro Dalcin 
1265673baf8SLisandro Dalcin   /*
1275673baf8SLisandro Dalcin      --- unimplemented ---
1285673baf8SLisandro Dalcin   */
129ebd79076SLisandro Dalcin #else
130e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
131ebd79076SLisandro Dalcin #endif
132ebd79076SLisandro Dalcin 
133ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
134ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
135ebd79076SLisandro Dalcin }
136ebd79076SLisandro Dalcin 
137ebd79076SLisandro Dalcin 
138ebd79076SLisandro Dalcin /*@C
139b235ab32SBarry Smith    PetscDLClose -  closes a dynamic library
140b235ab32SBarry Smith 
141b235ab32SBarry Smith    Not Collective
142b235ab32SBarry Smith 
143b235ab32SBarry Smith   Input Parameter:
144b235ab32SBarry Smith .   handle - the handle for the library obtained with PetscDLOpen()
145b235ab32SBarry Smith 
146b235ab32SBarry Smith   Level: developer
147ebd79076SLisandro Dalcin @*/
1487087cfbeSBarry Smith PetscErrorCode  PetscDLClose(PetscDLHandle *handle)
149ebd79076SLisandro Dalcin {
150ebd79076SLisandro Dalcin 
151ebd79076SLisandro Dalcin   PetscFunctionBegin;
152ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
153ebd79076SLisandro Dalcin 
1545673baf8SLisandro Dalcin   /*
1555673baf8SLisandro Dalcin      --- FreeLibrary ---
1565673baf8SLisandro Dalcin   */
157ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
158be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1598e049581SJed Brown   if (FreeLibrary((dlhandle_t)*handle) == 0) {
1605673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
161b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
162a21658a3SLisandro Dalcin     DWORD erc   = GetLastError();
1630298fd71SBarry 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);
1645673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1655673baf8SLisandro Dalcin     LocalFree(buff);
1665673baf8SLisandro Dalcin #else
1675673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1685673baf8SLisandro Dalcin #endif
1695673baf8SLisandro Dalcin   }
170be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
171ebd79076SLisandro Dalcin 
1725673baf8SLisandro Dalcin   /*
1735673baf8SLisandro Dalcin      --- dclose ---
1745673baf8SLisandro Dalcin   */
175ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
176a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
177be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
178be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
179be1c6ad7SLisandro Dalcin #endif
1808e049581SJed Brown   if (dlclose((dlhandle_t)*handle) < 0) {
181ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
182ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
183ebd79076SLisandro Dalcin #else
184ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
185ebd79076SLisandro Dalcin #endif
1865673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
187ebd79076SLisandro Dalcin   }
188a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1895673baf8SLisandro Dalcin 
1905673baf8SLisandro Dalcin   /*
1915673baf8SLisandro Dalcin      --- unimplemented ---
1925673baf8SLisandro Dalcin   */
193ebd79076SLisandro Dalcin #else
194e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
195ebd79076SLisandro Dalcin #endif
196ebd79076SLisandro Dalcin 
1970298fd71SBarry Smith   *handle = NULL;
198ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
199ebd79076SLisandro Dalcin }
200ebd79076SLisandro Dalcin 
201ebd79076SLisandro Dalcin /*@C
202b235ab32SBarry Smith    PetscDLSym - finds a symbol in a dynamic library
203b235ab32SBarry Smith 
204b235ab32SBarry Smith    Not Collective
205b235ab32SBarry Smith 
206b235ab32SBarry Smith    Input Parameters:
2070298fd71SBarry Smith +   handle - obtained with PetscDLOpen() or NULL
208b235ab32SBarry Smith -   symbol - name of symbol
209b235ab32SBarry Smith 
210b235ab32SBarry Smith    Output Parameter:
2110298fd71SBarry Smith .   value - pointer to the function, NULL if not found
212b235ab32SBarry Smith 
213b235ab32SBarry Smith    Level: developer
214b235ab32SBarry Smith 
2157c62f5d3SDmitry Karpeev   Notes:
2160298fd71SBarry Smith    If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
2177c62f5d3SDmitry Karpeev    In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
2187c62f5d3SDmitry Karpeev    systems this requires platform-specific linker flags.
2197c62f5d3SDmitry Karpeev 
220ebd79076SLisandro Dalcin @*/
2217087cfbeSBarry Smith PetscErrorCode  PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
222ebd79076SLisandro Dalcin {
2238e049581SJed Brown   PETSC_UNUSED dlhandle_t dlhandle;
2246ea75d68SLisandro Dalcin   dlsymbol_t              dlsymbol;
225ebd79076SLisandro Dalcin 
226ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
227ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
228ebd79076SLisandro Dalcin 
229be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
2306ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) 0;
231a21658a3SLisandro Dalcin   *value   = (void*) 0;
232ebd79076SLisandro Dalcin 
2335673baf8SLisandro Dalcin   /*
2345673baf8SLisandro Dalcin      --- GetProcAddress ---
2355673baf8SLisandro Dalcin   */
236a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
237a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
238e4d177b5SBarry Smith   if (handle) dlhandle = (dlhandle_t) handle;
239e4d177b5SBarry Smith   else dlhandle = (dlhandle_t) GetCurrentProcess();
2406ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
241a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
242a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
243a21658a3SLisandro Dalcin #endif
244a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2455673baf8SLisandro Dalcin 
2465673baf8SLisandro Dalcin   /*
2475673baf8SLisandro Dalcin      --- dlsym ---
2485673baf8SLisandro Dalcin   */
249ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
250a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
251a297a907SKarl Rupp   if (handle) dlhandle = (dlhandle_t) handle;
252a297a907SKarl Rupp   else {
2537c62f5d3SDmitry Karpeev 
254bfef2c86SBarry Smith #if defined(PETSC_HAVE_DLOPEN) && defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
2557c62f5d3SDmitry Karpeev     /* Attempt to retrieve the main executable's dlhandle. */
2567c62f5d3SDmitry Karpeev     { int dlflags1 = 0, dlflags2 = 0;
2577c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY)
2587c62f5d3SDmitry Karpeev       dlflags1 = RTLD_LAZY;
2597c62f5d3SDmitry Karpeev #endif
2607c62f5d3SDmitry Karpeev       if (!dlflags1) {
2617c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW)
2627c62f5d3SDmitry Karpeev         dlflags1 = RTLD_NOW;
2637c62f5d3SDmitry Karpeev #endif
2647c62f5d3SDmitry Karpeev       }
2657c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL)
2667c62f5d3SDmitry Karpeev       dlflags2 = RTLD_LOCAL;
2677c62f5d3SDmitry Karpeev #endif
2687c62f5d3SDmitry Karpeev       if (!dlflags2) {
2697c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL)
2707c62f5d3SDmitry Karpeev         dlflags2 = RTLD_GLOBAL;
2717c62f5d3SDmitry Karpeev #endif
2727c62f5d3SDmitry Karpeev       }
2737c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
274cae2f346SBarry Smith       if (!(PETSC_RUNNING_ON_VALGRIND)) {
2757bb14e67SBarry Smith         dlerror(); /* clear any previous error; valgrind does not like this */
2767bb14e67SBarry Smith       }
2777bb14e67SBarry Smith #endif
2787c62f5d3SDmitry Karpeev       /* Attempt to open the main executable as a dynamic library. */
2797d421530SBarry Smith #if defined(PETSC_HAVE_RTDL_DEFAULT)
2807d421530SBarry Smith       dlhandle = RTLD_DEFAULT;
2817d421530SBarry Smith #else
28202c9f0b5SLisandro Dalcin       dlhandle = dlopen(NULL, dlflags1|dlflags2);
2837c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2844956914eSSatish Balay       { const char *e = (const char*) dlerror();
2857d421530SBarry Smith         if (e) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library:\n  Error message from dlopen(): '%s'\n", e);
2867c62f5d3SDmitry Karpeev       }
2877c62f5d3SDmitry Karpeev #endif
2887d421530SBarry Smith #endif
289be1c6ad7SLisandro Dalcin     }
290be1c6ad7SLisandro Dalcin #endif
291aa2d57e9SJed Brown #endif /* PETSC_HAVE_DLOPEN && PETSC_HAVE_DYNAMIC_LIBRARIES */
2924956914eSSatish Balay   }
293be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
294be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
295be1c6ad7SLisandro Dalcin #endif
2966ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
2975673baf8SLisandro Dalcin   /*
2985673baf8SLisandro Dalcin      --- unimplemented ---
2995673baf8SLisandro Dalcin   */
300ebd79076SLisandro Dalcin #else
301e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
302ebd79076SLisandro Dalcin #endif
303ebd79076SLisandro Dalcin 
3046ea75d68SLisandro Dalcin   *value = *((void**)&dlsymbol);
305ebd79076SLisandro Dalcin 
3062d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3072d53ad75SBarry Smith   if (*value) {
3082d53ad75SBarry Smith     PetscErrorCode ierr;
3092d53ad75SBarry Smith     ierr = PetscFPTAdd(*value,symbol);CHKERRQ(ierr);
3102d53ad75SBarry Smith   }
3112d53ad75SBarry Smith #endif
3122d53ad75SBarry Smith   return(0);
313ebd79076SLisandro Dalcin }
314*184ce1a2SMatthew G. Knepley 
315*184ce1a2SMatthew G. Knepley 
316*184ce1a2SMatthew G. Knepley /*@C
317*184ce1a2SMatthew G. Knepley   PetscDLAddr - find the name of a symbol in a dynamic library
318*184ce1a2SMatthew G. Knepley 
319*184ce1a2SMatthew G. Knepley   Not Collective
320*184ce1a2SMatthew G. Knepley 
321*184ce1a2SMatthew G. Knepley   Input Parameters:
322*184ce1a2SMatthew G. Knepley + handle - obtained with PetscDLOpen() or NULL
323*184ce1a2SMatthew G. Knepley - func   - pointer to the function, NULL if not found
324*184ce1a2SMatthew G. Knepley 
325*184ce1a2SMatthew G. Knepley   Output Parameter:
326*184ce1a2SMatthew G. Knepley . name   - name of symbol, or NULL if name lookup is not supported
327*184ce1a2SMatthew G. Knepley 
328*184ce1a2SMatthew G. Knepley   Level: developer
329*184ce1a2SMatthew G. Knepley 
330*184ce1a2SMatthew G. Knepley   Notes:
331*184ce1a2SMatthew G. Knepley   In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
332*184ce1a2SMatthew G. Knepley   systems this requires platform-specific linker flags.
333*184ce1a2SMatthew G. Knepley @*/
334*184ce1a2SMatthew G. Knepley PetscErrorCode PetscDLAddr(void (*func)(void), const char **name)
335*184ce1a2SMatthew G. Knepley {
336*184ce1a2SMatthew G. Knepley   PetscFunctionBegin;
337*184ce1a2SMatthew G. Knepley   PetscValidCharPointer(name,3);
338*184ce1a2SMatthew G. Knepley   *name = NULL;
339*184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLADDR)
340*184ce1a2SMatthew G. Knepley   dlerror(); /* clear any previous error */
341*184ce1a2SMatthew G. Knepley   {
342*184ce1a2SMatthew G. Knepley     Dl_info        info;
343*184ce1a2SMatthew G. Knepley     PetscErrorCode ierr;
344*184ce1a2SMatthew G. Knepley 
345*184ce1a2SMatthew G. Knepley     ierr = dladdr(*(void **) &func, &info);if (!ierr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
346*184ce1a2SMatthew G. Knepley     *name = info.dli_sname;
347*184ce1a2SMatthew G. Knepley   }
348*184ce1a2SMatthew G. Knepley #endif
349*184ce1a2SMatthew G. Knepley   PetscFunctionReturn(0);
350*184ce1a2SMatthew G. Knepley }
351