xref: /petsc/src/sys/dll/dlimpl.c (revision 6ea75d6886263ceb9597f2b9d77d2f7d4a156e33)
1ebd79076SLisandro Dalcin #define PETSC_DLL
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
67c4f633dSBarry Smith #include "../src/sys/dll/dlimpl.h"
7ebd79076SLisandro Dalcin 
8ebd79076SLisandro Dalcin /* XXX Should be done better !!!*/
9be1c6ad7SLisandro Dalcin #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
10ebd79076SLisandro Dalcin #undef PETSC_HAVE_WINDOWS_H
11ebd79076SLisandro Dalcin #undef PETSC_HAVE_DLFCN_H
12ebd79076SLisandro Dalcin #endif
13ebd79076SLisandro Dalcin 
14ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
15ebd79076SLisandro Dalcin #include <windows.h>
16be1c6ad7SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
17ebd79076SLisandro Dalcin #include <dlfcn.h>
18ebd79076SLisandro Dalcin #endif
19ebd79076SLisandro Dalcin 
20ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
21ebd79076SLisandro Dalcin typedef HMODULE dlhandle_t;
22*6ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t;
23ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
24ebd79076SLisandro Dalcin typedef void* dlhandle_t;
25*6ea75d68SLisandro Dalcin typedef void* dlsymbol_t;
26ebd79076SLisandro Dalcin #else
27ebd79076SLisandro Dalcin typedef void* dlhandle_t;
28*6ea75d68SLisandro Dalcin typedef void* dlsymbol_t;
29ebd79076SLisandro Dalcin #endif
30ebd79076SLisandro Dalcin 
31ebd79076SLisandro Dalcin #undef __FUNCT__
32ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen"
33ebd79076SLisandro Dalcin /*@C
34ebd79076SLisandro Dalcin    PetscDLOpen -
35ebd79076SLisandro Dalcin @*/
365673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
37ebd79076SLisandro Dalcin {
38be1c6ad7SLisandro Dalcin   int        dlflags1,dlflags2;
39ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
40ebd79076SLisandro Dalcin 
41ebd79076SLisandro Dalcin   PetscFunctionBegin;
42ebd79076SLisandro Dalcin   PetscValidCharPointer(name,1);
43ebd79076SLisandro Dalcin   PetscValidPointer(handle,3);
44ebd79076SLisandro Dalcin 
45be1c6ad7SLisandro Dalcin   dlflags1 = 0;
46be1c6ad7SLisandro Dalcin   dlflags2 = 0;
475673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
48be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle) 0;
49ebd79076SLisandro Dalcin 
505673baf8SLisandro Dalcin   /*
515673baf8SLisandro Dalcin      --- LoadLibrary ---
525673baf8SLisandro Dalcin   */
53be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
54be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
55ebd79076SLisandro Dalcin   if (!dlhandle) {
56ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
57ebd79076SLisandro Dalcin     PetscErrorCode ierr;
58ebd79076SLisandro Dalcin     DWORD erc;
59b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
60ebd79076SLisandro Dalcin     erc = GetLastError();
61ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
62ebd79076SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
63ebd79076SLisandro Dalcin     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
64be1c6ad7SLisandro Dalcin 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
65ebd79076SLisandro Dalcin     LocalFree(buff);
66ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
67ebd79076SLisandro Dalcin #else
68be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
69ebd79076SLisandro Dalcin #endif
70ebd79076SLisandro Dalcin   }
715673baf8SLisandro Dalcin 
725673baf8SLisandro Dalcin   /*
735673baf8SLisandro Dalcin      --- dlopen ---
745673baf8SLisandro Dalcin   */
75a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
76ebd79076SLisandro Dalcin   /*
77ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
78ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
79ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
80ebd79076SLisandro Dalcin      with dlopen()
81ebd79076SLisandro Dalcin   */
82be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
83be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
84be1c6ad7SLisandro Dalcin #endif
85ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
865673baf8SLisandro Dalcin   if (flags & PETSC_DL_NOW)
87be1c6ad7SLisandro Dalcin     dlflags1 = RTLD_NOW;
88ebd79076SLisandro Dalcin #endif
89ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
90be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
91ebd79076SLisandro Dalcin #endif
92b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
93b3bb0f5eSLisandro Dalcin   if (flags & PETSC_DL_LOCAL)
94b3bb0f5eSLisandro Dalcin     dlflags2 = RTLD_LOCAL;
95b3bb0f5eSLisandro Dalcin #endif
96be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
97be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
98be1c6ad7SLisandro Dalcin #endif
99be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name,dlflags1|dlflags2);
100ebd79076SLisandro Dalcin   if (!dlhandle) {
101ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
102ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
103ebd79076SLisandro Dalcin #else
104ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
105ebd79076SLisandro Dalcin #endif
106be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n",name,errmsg)
107ebd79076SLisandro Dalcin   }
1085673baf8SLisandro Dalcin 
1095673baf8SLisandro Dalcin   /*
1105673baf8SLisandro Dalcin      --- unimplemented ---
1115673baf8SLisandro Dalcin   */
112ebd79076SLisandro Dalcin #else
113be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
114ebd79076SLisandro Dalcin #endif
115ebd79076SLisandro Dalcin 
116ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
117ebd79076SLisandro Dalcin 
118ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
119ebd79076SLisandro Dalcin }
120ebd79076SLisandro Dalcin 
121ebd79076SLisandro Dalcin 
122ebd79076SLisandro Dalcin #undef __FUNCT__
123ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose"
124ebd79076SLisandro Dalcin /*@C
125ebd79076SLisandro Dalcin    PetscDLClose -
126ebd79076SLisandro Dalcin @*/
127ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle)
128ebd79076SLisandro Dalcin {
129ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
130ebd79076SLisandro Dalcin 
131ebd79076SLisandro Dalcin   PetscFunctionBegin;
132ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
133ebd79076SLisandro Dalcin 
134ebd79076SLisandro Dalcin   dlhandle = (dlhandle_t) *handle;
135ebd79076SLisandro Dalcin 
1365673baf8SLisandro Dalcin   /*
1375673baf8SLisandro Dalcin      --- FreeLibrary ---
1385673baf8SLisandro Dalcin   */
139ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
140be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1415673baf8SLisandro Dalcin   if (FreeLibrary(dlhandle) == 0) {
1425673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
143b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
144a21658a3SLisandro Dalcin     DWORD erc   = GetLastError();
1455673baf8SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
1465673baf8SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
1475673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1485673baf8SLisandro Dalcin     LocalFree(buff);
1495673baf8SLisandro Dalcin #else
1505673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1515673baf8SLisandro Dalcin #endif
1525673baf8SLisandro Dalcin   }
153be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
154ebd79076SLisandro Dalcin 
1555673baf8SLisandro Dalcin   /*
1565673baf8SLisandro Dalcin      --- dclose ---
1575673baf8SLisandro Dalcin   */
158ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
159a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
160be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
161be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
162be1c6ad7SLisandro Dalcin #endif
163ebd79076SLisandro Dalcin   if (dlclose(dlhandle) < 0) {
164ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
165ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
166ebd79076SLisandro Dalcin #else
167ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
168ebd79076SLisandro Dalcin #endif
1695673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
170ebd79076SLisandro Dalcin   }
171a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1725673baf8SLisandro Dalcin 
1735673baf8SLisandro Dalcin   /*
1745673baf8SLisandro Dalcin      --- unimplemented ---
1755673baf8SLisandro Dalcin   */
176ebd79076SLisandro Dalcin #else
177be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
178ebd79076SLisandro Dalcin #endif
179ebd79076SLisandro Dalcin 
180ebd79076SLisandro Dalcin   *handle = PETSC_NULL;
181ebd79076SLisandro Dalcin 
182ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
183ebd79076SLisandro Dalcin }
184ebd79076SLisandro Dalcin 
185ebd79076SLisandro Dalcin 
186ebd79076SLisandro Dalcin #undef __FUNCT__
187ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym"
188ebd79076SLisandro Dalcin /*@C
189ebd79076SLisandro Dalcin    PetscDLSym -
190ebd79076SLisandro Dalcin @*/
1915673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
192ebd79076SLisandro Dalcin {
193ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
194*6ea75d68SLisandro Dalcin   dlsymbol_t dlsymbol;
195ebd79076SLisandro Dalcin 
196ebd79076SLisandro Dalcin   PetscFunctionBegin;
197ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
198ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
199ebd79076SLisandro Dalcin 
200be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
201*6ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) 0;
202*6ea75d68SLisandro Dalcin 
203a21658a3SLisandro Dalcin   *value   = (void *) 0;
204ebd79076SLisandro Dalcin 
2055673baf8SLisandro Dalcin   /*
2065673baf8SLisandro Dalcin      --- GetProcAddress ---
2075673baf8SLisandro Dalcin   */
208a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
209a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
210be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
211be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
212be1c6ad7SLisandro Dalcin   else
213be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) GetCurrentProcess();
214*6ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
215a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
216a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
217a21658a3SLisandro Dalcin #endif
218a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2195673baf8SLisandro Dalcin 
2205673baf8SLisandro Dalcin   /*
2215673baf8SLisandro Dalcin      --- dlsym ---
2225673baf8SLisandro Dalcin   */
223ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
224a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
225be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
226be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
227be1c6ad7SLisandro Dalcin   else
228be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) 0;
229be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
230be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
231be1c6ad7SLisandro Dalcin #endif
232*6ea75d68SLisandro Dalcin   dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
233be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
234b3bb0f5eSLisandro Dalcin   dlerror(); /* clear any previous error */
235be1c6ad7SLisandro Dalcin #endif
236a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLSYM */
2375673baf8SLisandro Dalcin 
2385673baf8SLisandro Dalcin   /*
2395673baf8SLisandro Dalcin      --- unimplemented ---
2405673baf8SLisandro Dalcin   */
241ebd79076SLisandro Dalcin #else
242be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
243ebd79076SLisandro Dalcin #endif
244ebd79076SLisandro Dalcin 
245*6ea75d68SLisandro Dalcin   *value = *((void**)&dlsymbol);
246ebd79076SLisandro Dalcin 
247ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
248ebd79076SLisandro Dalcin }
249