Actual source code: dlimpl.c
petsc-3.5.4 2015-05-23
2: /*
3: Low-level routines for managing dynamic link libraries (DLLs).
4: */
6: #include <petsc-private/petscimpl.h>
8: /* XXX Should be done better !!!*/
9: #if !defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
10: #undef PETSC_HAVE_WINDOWS_H
11: #undef PETSC_HAVE_DLFCN_H
12: #endif
14: #if defined(PETSC_HAVE_WINDOWS_H)
15: #include <windows.h>
16: #elif defined(PETSC_HAVE_DLFCN_H)
17: #include <dlfcn.h>
18: #endif
20: #if defined(PETSC_HAVE_WINDOWS_H)
21: typedef HMODULE dlhandle_t;
22: typedef FARPROC dlsymbol_t;
23: #elif defined(PETSC_HAVE_DLFCN_H)
24: typedef void* dlhandle_t;
25: typedef void* dlsymbol_t;
26: #else
27: typedef void* dlhandle_t;
28: typedef void* dlsymbol_t;
29: #endif
33: /*@C
34: PetscDLOpen - opens dynamic library
36: Not Collective
38: Input Parameters:
39: + name - name of library
40: - mode - options on how to open library
42: Output Parameter:
43: . handle
45: Level: developer
47: @*/
48: PetscErrorCode PetscDLOpen(const char name[],PetscDLMode mode,PetscDLHandle *handle)
49: {
50: PETSC_UNUSED int dlflags1,dlflags2; /* There are some preprocessor paths where these variables are set, but not used */
51: dlhandle_t dlhandle;
57: dlflags1 = 0;
58: dlflags2 = 0;
59: dlhandle = (dlhandle_t) 0;
60: *handle = (PetscDLHandle) 0;
62: /*
63: --- LoadLibrary ---
64: */
65: #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY)
66: dlhandle = LoadLibrary(name);
67: if (!dlhandle) {
68: #if defined(PETSC_HAVE_GETLASTERROR)
70: DWORD erc;
71: char *buff = NULL;
72: erc = GetLastError();
73: FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
74: NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
75: PetscError(PETSC_COMM_SELF,__LINE__,__FUNCT__,__FILE__,PETSC_ERR_FILE_OPEN,PETSC_ERROR_REPEAT,
76: "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff);
77: LocalFree(buff);
78: PetscFunctionReturn(ierr);
79: #else
80: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable");
81: #endif
82: }
84: /*
85: --- dlopen ---
86: */
87: #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN)
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: #if defined(PETSC_HAVE_RTLD_LAZY)
95: dlflags1 = RTLD_LAZY;
96: #endif
97: #if defined(PETSC_HAVE_RTLD_NOW)
98: if (mode & PETSC_DL_NOW) dlflags1 = RTLD_NOW;
99: #endif
100: #if defined(PETSC_HAVE_RTLD_GLOBAL)
101: dlflags2 = RTLD_GLOBAL;
102: #endif
103: #if defined(PETSC_HAVE_RTLD_LOCAL)
104: if (mode & PETSC_DL_LOCAL) dlflags2 = RTLD_LOCAL;
105: #endif
106: #if defined(PETSC_HAVE_DLERROR)
107: dlerror(); /* clear any previous error */
108: #endif
109: dlhandle = dlopen(name,dlflags1|dlflags2);
110: if (!dlhandle) {
111: #if defined(PETSC_HAVE_DLERROR)
112: const char *errmsg = dlerror();
113: #else
114: const char *errmsg = "unavailable";
115: #endif
116: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg);
117: }
119: /*
120: --- unimplemented ---
121: */
122: #else
123: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
124: #endif
126: *handle = (PetscDLHandle) dlhandle;
127: return(0);
128: }
133: /*@C
134: PetscDLClose - closes a dynamic library
136: Not Collective
138: Input Parameter:
139: . handle - the handle for the library obtained with PetscDLOpen()
141: Level: developer
142: @*/
143: PetscErrorCode PetscDLClose(PetscDLHandle *handle)
144: {
149: /*
150: --- FreeLibrary ---
151: */
152: #if defined(PETSC_HAVE_WINDOWS_H)
153: #if defined(PETSC_HAVE_FREELIBRARY)
154: if (FreeLibrary((dlhandle_t)*handle) == 0) {
155: #if defined(PETSC_HAVE_GETLASTERROR)
156: char *buff = NULL;
157: DWORD erc = GetLastError();
158: FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
159: PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff);
160: LocalFree(buff);
161: #else
162: PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable");
163: #endif
164: }
165: #endif /* !PETSC_HAVE_FREELIBRARY */
167: /*
168: --- dclose ---
169: */
170: #elif defined(PETSC_HAVE_DLFCN_H)
171: #if defined(PETSC_HAVE_DLCLOSE)
172: #if defined(PETSC_HAVE_DLERROR)
173: dlerror(); /* clear any previous error */
174: #endif
175: if (dlclose((dlhandle_t)*handle) < 0) {
176: #if defined(PETSC_HAVE_DLERROR)
177: const char *errmsg = dlerror();
178: #else
179: const char *errmsg = "unavailable";
180: #endif
181: PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg);
182: }
183: #endif /* !PETSC_HAVE_DLCLOSE */
185: /*
186: --- unimplemented ---
187: */
188: #else
189: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
190: #endif
192: *handle = NULL;
193: return(0);
194: }
198: /*@C
199: PetscDLSym - finds a symbol in a dynamic library
201: Not Collective
203: Input Parameters:
204: + handle - obtained with PetscDLOpen() or NULL
205: - symbol - name of symbol
207: Output Parameter:
208: . value - pointer to the function, NULL if not found
210: Level: developer
212: Notes:
213: If handle is NULL, the symbol is looked for in the main executable's dynamic symbol table.
214: In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like
215: systems this requires platform-specific linker flags.
217: @*/
218: PetscErrorCode PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
219: {
220: PETSC_UNUSED dlhandle_t dlhandle;
221: dlsymbol_t dlsymbol;
226: dlhandle = (dlhandle_t) 0;
227: dlsymbol = (dlsymbol_t) 0;
228: *value = (void*) 0;
230: /*
231: --- GetProcAddress ---
232: */
233: #if defined(PETSC_HAVE_WINDOWS_H)
234: #if defined(PETSC_HAVE_GETPROCADDRESS)
235: if (handle) dlhandle = (dlhandle_t) handle;
236: else dlhandle = (dlhandle_t) GetCurrentProcess();
237: dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
238: #if defined(PETSC_HAVE_SETLASTERROR)
239: SetLastError((DWORD)0); /* clear any previous error */
240: #endif
241: #endif /* !PETSC_HAVE_GETPROCADDRESS */
243: /*
244: --- dlsym ---
245: */
246: #elif defined(PETSC_HAVE_DLFCN_H)
247: #if defined(PETSC_HAVE_DLSYM)
248: if (handle) dlhandle = (dlhandle_t) handle;
249: else {
251: #if defined(PETSC_HAVE_DLOPEN) && defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
252: /* Attempt to retrieve the main executable's dlhandle. */
253: { int dlflags1 = 0, dlflags2 = 0;
254: #if defined(PETSC_HAVE_RTLD_LAZY)
255: dlflags1 = RTLD_LAZY;
256: #endif
257: if (!dlflags1) {
258: #if defined(PETSC_HAVE_RTLD_NOW)
259: dlflags1 = RTLD_NOW;
260: #endif
261: }
262: #if defined(PETSC_HAVE_RTLD_LOCAL)
263: dlflags2 = RTLD_LOCAL;
264: #endif
265: if (!dlflags2) {
266: #if defined(PETSC_HAVE_RTLD_GLOBAL)
267: dlflags2 = RTLD_GLOBAL;
268: #endif
269: }
270: #if defined(PETSC_HAVE_DLERROR)
271: if (!(PETSC_RUNNING_ON_VALGRIND)) {
272: dlerror(); /* clear any previous error; valgrind does not like this */
273: }
274: #endif
275: /* Attempt to open the main executable as a dynamic library. */
276: #if defined(PETSC_HAVE_RTDL_DEFAULT)
277: dlhandle = RTLD_DEFAULT;
278: #else
279: dlhandle = dlopen(0, dlflags1|dlflags2);
280: #if defined(PETSC_HAVE_DLERROR)
281: { const char *e = (const char*) dlerror();
282: if (e) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library:\n Error message from dlopen(): '%s'\n", e);
283: }
284: #endif
285: #endif
286: }
287: #endif
288: #endif /* PETSC_HAVE_DLOPEN && PETSC_HAVE_DYNAMIC_LIBRARIES */
289: }
290: #if defined(PETSC_HAVE_DLERROR)
291: dlerror(); /* clear any previous error */
292: #endif
293: dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
294: /*
295: --- unimplemented ---
296: */
297: #else
298: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
299: #endif
301: *value = *((void**)&dlsymbol);
303: #if defined(PETSC_SERIALIZE_FUNCTIONS)
304: if (*value) {
306: PetscFPTAdd(*value,symbol);
307: }
308: #endif
309: return(0);
310: }