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