From fd59962827a715d321f91c9bdb43f3e61f9ebbcb Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 13 Feb 2025 14:34:25 +0100 Subject: [PATCH 1/2] ntdll: Use signed type for IAT offset in LdrResolveDelayLoadedAPI. Allows negative IAT offsets. --- dlls/ntdll/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 3872f2b237b..5be6e44435f 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3739,7 +3739,7 @@ void* WINAPI LdrResolveDelayLoadedAPI( void* base, const IMAGE_DELAYLOAD_DESCRIP HMODULE *phmod; NTSTATUS nts; FARPROC fp; - DWORD id; + INT_PTR id; TRACE( "(%p, %p, %p, %p, %p, 0x%08lx)\n", base, desc, dllhook, syshook, addr, flags ); -- GitLab From c9519f68ea04915a60704534ab3afec5ec1b8fd7 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 13 Feb 2025 14:37:02 +0100 Subject: [PATCH 2/2] winebuild: Avoid using .idata section for delay-load import libraries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent binutils changes merge .idata sections into the read-only .rdata section. This is intended to make the IAT read-only, as with other modern linkers, but as a side effect, it broke delay-load import libraries. Delay-load import libraries should use separate sections regardless. Since these new sections are not recognized by the linker, it won’t apply special handling to maintain proper sorting. In practice, this isn’t an issue as long as the name table and IAT maintain the same order. This may result in negative IAT offsets (if the base symbol ends up in the middle of the IAT), but Windows appears to handle this without issues. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57819 --- tools/winebuild/import.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 6aee0fa98f8..9a635a8e8f7 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1331,6 +1331,16 @@ static void build_dlltool_import_lib( const char *lib_name, DLLSPEC *spec, struc if (files.count) output_static_lib( output_file_name, files, 0 ); } +static void output_import_section( int index, int is_delay ) +{ + if (!is_delay) + output( "\n\t.section .idata$%d\n", index ); + else if (index == 5) + output( "\n\t.section .data$didat%d\n", index ); + else + output( "\n\t.section .rdata$didat%d\n", index ); +} + /* create a Windows-style import library */ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struct strarray files ) { @@ -1454,20 +1464,20 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc output( "\t.long 0\n" ); /* UnloadInformationTableRVA */ output( "\t.long 0\n" ); /* TimeDateStamp */ - output( "\n\t.section .idata$5\n" ); + output_import_section( 5, is_delay ); output( "\t%s 0\n", get_asm_ptr_keyword() ); /* FirstThunk tail */ output( ".L__wine_import_addrs:\n" ); - output( "\n\t.section .idata$4\n" ); + output_import_section( 4, is_delay ); output( "\t%s 0\n", get_asm_ptr_keyword() ); /* OriginalFirstThunk tail */ output( ".L__wine_import_names:\n" ); /* required to avoid internal linker errors with some binutils versions */ - output( "\n\t.section .idata$2\n" ); + output_import_section( 2, is_delay ); } else { - output( "\n\t.section .idata$2\n" ); + output_import_section( 2, is_delay ); output( "%s\n", asm_globl( import_desc ) ); output_rva( ".L__wine_import_names" ); /* OriginalFirstThunk */ output( "\t.long 0\n" ); /* TimeDateStamp */ @@ -1475,10 +1485,10 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc output_rva( "%s", asm_name( import_name ) ); /* Name */ output_rva( ".L__wine_import_addrs" ); /* FirstThunk */ - output( "\n\t.section .idata$4\n" ); + output_import_section( 4, is_delay ); output( ".L__wine_import_names:\n" ); /* OriginalFirstThunk head */ - output( "\n\t.section .idata$5\n" ); + output_import_section( 5, is_delay ); output( ".L__wine_import_addrs:\n" ); /* FirstThunk head */ } @@ -1489,11 +1499,11 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc new_output_as_file(); - output( "\n\t.section .idata$4\n" ); + output_import_section( 4, is_delay ); output( "\t%s 0\n", get_asm_ptr_keyword() ); /* OriginalFirstThunk tail */ - output( "\n\t.section .idata$5\n" ); + output_import_section( 5, is_delay ); output( "\t%s 0\n", get_asm_ptr_keyword() ); /* FirstThunk tail */ - output( "\n\t.section .idata$7\n" ); + output_import_section( 7, is_delay ); output( "%s\n", asm_globl( import_name ) ); output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); @@ -1584,10 +1594,10 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc break; } - output( "\n\t.section .idata$4\n" ); + output_import_section( 4, is_delay ); output_thunk_rva( by_name ? -1 : odp->ordinal, ".L__wine_import_name" ); - output( "\n\t.section .idata$5\n" ); + output_import_section( 5, is_delay ); output( "%s\n", asm_globl( imp_name ) ); if (is_delay) output( "\t%s .L__wine_delay_import\n", get_asm_ptr_keyword() ); @@ -1596,14 +1606,14 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc if (by_name) { - output( "\n\t.section .idata$6\n" ); + output_import_section( 6, is_delay ); output( ".L__wine_import_name:\n" ); output( "\t.short %d\n", odp->hint ); output( "\t%s \"%s\"\n", get_asm_string_keyword(), name ); } /* reference head object to always pull its sections */ - output( "\n\t.section .idata$7\n" ); + output_import_section( 7, is_delay ); output_rva( "%s", asm_name( import_desc ) ); free( imp_name ); -- GitLab