xref: /petsc/src/sys/dll/dlimpl.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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
33811af0c4SBarry 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:
42811af0c4SBarry 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 @*/
48d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLOpen(const char name[], PetscDLMode mode, PetscDLHandle *handle)
49d71ae5a4SJacob Faibussowitsch {
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) {
68d0609cedSBarry Smith     /* TODO: Seem to need fixing, why not just return with an error with SETERRQ() */
69ebd79076SLisandro Dalcin   #if defined(PETSC_HAVE_GETLASTERROR)
70ebd79076SLisandro Dalcin     DWORD erc;
71b3bb0f5eSLisandro Dalcin     char *buff = NULL;
72ebd79076SLisandro Dalcin     erc        = GetLastError();
739371c9d4SSatish 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);
749371c9d4SSatish 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));
75ebd79076SLisandro Dalcin     LocalFree(buff);
76*3ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
77ebd79076SLisandro Dalcin   #else
7898921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s", name, "unavailable");
79ebd79076SLisandro Dalcin   #endif
80ebd79076SLisandro Dalcin   }
815673baf8SLisandro Dalcin 
825673baf8SLisandro Dalcin   /*
835673baf8SLisandro Dalcin      --- dlopen ---
845673baf8SLisandro Dalcin   */
85a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
86ebd79076SLisandro Dalcin   /*
87ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
88ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
89ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
90ebd79076SLisandro Dalcin      with dlopen()
91ebd79076SLisandro Dalcin   */
92be1c6ad7SLisandro Dalcin   #if defined(PETSC_HAVE_RTLD_LAZY)
93be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
94be1c6ad7SLisandro Dalcin   #endif
95ebd79076SLisandro Dalcin   #if defined(PETSC_HAVE_RTLD_NOW)
96a297a907SKarl Rupp   if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
97ebd79076SLisandro Dalcin   #endif
98ebd79076SLisandro Dalcin   #if defined(PETSC_HAVE_RTLD_GLOBAL)
99be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
100ebd79076SLisandro Dalcin   #endif
101b3bb0f5eSLisandro Dalcin   #if defined(PETSC_HAVE_RTLD_LOCAL)
102a297a907SKarl Rupp   if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
103b3bb0f5eSLisandro Dalcin   #endif
104be1c6ad7SLisandro Dalcin   #if defined(PETSC_HAVE_DLERROR)
105be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
106be1c6ad7SLisandro Dalcin   #endif
107be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name, dlflags1 | dlflags2);
108ebd79076SLisandro Dalcin   if (!dlhandle) {
109ebd79076SLisandro Dalcin   #if defined(PETSC_HAVE_DLERROR)
110ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
111ebd79076SLisandro Dalcin   #else
112ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
113ebd79076SLisandro Dalcin   #endif
11498921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s", name, errmsg);
115ebd79076SLisandro Dalcin   }
1165673baf8SLisandro Dalcin   /*
1175673baf8SLisandro Dalcin      --- unimplemented ---
1185673baf8SLisandro Dalcin   */
119ebd79076SLisandro Dalcin #else
120e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
121ebd79076SLisandro Dalcin #endif
122ebd79076SLisandro Dalcin 
123ebd79076SLisandro Dalcin   *handle = (PetscDLHandle)dlhandle;
124*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
125ebd79076SLisandro Dalcin }
126ebd79076SLisandro Dalcin 
127ebd79076SLisandro Dalcin /*@C
128b235ab32SBarry Smith    PetscDLClose -  closes a dynamic library
129b235ab32SBarry Smith 
130b235ab32SBarry Smith    Not Collective
131b235ab32SBarry Smith 
132b235ab32SBarry Smith   Input Parameter:
133811af0c4SBarry Smith .   handle - the handle for the library obtained with `PetscDLOpen()`
134b235ab32SBarry Smith 
135b235ab32SBarry Smith   Level: developer
13610699b91SBarry Smith 
137db781477SPatrick Sanan .seealso: `PetscDLOpen()`, `PetscDLSym()`, `PetscDLAddr()`
138ebd79076SLisandro Dalcin @*/
139d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLClose(PetscDLHandle *handle)
140d71ae5a4SJacob Faibussowitsch {
141ebd79076SLisandro Dalcin   PetscFunctionBegin;
142ebd79076SLisandro Dalcin   PetscValidPointer(handle, 1);
143ebd79076SLisandro Dalcin 
1445673baf8SLisandro Dalcin   /*
1455673baf8SLisandro Dalcin      --- FreeLibrary ---
1465673baf8SLisandro Dalcin   */
147ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
148be1c6ad7SLisandro Dalcin   #if defined(PETSC_HAVE_FREELIBRARY)
1498e049581SJed Brown   if (FreeLibrary((dlhandle_t)*handle) == 0) {
1505673baf8SLisandro Dalcin     #if defined(PETSC_HAVE_GETLASTERROR)
151b3bb0f5eSLisandro Dalcin     char *buff = NULL;
152a21658a3SLisandro Dalcin     DWORD erc  = GetLastError();
1530298fd71SBarry 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);
154*3ba16761SJacob Faibussowitsch     PetscCall(PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n", buff));
1555673baf8SLisandro Dalcin     LocalFree(buff);
1565673baf8SLisandro Dalcin     #else
157*3ba16761SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n  Error message from FreeLibrary() %s", "unavailable");
1585673baf8SLisandro Dalcin     #endif
1595673baf8SLisandro Dalcin   }
160be1c6ad7SLisandro Dalcin   #endif /* !PETSC_HAVE_FREELIBRARY */
161ebd79076SLisandro Dalcin 
1625673baf8SLisandro Dalcin   /*
1635673baf8SLisandro Dalcin      --- dclose ---
1645673baf8SLisandro Dalcin   */
165ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
166a21658a3SLisandro Dalcin   #if defined(PETSC_HAVE_DLCLOSE)
167be1c6ad7SLisandro Dalcin     #if defined(PETSC_HAVE_DLERROR)
168be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
169be1c6ad7SLisandro Dalcin     #endif
1708e049581SJed Brown   if (dlclose((dlhandle_t)*handle) < 0) {
171ebd79076SLisandro Dalcin     #if defined(PETSC_HAVE_DLERROR)
172ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
173ebd79076SLisandro Dalcin     #else
174ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
175ebd79076SLisandro Dalcin     #endif
176*3ba16761SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Error closing dynamic library:\n  Error message from dlclose() %s", errmsg);
177ebd79076SLisandro Dalcin   }
178a21658a3SLisandro Dalcin   #endif /* !PETSC_HAVE_DLCLOSE */
1795673baf8SLisandro Dalcin 
1805673baf8SLisandro Dalcin   /*
1815673baf8SLisandro Dalcin      --- unimplemented ---
1825673baf8SLisandro Dalcin   */
183ebd79076SLisandro Dalcin #else
184e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
185ebd79076SLisandro Dalcin #endif
186ebd79076SLisandro Dalcin 
1870298fd71SBarry Smith   *handle = NULL;
188*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
189ebd79076SLisandro Dalcin }
190ebd79076SLisandro Dalcin 
191accbd18bSBarry Smith // clang-format off
192accbd18bSBarry Smith 
193ebd79076SLisandro Dalcin /*@C
194b235ab32SBarry Smith    PetscDLSym - finds a symbol in a dynamic library
195b235ab32SBarry Smith 
196b235ab32SBarry Smith    Not Collective
197b235ab32SBarry Smith 
198b235ab32SBarry Smith    Input Parameters:
199811af0c4SBarry Smith +   handle - obtained with `PetscDLOpen()` or NULL
200b235ab32SBarry Smith -   symbol - name of symbol
201b235ab32SBarry Smith 
202b235ab32SBarry Smith    Output Parameter:
2030298fd71SBarry Smith .   value - pointer to the function, NULL if not found
204b235ab32SBarry Smith 
205b235ab32SBarry Smith    Level: developer
206b235ab32SBarry Smith 
207811af0c4SBarry Smith   Note:
2080298fd71SBarry Smith    If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
2097c62f5d3SDmitry Karpeev    In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
2107c62f5d3SDmitry Karpeev    systems this requires platform-specific linker flags.
2117c62f5d3SDmitry Karpeev 
212db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLOpen()`, `PetscDLAddr()`
213ebd79076SLisandro Dalcin @*/
214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLSym(PetscDLHandle handle, const char symbol[], void **value)
215d71ae5a4SJacob Faibussowitsch {
2168e049581SJed Brown   PETSC_UNUSED dlhandle_t dlhandle;
2176ea75d68SLisandro Dalcin   dlsymbol_t              dlsymbol;
218ebd79076SLisandro Dalcin 
219*3ba16761SJacob Faibussowitsch   PetscFunctionBegin;
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 */
237accbd18bSBarry Smith       #endif /* PETSC_HAVE_SETLASTERROR */
238a21658a3SLisandro Dalcin     #endif /* !PETSC_HAVE_GETPROCADDRESS */
2395673baf8SLisandro Dalcin 
2405673baf8SLisandro Dalcin   /*
2415673baf8SLisandro Dalcin      --- dlsym ---
2425673baf8SLisandro Dalcin   */
243accbd18bSBarry Smith   #elif defined(PETSC_HAVE_DLFCN_H) /* PETSC_HAVE_WINDOWS_H */
244a21658a3SLisandro Dalcin     #if defined(PETSC_HAVE_DLSYM)
245a297a907SKarl Rupp       if (handle) dlhandle = (dlhandle_t)handle;
246a297a907SKarl Rupp       else {
2475617e356SJunchao Zhang         #if defined(PETSC_HAVE_DLOPEN)
2487c62f5d3SDmitry Karpeev           /* Attempt to retrieve the main executable's dlhandle. */
2499371c9d4SSatish Balay           {
2509371c9d4SSatish Balay             int dlflags1 = 0, dlflags2 = 0;
2517c62f5d3SDmitry Karpeev             #if defined(PETSC_HAVE_RTLD_LAZY)
2527c62f5d3SDmitry Karpeev               dlflags1 = RTLD_LAZY;
253accbd18bSBarry Smith             #endif /* PETSC_HAVE_RTLD_LAZY */
2547c62f5d3SDmitry Karpeev             #if defined(PETSC_HAVE_RTLD_NOW)
255accbd18bSBarry Smith               if (!dlflags1) {
2567c62f5d3SDmitry Karpeev                 dlflags1 = RTLD_NOW;
2577c62f5d3SDmitry Karpeev               }
258accbd18bSBarry Smith             #endif /* PETSC_HAVE_RTLD_NOW */
2597c62f5d3SDmitry Karpeev             #if defined(PETSC_HAVE_RTLD_LOCAL)
2607c62f5d3SDmitry Karpeev               dlflags2 = RTLD_LOCAL;
261accbd18bSBarry Smith             #endif /* PETSC_HAVE_RTLD_LOCAL */
2627c62f5d3SDmitry Karpeev             #if defined(PETSC_HAVE_RTLD_GLOBAL)
263accbd18bSBarry Smith               if (!dlflags2) {
2647c62f5d3SDmitry Karpeev                 dlflags2 = RTLD_GLOBAL;
2657c62f5d3SDmitry Karpeev               }
266accbd18bSBarry Smith             #endif /* PETSC_HAVE_RTLD_GLOBAL */
2677c62f5d3SDmitry Karpeev             #if defined(PETSC_HAVE_DLERROR)
2689371c9d4SSatish Balay               if (!(PETSC_RUNNING_ON_VALGRIND)) { dlerror(); /* clear any previous error; valgrind does not like this */ }
269accbd18bSBarry Smith             #endif /* PETSC_HAVE_DLERROR */
270618dc07dSPierre Jolivet             #if defined(PETSC_HAVE_RTLD_DEFAULT)
2717d421530SBarry Smith               dlhandle = RTLD_DEFAULT;
272d1408c41SPierre Jolivet             #else /* PETSC_HAVE_RTLD_DEFAULT */
273accbd18bSBarry Smith               /* Attempt to open the main executable as a dynamic library. */
27402c9f0b5SLisandro Dalcin               dlhandle = dlopen(NULL, dlflags1 | dlflags2);
2757c62f5d3SDmitry Karpeev               #if defined(PETSC_HAVE_DLERROR)
2769371c9d4SSatish Balay                 {
2779371c9d4SSatish Balay                   const char *e = (const char *)dlerror();
27828b400f6SJacob 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);
2797c62f5d3SDmitry Karpeev                 }
280accbd18bSBarry Smith               #endif /* PETSC_HAVE_DLERROR */
281d1408c41SPierre Jolivet             #endif /* PETSC_HAVE_RTLD_DEFAULT */
2827c62f5d3SDmitry Karpeev           }
283accbd18bSBarry Smith         #endif /* PETSC_HAVE_DLOPEN */
2844956914eSSatish Balay       }
285be1c6ad7SLisandro Dalcin       #if defined(PETSC_HAVE_DLERROR)
286be1c6ad7SLisandro Dalcin         dlerror(); /* clear any previous error */
287accbd18bSBarry Smith       #endif /* PETSC_HAVE_DLERROR */
2886ea75d68SLisandro Dalcin       dlsymbol = (dlsymbol_t)dlsym(dlhandle, symbol);
289accbd18bSBarry Smith     #else /* PETSC_HAVE_DLSYM */
290e32f2f54SBarry Smith       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
291accbd18bSBarry Smith     #endif /* PETSC_HAVE_DLSYM */
292accbd18bSBarry Smith   #else /* PETSC_HAVE_DLFCN_H */
293accbd18bSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
294accbd18bSBarry Smith   #endif /* PETSC_HAVE_WINDOWS_H */
295accbd18bSBarry Smith   // clang-format on
296ebd79076SLisandro Dalcin 
2976ea75d68SLisandro Dalcin   *value = *((void **)&dlsymbol);
298ebd79076SLisandro Dalcin 
2992d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
3009566063dSJacob Faibussowitsch   if (*value) PetscCall(PetscFPTAdd(*value, symbol));
301accbd18bSBarry Smith #endif /* PETSC_SERIALIZE_FUNCTIONS */
302*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
303ebd79076SLisandro Dalcin }
304184ce1a2SMatthew G. Knepley 
305184ce1a2SMatthew G. Knepley /*@C
306184ce1a2SMatthew G. Knepley   PetscDLAddr - find the name of a symbol in a dynamic library
307184ce1a2SMatthew G. Knepley 
308184ce1a2SMatthew G. Knepley   Not Collective
309184ce1a2SMatthew G. Knepley 
310184ce1a2SMatthew G. Knepley   Input Parameters:
311811af0c4SBarry Smith + handle - obtained with `PetscDLOpen()` or NULL
312184ce1a2SMatthew G. Knepley - func   - pointer to the function, NULL if not found
313184ce1a2SMatthew G. Knepley 
314184ce1a2SMatthew G. Knepley   Output Parameter:
31504c51a94SMatthew G. Knepley . name   - name of symbol, or NULL if name lookup is not supported.
316184ce1a2SMatthew G. Knepley 
317184ce1a2SMatthew G. Knepley   Level: developer
318184ce1a2SMatthew G. Knepley 
319184ce1a2SMatthew G. Knepley   Notes:
32004c51a94SMatthew G. Knepley   The caller must free the returned name.
321258ec3d2SMatthew G. Knepley 
322184ce1a2SMatthew G. Knepley   In order to be dynamically loadable, the symbol has to be exported as such.  On many UNIX-like
323184ce1a2SMatthew G. Knepley   systems this requires platform-specific linker flags.
32410699b91SBarry Smith 
325db781477SPatrick Sanan .seealso: `PetscDLClose()`, `PetscDLSym()`, `PetscDLOpen()`
326184ce1a2SMatthew G. Knepley @*/
327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDLAddr(void (*func)(void), char **name)
328d71ae5a4SJacob Faibussowitsch {
329184ce1a2SMatthew G. Knepley   PetscFunctionBegin;
330dadcf809SJacob Faibussowitsch   PetscValidPointer(name, 2);
331184ce1a2SMatthew G. Knepley   *name = NULL;
332e8953f01SSatish Balay #if defined(PETSC_HAVE_DLADDR) && !(defined(__cray__) && defined(__clang__))
333184ce1a2SMatthew G. Knepley   dlerror(); /* clear any previous error */
334184ce1a2SMatthew G. Knepley   {
335184ce1a2SMatthew G. Knepley     Dl_info info;
336184ce1a2SMatthew G. Knepley 
3375f80ce2aSJacob Faibussowitsch     PetscCheck(dladdr(*(void **)&func, &info), PETSC_COMM_SELF, PETSC_ERR_LIB, "Failed to lookup symbol: %s", dlerror());
338258ec3d2SMatthew G. Knepley   #ifdef PETSC_HAVE_CXX
3399566063dSJacob Faibussowitsch     PetscCall(PetscDemangleSymbol(info.dli_sname, name));
340258ec3d2SMatthew G. Knepley   #else
3419566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(info.dli_sname, name));
342258ec3d2SMatthew G. Knepley   #endif
343184ce1a2SMatthew G. Knepley   }
344184ce1a2SMatthew G. Knepley #endif
345*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
346184ce1a2SMatthew G. Knepley }
347