dlfcn.c


Log

Author Commit Date CI Message
Pali Rohár e1d593d9 2020-08-04T18:35:01 Fix compilation with older environments This change should fix following compile error: dlfcn.c: In function 'dlsym': dlfcn.c:374:14: warning: implicit declaration of function 'GetModuleHandleExA' dlfcn.c: undefined reference to `GetModuleHandleExA' Documentation for function GetModuleHandleExA() says: To compile an application that uses this function, define _WIN32_WINNT as 0x0501 or later. Fixes: https://github.com/dlfcn-win32/dlfcn-win32/issues/75
Pali Rohár 8ec5ffef 2020-07-14T21:14:56 Replace VirtualQueryEx() call by GetModuleHandleExA() call Usage of VirtualQueryEx() call is needed for retrieving HMODULE of passed function address and it is just an undocumented hack. Based on @rhabacker's tests it is unstable and does not work correctly. https://github.com/dlfcn-win32/dlfcn-win32/pull/72#issuecomment-656581418 So replace VirtualQueryEx() call by standard GetModuleHandleExA() function with special GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag which should do the same thing but it is documented and it is working correctly.
Mars Cheng cea65639 2020-03-24T20:05:29 fix memory leak in dlsym()
Pali Rohár 70c5c20a 2020-02-19T22:39:29 Show "(null)" in error message when passed filname to dlopen() was NULL and error occurred It does not make sense to pass file variable (which is NULL) to function save_err_ptr_str() which converts its argument to string. We can call directly save_err_str() with string value. Also it is highly unexpected that GetModuleHandle(NULL) call fails.
Pali Rohár 5d576e6d 2019-08-29T21:07:32 Update documentation in dlfcn.h, specially for RTLD_LAZY
Pali Rohár 588b5782 2019-08-22T17:25:11 Reduce memory usage by 64K One buffer for error message is enough.
Pali Rohár 2bb5f487 2019-07-25T20:34:46 Fix gcc warning: ISO C forbids return between function pointer and void * Instead of using compiler specific pragma to disable particular warning, rewrite code which cast from function pointer to data pointer according to POSIX dlopen() documentation. This also fix compile warning under MSVC. According to the ISO C standard, casting between function pointers and 'void *', as done above, produces undefined results. POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround: *(void **) (&cosine) = dlsym(handle, "cos"); This (clumsy) cast conforms with the ISO C standard and will avoid any compiler warnings.
Pali Rohár 39ff58c2 2019-07-25T20:32:53 Do not include intrin.h file Include file intrin.h is not needed for compiling dlfcn.c as _ReturnAddress intrinsic is defined in dlfcn.c manually. Moreover _ReturnAddress is available only as an intrinsic, there is no function implementation. So even including intrin.h file does not provide function variant for _ReturnAddress. More important, include file intrin.h is not available in older Windows Driver Kit 7.1.0. So removing usage of intrin.h file makes compilation of dlfcn-win32 also under these older WDK versions.
Pali Rohár 242b94ac 2019-07-24T23:06:57 Correctly process malloc() error in dlsym() malloc() may fail, so propagate this error to caller.
Pali Rohár 207311ce 2019-05-23T20:23:58 Correctly process and indicate error when file name is too long
Pali Rohár 44589dba 2019-05-23T20:23:50 Correctly process malloc() error in local_add() malloc() may fail, so propagate this error to caller of dlopen().
Pali Rohár 4fe419ca 2019-05-23T20:23:33 Correctly process and indicate error in dlsym() function Function save_err_str() checks for error by GetLastError() call. So ensure that last error is always set when error occurs.
Pali Rohár a5c0031e 2019-05-23T20:22:44 Correctly process and indicate error from LoadLibraryExA() function Function save_err_str() checks for error by GetLastError() call. Calling EnumProcessModules() may change or reset it. So call save_err_str() immediately after LoadLibraryExA().
Pali Rohár 9ce1ba6f 2019-05-21T00:35:11 Call FormatMessage() with FORMAT_MESSAGE_IGNORE_INSERTS Documentation says: In particular, it is unsafe to take an arbitrary system error code returned from an API and use FORMAT_MESSAGE_FROM_SYSTEM without FORMAT_MESSAGE_IGNORE_INSERTS.
Pali Rohár f3da31d7 2019-05-06T21:47:33 Load Psapi.dll at runtime, this avoids linking caveat
Pali Rohár 83add392 2019-04-25T19:36:57 Simplify implementation of save_err_str() Check return value of FormatMessageA() function and remove copy_string() function as it is not needed.
Pali Rohár d9d49f2d 2019-04-25T19:26:23 Remove ifdef hack for snprintf() Old version of MSVC does not support snprintf() function and sprintf_s() is not replacement for C99 snprintf(). As the only usage of snprintf() is to format void* pointer we can use sprintf() with enough long buffer.
Pali Rohár 04bbf248 2019-04-25T18:18:31 Simplify code around #ifdef UNICODE The whole dlfcn.h API works with char* (ANSI) strings. For WINAPI UNICODE builds it is still possible to call WINAPI ANSI functions with -A suffix. E.g. LoadLibraryExA() instead of LoadLibraryEx() or FormatMessageA() instead of FormatMessage(). This simplify whole implementation when compiling with UNICODE support as there is no need to do conversion from wchar_t to char and vice-versa.
Pali Rohár 63d7bda4 2019-01-29T22:57:04 Implement support for dlsym() with RTLD_DEFAULT and RTLD_NEXT dlsym() with RTLD_DEFAULT handle behaves in same way like with global handle returned by dlopen() with NULL file name. dlsym() with RTLD_NEXT handle search for next loaded module which provides specified symbol. "Next" means module which in EnumProcessModules() result after the module which called dlsym(). To get caller function of dlsym() use _ReturnAddress() intrinsic. To get module where is caller function use the fact that HMODULE is the same value as the module's base address. When compiling under gcc, defines _ReturnAddress() macro via gcc's builtin as it does not provide MSC's specific _ReturnAddress() intrinsic. Added tests demonstrate that both RTLD_DEFAULT and RTLD_NEXT are working as expected.
Pali Rohár 29c46a54 2019-01-29T22:38:42 Fix resolving global symbols when LoadLibrary() is called after dlopen() Usage of first_automatic_object cache is wrong. This cache is filled by all loaded DLL files (either implicitly or explicitly with LoadLibrary() call) by EnumProcessModules() call at first usage of dlopen(). So dlsym() can resolve global symbols only if they were loaded prior to dlopen() call. Any future usage of LoadLibrary() does not include newly loaded DLLs into first_automatic_object cache. To fix this problem, first_automatic_object cache is fully removed and EnumProcessModules() call is issued directly in dlsym() call. As EnumProcessModules() returns all DLLs, included those which were loaded by dlopen() with RTLD_LOCAL, it may break RTLD_LOCAL support. To address this problem switch linked-list of all loaded DLLs with RTLD_GLOBAL to linked-list of all loaded DLLs with RTLD_LOCAL flag. And then skip modules from EnumProcessModules() which are in linked-list. Also in WinAPI all DLLs loaded by LoadLibrary() behaves like RTLD_GLOBAL. So above change is compatible with this behavior. There may be another problem. Before retrieving HMODULE for DLL filename (which is done by LoadLibrary()), it is not possible to detect if DLL was already loaded by RTLD_LOCAL or not. And after calling LoadLibrary() it is not possible to know if DLL was loaded either by dlsym() with RTLD_LOCAL or by LoadLibrary() (which is equivalent to RTLD_GLOBAL). To address this problem, compare number of loaded modules (counted by EnumProcessModules()) before and after LoadLibrary() called from dlsym(). If number does not change it means that DLL was already loaded. So based on this result either add or remove HMODULE from linked-list of RTLD_LOCAL modules. Added test demonstrate usage of: global = dlopen(NULL, RTLD_GLOBAL); /* global handle */ LoadLibrary("library.dll"); /* this provides function */ function = dlsym(global, "function"); /* resolve function from library.dll */
Jean-Damien Durand d26298df 2018-01-17T10:02:39 #include <stdlib.h>
Silvio 5bcd8c53 2017-05-01T11:03:01 Fix bug in dlerror second consecutive call According to the specs, a second consecutive call to dlerror should always return NULL . This was the case in dlfcn-win32 before https://github.com/dlfcn-win32/dlfcn-win32/pull/20 introduce a regression that caused dlerror to crash on the second consecutive call. In this commit the issue is fixed as suggested in https://github.com/dlfcn-win32/dlfcn-win32/issues/34 and a regression test has been added.
Guohui Wang aa1401bf 2015-04-09T03:30:39 Added support for unicode character set.
Timothy Gu 98cc37be 2015-03-15T19:07:44 Add my copyright Not that I care…
Timothy Gu c5501073 2015-03-15T17:32:10 Warning control in MSVC
Timothy Gu f5e9a16f 2015-03-15T17:21:34 Use SHARED macro to handle DLL export (Originally the SHARED macro is created not to handle this case, but it seems like it works fine for this purpose as well.) Closes #12.
Timothy Gu dd4254a3 2014-10-08T15:50:21 Add linked modules to a separate global list Fixes #2.
Timothy Gu c421b701 2015-03-15T16:09:44 Check for memory leak when _DEBUG is defined
Dennis Nienhüser 83432ba2 2015-03-11T20:00:11 Add import/export symbols for MSVC. This results in an import .lib file. Closes #4. Some fixes by Timothy Gu <timothygu99@gmail.com> Signed-off-by: Timothy Gu <timothygu99@gmail.com>
Timothy Gu 87f5cd06 2015-03-11T19:48:56 Use more secure sprintf_s()
Timothy Gu 346543d6 2014-02-10T03:05:45 License stuff
Timothy Gu 539e732b 2014-01-22T04:12:43 Fix error checking in copy_string()
Timothy Gu b9be226f 2014-01-20T16:36:17 Remove extraneous CloseHandle Fixes issue 13.
Ramiro Polla 5976daa8 2009-01-11T21:59:46 Clear ->next after creating nobject.
Ramiro Polla 74b330c1 2008-12-09T21:17:44 Rename save_err_ptr( ) to save_err_ptr_str( ) to avoid confusion. Based on patch by Dan DuVarney.
Ramiro Polla 23e6a482 2008-12-09T21:14:31 Fix bug reported by Dan DuVarney, based on a patch by himself. POSIX says: If no dynamic linking errors have occurred since the last invocation of dlerror(), dlerror() shall return NULL. The code was returning an empty string. The way dlerror( ) returns the error string has been changed.
Ramiro Polla 66a5baf7 2007-06-29T23:42:51 Use double linked list instead of static array of 255 global objects.
Ramiro Polla 40f1a4cc 2007-06-29T22:42:58 Take care of our own error messages
Ramiro Polla 649282b7 2007-06-29T22:13:50 Fix copy_string( )
Ramiro Polla 85d184f7 2007-06-29T20:36:07 Cosmetics: white space
Ramiro Polla 4c4b268c 2007-06-28T05:50:08 Initial Revision