xref: /petsc/src/sys/dll/dlimpl.c (revision b3bb0f5ecefb682ae1a0272025cbe5bfbdb38d92)
1 #define PETSC_DLL
2 /*
3    Low-level routines for managing dynamic link libraries (DLLs).
4 */
5 
6 #include "src/sys/dll/dlimpl.h"
7 
8 /* XXX Should be done better !!!*/
9 #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
10 #undef PETSC_HAVE_WINDOWS_H
11 #undef PETSC_HAVE_DLFCN_H
12 #endif
13 
14 #if defined(PETSC_HAVE_WINDOWS_H)
15 #include <windows.h>
16 #elif defined(PETSC_HAVE_DLFCN_H)
17 #include <dlfcn.h>
18 #endif
19 
20 /* XXX ----------------------------------- */
21 /* Just for testing, REMOVE THIS when done */
22 #if 0
23 #undef PETSC_HAVE_WINDOWS_H
24 #undef PETSC_HAVE_DLFCN_H
25 #elif 0
26 #undef  PETSC_HAVE_DLFCN_H
27 #define PETSC_HAVE_WINDOWS_H
28 #define PETSC_HAVE_LOADLIBRARY
29 #define PETSC_HAVE_GETPROCADDRESS
30 #define PETSC_HAVE_FREELIBRARY
31 #define HMODULE int
32 extern HMODULE LoadLibrary(const char*);
33 extern int     FreeLibrary(HMODULE);
34 extern HMODULE GetCurrentProcess(void);
35 extern void*   GetProcAddress(HMODULE,const char*);
36 #endif
37 /* XXX ----------------------------------- */
38 
39 
40 #if defined(PETSC_HAVE_WINDOWS_H)
41 typedef HMODULE dlhandle_t;
42 #elif defined(PETSC_HAVE_DLFCN_H)
43 typedef void* dlhandle_t;
44 #else
45 typedef void* dlhandle_t;
46 #endif
47 
48 #undef __FUNCT__
49 #define __FUNCT__ "PetscDLOpen"
50 /*@C
51    PetscDLOpen -
52 @*/
53 PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
54 {
55   int        dlflags1,dlflags2;
56   dlhandle_t dlhandle;
57 
58   PetscFunctionBegin;
59   PetscValidCharPointer(name, 1);
60   PetscValidPointer(handle, 3);
61 
62   dlflags1 = 0;
63   dlflags2 = 0;
64   dlhandle = (dlhandle_t) 0;
65   *handle = (PetscDLHandle) 0;
66 
67   /*
68      --- LoadLibrary ---
69   */
70 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
71   dlhandle = LoadLibrary(name);
72   if (!dlhandle) {
73 #if defined(PETSC_HAVE_GETLASTERROR)
74     PetscErrorCode ierr;
75     DWORD erc;
76     char  *buff = NULL;
77     erc = GetLastError();
78     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
79 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
80     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
81 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
82     LocalFree(buff);
83     PetscFunctionReturn(ierr);
84 #else
85     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
86 #endif
87   }
88 
89   /*
90      --- dlopen ---
91   */
92 #elif defined(PETSC_HAVE_DLFCN_H)
93   /*
94       Mode indicates symbols required by symbol loaded with dlsym()
95      are only loaded when required (not all together) also indicates
96      symbols required can be contained in other libraries also opened
97      with dlopen()
98   */
99 #if defined(PETSC_HAVE_RTLD_LAZY)
100   dlflags1 = RTLD_LAZY;
101 #endif
102 #if defined(PETSC_HAVE_RTLD_NOW)
103   if (flags & PETSC_DL_NOW)
104     dlflags1 = RTLD_NOW;
105 #endif
106 #if defined(PETSC_HAVE_RTLD_GLOBAL)
107   dlflags2 = RTLD_GLOBAL;
108 #endif
109 #if defined(PETSC_HAVE_RTLD_LOCAL)
110   if (flags & PETSC_DL_LOCAL)
111     dlflags2 = RTLD_LOCAL;
112 #endif
113 #if defined(PETSC_HAVE_DLERROR)
114   dlerror(); /* clear any previous error */
115 #endif
116   dlhandle = dlopen(name,dlflags1|dlflags2);
117   if (!dlhandle) {
118 #if defined(PETSC_HAVE_DLERROR)
119     const char *errmsg = dlerror();
120 #else
121     const char *errmsg = "unavailable";
122 #endif
123     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n",name,errmsg)
124   }
125 
126   /*
127      --- unimplemented ---
128   */
129 #else
130   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
131 #endif
132 
133   *handle = (PetscDLHandle) dlhandle;
134 
135   PetscFunctionReturn(0);
136 }
137 
138 
139 #undef __FUNCT__
140 #define __FUNCT__ "PetscDLClose"
141 /*@C
142    PetscDLClose -
143 @*/
144 PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle)
145 {
146   dlhandle_t dlhandle;
147 
148   PetscFunctionBegin;
149   PetscValidPointer(handle,1);
150 
151   dlhandle = (dlhandle_t) *handle;
152 
153   /*
154      --- FreeLibrary ---
155   */
156 #if defined(PETSC_HAVE_WINDOWS_H)
157 #if defined(PETSC_HAVE_FREELIBRARY)
158   if (FreeLibrary(dlhandle) == 0) {
159 #if defined(PETSC_HAVE_GETLASTERROR)
160     DWORD erc;
161     char  *buff = NULL;
162     erc = GetLastError();
163     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
164 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
165     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
166     LocalFree(buff);
167 #else
168     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
169 #endif
170   }
171 #endif /* !PETSC_HAVE_FREELIBRARY */
172 
173   /*
174      --- dclose ---
175   */
176 #elif defined(PETSC_HAVE_DLFCN_H)
177 #if defined(PETSC_HAVE_DLERROR)
178   dlerror(); /* clear any previous error */
179 #endif
180   if (dlclose(dlhandle) < 0) {
181 #if defined(PETSC_HAVE_DLERROR)
182     const char *errmsg = dlerror();
183 #else
184     const char *errmsg = "unavailable";
185 #endif
186     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
187   }
188 
189   /*
190      --- unimplemented ---
191   */
192 #else
193   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
194 #endif
195 
196   *handle = PETSC_NULL;
197 
198   PetscFunctionReturn(0);
199 }
200 
201 
202 #undef __FUNCT__
203 #define __FUNCT__ "PetscDLSym"
204 /*@C
205    PetscDLSym -
206 @*/
207 PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
208 {
209   dlhandle_t dlhandle;
210   void       *dlvalue;
211 
212   PetscFunctionBegin;
213   PetscValidCharPointer(symbol,2);
214   PetscValidPointer(value,3);
215 
216   dlhandle = (dlhandle_t) 0;
217   *value = 0;
218 
219   /*
220      --- GetProcAddress ---
221   */
222 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS)
223   if (handle != PETSC_NULL)
224     dlhandle = (dlhandle_t) handle;
225   else
226     dlhandle = (dlhandle_t) GetCurrentProcess();
227   dlvalue = GetProcAddress(dlhandle,symbol);
228 
229   /*
230      --- dlsym ---
231   */
232 #elif defined(PETSC_HAVE_DLFCN_H)
233   if (handle != PETSC_NULL)
234     dlhandle = (dlhandle_t) handle;
235   else
236     dlhandle = (dlhandle_t) 0;
237 #if defined(PETSC_HAVE_DLERROR)
238   dlerror(); /* clear any previous error */
239 #endif
240   dlvalue = dlsym(dlhandle,symbol);
241 #if defined(PETSC_HAVE_DLERROR)
242   dlerror(); /* clear any previous error */
243 #endif
244 
245   /*
246      --- unimplemented ---
247   */
248 #else
249   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
250 #endif
251 
252   *value = dlvalue;
253 
254   PetscFunctionReturn(0);
255 }
256