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