Actual source code: dlimpl.c
petsc-3.3-p7 2013-05-11
2: /*
3: Low-level routines for managing dynamic link libraries (DLLs).
4: */
6: #include <../src/sys/dll/dlimpl.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: - flags - options on how to open library
42: Output Parameter:
43: . handle
45: Level: developer
47: @*/
48: PetscErrorCode PetscDLOpen(const char name[],int flags,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__,__SDIR__,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 (flags & PETSC_DL_NOW)
99: dlflags1 = RTLD_NOW;
100: #endif
101: #if defined(PETSC_HAVE_RTLD_GLOBAL)
102: dlflags2 = RTLD_GLOBAL;
103: #endif
104: #if defined(PETSC_HAVE_RTLD_LOCAL)
105: if (flags & PETSC_DL_LOCAL)
106: dlflags2 = RTLD_LOCAL;
107: #endif
108: #if defined(PETSC_HAVE_DLERROR)
109: dlerror(); /* clear any previous error */
110: #endif
111: dlhandle = dlopen(name,dlflags1|dlflags2);
112: if (!dlhandle) {
113: #if defined(PETSC_HAVE_DLERROR)
114: const char *errmsg = dlerror();
115: #else
116: const char *errmsg = "unavailable";
117: #endif
118: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg);
119: }
121: /*
122: --- unimplemented ---
123: */
124: #else
125: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
126: #endif
128: *handle = (PetscDLHandle) dlhandle;
130: return(0);
131: }
136: /*@C
137: PetscDLClose - closes a dynamic library
139: Not Collective
141: Input Parameter:
142: . handle - the handle for the library obtained with PetscDLOpen()
144: Level: developer
145: @*/
146: PetscErrorCode PetscDLClose(PetscDLHandle *handle)
147: {
152: /*
153: --- FreeLibrary ---
154: */
155: #if defined(PETSC_HAVE_WINDOWS_H)
156: #if defined(PETSC_HAVE_FREELIBRARY)
157: if (FreeLibrary((dlhandle_t)*handle) == 0) {
158: #if defined(PETSC_HAVE_GETLASTERROR)
159: char *buff = NULL;
160: DWORD erc = GetLastError();
161: FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
162: NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL);
163: PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff);
164: LocalFree(buff);
165: #else
166: PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable");
167: #endif
168: }
169: #endif /* !PETSC_HAVE_FREELIBRARY */
171: /*
172: --- dclose ---
173: */
174: #elif defined(PETSC_HAVE_DLFCN_H)
175: #if defined(PETSC_HAVE_DLCLOSE)
176: #if defined(PETSC_HAVE_DLERROR)
177: dlerror(); /* clear any previous error */
178: #endif
179: if (dlclose((dlhandle_t)*handle) < 0) {
180: #if defined(PETSC_HAVE_DLERROR)
181: const char *errmsg = dlerror();
182: #else
183: const char *errmsg = "unavailable";
184: #endif
185: PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg);
186: }
187: #endif /* !PETSC_HAVE_DLCLOSE */
189: /*
190: --- unimplemented ---
191: */
192: #else
193: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
194: #endif
196: *handle = PETSC_NULL;
198: return(0);
199: }
201: #if defined(PETSC_HAVE_VALGRIND)
202: #include <valgrind/valgrind.h>
203: #endif
207: /*@C
208: PetscDLSym - finds a symbol in a dynamic library
210: Not Collective
212: Input Parameters:
213: + handle - obtained with PetscDLOpen() or PETSC_NULL
214: - symbol - name of symbol
216: Output Parameter:
217: . value - pointer to the function
219: Level: developer
221: Notes:
222: If handle is PETSC_NULL, the symbol is looked for in the main executable's dynamic symbol table.
223: In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like
224: systems this requires platform-specific linker flags.
226: @*/
227: PetscErrorCode PetscDLSym(PetscDLHandle handle,const char symbol[],void **value)
228: {
229: PETSC_UNUSED dlhandle_t dlhandle;
230: dlsymbol_t dlsymbol;
236: dlhandle = (dlhandle_t) 0;
237: dlsymbol = (dlsymbol_t) 0;
239: *value = (void *) 0;
241: /*
242: --- GetProcAddress ---
243: */
244: #if defined(PETSC_HAVE_WINDOWS_H)
245: #if defined(PETSC_HAVE_GETPROCADDRESS)
246: if (handle)
247: dlhandle = (dlhandle_t) handle;
248: else
249: dlhandle = (dlhandle_t) GetCurrentProcess();
250: dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol);
251: #if defined(PETSC_HAVE_SETLASTERROR)
252: SetLastError((DWORD)0); /* clear any previous error */
253: #endif
254: #endif /* !PETSC_HAVE_GETPROCADDRESS */
256: /*
257: --- dlsym ---
258: */
259: #elif defined(PETSC_HAVE_DLFCN_H)
260: #if defined(PETSC_HAVE_DLSYM)
261: if (handle) {
262: dlhandle = (dlhandle_t) handle;
263: } else {
265:
266: #if defined(PETSC_HAVE_DLOPEN) && defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
267: /* Attempt to retrieve the main executable's dlhandle. */
268: { int dlflags1 = 0, dlflags2 = 0;
269: #if defined(PETSC_HAVE_RTLD_LAZY)
270: dlflags1 = RTLD_LAZY;
271: #endif
272: if (!dlflags1) {
273: #if defined(PETSC_HAVE_RTLD_NOW)
274: dlflags1 = RTLD_NOW;
275: #endif
276: }
277: #if defined(PETSC_HAVE_RTLD_LOCAL)
278: dlflags2 = RTLD_LOCAL;
279: #endif
280: if(!dlflags2) {
281: #if defined(PETSC_HAVE_RTLD_GLOBAL)
282: dlflags2 = RTLD_GLOBAL;
283: #endif
284: }
285: #if defined(PETSC_HAVE_DLERROR)
286: #if defined(PETSC_HAVE_VALGRIND)
287: if (!(RUNNING_ON_VALGRIND)) {
288: #endif
289: dlerror(); /* clear any previous error; valgrind does not like this */
290: #if defined(PETSC_HAVE_VALGRIND)
291: }
292: #endif
293: #endif
294: /* Attempt to open the main executable as a dynamic library. */
295: #if defined(PETSC_HAVE_RTDL_DEFAULT)
296: dlhandle = RTLD_DEFAULT;
297: #else
298: dlhandle = dlopen(0, dlflags1|dlflags2);
299: #if defined(PETSC_HAVE_DLERROR)
300: { const char *e = (const char*) dlerror();
301: 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);
302: }
303: #endif
304: #endif
305: }
306: #endif
307: #endif /* PETSC_HAVE_DLOPEN && PETSC_USE_DYNAMIC_LIBRARIES */
308: }
309: #if defined(PETSC_HAVE_DLERROR)
310: dlerror(); /* clear any previous error */
311: #endif
312: dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol);
313: /*
314: --- unimplemented ---
315: */
316: #else
317: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform");
318: #endif
320: *value = *((void**)&dlsymbol);
322: return(0);
323: }