Loading projects/binutils/config +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,11 @@ var: use_container: 1 targets: # We use the windows-clang target for the binutils we use for building # clang during windows builds. See projects/clang/config. windows-clang: var: configure_opt: '--disable-multilib --enable-gold --enable-deterministic-archives --enable-plugins' windows: var: configure_opt: '--target=[% c("arch") %]-w64-mingw32 --disable-multilib --enable-deterministic-archives' Loading projects/clang-source/build +3 −7 Original line number Diff line number Diff line Loading @@ -10,22 +10,18 @@ tar -xf $rootdir/[% c('input_files_by_name/compiler-rt') %] tar -xf $rootdir/[% c('input_files_by_name/libunwind') %] mv llvm-[% c("version") %].src llvm [% IF ! c("var/windows") -%] # LLVM has reproducibility issues when optimizing bitcode, which we need to # patch. See: #32053 for more details. patch -p1 < $rootdir/43909.patch [% END -%] mv clang-[% c("version") %].src llvm/tools/clang # Having clang-tidy available seems like a good idea mv clang-tools-extra-[% c("version") %].src llvm/tools/clang/tools/extra mv libcxx-[% c("version") %].src llvm/projects/libcxx mv libcxxabi-[% c("version") %].src llvm/projects/libcxxabi mv lld-[% c("version") %].src llvm/tools/lld [% IF c("var/windows-i686") %] # mingw-w64 does not support SEH on 32bit systems. Make it possible to # explicitly disable it. cd llvm/tools patch -p1 < $rootdir/no-seh.patch cd ../../ [% END %] mv compiler-rt-[% c("version") %].src llvm/projects/compiler-rt # We need libunwind only for mingw-w64-clang, don't include it as tightly by # putting it into projects/ Loading projects/clang-source/config +7 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,12 @@ filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz' gpg_keyring: clang.gpg sig_ext: sig targets: windows: # We use clang 11 for Windows builds: # https://hg.mozilla.org/releases/mozilla-esr78/rev/cc840a008393 version: 11.0.1 input_files: - URL: 'https://github.com/llvm/llvm-project/releases/download/llvmorg-[% c("version") %]/llvm-[% c("version") %].src.tar.xz' name: llvm Loading @@ -30,5 +36,4 @@ input_files: name: libunwind file_gpg_id: 1 - filename: 43909.patch - filename: no-seh.patch enable: '[% c("var/windows-i686") %]' enable: '[% ! c("var/windows") %]' projects/clang-source/no-seh.patchdeleted 100644 → 0 +0 −145 Original line number Diff line number Diff line From 38cbe873d45cf3c881ef4113b48193edfd418f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Mon, 27 Jul 2020 23:44:41 +0300 Subject: [PATCH] Implement the --no-seh flag Previously this flag was just ignored. If set, set the IMAGE_DLL_CHARACTERISTICS_NO_SEH bit, regardless of the normal safeSEH machinery. In mingw configurations, the safeSEH bit might not be set in e.g. object files built from handwritten assembly, making it impossible to use the normal safeseh flag. As mingw setups don't generally use SEH on 32 bit x86 at all, it should be fine to set that flag bit though - hook up the existing GNU ld flag for controlling that. Differential Revision: https://reviews.llvm.org/D84701 diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 4b62cd05f4f..17ea0f8bcab 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -135,6 +135,7 @@ struct Configuration { bool safeSEH = false; Symbol *sehTable = nullptr; Symbol *sehCount = nullptr; + bool noSEH = false; // Used for /opt:lldlto=N unsigned ltoo = 2; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 15d6fb5121a..b569df07601 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1574,9 +1574,10 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) { config->wordsize = config->is64() ? 8 : 4; // Handle /safeseh, x86 only, on by default, except for mingw. - if (config->machine == I386 && - args.hasFlag(OPT_safeseh, OPT_safeseh_no, !config->mingw)) - config->safeSEH = true; + if (config->machine == I386) { + config->safeSEH = args.hasFlag(OPT_safeseh, OPT_safeseh_no, !config->mingw); + config->noSEH = args.hasArg(OPT_noseh); + } // Handle /functionpadmin for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 024b7be8f78..c7e2a5ea57e 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -171,6 +171,7 @@ def include_optional : Joined<["/", "-", "/?", "-?"], "includeoptional:">, HelpText<"Add symbol as undefined, but allow it to remain undefined">; def kill_at : F<"kill-at">; def lldmingw : F<"lldmingw">; +def noseh : F<"noseh">; def output_def : Joined<["/", "-", "/?", "-?"], "output-def:">; def pdb_source_path : P<"pdbsourcepath", "Base path used to make relative source file path absolute in PDB">; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 5736281958f..aead781d38b 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1352,7 +1352,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() { pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF; if (config->integrityCheck) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; - if (setNoSEHCharacteristic) + if (setNoSEHCharacteristic || config->noSEH) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; if (config->terminalServerAware) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index be1b757e45b..1d292817cfb 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -249,6 +249,8 @@ bool mingw::link(ArrayRef<const char *> argsArr, raw_ostream &diag) { add("-kill-at"); if (args.hasArg(OPT_appcontainer)) add("-appcontainer"); + if (args.hasArg(OPT_no_seh)) + add("-noseh"); if (args.getLastArgValue(OPT_m) != "thumb2pe" && args.getLastArgValue(OPT_m) != "arm64pe" && !args.hasArg(OPT_dynamicbase)) diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td index 86400433d04..931cf264837 100644 --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -45,6 +45,7 @@ def minor_subsystem_version_eq: Joined<["--"], "minor-subsystem-version=">, Alias<minor_subsystem_version>; def no_insert_timestamp: F<"no-insert-timestamp">, HelpText<"Don't include PE header timestamp">; +def no_seh: F<"no-seh">, HelpText<"Set the 'no SEH' flag in the executable">; def no_whole_archive: F<"no-whole-archive">, HelpText<"No longer include all object files for following archives">; def large_address_aware: Flag<["--"], "large-address-aware">, @@ -104,7 +105,6 @@ def: Flag<["--"], "full-shutdown">; def: F<"high-entropy-va">; def: S<"major-image-version">; def: S<"minor-image-version">; -def: F<"no-seh">; def: F<"nxcompat">; def: F<"pic-executable">; def: S<"plugin">; diff --git a/lld/test/COFF/noseh.s b/lld/test/COFF/noseh.s new file mode 100644 index 00000000000..44295228622 --- /dev/null +++ b/lld/test/COFF/noseh.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -triple i686-w64-mingw32 %s -filetype=obj -o %t.obj +# RUN: lld-link -lldmingw %t.obj -out:%t.exe -entry:main +# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s --check-prefix=DEFAULT +# RUN: lld-link -lldmingw %t.obj -out:%t.noseh.exe -entry:main -noseh +# RUN: llvm-readobj --file-headers %t.noseh.exe | FileCheck %s --check-prefix=NOSEH + +# DEFAULT: Characteristics [ +# DEFAULT-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH +# DEFAULT: ] + +# NOSEH: Characteristics [ +# NOSEH: IMAGE_DLL_CHARACTERISTICS_NO_SEH +# NOSEH: ] + + .text + .globl _main +_main: + ret diff --git a/lld/test/MinGW/driver.test b/lld/test/MinGW/driver.test index b8bc2ddea8a..1d53205927b 100644 --- a/lld/test/MinGW/driver.test +++ b/lld/test/MinGW/driver.test @@ -204,3 +204,7 @@ APPCONTAINER: -appcontainer RUN: ld.lld -### -m i386pep foo.o -delayload user32.dll --delayload shell32.dll | FileCheck -check-prefix DELAYLOAD %s RUN: ld.lld -### -m i386pep foo.o -delayload=user32.dll --delayload=shell32.dll | FileCheck -check-prefix DELAYLOAD %s DELAYLOAD: -delayload:user32.dll -delayload:shell32.dll + +RUN: ld.lld -### -m i386pe foo.o -no-seh | FileCheck -check-prefix NOSEH %s +RUN: ld.lld -### -m i386pe foo.o --no-seh | FileCheck -check-prefix NOSEH %s +NOSEH: -noseh -- 2.28.0 projects/clang/build +2 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ export PATH="/var/tmp/dist/cmake/bin:$PATH" [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'), hardened_gcc => 0 }) %] ln -s gcc /var/tmp/dist/gcc/bin/cc [% END -%] [% IF c("var/linux") || c("var/windows") -%] tar -C /var/tmp/dist -xf [% c('input_files_by_name/binutils') %] export PATH="/var/tmp/dist/binutils/bin:$PATH" [% END -%] Loading Loading
projects/binutils/config +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,11 @@ var: use_container: 1 targets: # We use the windows-clang target for the binutils we use for building # clang during windows builds. See projects/clang/config. windows-clang: var: configure_opt: '--disable-multilib --enable-gold --enable-deterministic-archives --enable-plugins' windows: var: configure_opt: '--target=[% c("arch") %]-w64-mingw32 --disable-multilib --enable-deterministic-archives' Loading
projects/clang-source/build +3 −7 Original line number Diff line number Diff line Loading @@ -10,22 +10,18 @@ tar -xf $rootdir/[% c('input_files_by_name/compiler-rt') %] tar -xf $rootdir/[% c('input_files_by_name/libunwind') %] mv llvm-[% c("version") %].src llvm [% IF ! c("var/windows") -%] # LLVM has reproducibility issues when optimizing bitcode, which we need to # patch. See: #32053 for more details. patch -p1 < $rootdir/43909.patch [% END -%] mv clang-[% c("version") %].src llvm/tools/clang # Having clang-tidy available seems like a good idea mv clang-tools-extra-[% c("version") %].src llvm/tools/clang/tools/extra mv libcxx-[% c("version") %].src llvm/projects/libcxx mv libcxxabi-[% c("version") %].src llvm/projects/libcxxabi mv lld-[% c("version") %].src llvm/tools/lld [% IF c("var/windows-i686") %] # mingw-w64 does not support SEH on 32bit systems. Make it possible to # explicitly disable it. cd llvm/tools patch -p1 < $rootdir/no-seh.patch cd ../../ [% END %] mv compiler-rt-[% c("version") %].src llvm/projects/compiler-rt # We need libunwind only for mingw-w64-clang, don't include it as tightly by # putting it into projects/ Loading
projects/clang-source/config +7 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,12 @@ filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz' gpg_keyring: clang.gpg sig_ext: sig targets: windows: # We use clang 11 for Windows builds: # https://hg.mozilla.org/releases/mozilla-esr78/rev/cc840a008393 version: 11.0.1 input_files: - URL: 'https://github.com/llvm/llvm-project/releases/download/llvmorg-[% c("version") %]/llvm-[% c("version") %].src.tar.xz' name: llvm Loading @@ -30,5 +36,4 @@ input_files: name: libunwind file_gpg_id: 1 - filename: 43909.patch - filename: no-seh.patch enable: '[% c("var/windows-i686") %]' enable: '[% ! c("var/windows") %]'
projects/clang-source/no-seh.patchdeleted 100644 → 0 +0 −145 Original line number Diff line number Diff line From 38cbe873d45cf3c881ef4113b48193edfd418f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Mon, 27 Jul 2020 23:44:41 +0300 Subject: [PATCH] Implement the --no-seh flag Previously this flag was just ignored. If set, set the IMAGE_DLL_CHARACTERISTICS_NO_SEH bit, regardless of the normal safeSEH machinery. In mingw configurations, the safeSEH bit might not be set in e.g. object files built from handwritten assembly, making it impossible to use the normal safeseh flag. As mingw setups don't generally use SEH on 32 bit x86 at all, it should be fine to set that flag bit though - hook up the existing GNU ld flag for controlling that. Differential Revision: https://reviews.llvm.org/D84701 diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 4b62cd05f4f..17ea0f8bcab 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -135,6 +135,7 @@ struct Configuration { bool safeSEH = false; Symbol *sehTable = nullptr; Symbol *sehCount = nullptr; + bool noSEH = false; // Used for /opt:lldlto=N unsigned ltoo = 2; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 15d6fb5121a..b569df07601 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1574,9 +1574,10 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) { config->wordsize = config->is64() ? 8 : 4; // Handle /safeseh, x86 only, on by default, except for mingw. - if (config->machine == I386 && - args.hasFlag(OPT_safeseh, OPT_safeseh_no, !config->mingw)) - config->safeSEH = true; + if (config->machine == I386) { + config->safeSEH = args.hasFlag(OPT_safeseh, OPT_safeseh_no, !config->mingw); + config->noSEH = args.hasArg(OPT_noseh); + } // Handle /functionpadmin for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 024b7be8f78..c7e2a5ea57e 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -171,6 +171,7 @@ def include_optional : Joined<["/", "-", "/?", "-?"], "includeoptional:">, HelpText<"Add symbol as undefined, but allow it to remain undefined">; def kill_at : F<"kill-at">; def lldmingw : F<"lldmingw">; +def noseh : F<"noseh">; def output_def : Joined<["/", "-", "/?", "-?"], "output-def:">; def pdb_source_path : P<"pdbsourcepath", "Base path used to make relative source file path absolute in PDB">; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 5736281958f..aead781d38b 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1352,7 +1352,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() { pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF; if (config->integrityCheck) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; - if (setNoSEHCharacteristic) + if (setNoSEHCharacteristic || config->noSEH) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; if (config->terminalServerAware) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp index be1b757e45b..1d292817cfb 100644 --- a/lld/MinGW/Driver.cpp +++ b/lld/MinGW/Driver.cpp @@ -249,6 +249,8 @@ bool mingw::link(ArrayRef<const char *> argsArr, raw_ostream &diag) { add("-kill-at"); if (args.hasArg(OPT_appcontainer)) add("-appcontainer"); + if (args.hasArg(OPT_no_seh)) + add("-noseh"); if (args.getLastArgValue(OPT_m) != "thumb2pe" && args.getLastArgValue(OPT_m) != "arm64pe" && !args.hasArg(OPT_dynamicbase)) diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td index 86400433d04..931cf264837 100644 --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -45,6 +45,7 @@ def minor_subsystem_version_eq: Joined<["--"], "minor-subsystem-version=">, Alias<minor_subsystem_version>; def no_insert_timestamp: F<"no-insert-timestamp">, HelpText<"Don't include PE header timestamp">; +def no_seh: F<"no-seh">, HelpText<"Set the 'no SEH' flag in the executable">; def no_whole_archive: F<"no-whole-archive">, HelpText<"No longer include all object files for following archives">; def large_address_aware: Flag<["--"], "large-address-aware">, @@ -104,7 +105,6 @@ def: Flag<["--"], "full-shutdown">; def: F<"high-entropy-va">; def: S<"major-image-version">; def: S<"minor-image-version">; -def: F<"no-seh">; def: F<"nxcompat">; def: F<"pic-executable">; def: S<"plugin">; diff --git a/lld/test/COFF/noseh.s b/lld/test/COFF/noseh.s new file mode 100644 index 00000000000..44295228622 --- /dev/null +++ b/lld/test/COFF/noseh.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -triple i686-w64-mingw32 %s -filetype=obj -o %t.obj +# RUN: lld-link -lldmingw %t.obj -out:%t.exe -entry:main +# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s --check-prefix=DEFAULT +# RUN: lld-link -lldmingw %t.obj -out:%t.noseh.exe -entry:main -noseh +# RUN: llvm-readobj --file-headers %t.noseh.exe | FileCheck %s --check-prefix=NOSEH + +# DEFAULT: Characteristics [ +# DEFAULT-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH +# DEFAULT: ] + +# NOSEH: Characteristics [ +# NOSEH: IMAGE_DLL_CHARACTERISTICS_NO_SEH +# NOSEH: ] + + .text + .globl _main +_main: + ret diff --git a/lld/test/MinGW/driver.test b/lld/test/MinGW/driver.test index b8bc2ddea8a..1d53205927b 100644 --- a/lld/test/MinGW/driver.test +++ b/lld/test/MinGW/driver.test @@ -204,3 +204,7 @@ APPCONTAINER: -appcontainer RUN: ld.lld -### -m i386pep foo.o -delayload user32.dll --delayload shell32.dll | FileCheck -check-prefix DELAYLOAD %s RUN: ld.lld -### -m i386pep foo.o -delayload=user32.dll --delayload=shell32.dll | FileCheck -check-prefix DELAYLOAD %s DELAYLOAD: -delayload:user32.dll -delayload:shell32.dll + +RUN: ld.lld -### -m i386pe foo.o -no-seh | FileCheck -check-prefix NOSEH %s +RUN: ld.lld -### -m i386pe foo.o --no-seh | FileCheck -check-prefix NOSEH %s +NOSEH: -noseh -- 2.28.0
projects/clang/build +2 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ export PATH="/var/tmp/dist/cmake/bin:$PATH" [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'), hardened_gcc => 0 }) %] ln -s gcc /var/tmp/dist/gcc/bin/cc [% END -%] [% IF c("var/linux") || c("var/windows") -%] tar -C /var/tmp/dist -xf [% c('input_files_by_name/binutils') %] export PATH="/var/tmp/dist/binutils/bin:$PATH" [% END -%] Loading