diff options
author | Ron Yorston <rmy@pobox.com> | 2019-01-04 12:29:19 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-01-04 15:06:26 +0000 |
commit | 0ffd8b3261e764179572d58179ae8e2c21635220 (patch) | |
tree | 29b297fe574d2d31564112a8c75becb3fb1d8464 | |
parent | 6b6c55e16f121976334b857a646d82c2fec0a07b (diff) | |
download | busybox-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.h | 26 | ||||
-rw-r--r-- | win32/mingw.c | 10 |
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 | ||
6 | struct proc_addr { | 6 | struct 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 | ||
26 | static inline void *get_proc_addr(struct proc_addr *proc) | 24 | static 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) | |||
881 | static char *resolve_symlinks(char *path) | 881 | static 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 | ||
1283 | ULONGLONG CompatGetTickCount64(void) | 1281 | ULONGLONG 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 | ||