Loading
+5 −0
Original line number Diff line number Diff line
@@ -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'
+3 −7
Original line number Diff line number Diff line
@@ -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/
+7 −2
Original line number Diff line number Diff line
@@ -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
@@ -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") %]'
+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
+2 −0
Original line number Diff line number Diff line
@@ -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