aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-01-04 12:29:19 +0000
committerRon Yorston <rmy@pobox.com>2019-01-04 15:06:26 +0000
commit0ffd8b3261e764179572d58179ae8e2c21635220 (patch)
tree29b297fe574d2d31564112a8c75becb3fb1d8464
parent6b6c55e16f121976334b857a646d82c2fec0a07b (diff)
downloadbusybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.tar.gz
busybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.tar.bz2
busybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.zip
win32: reduce static storage needed for lazy loading
Only the generic function pointer and initialisation flag need to be in static storage. The DLL and function names and the specialised function pointer can be local.
-rw-r--r--win32/lazyload.h26
-rw-r--r--win32/mingw.c10
2 files changed, 15 insertions, 21 deletions
diff --git a/win32/lazyload.h b/win32/lazyload.h
index 9d1a05550..a9fcff209 100644
--- a/win32/lazyload.h
+++ b/win32/lazyload.h
@@ -4,35 +4,31 @@
4/* simplify loading of DLL functions */ 4/* simplify loading of DLL functions */
5 5
6struct proc_addr { 6struct proc_addr {
7 const char *const dll;
8 const char *const function;
9 FARPROC pfunction; 7 FARPROC pfunction;
10 unsigned initialized : 1; 8 unsigned initialized;
11}; 9};
12 10
13/* Declares a function to be loaded dynamically from a DLL. */ 11/* Declares a function to be loaded dynamically from a DLL. */
14#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \ 12#define DECLARE_PROC_ADDR(rettype, function, ...) \
15 static struct proc_addr proc_addr_##function = \ 13 static struct proc_addr proc_addr_##function = { NULL, 0 }; \
16 { #dll, #function, NULL, 0 }; \ 14 rettype (WINAPI *function)(__VA_ARGS__)
17 static rettype (WINAPI *function)(__VA_ARGS__)
18 15
19/* 16/*
20 * Loads a function from a DLL (once-only). 17 * Loads a function from a DLL (once-only).
21 * Returns non-NULL function pointer on success. 18 * Returns non-NULL function pointer on success.
22 * Returns NULL + errno == ENOSYS on failure. 19 * Returns NULL and sets errno == ENOSYS on failure.
23 */ 20 */
24#define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function)) 21#define INIT_PROC_ADDR(dll, function) \
22 (function = get_proc_addr(#dll, #function, &proc_addr_##function))
25 23
26static inline void *get_proc_addr(struct proc_addr *proc) 24static inline void *get_proc_addr(const char *dll, const char *function, struct proc_addr *proc)
27{ 25{
28 /* only do this once */ 26 /* only do this once */
29 if (!proc->initialized) { 27 if (!proc->initialized) {
30 HANDLE hnd; 28 HANDLE hnd = LoadLibraryExA(dll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
31 proc->initialized = 1;
32 hnd = LoadLibraryExA(proc->dll, NULL,
33 LOAD_LIBRARY_SEARCH_SYSTEM32);
34 if (hnd) 29 if (hnd)
35 proc->pfunction = GetProcAddress(hnd, proc->function); 30 proc->pfunction = GetProcAddress(hnd, function);
31 proc->initialized = 1;
36 } 32 }
37 /* set ENOSYS if DLL or function was not found */ 33 /* set ENOSYS if DLL or function was not found */
38 if (!proc->pfunction) 34 if (!proc->pfunction)
diff --git a/win32/mingw.c b/win32/mingw.c
index 15f94d86c..c420992d5 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -881,13 +881,11 @@ int link(const char *oldpath, const char *newpath)
881static char *resolve_symlinks(char *path) 881static char *resolve_symlinks(char *path)
882{ 882{
883 HANDLE h = INVALID_HANDLE_VALUE; 883 HANDLE h = INVALID_HANDLE_VALUE;
884 DECLARE_PROC_ADDR(kernel32.dll, DWORD, GetFinalPathNameByHandleA, HANDLE, 884 DECLARE_PROC_ADDR(DWORD, GetFinalPathNameByHandleA, HANDLE,
885 LPSTR, DWORD, DWORD); 885 LPSTR, DWORD, DWORD);
886 886
887 if (!INIT_PROC_ADDR(GetFinalPathNameByHandleA)) { 887 if (!INIT_PROC_ADDR(kernel32.dll, GetFinalPathNameByHandleA))
888 errno = ENOSYS;
889 return NULL; 888 return NULL;
890 }
891 889
892 /* need a file handle to resolve symlinks */ 890 /* need a file handle to resolve symlinks */
893 h = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, 891 h = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL,
@@ -1282,9 +1280,9 @@ off_t mingw_lseek(int fd, off_t offset, int whence)
1282 1280
1283ULONGLONG CompatGetTickCount64(void) 1281ULONGLONG CompatGetTickCount64(void)
1284{ 1282{
1285 DECLARE_PROC_ADDR(kernel32.dll, ULONGLONG, GetTickCount64, void); 1283 DECLARE_PROC_ADDR(ULONGLONG, GetTickCount64, void);
1286 1284
1287 if (!INIT_PROC_ADDR(GetTickCount64)) { 1285 if (!INIT_PROC_ADDR(kernel32.dll, GetTickCount64)) {
1288 return (ULONGLONG)GetTickCount(); 1286 return (ULONGLONG)GetTickCount();
1289 } 1287 }
1290 1288