Hi,
Thanks for looking into this. We probably need something like that in
mingw-w64, but unfortunately, it's more complicated for Wine.
On 11.02.2025 04:18, LIU Hao wrote:
Since Binutils 2.44, the import address table (abbr. IAT) is now read-only,
in alignment with Microsoft LINK and LLD. It is now required to make the IAT
writeable before modifying it.
Similar code exists in Microsoft delayhlp.cpp.
Reference:https://devblogs.microsoft.com/oldnewthing/20221006-07/?p=107257
Reference:https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=db00f6c3aceabbf03acdb69e74b59b2d2b043cd7
Reference:https://bugs.winehq.org/show_bug.cgi?id=57819
Reference:https://sourceware.org/bugzilla/show_bug.cgi?id=32675
Signed-off-by: LIU Hao<lh_mo...@126.com>
This isn't entirely true for other linkers. While those linkers do place
.idata sections, including the IAT itself, in .rdata, they don’t use
.idata sections for delay imports. Instead, they implement delay loading
within the linker itself rather than relying on special delay import
libraries, placing the delay IAT in the .data section.
I’ve seen a blog claim that MSVC makes them read-only, but in my testing
with modern MSVC, that doesn’t appear to be the case, perhaps they
realized it wasn’t a good fit and reverted the change? I’m not sure.
I say it’s not a good fit because changing permissions like that is
generally a bad idea. Another thread might be executing code that relies
on data in the same page remaining read-only or might be performing
similar permission changes for other reasons. Taking a lock only
protects against concurrent __delayLoadHelper2 calls.
Wine provides its own __delayLoadHelper2 implementation, which simply
forwards the call to the public ResolveDelayLoadedAPI function. I’m
attaching a hack that does the same for mingw-w64 (since it’s a Windows
8 API, it’s not something mingw-w64 could use by default).
ResolveDelayLoadedAPI doesn’t seem to perform the protection change. at
least in this case, though maybe there’s a way to trigger it? Either
way, the test case crashes. The only workaround would be modifying
Wine’s __delayLoadHelper2 to duplicate ResolveDelayLoadedAPI inside a
static library and add the necessary permission changes.
That’s unfortunate. If anyone has a better idea, please let me know.
Ideally, I’d like to restore the previous behavior for delay load
imports. Wine doesn’t use dlltool to create delay load import libraries;
it generates them itself. In theory, this gives Wine more flexibility,
but I haven’t found a way to make it work.
SetEntryHookBypass:
+ while(InterlockedExchange(&gDelayLoadLock, 1) != 0)
+ Sleep(100);
You could just use a critical section.
Thanks,
Jacek
diff --git a/mingw-w64-crt/misc/delayimp.c b/mingw-w64-crt/misc/delayimp.c
index 6ced2d327..1b5864ba9 100644
--- a/mingw-w64-crt/misc/delayimp.c
+++ b/mingw-w64-crt/misc/delayimp.c
@@ -135,9 +135,11 @@ static int WINAPI FLoadedAtPreferredAddress(PIMAGE_NT_HEADERS pinh,HMODULE hmod)
static volatile LONG gDelayLoadLock = 0;
FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry);
+WINBASEAPI void *WINAPI DelayLoadFailureHook( LPCSTR name, LPCSTR function );
FARPROC WINAPI __delayLoadHelper2(PCImgDelayDescr pidd,FARPROC *ppfnIATEntry)
{
+ return ResolveDelayLoadedAPI( &__ImageBase, pidd, NULL, DelayLoadFailureHook, ppfnIATEntry, 0 );
InternalImgDelayDescr idd = {
pidd->grAttrs,(LPCTSTR) PtrFromRVA(pidd->rvaDLLName),(HMODULE *) PtrFromRVA(pidd->rvaHmod),
(PImgThunkData) PtrFromRVA(pidd->rvaIAT), (PCImgThunkData) PtrFromRVA(pidd->rvaINT),
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public