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