Based on mingw-w64.
System modules on Windows have load config available. In fact, all applications using the default MSVC for crt have it. mingw-w64 provides the load config, but it also requires linker to use it and currently only LLD supports it. This MR does the same in winecrt0. We will need it on both ARM64 and ARM64EC targets to support ARM64X (which requires LLD for other reasons anyway).
-- v3: winecrt0: Use load config on all targets.
From: Jacek Caban jacek@codeweavers.com
Based on mingw-w64. --- dlls/winecrt0/Makefile.in | 1 + dlls/winecrt0/arm64ec.c | 22 --------- dlls/winecrt0/load_config.c | 98 +++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 22 deletions(-) create mode 100644 dlls/winecrt0/load_config.c
diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index 863e5ed4190..d129a009400 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in @@ -17,6 +17,7 @@ SOURCES = \ exe_main.c \ exe_wentry.c \ exe_wmain.c \ + load_config.c \ register.c \ setjmp.c \ stub.c \ diff --git a/dlls/winecrt0/arm64ec.c b/dlls/winecrt0/arm64ec.c index 949de0a4e0c..64bb001274a 100644 --- a/dlls/winecrt0/arm64ec.c +++ b/dlls/winecrt0/arm64ec.c @@ -102,26 +102,4 @@ asm( "\t.section .rdata,"dr"\n" "\t.rva __os_arm64x_helper7\n" "\t.rva __os_arm64x_helper8\n" );
-asm( "\t.section .rdata,"dr"\n" - "\t.globl _load_config_used\n" - "\t.balign 8\n" - "_load_config_used:\n" - "\t.word 0x140\n" - "\t.fill 0x54, 1, 0\n" - "\t.xword 0\n" /* FIXME: __security_cookie */ - "\t.fill 0x10, 1, 0\n" - "\t.xword __guard_check_icall_fptr\n" - "\t.xword __guard_dispatch_icall_fptr\n" - "\t.xword __guard_fids_table\n" - "\t.xword __guard_fids_count\n" - "\t.xword __guard_flags\n" - "\t.xword 0\n" - "\t.xword __guard_iat_table\n" - "\t.xword __guard_iat_count\n" - "\t.xword __guard_longjmp_table\n" - "\t.xword __guard_longjmp_count\n" - "\t.xword 0\n" - "\t.xword __chpe_metadata\n" - "\t.fill 0x78, 1, 0\n" ); - #endif /* __arm64ec__ */ diff --git a/dlls/winecrt0/load_config.c b/dlls/winecrt0/load_config.c new file mode 100644 index 00000000000..c60b6c6c35e --- /dev/null +++ b/dlls/winecrt0/load_config.c @@ -0,0 +1,98 @@ +/* + * Load config support + * + * Copyright 2024 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WINE_PE_BUILD + +#include "wine/asm.h" + +#ifdef _WIN64 +#define PTR ".quad" +#else +#define PTR ".long" +#endif + +asm( "\t.section .rdata,"dr"\n" + "\t.globl " __ASM_NAME("_load_config_used") "\n" + "\t.balign 8\n" + __ASM_NAME("_load_config_used") ":\n" + "\t.long " __ASM_NAME("_load_config_used_end") "-" __ASM_NAME("_load_config_used") "\n" /* Size */ + "\t.long 0\n" /* TimeDateStamp */ + "\t.short 0\n" /* MajorVersion */ + "\t.short 0\n" /* MinorVersion */ + "\t.long 0\n" /* GlobalFlagsClear */ + "\t.long 0\n" /* GlobalFlagsSet */ + "\t.long 0\n" /* CriticalSectionDefaultTimeout */ + "\t"PTR" 0\n" /* DeCommitFreeBlockThreshold */ + "\t"PTR" 0\n" /* DeCommitTotalFreeThreshold */ + "\t"PTR" 0\n" /* LockPrefixTable */ + "\t"PTR" 0\n" /* MaximumAllocationSize */ + "\t"PTR" 0\n" /* VirtualMemoryThreshold */ + "\t"PTR" 0\n" /* ProcessAffinityMask */ + "\t.long 0\n" /* ProcessHeapFlags */ + "\t.short 0\n" /* CSDVersion */ + "\t.short 0\n" /* DependentLoadFlags */ + "\t"PTR" 0\n" /* EditList */ + "\t"PTR" 0\n" /* SecurityCookie */ + "\t"PTR" 0\n" /* SEHandlerTable */ + "\t"PTR" 0\n" /* SEHandlerCount */ +#ifdef __arm64ec__ + "\t"PTR" "__ASM_NAME("__guard_check_icall_fptr") "\n" /* GuardCFCheckFunctionPointer */ + "\t"PTR" "__ASM_NAME("__guard_dispatch_icall_fptr") "\n" /* GuardCFDispatchFunctionPointer */ +#else + "\t"PTR" 0\n" /* GuardCFCheckFunctionPointer */ + "\t"PTR " 0\n" /* GuardCFDispatchFunctionPointer */ +#endif + "\t"PTR" "__ASM_NAME("__guard_fids_table") "\n" /* GuardCFFunctionTable */ + "\t"PTR" "__ASM_NAME("__guard_fids_count") "\n" /* GuardCFFunctionCount */ + "\t.long "__ASM_NAME("__guard_flags") "\n" /* GuardFlags */ + "\t.short 0\n" /* CodeIntegrity.Flags */ + "\t.short 0\n" /* CodeIntegrity.Catalog */ + "\t.long 0\n" /* CodeIntegrity.CatalogOffset */ + "\t.long 0\n" /* CodeIntegrity.Reserved */ + "\t"PTR" "__ASM_NAME("__guard_iat_table") "\n" /* GuardAddressTakenIatEntryTable */ + "\t"PTR" "__ASM_NAME("__guard_iat_count") "\n" /* GuardAddressTakenIatEntryCount */ + "\t"PTR" "__ASM_NAME("__guard_longjmp_table") "\n" /* GuardLongJumpTargetTable */ + "\t"PTR" "__ASM_NAME("__guard_longjmp_count") "\n" /* GuardLongJumpTargetCount */ + "\t"PTR" 0\n" /* DynamicValueRelocTable */ +#ifdef __arm64ec__ + "\t"PTR" "__ASM_NAME("__chpe_metadata") "\n" /* CHPEMetadataPointer */ +#else + "\t"PTR" 0\n" /* CHPEMetadataPointer */ +#endif + "\t"PTR" 0\n" /* GuardRFFailureRoutine */ + "\t"PTR" 0\n" /* GuardRFFailureRoutineFunctionPointer */ + "\t.long 0\n" /* DynamicValueRelocTableOffset */ + "\t.short 0\n" /* DynamicValueRelocTableSection */ + "\t.short 0\n" /* Reserved2 */ + "\t"PTR" 0\n" /* GuardRFVerifyStackPointerFunctionPointer */ + "\t.long 0\n" /* HotPatchTableOffset */ + "\t.long 0\n" /* Reserved3 */ + "\t"PTR" 0\n" /* EnclaveConfigurationPointer */ + "\t"PTR" 0\n" /* VolatileMetadataPointer */ + "\t"PTR" 0\n" /* GuardEHContinuationTable */ + "\t"PTR" 0\n" /* GuardEHContinuationCount */ + "\t"PTR" 0\n" /* GuardXFGCheckFunctionPointer */ + "\t"PTR" 0\n" /* GuardXFGDispatchFunctionPointer */ + "\t"PTR" 0\n" /* GuardXFGTableDispatchFunctionPointer */ + "\t"PTR" 0\n" /* CastGuardOsDeterminedFailureMode */ + "\t"PTR" 0\n" /* GuardMemcpyFunctionPointer */ + __ASM_NAME("_load_config_used_end") ":\n" ); + +#endif /* __WINE_PE_BUILD */
Couldn't this be generated from winebuild instead?
On Wed Feb 28 19:53:24 2024 +0000, Alexandre Julliard wrote:
Couldn't this be generated from winebuild instead?
We could, but it wouldn't help with binutils LD. PE header directories are generated by the linker, which is supposed to set its `LOAD_CONFIG_TABLE` entry to the value of `_load_config_used` symbol (and do other fixups, some of which winebuild could do itself). I think that setting those entries ourselves would need hacks like post-processing after linking.
Or is there another reason to prefer having it in winebuild?
Or is there another reason to prefer having it in winebuild?
No, it's mostly because it seems to fit better. We already have all the needed support for generating that sort of thing, instead of using a C file with an asm statement and custom macros.