xref: /petsc/src/sys/dll/dlimpl.c (revision ebd7907603c287a6093c4bfcf7b1f2da9f621a56)
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 #if 0
27 #undef PETSC_HAVE_WINDOWS_H
28 #undef PETSC_HAVE_DLFCN_H
29 #elif 0
30 #undef  PETSC_HAVE_DLFCN_H
31 #define PETSC_HAVE_WINDOWS_H
32 #define PETSC_HAVE_GETPROCADDRESS
33 #define HMODULE int
34 extern HMODULE LoadLibrary(const char*);
35 extern HMODULE GetCurrentProcess(void);
36 extern void*   GetProcAddress(HMODULE,const char*);
37 #endif
38 
39 #if defined(PETSC_HAVE_WINDOWS_H)
40 typedef HMODULE dlhandle_t;
41 #elif defined(PETSC_HAVE_DLFCN_H)
42 typedef void* dlhandle_t;
43 #else
44 typedef void* dlhandle_t;
45 #endif
46 
47 #undef __FUNCT__
48 #define __FUNCT__ "PetscDLOpen"
49 /*@C
50    PetscDLOpen -
51 @*/
52 PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char *name, PetscDLFlags flags, PetscDLHandle *handle)
53 {
54   const char *dlname;
55   int        dlflags;
56   dlhandle_t dlhandle;
57 
58   PetscFunctionBegin;
59   PetscValidCharPointer(name, 1);
60   PetscValidPointer(handle, 3);
61 
62   dlname   = name;
63   dlflags  = PETSC_DL_DEFAULT;
64   dlhandle = PETSC_NULL;
65 
66   /* --- LoadLibrary ---*/
67 #if defined(PETSC_HAVE_WINDOWS_H)
68   dlhandle = LoadLibrary(dlname);
69   if (!dlhandle) {
70 #if defined(PETSC_HAVE_GETLASTERROR)
71     PetscErrorCode ierr;
72     DWORD          erc;
73     char           *buff;
74     erc  = GetLastError();
75     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
76 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
77     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
78 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",dlname,buff);
79     LocalFree(buff);
80     PetscFunctionReturn(ierr);
81 #else
82     SETERRQ2(PETSC_ERR_FILE_OPEN,
83 	     "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",dlname,"unavailable");
84 #endif
85   }
86   /* --- dlopen ---*/
87 #elif defined(PETSC_HAVE_DLFCN_H)
88   /*
89       Mode indicates symbols required by symbol loaded with dlsym()
90      are only loaded when required (not all together) also indicates
91      symbols required can be contained in other libraries also opened
92      with dlopen()
93   */
94   dlflags = RTLD_LAZY;
95 #if defined(PETSC_HAVE_RTLD_NOW)
96   if (flags & PETSC_DL_NOW)  dlflags = RTLD_NOW;
97 #endif
98 #if defined(PETSC_HAVE_RTLD_GLOBAL)
99   if (flags & PETSC_DL_GLOBAL) dlflags |= RTLD_GLOBAL;
100 #endif
101   dlhandle = dlopen(dlname,flags);
102   if (!dlhandle) {
103 #if defined(PETSC_HAVE_DLERROR)
104     const char *errmsg = dlerror();
105 #else
106     const char *errmsg = "unavailable";
107 #endif
108     SETERRQ2(PETSC_ERR_FILE_OPEN,
109 	     "Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n", dlname, errmsg)
110   }
111   /* --- unimplemented ---*/
112 #else
113   SETERRQ(PETSC_ERR_SUP_SYS, "cannot open dynamic libraries");
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   /* --- FreeLibrary ?? ---*/
137 #if defined(PETSC_HAVE_WINDOWS_H)
138   /* XXXX Implement !!!*/
139 
140   /* --- dclose ---*/
141 #elif defined(PETSC_HAVE_DLFCN_H)
142   if (dlclose(dlhandle) < 0) {
143 #if defined(PETSC_HAVE_DLERROR)
144     const char *errmsg = dlerror();
145 #else
146     const char *errmsg = "unavailable";
147 #endif
148     SETERRQ1(PETSC_ERR_LIB, /* XXX Better error code ? */
149 	     "Unable to close dynamic library:\n  Error message from dlclose() %s\n", errmsg);
150   }
151   /* --- unimplemented ---*/
152 #else
153   SETERRQ(PETSC_ERR_SUP_SYS, "cannot close dynamic libraries");
154 #endif
155 
156   *handle = PETSC_NULL;
157 
158   PetscFunctionReturn(0);
159 }
160 
161 
162 #undef __FUNCT__
163 #define __FUNCT__ "PetscDLSym"
164 /*@C
165    PetscDLSym -
166 @*/
167 PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle, const char *symbol, void **value)
168 {
169   dlhandle_t dlhandle;
170   void       *dlvalue;
171 
172   PetscFunctionBegin;
173   PetscValidCharPointer(symbol, 2);
174   PetscValidPointer(value, 3);
175 
176   dlhandle = (dlhandle_t) handle;
177 
178 #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_GETPROCADDRESS)
179   if (!dlhandle) dlhandle = GetCurrentProcess();
180   dlvalue = GetProcAddress(dlhandle,symbol);
181 #elif defined(PETSC_HAVE_DLFCN_H)
182   if (!dlhandle) dlhandle = (dlhandle_t)0;
183   dlvalue = dlsym(dlhandle,symbol);
184 #else
185   SETERRQ(PETSC_ERR_SUP_SYS, "cannot load symbols from dynamic libraries");
186 #endif
187 
188   *value = dlvalue;
189 
190   PetscFunctionReturn(0);
191 }
192