GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still https://gitweb.torproject.org/ https://git.torproject.org/ and git-rw.torproject.org.

Bug 40071: Be explicit about no SEH with mingw-w64 on 32bit systems

parent f6e87613
......@@ -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/
......
......@@ -30,3 +30,5 @@ input_files:
name: libunwind
file_gpg_id: 1
- filename: 43909.patch
- filename: no-seh.patch
enable: '[% c("var/windows-i686") %]'
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
......@@ -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") %]
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment