[tor-commits] [tor-browser-build/master] Bug 40071: Be explicit about no SEH with mingw-w64 on 32bit systems

sysrqb at torproject.org sysrqb at torproject.org
Thu Sep 10 17:57:38 UTC 2020


commit d40f58678503123fcbacbbbcd6c19b37e167ab86
Author: Georg Koppen <gk at torproject.org>
Date:   Sat Sep 5 11:25:23 2020 +0000

    Bug 40071: Be explicit about no SEH with mingw-w64 on 32bit systems
---
 projects/clang-source/build        |   7 ++
 projects/clang-source/config       |   2 +
 projects/clang-source/no-seh.patch | 145 +++++++++++++++++++++++++++++++++++++
 projects/firefox/build             |   2 +
 projects/mingw-w64/build           |   4 +-
 rbm.conf                           |   4 +-
 6 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/projects/clang-source/build b/projects/clang-source/build
index 860b8e4..d94fcbe 100644
--- a/projects/clang-source/build
+++ b/projects/clang-source/build
@@ -19,6 +19,13 @@ 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/
diff --git a/projects/clang-source/config b/projects/clang-source/config
index d0ae90c..8adb18e 100644
--- a/projects/clang-source/config
+++ b/projects/clang-source/config
@@ -30,3 +30,5 @@ input_files:
     name: libunwind
     file_gpg_id: 1
   - filename: 43909.patch
+  - filename: no-seh.patch
+    enable: '[% c("var/windows-i686") %]'
diff --git a/projects/clang-source/no-seh.patch b/projects/clang-source/no-seh.patch
new file mode 100644
index 0000000..1a52e40
--- /dev/null
+++ b/projects/clang-source/no-seh.patch
@@ -0,0 +1,145 @@
+From 38cbe873d45cf3c881ef4113b48193edfd418f43 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at 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
+
diff --git a/projects/firefox/build b/projects/firefox/build
index d3c7139..63be146 100644
--- a/projects/firefox/build
+++ b/projects/firefox/build
@@ -77,6 +77,8 @@ fi
   # Make sure widl is not inserting random timestamps, see #21837.
   export WIDL_TIME_OVERRIDE="0"
   patch -p1 < $rootdir/nsis-uninstall.patch
+  # mingw-w64 does not support SEH on 32bit systems. Be explicit about that.
+  export LDFLAGS="[% c('var/flag_noSEH') %]"
 [% END -%]
 
 [% IF c("var/namecoin") %]
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index c5fcda6..155c531 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -24,7 +24,7 @@ cd gcc
 tar xJf $rootdir/gcc-[% c("var/gcc_version") %].tar.xz
 # LDFLAGS_FOR_TARGET does not work for some reason. Thus, we take
 # CFLAGS_FOR_TARGET.
-export CFLAGS_FOR_TARGET="-Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-insert-timestamp"
+export CFLAGS_FOR_TARGET="-Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-insert-timestamp [% c('var/flag_noSEH') %]"
 # Rust requires enabling pthreads
 gcc-[% c("var/gcc_version") %]/configure --prefix=$distdir --target=[% c("arch") %]-w64-mingw32 --with-gnu-ld --with-gnu-as --disable-multilib --enable-threads=posix --enable-languages=c,c++
 make -j[% c("buildconf/num_procs") %] all-gcc
@@ -40,7 +40,7 @@ make install
 mkdir -p /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
 cd /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
 /var/tmp/build/[% project %]-[% c("version") %]/mingw-w64-libraries/winpthreads/configure \
-  LDFLAGS="-Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp" \
+  LDFLAGS="-Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp [% c('var/flag_noSEH') %]" \
   --host=[% c("arch") %]-w64-mingw32 --prefix=$distdir/[% c("arch") %]-w64-mingw32
 make -j[% c("buildconf/num_procs") %]
 make install
diff --git a/rbm.conf b/rbm.conf
index b5dff53..9ee4f18 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -368,6 +368,8 @@ targets:
       windows-i686: 1
       windows-x86_64: 0
       osname: windows-i686
+      # mingw-w64 does not support SEH on 32bit systems. Be explicit about that.
+      flag_noSEH: '-Wl,--no-seh'
   windows:
     var:
       windows: 1
@@ -376,7 +378,7 @@ targets:
         arch: amd64
       configure_opt: '--host=[% c("arch") %]-w64-mingw32 CFLAGS="[% c("var/CFLAGS") %]" LDFLAGS="[% c("var/LDFLAGS") %]" [% c("var/configure_opt_project") %]'
       CFLAGS: '-fstack-protector-strong -fno-strict-overflow -Wno-missing-field-initializers -Wformat -Wformat-security [% c("var/flag_mwindows") %]'
-      LDFLAGS: '-Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs [% c("var/flag_HEASLR") %] [% c("var/flag_mwindows") %]'
+      LDFLAGS: '-Wl,--dynamicbase -Wl,--nxcompat -Wl,--enable-reloc-section -Wl,--no-insert-timestamp -lssp -L$gcclibs [% c("var/flag_HEASLR") %] [% c("var/flag_noSEH") %] [% c("var/flag_mwindows") %]'
       flag_mwindows: '-mwindows'
       compiler: mingw-w64
       faketime_path: /usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1



More information about the tor-commits mailing list