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