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