[lld] r330300 - [COFF] Mark images with no exception handlers for /safeseh

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 18 15:37:10 PDT 2018


Author: rnk
Date: Wed Apr 18 15:37:10 2018
New Revision: 330300

URL: http://llvm.org/viewvc/llvm-project?rev=330300&view=rev
Log:
[COFF] Mark images with no exception handlers for /safeseh

Summary:
DLLs and executables with no exception handlers need to be marked with
IMAGE_DLL_CHARACTERISTICS_NO_SEH, even if they have a load config.

Discovered here when building Chromium with LLD on Windows:
https://crbug.com/833951

Reviewers: ruiu, mstorsjo

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D45778

Added:
    lld/trunk/test/COFF/safeseh-notable.s
Modified:
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/safeseh.s

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=330300&r1=330299&r2=330300&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Apr 18 15:37:10 2018
@@ -185,8 +185,7 @@ private:
   IdataContents Idata;
   DelayLoadContents DelayIdata;
   EdataContents Edata;
-  RVATableChunk *GuardFidsTable = nullptr;
-  RVATableChunk *SEHTable = nullptr;
+  bool SetNoSEHCharacteristic = false;
 
   DebugDirectoryChunk *DebugDirectory = nullptr;
   std::vector<Chunk *> DebugRecords;
@@ -828,8 +827,7 @@ template <typename PEHeaderTy> void Writ
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
   if (Config->GuardCF != GuardCFLevel::Off)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
-  if (Config->Machine == I386 && !SEHTable &&
-      !Symtab->findUnderscore("_load_config_used"))
+  if (SetNoSEHCharacteristic)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
   if (Config->TerminalServerAware)
     PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
@@ -934,6 +932,10 @@ void Writer::openFile(StringRef Path) {
 }
 
 void Writer::createSEHTable() {
+  // Set the no SEH characteristic on x86 binaries unless we find exception
+  // handlers.
+  SetNoSEHCharacteristic = true;
+
   SymbolRVASet Handlers;
   for (ObjFile *File : ObjFile::Instances) {
     // FIXME: We should error here instead of earlier unless /safeseh:no was
@@ -944,6 +946,12 @@ void Writer::createSEHTable() {
     markSymbolsForRVATable(File, File->getSXDataChunks(), Handlers);
   }
 
+  // Remove the "no SEH" characteristic if all object files were built with
+  // safeseh, we found some exception handlers, and there is a load config in
+  // the object.
+  SetNoSEHCharacteristic =
+      Handlers.empty() || !Symtab->findUnderscore("_load_config_used");
+
   maybeAddRVATable(std::move(Handlers), "__safe_se_handler_table",
                    "__safe_se_handler_count");
 }

Added: lld/trunk/test/COFF/safeseh-notable.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/safeseh-notable.s?rev=330300&view=auto
==============================================================================
--- lld/trunk/test/COFF/safeseh-notable.s (added)
+++ lld/trunk/test/COFF/safeseh-notable.s Wed Apr 18 15:37:10 2018
@@ -0,0 +1,43 @@
+# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -safeseh -out:%t.exe -entry:main
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# This object lacks a _load_config_used global, so we set
+# IMAGE_DLL_CHARACTERISTICS_NO_SEH even though there is an exception handler.
+# This is a more secure default. If someone wants to use a CRT without a load
+# config and they want to use 32-bit SEH, they will need to provide a
+# safeseh-compatible load config.
+
+# CHECK-LABEL: Characteristics [
+# CHECK:   IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# CHECK: ]
+
+# CHECK-LABEL:  DataDirectory {
+# CHECK:    LoadConfigTableRVA: 0x0
+# CHECK:    LoadConfigTableSize: 0x0
+# CHECK:  }
+
+# CHECK-NOT: LoadConfig
+# CHECK-NOT: SEHTable
+
+        .def     @feat.00;
+        .scl    3;
+        .type   0;
+        .endef
+        .globl  @feat.00
+ at feat.00 = 1
+
+        .text
+        .def     _main; .scl    2; .type   32; .endef
+        .globl  _main
+_main:
+        pushl $_my_handler
+        movl $42, %eax
+        popl %ecx
+        ret
+
+        .def     _my_handler; .scl    3; .type   32; .endef
+_my_handler:
+        ret
+
+.safeseh _my_handler

Modified: lld/trunk/test/COFF/safeseh.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/safeseh.s?rev=330300&r1=330299&r2=330300&view=diff
==============================================================================
--- lld/trunk/test/COFF/safeseh.s (original)
+++ lld/trunk/test/COFF/safeseh.s Wed Apr 18 15:37:10 2018
@@ -6,6 +6,7 @@
 
 # __safe_se_handler_table needs to be relocated against ImageBase.
 # check that the relocation is present.
+#
 # CHECK-NOGC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH
 # CHECK-NOGC: BaseReloc [
 # CHECK-NOGC:   Entry {
@@ -19,9 +20,14 @@
 # CHECK-NOGC-NEXT:   0x401006
 # CHECK-NOGC-NEXT: ]
 
-# Without the SEH table, the address is absolute, so check that we do
-# not have a relocation for it.
-# CHECK-GC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# If we enable GC, the exception handler should be removed, and we should add
+# the DLL characteristic flag that indicates that there are no exception
+# handlers in this DLL. The exception handler table in the load config should
+# be empty and there should be no relocations for it.
+#
+# CHECK-GC: Characteristics [
+# CHECK-GC:   IMAGE_DLL_CHARACTERISTICS_NO_SEH
+# CHECK-GC: ]
 # CHECK-GC: BaseReloc [
 # CHECK-GC-NEXT: ]
 # CHECK-GC: LoadConfig [




More information about the llvm-commits mailing list