xref: /petsc/src/sys/dll/dlimpl.c (revision b3bb0f5ecefb682ae1a0272025cbe5bfbdb38d92)
1ebd79076SLisandro Dalcin #define PETSC_DLL
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
6*b3bb0f5eSLisandro Dalcin #include "src/sys/dll/dlimpl.h"
7ebd79076SLisandro Dalcin 
8ebd79076SLisandro Dalcin /* XXX Should be done better !!!*/
9be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
10ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
11ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
12ebd79076SLisandro Dalcin #endif
13ebd79076SLisandro Dalcin 
14ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
15ebd79076SLisandro Dalcin #include <windows.h>
16be1c6ad7SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
17ebd79076SLisandro Dalcin #include <dlfcn.h>
18ebd79076SLisandro Dalcin #endif
19ebd79076SLisandro Dalcin 
20be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */
21be1c6ad7SLisandro Dalcin /* Just for testing, REMOVE THIS when done */
22ebd79076SLisandro Dalcin #if 0
23ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
24ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
25ebd79076SLisandro Dalcin #elif 0
26ebd79076SLisandro Dalcin #undef  PETSC_HAVE_DLFCN_H
27ebd79076SLisandro Dalcin #define PETSC_HAVE_WINDOWS_H
28be1c6ad7SLisandro Dalcin #define PETSC_HAVE_LOADLIBRARY
29ebd79076SLisandro Dalcin #define PETSC_HAVE_GETPROCADDRESS
30be1c6ad7SLisandro Dalcin #define PETSC_HAVE_FREELIBRARY
31ebd79076SLisandro Dalcin #define HMODULE int
32ebd79076SLisandro Dalcin extern HMODULE LoadLibrary(const char*);
335673baf8SLisandro Dalcin extern int     FreeLibrary(HMODULE);
34ebd79076SLisandro Dalcin extern HMODULE GetCurrentProcess(void);
35ebd79076SLisandro Dalcin extern void*   GetProcAddress(HMODULE,const char*);
36ebd79076SLisandro Dalcin #endif
37be1c6ad7SLisandro Dalcin /* XXX ----------------------------------- */
38be1c6ad7SLisandro Dalcin 
39ebd79076SLisandro Dalcin 
40ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
41ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t;
42ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
43ebd79076SLisandro Dalcin typedef void* dlhandle_t;
44ebd79076SLisandro Dalcin #else
45ebd79076SLisandro Dalcin typedef void* dlhandle_t;
46ebd79076SLisandro Dalcin #endif
47ebd79076SLisandro Dalcin 
48ebd79076SLisandro Dalcin #undef __FUNCT__
49ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen"
50ebd79076SLisandro Dalcin /*@C
51ebd79076SLisandro Dalcin    PetscDLOpen -
52ebd79076SLisandro Dalcin @*/
535673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
54ebd79076SLisandro Dalcin {
55be1c6ad7SLisandro Dalcin   int        dlflags1,dlflags2;
56ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
57ebd79076SLisandro Dalcin 
58ebd79076SLisandro Dalcin   PetscFunctionBegin;
59ebd79076SLisandro Dalcin   PetscValidCharPointer(name, 1);
60ebd79076SLisandro Dalcin   PetscValidPointer(handle, 3);
61ebd79076SLisandro Dalcin 
62be1c6ad7SLisandro Dalcin   dlflags1 = 0;
63be1c6ad7SLisandro Dalcin   dlflags2 = 0;
645673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
65be1c6ad7SLisandro Dalcin   *handle = (PetscDLHandle) 0;
66ebd79076SLisandro Dalcin 
675673baf8SLisandro Dalcin   /*
685673baf8SLisandro Dalcin      --- LoadLibrary ---
695673baf8SLisandro Dalcin   */
70be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
71be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
72ebd79076SLisandro Dalcin   if (!dlhandle) {
73ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
74ebd79076SLisandro Dalcin     PetscErrorCode ierr;
75ebd79076SLisandro Dalcin     DWORD erc;
76*b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
77ebd79076SLisandro Dalcin     erc = GetLastError();
78ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
79ebd79076SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
80ebd79076SLisandro Dalcin     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
81be1c6ad7SLisandro Dalcin 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
82ebd79076SLisandro Dalcin     LocalFree(buff);
83ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
84ebd79076SLisandro Dalcin #else
85be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
86ebd79076SLisandro Dalcin #endif
87ebd79076SLisandro Dalcin   }
885673baf8SLisandro Dalcin 
895673baf8SLisandro Dalcin   /*
905673baf8SLisandro Dalcin      --- dlopen ---
915673baf8SLisandro Dalcin   */
92ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
93ebd79076SLisandro Dalcin   /*
94ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
95ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
96ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
97ebd79076SLisandro Dalcin      with dlopen()
98ebd79076SLisandro Dalcin   */
99be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
100be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
101be1c6ad7SLisandro Dalcin #endif
102ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
1035673baf8SLisandro Dalcin   if (flags & PETSC_DL_NOW)
104be1c6ad7SLisandro Dalcin     dlflags1 = RTLD_NOW;
105ebd79076SLisandro Dalcin #endif
106ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
107be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
108ebd79076SLisandro Dalcin #endif
109*b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
110*b3bb0f5eSLisandro Dalcin   if (flags & PETSC_DL_LOCAL)
111*b3bb0f5eSLisandro Dalcin     dlflags2 = RTLD_LOCAL;
112*b3bb0f5eSLisandro 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
123be1c6ad7SLisandro Dalcin     SETERRQ2(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
130be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
131ebd79076SLisandro Dalcin #endif
132ebd79076SLisandro Dalcin 
133ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
134ebd79076SLisandro Dalcin 
135ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
136ebd79076SLisandro Dalcin }
137ebd79076SLisandro Dalcin 
138ebd79076SLisandro Dalcin 
139ebd79076SLisandro Dalcin #undef __FUNCT__
140ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose"
141ebd79076SLisandro Dalcin /*@C
142ebd79076SLisandro Dalcin    PetscDLClose -
143ebd79076SLisandro Dalcin @*/
144ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle)
145ebd79076SLisandro Dalcin {
146ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
147ebd79076SLisandro Dalcin 
148ebd79076SLisandro Dalcin   PetscFunctionBegin;
149ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
150ebd79076SLisandro Dalcin 
151ebd79076SLisandro Dalcin   dlhandle = (dlhandle_t) *handle;
152ebd79076SLisandro Dalcin 
1535673baf8SLisandro Dalcin   /*
1545673baf8SLisandro Dalcin      --- FreeLibrary ---
1555673baf8SLisandro Dalcin   */
156ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
157be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1585673baf8SLisandro Dalcin   if (FreeLibrary(dlhandle) == 0) {
1595673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
1605673baf8SLisandro Dalcin     DWORD erc;
161*b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
1625673baf8SLisandro Dalcin     erc = GetLastError();
1635673baf8SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
1645673baf8SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
1655673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1665673baf8SLisandro Dalcin     LocalFree(buff);
1675673baf8SLisandro Dalcin #else
1685673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1695673baf8SLisandro Dalcin #endif
1705673baf8SLisandro Dalcin   }
171be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
172ebd79076SLisandro Dalcin 
1735673baf8SLisandro Dalcin   /*
1745673baf8SLisandro Dalcin      --- dclose ---
1755673baf8SLisandro Dalcin   */
176ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
177be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
178be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
179be1c6ad7SLisandro Dalcin #endif
180ebd79076SLisandro Dalcin   if (dlclose(dlhandle) < 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   }
1885673baf8SLisandro Dalcin 
1895673baf8SLisandro Dalcin   /*
1905673baf8SLisandro Dalcin      --- unimplemented ---
1915673baf8SLisandro Dalcin   */
192ebd79076SLisandro Dalcin #else
193be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
194ebd79076SLisandro Dalcin #endif
195ebd79076SLisandro Dalcin 
196ebd79076SLisandro Dalcin   *handle = PETSC_NULL;
197ebd79076SLisandro Dalcin 
198ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
199ebd79076SLisandro Dalcin }
200ebd79076SLisandro Dalcin 
201ebd79076SLisandro Dalcin 
202ebd79076SLisandro Dalcin #undef __FUNCT__
203ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym"
204ebd79076SLisandro Dalcin /*@C
205ebd79076SLisandro Dalcin    PetscDLSym -
206ebd79076SLisandro Dalcin @*/
2075673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
208ebd79076SLisandro Dalcin {
209ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
210ebd79076SLisandro Dalcin   void       *dlvalue;
211ebd79076SLisandro Dalcin 
212ebd79076SLisandro Dalcin   PetscFunctionBegin;
213ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
214ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
215ebd79076SLisandro Dalcin 
216be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
217be1c6ad7SLisandro Dalcin   *value = 0;
218ebd79076SLisandro Dalcin 
2195673baf8SLisandro Dalcin   /*
2205673baf8SLisandro Dalcin      --- GetProcAddress ---
2215673baf8SLisandro Dalcin   */
222ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS)
223be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
224be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
225be1c6ad7SLisandro Dalcin   else
226be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) GetCurrentProcess();
227ebd79076SLisandro Dalcin   dlvalue = GetProcAddress(dlhandle,symbol);
2285673baf8SLisandro Dalcin 
2295673baf8SLisandro Dalcin   /*
2305673baf8SLisandro Dalcin      --- dlsym ---
2315673baf8SLisandro Dalcin   */
232ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
233be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
234be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
235be1c6ad7SLisandro Dalcin   else
236be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) 0;
237be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
238be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
239be1c6ad7SLisandro Dalcin #endif
240ebd79076SLisandro Dalcin   dlvalue = dlsym(dlhandle,symbol);
241be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
242*b3bb0f5eSLisandro Dalcin   dlerror(); /* clear any previous error */
243be1c6ad7SLisandro Dalcin #endif
2445673baf8SLisandro Dalcin 
2455673baf8SLisandro Dalcin   /*
2465673baf8SLisandro Dalcin      --- unimplemented ---
2475673baf8SLisandro Dalcin   */
248ebd79076SLisandro Dalcin #else
249be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
250ebd79076SLisandro Dalcin #endif
251ebd79076SLisandro Dalcin 
252ebd79076SLisandro Dalcin   *value = dlvalue;
253ebd79076SLisandro Dalcin 
254ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
255ebd79076SLisandro Dalcin }
256