xref: /petsc/src/sys/dll/dlimpl.c (revision 10699b917c2ca523f62b603029bfcc018e13d799)
17d0a6c19SBarry Smith 
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
6184ce1a2SMatthew G. Knepley #include <petscconf.h>
7184ce1a2SMatthew G. Knepley #if defined(PETSC__GNU_SOURCE)
8184ce1a2SMatthew G. Knepley   #if !defined(_GNU_SOURCE)
9184ce1a2SMatthew G. Knepley     #define _GNU_SOURCE 1
10184ce1a2SMatthew G. Knepley   #endif
11184ce1a2SMatthew G. Knepley #endif
12184ce1a2SMatthew 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>
24184ce1a2SMatthew G. Knepley #endif
25184ce1a2SMatthew 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:
50*10699b91SBarry Smith .    handle - opague pointer to be used with PetscDLSym()
51b235ab32SBarry Smith 
52b235ab32SBarry Smith    Level: developer
53b235ab32SBarry Smith 
54*10699b91SBarry Smith .seealso: PetscDLClose(), PetscDLSym(), PetscDLAddr()
55ebd79076SLisandro Dalcin @*/
56e4d177b5SBarry Smith PetscErrorCode  PetscDLOpen(const char name[],PetscDLMode mode,PetscDLHandle *handle)
57ebd79076SLisandro Dalcin {
588e049581SJed Brown   PETSC_UNUSED int dlflags1,dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
59ebd79076SLisandro Dalcin   dlhandle_t       dlhandle;
60ebd79076SLisandro Dalcin 
61ebd79076SLisandro Dalcin   PetscFunctionBegin;
62ebd79076SLisandro Dalcin   PetscValidCharPointer(name,1);
63ebd79076SLisandro Dalcin   PetscValidPointer(handle,3);
64ebd79076SLisandro Dalcin 
65be1c6ad7SLisandro Dalcin   dlflags1 = 0;
66be1c6ad7SLisandro Dalcin   dlflags2 = 0;
675673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
68be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle) 0;
69ebd79076SLisandro Dalcin 
705673baf8SLisandro Dalcin   /*
715673baf8SLisandro Dalcin      --- LoadLibrary ---
725673baf8SLisandro Dalcin   */
73be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
74be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
75ebd79076SLisandro Dalcin   if (!dlhandle) {
76ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
77ebd79076SLisandro Dalcin     PetscErrorCode ierr;
78ebd79076SLisandro Dalcin     DWORD          erc;
79b3bb0f5eSLisandro Dalcin     char           *buff = NULL;
80ebd79076SLisandro Dalcin     erc = GetLastError();
81ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
820298fd71SBarry Smith                   NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
83fbfcfee5SBarry Smith     ierr = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_ERR_FILE_OPEN,PETSC_ERROR_REPEAT,
84be1c6ad7SLisandro Dalcin                       "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
85ebd79076SLisandro Dalcin     LocalFree(buff);
86ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
87ebd79076SLisandro Dalcin #else
88e32f2f54SBarry 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");
89ebd79076SLisandro Dalcin #endif
90ebd79076SLisandro Dalcin   }
915673baf8SLisandro Dalcin 
925673baf8SLisandro Dalcin   /*
935673baf8SLisandro Dalcin      --- dlopen ---
945673baf8SLisandro Dalcin   */
95a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
96ebd79076SLisandro Dalcin   /*
97ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
98ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
99ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
100ebd79076SLisandro Dalcin      with dlopen()
101ebd79076SLisandro Dalcin   */
102be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
103be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
104be1c6ad7SLisandro Dalcin #endif
105ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
106a297a907SKarl Rupp   if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
107ebd79076SLisandro Dalcin #endif
108ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
109be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
110ebd79076SLisandro Dalcin #endif
111b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
112a297a907SKarl Rupp   if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
113b3bb0f5eSLisandro Dalcin #endif
114be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
115be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
116be1c6ad7SLisandro Dalcin #endif
117be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name,dlflags1|dlflags2);
118ebd79076SLisandro Dalcin   if (!dlhandle) {
119ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
120ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
121ebd79076SLisandro Dalcin #else
122ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
123ebd79076SLisandro Dalcin #endif
124be015529SBarry 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);
125ebd79076SLisandro 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
147*10699b91SBarry Smith 
148*10699b91SBarry Smith .seealso: PetscDLOpen(), PetscDLSym(), PetscDLAddr()
149ebd79076SLisandro Dalcin @*/
1507087cfbeSBarry Smith PetscErrorCode  PetscDLClose(PetscDLHandle *handle)
151ebd79076SLisandro Dalcin {
152ebd79076SLisandro Dalcin 
153ebd79076SLisandro Dalcin   PetscFunctionBegin;
154ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
155ebd79076SLisandro Dalcin 
1565673baf8SLisandro Dalcin   /*
1575673baf8SLisandro Dalcin      --- FreeLibrary ---
1585673baf8SLisandro Dalcin   */
159ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
160be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1618e049581SJed Brown   if (FreeLibrary((dlhandle_t)*handle) == 0) {
1625673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
163b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
164a21658a3SLisandro Dalcin     DWORD erc   = GetLastError();
1650298fd71SBarry 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);
1665673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1675673baf8SLisandro Dalcin     LocalFree(buff);
1685673baf8SLisandro Dalcin #else
1695673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1705673baf8SLisandro Dalcin #endif
1715673baf8SLisandro Dalcin   }
172be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
173ebd79076SLisandro Dalcin 
1745673baf8SLisandro Dalcin   /*
1755673baf8SLisandro Dalcin      --- dclose ---
1765673baf8SLisandro Dalcin   */
177ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
178a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
179be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
180be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
181be1c6ad7SLisandro Dalcin #endif
1828e049581SJed Brown   if (dlclose((dlhandle_t)*handle) < 0) {
183ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
184ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
185ebd79076SLisandro Dalcin #else
186ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
187ebd79076SLisandro Dalcin #endif
1885673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
189ebd79076SLisandro Dalcin   }
190a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1915673baf8SLisandro Dalcin 
1925673baf8SLisandro Dalcin   /*
1935673baf8SLisandro Dalcin      --- unimplemented ---
1945673baf8SLisandro Dalcin   */
195ebd79076SLisandro Dalcin #else
196e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
197ebd79076SLisandro Dalcin #endif
198ebd79076SLisandro Dalcin 
1990298fd71SBarry Smith   *handle = NULL;
200ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
201ebd79076SLisandro Dalcin }
202ebd79076SLisandro Dalcin 
203ebd79076SLisandro Dalcin /*@C
204b235ab32SBarry Smith    PetscDLSym - finds a symbol in a dynamic library
205b235ab32SBarry Smith 
206b235ab32SBarry Smith    Not Collective
207b235ab32SBarry Smith 
208b235ab32SBarry Smith    Input Parameters:
2090298fd71SBarry Smith +   handle - obtained with PetscDLOpen() or NULL
210b235ab32SBarry Smith -   symbol - name of symbol
211b235ab32SBarry Smith 
212b235ab32SBarry Smith    Output Parameter:
2130298fd71SBarry Smith .   value - pointer to the function, NULL if not found
214b235ab32SBarry Smith 
215b235ab32SBarry Smith    Level: developer
216b235ab32SBarry Smith 
2177c62f5d3SDmitry Karpeev   Notes:
2180298fd71SBarry Smith    If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
2197c62f5d3SDmitry Karpeev    In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
2207c62f5d3SDmitry Karpeev    systems this requires platform-specific linker flags.
2217c62f5d3SDmitry Karpeev 
222*10699b91SBarry Smith .seealso: PetscDLClose(), PetscDLOpen(), PetscDLAddr()
223ebd79076SLisandro Dalcin @*/
2247087cfbeSBarry Smith PetscErrorCode  PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
225ebd79076SLisandro Dalcin {
2268e049581SJed Brown   PETSC_UNUSED dlhandle_t dlhandle;
2276ea75d68SLisandro Dalcin   dlsymbol_t              dlsymbol;
228ebd79076SLisandro Dalcin 
229ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
230ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
231ebd79076SLisandro Dalcin 
232be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
2336ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) 0;
234a21658a3SLisandro Dalcin   *value   = (void*) 0;
235ebd79076SLisandro Dalcin 
2365673baf8SLisandro Dalcin   /*
2375673baf8SLisandro Dalcin      --- GetProcAddress ---
2385673baf8SLisandro Dalcin   */
239a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
240a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
241e4d177b5SBarry Smith   if (handle) dlhandle = (dlhandle_t) handle;
242e4d177b5SBarry Smith   else dlhandle = (dlhandle_t) GetCurrentProcess();
2436ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
244a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
245a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
246a21658a3SLisandro Dalcin #endif
247a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2485673baf8SLisandro Dalcin 
2495673baf8SLisandro Dalcin   /*
2505673baf8SLisandro Dalcin      --- dlsym ---
2515673baf8SLisandro Dalcin   */
252ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
253a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
254a297a907SKarl Rupp   if (handle) dlhandle = (dlhandle_t) handle;
255a297a907SKarl Rupp   else {
2567c62f5d3SDmitry Karpeev 
257bfef2c86SBarry Smith #if defined(PETSC_HAVE_DLOPEN) && defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
2587c62f5d3SDmitry Karpeev     /* Attempt to retrieve the main executable's dlhandle. */
2597c62f5d3SDmitry Karpeev     { int dlflags1 = 0, dlflags2 = 0;
2607c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY)
2617c62f5d3SDmitry Karpeev       dlflags1 = RTLD_LAZY;
2627c62f5d3SDmitry Karpeev #endif
2637c62f5d3SDmitry Karpeev       if (!dlflags1) {
2647c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW)
2657c62f5d3SDmitry Karpeev         dlflags1 = RTLD_NOW;
2667c62f5d3SDmitry Karpeev #endif
2677c62f5d3SDmitry Karpeev       }
2687c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL)
2697c62f5d3SDmitry Karpeev       dlflags2 = RTLD_LOCAL;
2707c62f5d3SDmitry Karpeev #endif
2717c62f5d3SDmitry Karpeev       if (!dlflags2) {
2727c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL)
2737c62f5d3SDmitry Karpeev         dlflags2 = RTLD_GLOBAL;
2747c62f5d3SDmitry Karpeev #endif
2757c62f5d3SDmitry Karpeev       }
2767c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
277cae2f346SBarry Smith       if (!(PETSC_RUNNING_ON_VALGRIND)) {
2787bb14e67SBarry Smith         dlerror(); /* clear any previous error; valgrind does not like this */
2797bb14e67SBarry Smith       }
2807bb14e67SBarry Smith #endif
2817c62f5d3SDmitry Karpeev       /* Attempt to open the main executable as a dynamic library. */
2827d421530SBarry Smith #if defined(PETSC_HAVE_RTDL_DEFAULT)
2837d421530SBarry Smith       dlhandle = RTLD_DEFAULT;
2847d421530SBarry Smith #else
28502c9f0b5SLisandro Dalcin       dlhandle = dlopen(NULL, dlflags1|dlflags2);
2867c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR)
2874956914eSSatish Balay       { const char *e = (const char*) dlerror();
2887d421530SBarry 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);
2897c62f5d3SDmitry Karpeev       }
2907c62f5d3SDmitry Karpeev #endif
2917d421530SBarry Smith #endif
292be1c6ad7SLisandro Dalcin     }
293be1c6ad7SLisandro Dalcin #endif
294aa2d57e9SJed Brown #endif /* PETSC_HAVE_DLOPEN && PETSC_HAVE_DYNAMIC_LIBRARIES */
2954956914eSSatish Balay   }
296be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
297be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
298be1c6ad7SLisandro Dalcin #endif
2996ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
3005673baf8SLisandro Dalcin   /*
3015673baf8SLisandro Dalcin      --- unimplemented ---
3025673baf8SLisandro Dalcin   */
303ebd79076SLisandro Dalcin #else
304e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
305ebd79076SLisandro Dalcin #endif
306ebd79076SLisandro Dalcin 
3076ea75d68SLisandro Dalcin   *value = *((void**)&dlsymbol);
308ebd79076SLisandro Dalcin 
3092d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3102d53ad75SBarry Smith   if (*value) {
3112d53ad75SBarry Smith     PetscErrorCode ierr;
3122d53ad75SBarry Smith     ierr = PetscFPTAdd(*value,symbol);CHKERRQ(ierr);
3132d53ad75SBarry Smith   }
3142d53ad75SBarry Smith #endif
3152d53ad75SBarry Smith   return(0);
316ebd79076SLisandro Dalcin }
317184ce1a2SMatthew G. Knepley 
318184ce1a2SMatthew G. Knepley 
319184ce1a2SMatthew G. Knepley /*@C
320184ce1a2SMatthew G. Knepley   PetscDLAddr - find the name of a symbol in a dynamic library
321184ce1a2SMatthew G. Knepley 
322184ce1a2SMatthew G. Knepley   Not Collective
323184ce1a2SMatthew G. Knepley 
324184ce1a2SMatthew G. Knepley   Input Parameters:
325184ce1a2SMatthew G. Knepley + handle - obtained with PetscDLOpen() or NULL
326184ce1a2SMatthew G. Knepley - func   - pointer to the function, NULL if not found
327184ce1a2SMatthew G. Knepley 
328184ce1a2SMatthew G. Knepley   Output Parameter:
329184ce1a2SMatthew G. Knepley . name   - name of symbol, or NULL if name lookup is not supported
330184ce1a2SMatthew G. Knepley 
331184ce1a2SMatthew G. Knepley   Level: developer
332184ce1a2SMatthew G. Knepley 
333184ce1a2SMatthew G. Knepley   Notes:
334184ce1a2SMatthew G. Knepley   In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
335184ce1a2SMatthew G. Knepley   systems this requires platform-specific linker flags.
336*10699b91SBarry Smith 
337*10699b91SBarry Smith .seealso: PetscDLClose(), PetscDLSym(), PetscDLOpen()
338184ce1a2SMatthew G. Knepley @*/
339184ce1a2SMatthew G. Knepley PetscErrorCode PetscDLAddr(void (*func)(void), const char **name)
340184ce1a2SMatthew G. Knepley {
341184ce1a2SMatthew G. Knepley   PetscFunctionBegin;
342184ce1a2SMatthew G. Knepley   PetscValidCharPointer(name,3);
343184ce1a2SMatthew G. Knepley   *name = NULL;
344184ce1a2SMatthew G. Knepley #if defined(PETSC_HAVE_DLADDR)
345184ce1a2SMatthew G. Knepley   dlerror(); /* clear any previous error */
346184ce1a2SMatthew G. Knepley   {
347184ce1a2SMatthew G. Knepley     Dl_info        info;
348184ce1a2SMatthew G. Knepley     PetscErrorCode ierr;
349184ce1a2SMatthew G. Knepley 
350184ce1a2SMatthew G. Knepley     ierr = dladdr(*(void **) &func, &info);if (!ierr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
351184ce1a2SMatthew G. Knepley     *name = info.dli_sname;
352184ce1a2SMatthew G. Knepley   }
353184ce1a2SMatthew G. Knepley #endif
354184ce1a2SMatthew G. Knepley   PetscFunctionReturn(0);
355184ce1a2SMatthew G. Knepley }
356