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; 226ea75d68SLisandro Dalcin typedef FARPROC dlsymbol_t; 23ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 24ebd79076SLisandro Dalcin typedef void* dlhandle_t; 256ea75d68SLisandro Dalcin typedef void* dlsymbol_t; 26ebd79076SLisandro Dalcin #else 27ebd79076SLisandro Dalcin typedef void* dlhandle_t; 286ea75d68SLisandro Dalcin typedef void* dlsymbol_t; 29ebd79076SLisandro Dalcin #endif 30ebd79076SLisandro Dalcin 31ebd79076SLisandro Dalcin #undef __FUNCT__ 32ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLOpen" 33ebd79076SLisandro Dalcin /*@C 34b235ab32SBarry Smith PetscDLOpen - opens dynamic library 35b235ab32SBarry Smith 36b235ab32SBarry Smith Not Collective 37b235ab32SBarry Smith 38b235ab32SBarry Smith Input Parameters: 39b235ab32SBarry Smith + name - name of library 40b235ab32SBarry Smith - flags - options on how to open library 41b235ab32SBarry Smith 42b235ab32SBarry Smith Output Parameter: 43b235ab32SBarry Smith . handle 44b235ab32SBarry Smith 45b235ab32SBarry Smith Level: developer 46b235ab32SBarry Smith 47ebd79076SLisandro Dalcin @*/ 488738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscDLOpen(const char name[],int flags,PetscDLHandle *handle) 49ebd79076SLisandro Dalcin { 50be1c6ad7SLisandro Dalcin int dlflags1,dlflags2; 51ebd79076SLisandro Dalcin dlhandle_t dlhandle; 52ebd79076SLisandro Dalcin 53ebd79076SLisandro Dalcin PetscFunctionBegin; 54ebd79076SLisandro Dalcin PetscValidCharPointer(name,1); 55ebd79076SLisandro Dalcin PetscValidPointer(handle,3); 56ebd79076SLisandro Dalcin 57be1c6ad7SLisandro Dalcin dlflags1 = 0; 58be1c6ad7SLisandro Dalcin dlflags2 = 0; 595673baf8SLisandro Dalcin dlhandle = (dlhandle_t) 0; 60be1c6ad7SLisandro Dalcin *handle = (PetscDLHandle) 0; 61ebd79076SLisandro Dalcin 625673baf8SLisandro Dalcin /* 635673baf8SLisandro Dalcin --- LoadLibrary --- 645673baf8SLisandro Dalcin */ 65be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) && defined(PETSC_HAVE_LOADLIBRARY) 66be1c6ad7SLisandro Dalcin dlhandle = LoadLibrary(name); 67ebd79076SLisandro Dalcin if (!dlhandle) { 68ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 69ebd79076SLisandro Dalcin PetscErrorCode ierr; 70ebd79076SLisandro Dalcin DWORD erc; 71b3bb0f5eSLisandro Dalcin char *buff = NULL; 72ebd79076SLisandro Dalcin erc = GetLastError(); 73ebd79076SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 74ebd79076SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 7530b327c4SMatthew G Knepley ierr = PetscError(PETSC_COMM_SELF,__LINE__,__FUNCT__,__FILE__,__SDIR__,PETSC_ERR_FILE_OPEN,PETSC_ERROR_REPEAT, 76be1c6ad7SLisandro Dalcin "Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,buff); 77ebd79076SLisandro Dalcin LocalFree(buff); 78ebd79076SLisandro Dalcin PetscFunctionReturn(ierr); 79ebd79076SLisandro Dalcin #else 80e32f2f54SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from LoadLibrary() %s\n",name,"unavailable"); 81ebd79076SLisandro Dalcin #endif 82ebd79076SLisandro Dalcin } 835673baf8SLisandro Dalcin 845673baf8SLisandro Dalcin /* 855673baf8SLisandro Dalcin --- dlopen --- 865673baf8SLisandro Dalcin */ 87a21658a3SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) && defined(PETSC_HAVE_DLOPEN) 88ebd79076SLisandro Dalcin /* 89ebd79076SLisandro Dalcin Mode indicates symbols required by symbol loaded with dlsym() 90ebd79076SLisandro Dalcin are only loaded when required (not all together) also indicates 91ebd79076SLisandro Dalcin symbols required can be contained in other libraries also opened 92ebd79076SLisandro Dalcin with dlopen() 93ebd79076SLisandro Dalcin */ 94be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LAZY) 95be1c6ad7SLisandro Dalcin dlflags1 = RTLD_LAZY; 96be1c6ad7SLisandro Dalcin #endif 97ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_NOW) 985673baf8SLisandro Dalcin if (flags & PETSC_DL_NOW) 99be1c6ad7SLisandro Dalcin dlflags1 = RTLD_NOW; 100ebd79076SLisandro Dalcin #endif 101ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_RTLD_GLOBAL) 102be1c6ad7SLisandro Dalcin dlflags2 = RTLD_GLOBAL; 103ebd79076SLisandro Dalcin #endif 104b3bb0f5eSLisandro Dalcin #if defined(PETSC_HAVE_RTLD_LOCAL) 105b3bb0f5eSLisandro Dalcin if (flags & PETSC_DL_LOCAL) 106b3bb0f5eSLisandro Dalcin dlflags2 = RTLD_LOCAL; 107b3bb0f5eSLisandro Dalcin #endif 108be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 109be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 110be1c6ad7SLisandro Dalcin #endif 111be1c6ad7SLisandro Dalcin dlhandle = dlopen(name,dlflags1|dlflags2); 112ebd79076SLisandro Dalcin if (!dlhandle) { 113ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 114ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 115ebd79076SLisandro Dalcin #else 116ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 117ebd79076SLisandro Dalcin #endif 118be015529SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open dynamic library:\n %s\n Error message from dlopen() %s\n",name,errmsg); 119ebd79076SLisandro Dalcin } 1205673baf8SLisandro Dalcin 1215673baf8SLisandro Dalcin /* 1225673baf8SLisandro Dalcin --- unimplemented --- 1235673baf8SLisandro Dalcin */ 124ebd79076SLisandro Dalcin #else 125e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 126ebd79076SLisandro Dalcin #endif 127ebd79076SLisandro Dalcin 128ebd79076SLisandro Dalcin *handle = (PetscDLHandle) dlhandle; 129ebd79076SLisandro Dalcin 130ebd79076SLisandro Dalcin PetscFunctionReturn(0); 131ebd79076SLisandro Dalcin } 132ebd79076SLisandro Dalcin 133ebd79076SLisandro Dalcin 134ebd79076SLisandro Dalcin #undef __FUNCT__ 135ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLClose" 136ebd79076SLisandro Dalcin /*@C 137b235ab32SBarry Smith PetscDLClose - closes a dynamic library 138b235ab32SBarry Smith 139b235ab32SBarry Smith Not Collective 140b235ab32SBarry Smith 141b235ab32SBarry Smith Input Parameter: 142b235ab32SBarry Smith . handle - the handle for the library obtained with PetscDLOpen() 143b235ab32SBarry Smith 144b235ab32SBarry Smith Level: developer 145ebd79076SLisandro Dalcin @*/ 1468738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscDLClose(PetscDLHandle *handle) 147ebd79076SLisandro Dalcin { 148ebd79076SLisandro Dalcin dlhandle_t dlhandle; 149ebd79076SLisandro Dalcin 150ebd79076SLisandro Dalcin PetscFunctionBegin; 151ebd79076SLisandro Dalcin PetscValidPointer(handle,1); 152ebd79076SLisandro Dalcin 153ebd79076SLisandro Dalcin dlhandle = (dlhandle_t) *handle; 154ebd79076SLisandro Dalcin 1555673baf8SLisandro Dalcin /* 1565673baf8SLisandro Dalcin --- FreeLibrary --- 1575673baf8SLisandro Dalcin */ 158ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 159be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_FREELIBRARY) 1605673baf8SLisandro Dalcin if (FreeLibrary(dlhandle) == 0) { 1615673baf8SLisandro Dalcin #if defined(PETSC_HAVE_GETLASTERROR) 162b3bb0f5eSLisandro Dalcin char *buff = NULL; 163a21658a3SLisandro Dalcin DWORD erc = GetLastError(); 1645673baf8SLisandro Dalcin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 1655673baf8SLisandro Dalcin NULL,erc,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPSTR)&buff,0,NULL); 1665673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n",buff); 1675673baf8SLisandro Dalcin LocalFree(buff); 1685673baf8SLisandro Dalcin #else 1695673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from FreeLibrary() %s\n","unavailable"); 1705673baf8SLisandro Dalcin #endif 1715673baf8SLisandro Dalcin } 172be1c6ad7SLisandro Dalcin #endif /* !PETSC_HAVE_FREELIBRARY */ 173ebd79076SLisandro Dalcin 1745673baf8SLisandro Dalcin /* 1755673baf8SLisandro Dalcin --- dclose --- 1765673baf8SLisandro Dalcin */ 177ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 178a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLCLOSE) 179be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 180be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 181be1c6ad7SLisandro Dalcin #endif 182ebd79076SLisandro Dalcin if (dlclose(dlhandle) < 0) { 183ebd79076SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 184ebd79076SLisandro Dalcin const char *errmsg = dlerror(); 185ebd79076SLisandro Dalcin #else 186ebd79076SLisandro Dalcin const char *errmsg = "unavailable"; 187ebd79076SLisandro Dalcin #endif 1885673baf8SLisandro Dalcin PetscErrorPrintf("Error closing dynamic library:\n Error message from dlclose() %s\n", errmsg); 189ebd79076SLisandro Dalcin } 190a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLCLOSE */ 1915673baf8SLisandro Dalcin 1925673baf8SLisandro Dalcin /* 1935673baf8SLisandro Dalcin --- unimplemented --- 1945673baf8SLisandro Dalcin */ 195ebd79076SLisandro Dalcin #else 196e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 197ebd79076SLisandro Dalcin #endif 198ebd79076SLisandro Dalcin 199ebd79076SLisandro Dalcin *handle = PETSC_NULL; 200ebd79076SLisandro Dalcin 201ebd79076SLisandro Dalcin PetscFunctionReturn(0); 202ebd79076SLisandro Dalcin } 203ebd79076SLisandro Dalcin 204ebd79076SLisandro Dalcin 205ebd79076SLisandro Dalcin #undef __FUNCT__ 206ebd79076SLisandro Dalcin #define __FUNCT__ "PetscDLSym" 207ebd79076SLisandro Dalcin /*@C 208b235ab32SBarry Smith PetscDLSym - finds a symbol in a dynamic library 209b235ab32SBarry Smith 210b235ab32SBarry Smith Not Collective 211b235ab32SBarry Smith 212b235ab32SBarry Smith Input Parameters: 2137c62f5d3SDmitry Karpeev + handle - obtained with PetscDLOpen() or PETSC_NULL 214b235ab32SBarry Smith - symbol - name of symbol 215b235ab32SBarry Smith 216b235ab32SBarry Smith Output Parameter: 217b235ab32SBarry Smith . value - pointer to the function 218b235ab32SBarry Smith 219b235ab32SBarry Smith Level: developer 220b235ab32SBarry Smith 2217c62f5d3SDmitry Karpeev Notes: 2227c62f5d3SDmitry Karpeev If handle is PETSC_NULL, the symbol is looked for in the main executable's dynamic symbol table. 2237c62f5d3SDmitry Karpeev In order to be dynamically loadable, the symbol has to be exported as such. On many UNIX-like 2247c62f5d3SDmitry Karpeev systems this requires platform-specific linker flags. 2257c62f5d3SDmitry Karpeev 226ebd79076SLisandro Dalcin @*/ 2278738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscDLSym(PetscDLHandle handle,const char symbol[],void **value) 228ebd79076SLisandro Dalcin { 229ebd79076SLisandro Dalcin dlhandle_t dlhandle; 2306ea75d68SLisandro Dalcin dlsymbol_t dlsymbol; 231ebd79076SLisandro Dalcin 232ebd79076SLisandro Dalcin PetscFunctionBegin; 233ebd79076SLisandro Dalcin PetscValidCharPointer(symbol,2); 234ebd79076SLisandro Dalcin PetscValidPointer(value,3); 235ebd79076SLisandro Dalcin 236be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 2376ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) 0; 2386ea75d68SLisandro Dalcin 239a21658a3SLisandro Dalcin *value = (void *) 0; 240ebd79076SLisandro Dalcin 2415673baf8SLisandro Dalcin /* 2425673baf8SLisandro Dalcin --- GetProcAddress --- 2435673baf8SLisandro Dalcin */ 244a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_WINDOWS_H) 245a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_GETPROCADDRESS) 246be1c6ad7SLisandro Dalcin if (handle != PETSC_NULL) 247be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 248be1c6ad7SLisandro Dalcin else 249be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) GetCurrentProcess(); 2506ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) GetProcAddress(dlhandle,symbol); 251a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_SETLASTERROR) 252a21658a3SLisandro Dalcin SetLastError((DWORD)0); /* clear any previous error */ 253a21658a3SLisandro Dalcin #endif 254a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_GETPROCADDRESS */ 2555673baf8SLisandro Dalcin 2565673baf8SLisandro Dalcin /* 2575673baf8SLisandro Dalcin --- dlsym --- 2585673baf8SLisandro Dalcin */ 259ebd79076SLisandro Dalcin #elif defined(PETSC_HAVE_DLFCN_H) 260a21658a3SLisandro Dalcin #if defined(PETSC_HAVE_DLSYM) 2617c62f5d3SDmitry Karpeev if (handle != PETSC_NULL) { 262be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) handle; 2637c62f5d3SDmitry Karpeev } 2647c62f5d3SDmitry Karpeev else { 265be1c6ad7SLisandro Dalcin dlhandle = (dlhandle_t) 0; 2667c62f5d3SDmitry Karpeev 2677c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLOPEN) 2687c62f5d3SDmitry Karpeev /* Attempt to retrieve the main executable's dlhandle. */ 2697c62f5d3SDmitry Karpeev { int dlflags1 = 0, dlflags2 = 0; 2707c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LAZY) 2717c62f5d3SDmitry Karpeev dlflags1 = RTLD_LAZY; 2727c62f5d3SDmitry Karpeev #endif 2737c62f5d3SDmitry Karpeev if(!dlflags1) { 2747c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_NOW) 2757c62f5d3SDmitry Karpeev dlflags1 = RTLD_NOW; 2767c62f5d3SDmitry Karpeev #endif 2777c62f5d3SDmitry Karpeev } 2787c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_LOCAL) 2797c62f5d3SDmitry Karpeev dlflags2 = RTLD_LOCAL; 2807c62f5d3SDmitry Karpeev #endif 2817c62f5d3SDmitry Karpeev if(!dlflags2) { 2827c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_RTLD_GLOBAL) 2837c62f5d3SDmitry Karpeev dlflags2 = RTLD_GLOBAL; 2847c62f5d3SDmitry Karpeev #endif 2857c62f5d3SDmitry Karpeev } 2867c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 2877c62f5d3SDmitry Karpeev dlerror(); /* clear any previous error */ 2887c62f5d3SDmitry Karpeev #endif 2897c62f5d3SDmitry Karpeev /* Attempt to open the main executable as a dynamic library. */ 2907c62f5d3SDmitry Karpeev dlhandle = dlopen(0, dlflags1|dlflags2); 2917c62f5d3SDmitry Karpeev } 2927c62f5d3SDmitry Karpeev #if defined(PETSC_HAVE_DLERROR) 293*4956914eSSatish Balay { const char *e = (const char*) dlerror(); 2947c62f5d3SDmitry Karpeev if(e){ 2957c62f5d3SDmitry Karpeev SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error opening main executable as a dynamic library:\n Error message from dlopen(): '%s'\n", e); 2967c62f5d3SDmitry Karpeev } 2977c62f5d3SDmitry Karpeev } 2987c62f5d3SDmitry Karpeev #endif 299*4956914eSSatish Balay #endif /* PETSC_HAVE_DLOPEN */ 300*4956914eSSatish Balay } 301be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 302be1c6ad7SLisandro Dalcin dlerror(); /* clear any previous error */ 303be1c6ad7SLisandro Dalcin #endif 3046ea75d68SLisandro Dalcin dlsymbol = (dlsymbol_t) dlsym(dlhandle,symbol); 305be1c6ad7SLisandro Dalcin #if defined(PETSC_HAVE_DLERROR) 3067c62f5d3SDmitry Karpeev /* e = dlerror(); */ 3077c62f5d3SDmitry Karpeev /* if(e){ */ 3087c62f5d3SDmitry Karpeev /* SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Error obtaining symbol '%s' from dynamic library:\n Error message from dlsym(): '%s'\n", symbol, e); */ 3097c62f5d3SDmitry Karpeev /* } */ 310be1c6ad7SLisandro Dalcin #endif 311a21658a3SLisandro Dalcin #endif /* !PETSC_HAVE_DLSYM */ 3125673baf8SLisandro Dalcin 3135673baf8SLisandro Dalcin /* 3145673baf8SLisandro Dalcin --- unimplemented --- 3155673baf8SLisandro Dalcin */ 316ebd79076SLisandro Dalcin #else 317e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS, "Cannot use dynamic libraries on this platform"); 318ebd79076SLisandro Dalcin #endif 319ebd79076SLisandro Dalcin 3206ea75d68SLisandro Dalcin *value = *((void**)&dlsymbol); 321ebd79076SLisandro Dalcin 322ebd79076SLisandro Dalcin PetscFunctionReturn(0); 323ebd79076SLisandro Dalcin } 324