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