xref: /petsc/src/sys/dll/dlimpl.c (revision be1c6ad7b82603ce7da10837a4af262deba3970f)
1ebd79076SLisandro Dalcin #define PETSC_DLL
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
6ebd79076SLisandro Dalcin #include "petsc.h"
7ebd79076SLisandro Dalcin #include "petscfix.h"
8ebd79076SLisandro Dalcin 
9ebd79076SLisandro Dalcin /* XXX Should be done better !!!*/
10*be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
11ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
12ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
13ebd79076SLisandro Dalcin #endif
14ebd79076SLisandro Dalcin 
15ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
16ebd79076SLisandro Dalcin #include <windows.h>
17*be1c6ad7SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
18ebd79076SLisandro Dalcin #include <dlfcn.h>
19ebd79076SLisandro Dalcin #endif
20ebd79076SLisandro Dalcin 
21*be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */
22*be1c6ad7SLisandro Dalcin /* Just for testing, REMOVE THIS when done */
23ebd79076SLisandro Dalcin #if 0
24ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
25ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
26ebd79076SLisandro Dalcin #elif 0
27ebd79076SLisandro Dalcin #undef  PETSC_HAVE_DLFCN_H
28ebd79076SLisandro Dalcin #define PETSC_HAVE_WINDOWS_H
29*be1c6ad7SLisandro Dalcin #define PETSC_HAVE_LOADLIBRARY
30ebd79076SLisandro Dalcin #define PETSC_HAVE_GETPROCADDRESS
31*be1c6ad7SLisandro Dalcin #define PETSC_HAVE_FREELIBRARY
32ebd79076SLisandro Dalcin #define HMODULE int
33ebd79076SLisandro Dalcin extern HMODULE LoadLibrary(const char*);
345673baf8SLisandro Dalcin extern int     FreeLibrary(HMODULE);
35ebd79076SLisandro Dalcin extern HMODULE GetCurrentProcess(void);
36ebd79076SLisandro Dalcin extern void*   GetProcAddress(HMODULE,const char*);
37ebd79076SLisandro Dalcin #endif
38*be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */
39*be1c6ad7SLisandro Dalcin 
40ebd79076SLisandro Dalcin 
41ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
42ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t;
43ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
44ebd79076SLisandro Dalcin typedef void* dlhandle_t;
45ebd79076SLisandro Dalcin #else
46ebd79076SLisandro Dalcin typedef void* dlhandle_t;
47ebd79076SLisandro Dalcin #endif
48ebd79076SLisandro Dalcin 
49ebd79076SLisandro Dalcin #undef __FUNCT__
50ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen"
51ebd79076SLisandro Dalcin /*@C
52ebd79076SLisandro Dalcin    PetscDLOpen -
53ebd79076SLisandro Dalcin @*/
545673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
55ebd79076SLisandro Dalcin {
56*be1c6ad7SLisandro Dalcin   int        dlflags1,dlflags2;
57ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
58ebd79076SLisandro Dalcin 
59ebd79076SLisandro Dalcin   PetscFunctionBegin;
60ebd79076SLisandro Dalcin   PetscValidCharPointer(name, 1);
61ebd79076SLisandro Dalcin   PetscValidPointer(handle, 3);
62ebd79076SLisandro Dalcin 
63*be1c6ad7SLisandro Dalcin   dlflags1 = 0;
64*be1c6ad7SLisandro Dalcin   dlflags2 = 0;
655673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
66*be1c6ad7SLisandro Dalcin   *handle = (PetscDLHandle) 0;
67ebd79076SLisandro Dalcin 
685673baf8SLisandro Dalcin   /*
695673baf8SLisandro Dalcin      --- LoadLibrary ---
705673baf8SLisandro Dalcin   */
71*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
72*be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
73ebd79076SLisandro Dalcin   if (!dlhandle) {
74ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
75ebd79076SLisandro Dalcin     PetscErrorCode ierr;
76ebd79076SLisandro Dalcin     DWORD          erc;
77ebd79076SLisandro Dalcin     char           *buff;
78ebd79076SLisandro Dalcin     erc = GetLastError();
79ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
80ebd79076SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
81ebd79076SLisandro Dalcin     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
82*be1c6ad7SLisandro Dalcin 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
83ebd79076SLisandro Dalcin     LocalFree(buff);
84ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
85ebd79076SLisandro Dalcin #else
86*be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
87ebd79076SLisandro Dalcin #endif
88ebd79076SLisandro Dalcin   }
895673baf8SLisandro Dalcin 
905673baf8SLisandro Dalcin   /*
915673baf8SLisandro Dalcin      --- dlopen ---
925673baf8SLisandro Dalcin   */
93ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
94ebd79076SLisandro Dalcin   /*
95ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
96ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
97ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
98ebd79076SLisandro Dalcin      with dlopen()
99ebd79076SLisandro Dalcin   */
100*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
101*be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
102*be1c6ad7SLisandro Dalcin #endif
103ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
1045673baf8SLisandro Dalcin   if (flags & PETSC_DL_NOW)
105*be1c6ad7SLisandro Dalcin     dlflags1 = RTLD_NOW;
106ebd79076SLisandro Dalcin #endif
107*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
108*be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_LOCAL;
109*be1c6ad7SLisandro Dalcin #endif
110ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
1115673baf8SLisandro Dalcin   if (flags & PETSC_DL_GLOBAL)
112*be1c6ad7SLisandro Dalcin     dlflags2 = RTLD_GLOBAL;
113ebd79076SLisandro Dalcin #endif
114*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
115*be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
116*be1c6ad7SLisandro Dalcin #endif
117*be1c6ad7SLisandro 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
124*be1c6ad7SLisandro Dalcin     SETERRQ2(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   /*
1285673baf8SLisandro Dalcin      --- unimplemented ---
1295673baf8SLisandro Dalcin   */
130ebd79076SLisandro Dalcin #else
131*be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
132ebd79076SLisandro Dalcin #endif
133ebd79076SLisandro Dalcin 
134ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
135ebd79076SLisandro Dalcin 
136ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
137ebd79076SLisandro Dalcin }
138ebd79076SLisandro Dalcin 
139ebd79076SLisandro Dalcin 
140ebd79076SLisandro Dalcin #undef __FUNCT__
141ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose"
142ebd79076SLisandro Dalcin /*@C
143ebd79076SLisandro Dalcin    PetscDLClose -
144ebd79076SLisandro Dalcin @*/
145ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle)
146ebd79076SLisandro Dalcin {
147ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
148ebd79076SLisandro Dalcin 
149ebd79076SLisandro Dalcin   PetscFunctionBegin;
150ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
151ebd79076SLisandro Dalcin 
152ebd79076SLisandro Dalcin   dlhandle = (dlhandle_t) *handle;
153ebd79076SLisandro Dalcin 
1545673baf8SLisandro Dalcin   /*
1555673baf8SLisandro Dalcin      --- FreeLibrary ---
1565673baf8SLisandro Dalcin   */
157ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
158*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1595673baf8SLisandro Dalcin   if (FreeLibrary(dlhandle) == 0) {
1605673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
1615673baf8SLisandro Dalcin     DWORD erc;
1625673baf8SLisandro Dalcin     char  *buff;
1635673baf8SLisandro Dalcin     erc = GetLastError();
1645673baf8SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
1655673baf8SLisandro Dalcin 		  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   }
172*be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
173ebd79076SLisandro Dalcin 
1745673baf8SLisandro Dalcin   /*
1755673baf8SLisandro Dalcin      --- dclose ---
1765673baf8SLisandro Dalcin   */
177ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
178*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
179*be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
180*be1c6ad7SLisandro Dalcin #endif
181ebd79076SLisandro Dalcin   if (dlclose(dlhandle) < 0) {
182ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
183ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
184ebd79076SLisandro Dalcin #else
185ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
186ebd79076SLisandro Dalcin #endif
1875673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
188ebd79076SLisandro Dalcin   }
1895673baf8SLisandro Dalcin 
1905673baf8SLisandro Dalcin   /*
1915673baf8SLisandro Dalcin      --- unimplemented ---
1925673baf8SLisandro Dalcin   */
193ebd79076SLisandro Dalcin #else
194*be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
195ebd79076SLisandro Dalcin #endif
196ebd79076SLisandro Dalcin 
197ebd79076SLisandro Dalcin   *handle = PETSC_NULL;
198ebd79076SLisandro Dalcin 
199ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
200ebd79076SLisandro Dalcin }
201ebd79076SLisandro Dalcin 
202ebd79076SLisandro Dalcin 
203ebd79076SLisandro Dalcin #undef __FUNCT__
204ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym"
205ebd79076SLisandro Dalcin /*@C
206ebd79076SLisandro Dalcin    PetscDLSym -
207ebd79076SLisandro Dalcin @*/
2085673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
209ebd79076SLisandro Dalcin {
210ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
211ebd79076SLisandro Dalcin   void       *dlvalue;
212ebd79076SLisandro Dalcin 
213ebd79076SLisandro Dalcin   PetscFunctionBegin;
214ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
215ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
216ebd79076SLisandro Dalcin 
217*be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
218*be1c6ad7SLisandro Dalcin   *value = 0;
219ebd79076SLisandro Dalcin 
2205673baf8SLisandro Dalcin   /*
2215673baf8SLisandro Dalcin      --- GetProcAddress ---
2225673baf8SLisandro Dalcin   */
223ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS)
224*be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
225*be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
226*be1c6ad7SLisandro Dalcin   else
227*be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) GetCurrentProcess();
228ebd79076SLisandro Dalcin   dlvalue = GetProcAddress(dlhandle,symbol);
2295673baf8SLisandro Dalcin 
2305673baf8SLisandro Dalcin   /*
2315673baf8SLisandro Dalcin      --- dlsym ---
2325673baf8SLisandro Dalcin   */
233ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
234*be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
235*be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
236*be1c6ad7SLisandro Dalcin   else
237*be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) 0;
238*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
239*be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
240*be1c6ad7SLisandro Dalcin #endif
241ebd79076SLisandro Dalcin   dlvalue = dlsym(dlhandle,symbol);
242*be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
243*be1c6ad7SLisandro Dalcin   if (!dlvalue) { /* dvalue could be actually NULL */
244*be1c6ad7SLisandro Dalcin     const char *errmsg = dlerror();
245*be1c6ad7SLisandro Dalcin     if (errmsg) { /* XXX Should we fail/inform about this? */
246*be1c6ad7SLisandro Dalcin #if 0
247*be1c6ad7SLisandro Dalcin       SETERRQ2(PETSC_ERR_FILE_UNEXPECTED,"Unable to load symbol %s\n  Error message from dlsym() %s\n",symbol,errmsg);
248*be1c6ad7SLisandro Dalcin #else
249*be1c6ad7SLisandro Dalcin       errmsg = 0;
250*be1c6ad7SLisandro Dalcin #endif
251*be1c6ad7SLisandro Dalcin     }
252*be1c6ad7SLisandro Dalcin   }
253*be1c6ad7SLisandro Dalcin #endif
2545673baf8SLisandro Dalcin 
2555673baf8SLisandro Dalcin   /*
2565673baf8SLisandro Dalcin      --- unimplemented ---
2575673baf8SLisandro Dalcin   */
258ebd79076SLisandro Dalcin #else
259*be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
260ebd79076SLisandro Dalcin #endif
261ebd79076SLisandro Dalcin 
262ebd79076SLisandro Dalcin   *value = dlvalue;
263ebd79076SLisandro Dalcin 
264ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
265ebd79076SLisandro Dalcin }
266