xref: /petsc/src/sys/dll/dlimpl.c (revision 7c4f633dc6bb6149cca88d301ead35a99e103cbb)
1ebd79076SLisandro Dalcin #define PETSC_DLL
2ebd79076SLisandro Dalcin /*
3ebd79076SLisandro Dalcin    Low-level routines for managing dynamic link libraries (DLLs).
4ebd79076SLisandro Dalcin */
5ebd79076SLisandro Dalcin 
6*7c4f633dSBarry 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;
22ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
23ebd79076SLisandro Dalcin typedef void* dlhandle_t;
24ebd79076SLisandro Dalcin #else
25ebd79076SLisandro Dalcin typedef void* dlhandle_t;
26ebd79076SLisandro Dalcin #endif
27ebd79076SLisandro Dalcin 
28ebd79076SLisandro Dalcin #undef __FUNCT__
29ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen"
30ebd79076SLisandro Dalcin /*@C
31ebd79076SLisandro Dalcin    PetscDLOpen -
32ebd79076SLisandro Dalcin @*/
335673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle)
34ebd79076SLisandro Dalcin {
35be1c6ad7SLisandro Dalcin   int        dlflags1,dlflags2;
36ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
37ebd79076SLisandro Dalcin 
38ebd79076SLisandro Dalcin   PetscFunctionBegin;
39ebd79076SLisandro Dalcin   PetscValidCharPointer(name,1);
40ebd79076SLisandro Dalcin   PetscValidPointer(handle,3);
41ebd79076SLisandro Dalcin 
42be1c6ad7SLisandro Dalcin   dlflags1 = 0;
43be1c6ad7SLisandro Dalcin   dlflags2 = 0;
445673baf8SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
45be1c6ad7SLisandro Dalcin   *handle  = (PetscDLHandle) 0;
46ebd79076SLisandro Dalcin 
475673baf8SLisandro Dalcin   /*
485673baf8SLisandro Dalcin      --- LoadLibrary ---
495673baf8SLisandro Dalcin   */
50be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
51be1c6ad7SLisandro Dalcin   dlhandle = LoadLibrary(name);
52ebd79076SLisandro Dalcin   if (!dlhandle) {
53ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
54ebd79076SLisandro Dalcin     PetscErrorCode ierr;
55ebd79076SLisandro Dalcin     DWORD erc;
56b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
57ebd79076SLisandro Dalcin     erc = GetLastError();
58ebd79076SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
59ebd79076SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
60ebd79076SLisandro Dalcin     ierr = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,1,
61be1c6ad7SLisandro Dalcin 		      "Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,buff);
62ebd79076SLisandro Dalcin     LocalFree(buff);
63ebd79076SLisandro Dalcin     PetscFunctionReturn(ierr);
64ebd79076SLisandro Dalcin #else
65be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from LoadLibrary() %s\n",name,"unavailable");
66ebd79076SLisandro Dalcin #endif
67ebd79076SLisandro Dalcin   }
685673baf8SLisandro Dalcin 
695673baf8SLisandro Dalcin   /*
705673baf8SLisandro Dalcin      --- dlopen ---
715673baf8SLisandro Dalcin   */
72a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
73ebd79076SLisandro Dalcin   /*
74ebd79076SLisandro Dalcin       Mode indicates symbols required by symbol loaded with dlsym()
75ebd79076SLisandro Dalcin      are only loaded when required (not all together) also indicates
76ebd79076SLisandro Dalcin      symbols required can be contained in other libraries also opened
77ebd79076SLisandro Dalcin      with dlopen()
78ebd79076SLisandro Dalcin   */
79be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY)
80be1c6ad7SLisandro Dalcin   dlflags1 = RTLD_LAZY;
81be1c6ad7SLisandro Dalcin #endif
82ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW)
835673baf8SLisandro Dalcin   if (flags & PETSC_DL_NOW)
84be1c6ad7SLisandro Dalcin     dlflags1 = RTLD_NOW;
85ebd79076SLisandro Dalcin #endif
86ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL)
87be1c6ad7SLisandro Dalcin   dlflags2 = RTLD_GLOBAL;
88ebd79076SLisandro Dalcin #endif
89b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL)
90b3bb0f5eSLisandro Dalcin   if (flags & PETSC_DL_LOCAL)
91b3bb0f5eSLisandro Dalcin     dlflags2 = RTLD_LOCAL;
92b3bb0f5eSLisandro Dalcin #endif
93be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
94be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
95be1c6ad7SLisandro Dalcin #endif
96be1c6ad7SLisandro Dalcin   dlhandle = dlopen(name,dlflags1|dlflags2);
97ebd79076SLisandro Dalcin   if (!dlhandle) {
98ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
99ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
100ebd79076SLisandro Dalcin #else
101ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
102ebd79076SLisandro Dalcin #endif
103be1c6ad7SLisandro Dalcin     SETERRQ2(PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n  %s\n  Error message from dlopen() %s\n",name,errmsg)
104ebd79076SLisandro Dalcin   }
1055673baf8SLisandro Dalcin 
1065673baf8SLisandro Dalcin   /*
1075673baf8SLisandro Dalcin      --- unimplemented ---
1085673baf8SLisandro Dalcin   */
109ebd79076SLisandro Dalcin #else
110be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
111ebd79076SLisandro Dalcin #endif
112ebd79076SLisandro Dalcin 
113ebd79076SLisandro Dalcin   *handle = (PetscDLHandle) dlhandle;
114ebd79076SLisandro Dalcin 
115ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
116ebd79076SLisandro Dalcin }
117ebd79076SLisandro Dalcin 
118ebd79076SLisandro Dalcin 
119ebd79076SLisandro Dalcin #undef __FUNCT__
120ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose"
121ebd79076SLisandro Dalcin /*@C
122ebd79076SLisandro Dalcin    PetscDLClose -
123ebd79076SLisandro Dalcin @*/
124ebd79076SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLClose(PetscDLHandle *handle)
125ebd79076SLisandro Dalcin {
126ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
127ebd79076SLisandro Dalcin 
128ebd79076SLisandro Dalcin   PetscFunctionBegin;
129ebd79076SLisandro Dalcin   PetscValidPointer(handle,1);
130ebd79076SLisandro Dalcin 
131ebd79076SLisandro Dalcin   dlhandle = (dlhandle_t) *handle;
132ebd79076SLisandro Dalcin 
1335673baf8SLisandro Dalcin   /*
1345673baf8SLisandro Dalcin      --- FreeLibrary ---
1355673baf8SLisandro Dalcin   */
136ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
137be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY)
1385673baf8SLisandro Dalcin   if (FreeLibrary(dlhandle) == 0) {
1395673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR)
140b3bb0f5eSLisandro Dalcin     char  *buff = NULL;
141a21658a3SLisandro Dalcin     DWORD erc   = GetLastError();
1425673baf8SLisandro Dalcin     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
1435673baf8SLisandro Dalcin 		  NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
1445673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n",buff);
1455673baf8SLisandro Dalcin     LocalFree(buff);
1465673baf8SLisandro Dalcin #else
1475673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from FreeLibrary() %s\n","unavailable");
1485673baf8SLisandro Dalcin #endif
1495673baf8SLisandro Dalcin   }
150be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */
151ebd79076SLisandro Dalcin 
1525673baf8SLisandro Dalcin   /*
1535673baf8SLisandro Dalcin      --- dclose ---
1545673baf8SLisandro Dalcin   */
155ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
156a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE)
157be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
158be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
159be1c6ad7SLisandro Dalcin #endif
160ebd79076SLisandro Dalcin   if (dlclose(dlhandle) < 0) {
161ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
162ebd79076SLisandro Dalcin     const char *errmsg = dlerror();
163ebd79076SLisandro Dalcin #else
164ebd79076SLisandro Dalcin     const char *errmsg = "unavailable";
165ebd79076SLisandro Dalcin #endif
1665673baf8SLisandro Dalcin     PetscErrorPrintf("Error closing dynamic library:\n  Error message from dlclose() %s\n", errmsg);
167ebd79076SLisandro Dalcin   }
168a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */
1695673baf8SLisandro Dalcin 
1705673baf8SLisandro Dalcin   /*
1715673baf8SLisandro Dalcin      --- unimplemented ---
1725673baf8SLisandro Dalcin   */
173ebd79076SLisandro Dalcin #else
174be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
175ebd79076SLisandro Dalcin #endif
176ebd79076SLisandro Dalcin 
177ebd79076SLisandro Dalcin   *handle = PETSC_NULL;
178ebd79076SLisandro Dalcin 
179ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
180ebd79076SLisandro Dalcin }
181ebd79076SLisandro Dalcin 
182ebd79076SLisandro Dalcin 
183ebd79076SLisandro Dalcin #undef __FUNCT__
184ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym"
185ebd79076SLisandro Dalcin /*@C
186ebd79076SLisandro Dalcin    PetscDLSym -
187ebd79076SLisandro Dalcin @*/
1885673baf8SLisandro Dalcin PetscErrorCode PETSC_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
189ebd79076SLisandro Dalcin {
190ebd79076SLisandro Dalcin   dlhandle_t dlhandle;
191ebd79076SLisandro Dalcin   void       *dlvalue;
192ebd79076SLisandro Dalcin 
193ebd79076SLisandro Dalcin   PetscFunctionBegin;
194ebd79076SLisandro Dalcin   PetscValidCharPointer(symbol,2);
195ebd79076SLisandro Dalcin   PetscValidPointer(value,3);
196ebd79076SLisandro Dalcin 
197be1c6ad7SLisandro Dalcin   dlhandle = (dlhandle_t) 0;
198a21658a3SLisandro Dalcin   dlvalue  = (void *) 0;
199a21658a3SLisandro Dalcin   *value   = (void *) 0;
200ebd79076SLisandro Dalcin 
2015673baf8SLisandro Dalcin   /*
2025673baf8SLisandro Dalcin      --- GetProcAddress ---
2035673baf8SLisandro Dalcin   */
204a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H)
205a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS)
206be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
207be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
208be1c6ad7SLisandro Dalcin   else
209be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) GetCurrentProcess();
210ebd79076SLisandro Dalcin   dlvalue = GetProcAddress(dlhandle,symbol);
211a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR)
212a21658a3SLisandro Dalcin   SetLastError((DWORD)0); /* clear any previous error */
213a21658a3SLisandro Dalcin #endif
214a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */
2155673baf8SLisandro Dalcin 
2165673baf8SLisandro Dalcin   /*
2175673baf8SLisandro Dalcin      --- dlsym ---
2185673baf8SLisandro Dalcin   */
219ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H)
220a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM)
221be1c6ad7SLisandro Dalcin   if (handle != PETSC_NULL)
222be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) handle;
223be1c6ad7SLisandro Dalcin   else
224be1c6ad7SLisandro Dalcin     dlhandle = (dlhandle_t) 0;
225be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
226be1c6ad7SLisandro Dalcin   dlerror(); /* clear any previous error */
227be1c6ad7SLisandro Dalcin #endif
228ebd79076SLisandro Dalcin   dlvalue = dlsym(dlhandle,symbol);
229be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR)
230b3bb0f5eSLisandro Dalcin   dlerror(); /* clear any previous error */
231be1c6ad7SLisandro Dalcin #endif
232a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLSYM */
2335673baf8SLisandro Dalcin 
2345673baf8SLisandro Dalcin   /*
2355673baf8SLisandro Dalcin      --- unimplemented ---
2365673baf8SLisandro Dalcin   */
237ebd79076SLisandro Dalcin #else
238be1c6ad7SLisandro Dalcin   SETERRQ(PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
239ebd79076SLisandro Dalcin #endif
240ebd79076SLisandro Dalcin 
241ebd79076SLisandro Dalcin   *value = dlvalue;
242ebd79076SLisandro Dalcin 
243ebd79076SLisandro Dalcin   PetscFunctionReturn(0);
244ebd79076SLisandro Dalcin }
245