xref: /petsc/src/sys/dll/dlimpl.c (revision 98921bda46e76d7aaed9e0138c5ff9d0ce93f355)
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
33b235ab32SBarry Smith    PetscDLOpen - opens 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:
423222ab0cSSatish Balay .    handle - opaque pointer to be used with PetscDLSym()
43b235ab32SBarry Smith 
44b235ab32SBarry Smith    Level: developer
45b235ab32SBarry Smith 
4610699b91SBarry Smith .seealso: PetscDLClose(), PetscDLSym(), PetscDLAddr()
47ebd79076SLisandro Dalcin @*/
48e4d177b5SBarry Smith PetscErrorCode  PetscDLOpen(const char name[],PetscDLMode mode,PetscDLHandle *handle)
49ebd79076SLisandro Dalcin {
508e049581SJed Brown   PETSC_UNUSED int dlflags1,dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
51ebd79076SLisandro Dalcin   dlhandle_t       dlhandle;
52ebd79076SLisandro Dalcin 
53ebd79076SLisandro Dalcin   PetscFunctionBegin;
54ebd79076SLisandro Dalcin   PetscValidCharPointer(name,1);
55ebd79076SLisandro Dalcin   PetscValidPointer(handle,3);
56ebd79076SLisandro Dalcin 
57be1c6ad7SLisandro Dalcin   dlflags1 = 0;
58be1c6ad7SLisandro Dalcin   dlflags2 = 0;
595673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
60be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle) 0;
61ebd79076SLisandro Dalcin 
625673baf8SLisandro Dalcin   /*
635673baf8SLisandro Dalcin      --- LoadLibrary ---
645673baf8SLisandro Dalcin   */
65be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
66be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
67ebd79076SLisandro Dalcin   if (!dlhandle) {
68ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
69ebd79076SLisandro Dalcin     PetscErrorCode ierr;
70ebd79076SLisandro Dalcin     DWORD          erc;
71b3bb0f5eSLisandro Dalcin     char           *buff = NULL;
72ebd79076SLisandro Dalcin     erc = GetLastError();
73ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
740298fd71SBarry Smith                   NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
75fbfcfee5SBarry Smith     ierr = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_ERR_FILE_OPEN,PETSC_ERROR_REPEAT,
76be1c6ad7SLisandro Dalcin                       "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
77ebd79076SLisandro Dalcin     LocalFree(buff);
78ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
79ebd79076SLisandro Dalcin #else
80*98921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s",name,"unavailable");
81ebd79076SLisandro Dalcin #endif
82ebd79076SLisandro Dalcin   }
835673baf8SLisandro Dalcin 
845673baf8SLisandro Dalcin   /*
855673baf8SLisandro Dalcin      --- dlopen ---
865673baf8SLisandro Dalcin   */
87a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
88ebd79076SLisandro Dalcin   /*
89ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
90ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
91ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
92ebd79076SLisandro Dalcin      with dlopen()
93ebd79076SLisandro Dalcin   */
94be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
95be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
96be1c6ad7SLisandro Dalcin #endif
97ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
98a297a907SKarl Rupp   if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
99ebd79076SLisandro Dalcin #endif
100ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
101be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
102ebd79076SLisandro Dalcin #endif
103b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
104a297a907SKarl Rupp   if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
105b3bb0f5eSLisandro Dalcin #endif
106be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
107be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
108be1c6ad7SLisandro Dalcin #endif
109be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name,dlflags1|dlflags2);
110ebd79076SLisandro Dalcin   if (!dlhandle) {
111ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
112ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
113ebd79076SLisandro Dalcin #else
114ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
115ebd79076SLisandro Dalcin #endif
116*98921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s",name,errmsg);
117ebd79076SLisandro Dalcin   }
1185673baf8SLisandro Dalcin   /*
1195673baf8SLisandro Dalcin      --- unimplemented ---
1205673baf8SLisandro Dalcin   */
121ebd79076SLisandro Dalcin #else
122e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
123ebd79076SLisandro Dalcin #endif
124ebd79076SLisandro Dalcin 
125ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
126ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
127ebd79076SLisandro Dalcin }
128ebd79076SLisandro Dalcin 
129ebd79076SLisandro Dalcin /*@C
130b235ab32SBarry Smith    PetscDLClose -  closes a dynamic library
131b235ab32SBarry Smith 
132b235ab32SBarry Smith    Not Collective
133b235ab32SBarry Smith 
134b235ab32SBarry Smith   Input Parameter:
135b235ab32SBarry Smith .   handle - the handle for the library obtained with PetscDLOpen()
136b235ab32SBarry Smith 
137b235ab32SBarry Smith   Level: developer
13810699b91SBarry Smith 
13910699b91SBarry Smith .seealso: PetscDLOpen(), PetscDLSym(), PetscDLAddr()
140ebd79076SLisandro Dalcin @*/
1417087cfbeSBarry Smith PetscErrorCode  PetscDLClose(PetscDLHandle *handle)
142ebd79076SLisandro Dalcin {
143ebd79076SLisandro Dalcin 
144ebd79076SLisandro Dalcin   PetscFunctionBegin;
145ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
146ebd79076SLisandro Dalcin 
1475673baf8SLisandro Dalcin   /*
1485673baf8SLisandro Dalcin      --- FreeLibrary ---
1495673baf8SLisandro Dalcin   */
150ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
151be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1528e049581SJed Brown   if (FreeLibrary((dlhandle_t)*handle) == 0) {
1535673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
154b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
155a21658a3SLisandro Dalcin     DWORD erc   = GetLastError();
1560298fd71SBarry 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);
1575673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1585673baf8SLisandro Dalcin     LocalFree(buff);
1595673baf8SLisandro Dalcin #else
1605673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1615673baf8SLisandro Dalcin #endif
1625673baf8SLisandro Dalcin   }
163be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
164ebd79076SLisandro Dalcin 
1655673baf8SLisandro Dalcin   /*
1665673baf8SLisandro Dalcin      --- dclose ---
1675673baf8SLisandro Dalcin   */
168ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
169a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
170be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
171be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
172be1c6ad7SLisandro Dalcin #endif
1738e049581SJed Brown   if (dlclose((dlhandle_t)*handle) < 0) {
174ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
175ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
176ebd79076SLisandro Dalcin #else
177ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
178ebd79076SLisandro Dalcin #endif
1795673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
180ebd79076SLisandro Dalcin   }
181a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1825673baf8SLisandro Dalcin 
1835673baf8SLisandro Dalcin   /*
1845673baf8SLisandro Dalcin      --- unimplemented ---
1855673baf8SLisandro Dalcin   */
186ebd79076SLisandro Dalcin #else
187e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
188ebd79076SLisandro Dalcin #endif
189ebd79076SLisandro Dalcin 
1900298fd71SBarry Smith   *handle = NULL;
191ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
192ebd79076SLisandro Dalcin }
193ebd79076SLisandro Dalcin 
194ebd79076SLisandro Dalcin /*@C
195b235ab32SBarry Smith    PetscDLSym - finds a symbol in a dynamic library
196b235ab32SBarry Smith 
197b235ab32SBarry Smith    Not Collective
198b235ab32SBarry Smith 
199b235ab32SBarry Smith    Input Parameters:
2000298fd71SBarry Smith +   handle - obtained with PetscDLOpen() or NULL
201b235ab32SBarry Smith -   symbol - name of symbol
202b235ab32SBarry Smith 
203b235ab32SBarry Smith    Output Parameter:
2040298fd71SBarry Smith .   value - pointer to the function, NULL if not found
205b235ab32SBarry Smith 
206b235ab32SBarry Smith    Level: developer
207b235ab32SBarry Smith 
2087c62f5d3SDmitry Karpeev   Notes:
2090298fd71SBarry Smith    If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
2107c62f5d3SDmitry Karpeev    In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
2117c62f5d3SDmitry Karpeev    systems this requires platform-specific linker flags.
2127c62f5d3SDmitry Karpeev 
21310699b91SBarry Smith .seealso: PetscDLClose(), PetscDLOpen(), PetscDLAddr()
214ebd79076SLisandro Dalcin @*/
2157087cfbeSBarry Smith PetscErrorCode  PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
216ebd79076SLisandro Dalcin {
2178e049581SJed Brown   PETSC_UNUSED dlhandle_t dlhandle;
2186ea75d68SLisandro Dalcin   dlsymbol_t              dlsymbol;
219ebd79076SLisandro Dalcin 
220ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
221ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
222ebd79076SLisandro Dalcin 
223be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
2246ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) 0;
225a21658a3SLisandro Dalcin   *value   = (void*) 0;
226ebd79076SLisandro Dalcin 
2275673baf8SLisandro Dalcin   /*
2285673baf8SLisandro Dalcin      --- GetProcAddress ---
2295673baf8SLisandro Dalcin   */
230a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
231a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
232e4d177b5SBarry Smith   if (handle) dlhandle = (dlhandle_t) handle;
233e4d177b5SBarry Smith   else dlhandle = (dlhandle_t) GetCurrentProcess();
2346ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
235a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
236a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
237a21658a3SLisandro Dalcin #endif
238a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2395673baf8SLisandro Dalcin 
2405673baf8SLisandro Dalcin   /*
2415673baf8SLisandro Dalcin      --- dlsym ---
2425673baf8SLisandro Dalcin   */
243ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
244a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
245a297a907SKarl Rupp   if (handle) dlhandle = (dlhandle_t) handle;
246a297a907SKarl Rupp   else {
2477c62f5d3SDmitry Karpeev 
2485617e356SJunchao Zhang #if defined(PETSC_HAVE_DLOPEN)
2497c62f5d3SDmitry Karpeev     /* Attempt to retrieve the main executable's dlhandle. */
2507c62f5d3SDmitry Karpeev     { int dlflags1 = 0, dlflags2 = 0;
2517c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY)
2527c62f5d3SDmitry Karpeev       dlflags1 = RTLD_LAZY;
2537c62f5d3SDmitry Karpeev #endif
2547c62f5d3SDmitry Karpeev       if (!dlflags1) {
2557c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW)
2567c62f5d3SDmitry Karpeev         dlflags1 = RTLD_NOW;
2577c62f5d3SDmitry Karpeev #endif
2587c62f5d3SDmitry Karpeev       }
2597c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL)
2607c62f5d3SDmitry Karpeev       dlflags2 = RTLD_LOCAL;
2617c62f5d3SDmitry Karpeev #endif
2627c62f5d3SDmitry Karpeev       if (!dlflags2) {
2637c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL)
2647c62f5d3SDmitry Karpeev         dlflags2 = RTLD_GLOBAL;
2657c62f5d3SDmitry Karpeev #endif
2667c62f5d3SDmitry Karpeev       }
2677c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
268cae2f346SBarry Smith       if (!(PETSC_RUNNING_ON_VALGRIND)) {
2697bb14e67SBarry Smith         dlerror(); /* clear any previous error; valgrind does not like this */
2707bb14e67SBarry Smith       }
2717bb14e67SBarry Smith #endif
2727c62f5d3SDmitry Karpeev       /* Attempt to open the main executable as a dynamic library. */
2737d421530SBarry Smith #if defined(PETSC_HAVE_RTDL_DEFAULT)
2747d421530SBarry Smith       dlhandle = RTLD_DEFAULT;
2757d421530SBarry Smith #else
27602c9f0b5SLisandro Dalcin       dlhandle = dlopen(NULL, dlflags1|dlflags2);
2777c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2784956914eSSatish Balay       { const char *e = (const char*) dlerror();
279*98921bdaSJacob Faibussowitsch         if (e) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library:\n  Error message from dlopen(): '%s'", e);
2807c62f5d3SDmitry Karpeev       }
2817c62f5d3SDmitry Karpeev #endif
2827d421530SBarry Smith #endif
283be1c6ad7SLisandro Dalcin     }
284be1c6ad7SLisandro Dalcin #endif
285aa2d57e9SJed Brown #endif /* PETSC_HAVE_DLOPEN && PETSC_HAVE_DYNAMIC_LIBRARIES */
2864956914eSSatish Balay   }
287be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
288be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
289be1c6ad7SLisandro Dalcin #endif
2906ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
2915673baf8SLisandro Dalcin   /*
2925673baf8SLisandro Dalcin      --- unimplemented ---
2935673baf8SLisandro Dalcin   */
294ebd79076SLisandro Dalcin #else
295e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
296ebd79076SLisandro Dalcin #endif
297ebd79076SLisandro Dalcin 
2986ea75d68SLisandro Dalcin   *value = *((void**)&dlsymbol);
299ebd79076SLisandro Dalcin 
3002d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3012d53ad75SBarry Smith   if (*value) {
3022d53ad75SBarry Smith     PetscErrorCode ierr;
3032d53ad75SBarry Smith     ierr = PetscFPTAdd(*value,symbol);CHKERRQ(ierr);
3042d53ad75SBarry Smith   }
3052d53ad75SBarry Smith #endif
3062d53ad75SBarry Smith   return(0);
307ebd79076SLisandro Dalcin }
308184ce1a2SMatthew G. Knepley 
309184ce1a2SMatthew G. Knepley /*@C
310184ce1a2SMatthew G. Knepley   PetscDLAddr - find the name of a symbol in a dynamic library
311184ce1a2SMatthew G. Knepley 
312184ce1a2SMatthew G. Knepley   Not Collective
313184ce1a2SMatthew G. Knepley 
314184ce1a2SMatthew G. Knepley   Input Parameters:
315184ce1a2SMatthew G. Knepley + handle - obtained with PetscDLOpen() or NULL
316184ce1a2SMatthew G. Knepley - func   - pointer to the function, NULL if not found
317184ce1a2SMatthew G. Knepley 
318184ce1a2SMatthew G. Knepley   Output Parameter:
31904c51a94SMatthew G. Knepley . name   - name of symbol, or NULL if name lookup is not supported.
320184ce1a2SMatthew G. Knepley 
321184ce1a2SMatthew G. Knepley   Level: developer
322184ce1a2SMatthew G. Knepley 
323184ce1a2SMatthew G. Knepley   Notes:
32404c51a94SMatthew G. Knepley   The caller must free the returned name.
325258ec3d2SMatthew G. Knepley 
326184ce1a2SMatthew G. Knepley   In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
327184ce1a2SMatthew G. Knepley   systems this requires platform-specific linker flags.
32810699b91SBarry Smith 
32910699b91SBarry Smith .seealso: PetscDLClose(), PetscDLSym(), PetscDLOpen()
330184ce1a2SMatthew G. Knepley @*/
331258ec3d2SMatthew G. Knepley PetscErrorCode PetscDLAddr(void (*func)(void), char **name)
332184ce1a2SMatthew G. Knepley {
333184ce1a2SMatthew G. Knepley   PetscFunctionBegin;
334064a246eSJacob Faibussowitsch   PetscValidCharPointer(name,2);
335184ce1a2SMatthew G. Knepley   *name = NULL;
336184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLADDR)
337184ce1a2SMatthew G. Knepley   dlerror(); /* clear any previous error */
338184ce1a2SMatthew G. Knepley   {
339184ce1a2SMatthew G. Knepley     Dl_info        info;
340184ce1a2SMatthew G. Knepley     PetscErrorCode ierr;
341184ce1a2SMatthew G. Knepley 
342*98921bdaSJacob Faibussowitsch     ierr = dladdr(*(void **) &func, &info);if (!ierr) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
343258ec3d2SMatthew G. Knepley #ifdef PETSC_HAVE_CXX
344258ec3d2SMatthew G. Knepley     ierr = PetscDemangleSymbol(info.dli_sname, name);CHKERRQ(ierr);
345258ec3d2SMatthew G. Knepley #else
346258ec3d2SMatthew G. Knepley     ierr = PetscStrallocpy(info.dli_sname, name);CHKERRQ(ierr);
347258ec3d2SMatthew G. Knepley #endif
348184ce1a2SMatthew G. Knepley   }
349184ce1a2SMatthew G. Knepley #endif
350184ce1a2SMatthew G. Knepley   PetscFunctionReturn(0);
351184ce1a2SMatthew G. Knepley }
352