Index: lld/COFF/Config.h =================================================================== --- lld/COFF/Config.h +++ lld/COFF/Config.h @@ -235,6 +235,7 @@ bool swaprunNet = false; bool thinLTOEmitImportsFiles; bool thinLTOIndexOnly; + bool pseudoRelocs = false; }; extern Configuration *config; Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -393,6 +393,12 @@ case OPT_nodefaultlib: config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower()); break; + case OPT_runtime_pseudo_reloc: + config->pseudoRelocs = true; + break; + case OPT_runtime_pseudo_reloc_no: + config->pseudoRelocs = false; + break; case OPT_section: parseSection(arg->getValue()); break; @@ -1577,6 +1583,8 @@ config->debugDwarf = debug == DebugKind::Dwarf; config->debugGHashes = debug == DebugKind::GHash; config->debugSymtab = debug == DebugKind::Symtab; + config->pseudoRelocs = args.hasFlag( + OPT_runtime_pseudo_reloc, OPT_runtime_pseudo_reloc_no, config->mingw); // Don't warn about long section names, such as .debug_info, for mingw or when // -debug:dwarf is requested. @@ -1838,9 +1846,11 @@ // Needed for MSVC 2017 15.5 CRT. symtab->addAbsolute(mangle("__enclave_config"), 0); - if (config->mingw) { + if (config->pseudoRelocs) { symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0); symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0); + } + if (config->mingw) { symtab->addAbsolute(mangle("__CTOR_LIST__"), 0); symtab->addAbsolute(mangle("__DTOR_LIST__"), 0); } @@ -1898,7 +1908,8 @@ while (run()); } - if (config->mingw) { + if (config->pseudoRelocs) { + // MinGW specific. // Load any further object files that might be needed for doing automatic // imports. // Index: lld/COFF/Options.td =================================================================== --- lld/COFF/Options.td +++ lld/COFF/Options.td @@ -184,6 +184,7 @@ def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias; // LLD extensions +defm runtime_pseudo_reloc : B<"runtime-pseudo-reloc", "", "">; def end_lib : F<"end-lib">, HelpText<"Ends group of objects treated as if they were in a library">; def exclude_all_symbols : F<"exclude-all-symbols">; Index: lld/COFF/SymbolTable.cpp =================================================================== --- lld/COFF/SymbolTable.cpp +++ lld/COFF/SymbolTable.cpp @@ -438,7 +438,7 @@ if (name.contains("_PchSym_")) continue; - if (config->mingw && handleMinGWAutomaticImport(sym, name)) + if (config->pseudoRelocs && handleMinGWAutomaticImport(sym, name)) continue; // Remaining undefined symbols are not fatal if /force is specified. Index: lld/COFF/Writer.cpp =================================================================== --- lld/COFF/Writer.cpp +++ lld/COFF/Writer.cpp @@ -970,11 +970,11 @@ if (config->guardCF != GuardCFLevel::Off) createGuardCFTables(); - if (config->mingw) { + if (config->pseudoRelocs) createRuntimePseudoRelocs(); + if (config->mingw) insertCtorDtorSymbols(); - } } // Create .idata section for the DLL-imported symbol table. Index: lld/MinGW/Driver.cpp =================================================================== --- lld/MinGW/Driver.cpp +++ lld/MinGW/Driver.cpp @@ -295,6 +295,12 @@ else add("-opt:noref"); + if (args.hasFlag(OPT_enable_runtime_pseudo_reloc, + OPT_disable_runtime_pseudo_reloc, true)) + add("-runtime-pseudo-reloc"); + else + add("-runtime-pseudo-reloc:no"); + if (auto *a = args.getLastArg(OPT_icf)) { StringRef s = a->getValue(); if (s == "all") Index: lld/MinGW/Options.td =================================================================== --- lld/MinGW/Options.td +++ lld/MinGW/Options.td @@ -20,7 +20,11 @@ HelpText<"Add a directory to the library search path">; def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">; def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; +def disable_runtime_pseudo_reloc: F<"disable-runtime-pseudo-reloc">, + HelpText<"Don't automatically import data symbols from other DLLs without dllimport">; def dynamicbase: F<"dynamicbase">, HelpText<"Enable ASLR">; +def enable_runtime_pseudo_reloc: F<"enable-runtime-pseudo-reloc">, + HelpText<"Automatically import data symbols from other DLLs where needed">; defm entry: Eq<"entry", "Name of entry point symbol">, MetaVarName<"">; def exclude_all_symbols: F<"exclude-all-symbols">, HelpText<"Don't automatically export any symbols">; Index: lld/test/COFF/autoimport-drectve.s =================================================================== --- /dev/null +++ lld/test/COFF/autoimport-drectve.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 + +# RUN: echo -e ".global variable\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\n.data\nvariable:\n.long 42" > %t-lib.s +# RUN: llvm-mc -triple=x86_64-windows-gnu %t-lib.s -filetype=obj -o %t-lib.obj +# RUN: lld-link -out:%t-lib.dll -dll -entry:DllMainCRTStartup %t-lib.obj -lldmingw -implib:%t-lib.lib + +# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj +# RUN: not lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck --check-prefix=DISABLED %s + +# Check that we can disable runtime pseudo relocs via a .drectve in a +# linked object file: +# DISABLED: error: undefined symbol: variable + + .global main + .text +main: + movl variable(%rip), %eax + ret + .data +ptr: + .quad variable + + .section .drectve + .ascii "-runtime-pseudo-reloc:no" Index: lld/test/COFF/autoimport-x86.s =================================================================== --- lld/test/COFF/autoimport-x86.s +++ lld/test/COFF/autoimport-x86.s @@ -6,6 +6,7 @@ # RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj # RUN: lld-link -lldmingw -debug:symtab -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose +# RUN: not lld-link -lldmingw -runtime-pseudo-reloc:no -debug:symtab -out:%t.exe -entry:main %t.obj %t-lib.lib 2>&1 | FileCheck --check-prefix=DISABLED %s # RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s # RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s @@ -46,6 +47,9 @@ # the symbol table. # SYMBOLS-NOT: variable +# If runtime pseudo relocs are disabled, we get normal error messages instead: +# DISABLED: error: undefined symbol: variable + .global main .text main: Index: lld/test/MinGW/driver.test =================================================================== --- lld/test/MinGW/driver.test +++ lld/test/MinGW/driver.test @@ -223,3 +223,12 @@ RUN: not ld.lld -m i386pep 2>&1 | FileCheck -check-prefix NO_INPUT_FILES %s NO_INPUT_FILES: error: no input files + +RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix ENABLE_RUNTIME_PSEUDO_RELOC %s +RUN: ld.lld -### -m i386pep foo.o --disable-runtime-pseudo-reloc --enable-runtime-pseudo-reloc | FileCheck -check-prefix ENABLE_RUNTIME_PSEUDO_RELOC %s +RUN: ld.lld -### -m i386pep foo.o -enable-runtime-pseudo-reloc | FileCheck -check-prefix ENABLE_RUNTIME_PSEUDO_RELOC %s +ENABLE_RUNTIME_PSEUDO_RELOC: -runtime-pseudo-reloc{{ }} + +RUN: ld.lld -### -m i386pep foo.o --disable-runtime-pseudo-reloc | FileCheck -check-prefix DISABLE_RUNTIME_PSEUDO_RELOC %s +RUN: ld.lld -### -m i386pep foo.o -disable-runtime-pseudo-reloc | FileCheck -check-prefix DISABLE_RUNTIME_PSEUDO_RELOC %s +DISABLE_RUNTIME_PSEUDO_RELOC: -runtime-pseudo-reloc:no