[PATCH 0/2] MR7328: winebuild: Avoid using .idata section for delay-load import libraries.
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 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7328
From: Jacek Caban <jacek(a)codeweavers.com> 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 https://gitlab.winehq.org/wine/wine/-/merge_requests/7328
From: Jacek Caban <jacek(a)codeweavers.com> 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 https://gitlab.winehq.org/wine/wine/-/merge_requests/7328
participants (2)
-
Jacek Caban -
Jacek Caban (@jacek)