[PATCH] COFF: Ensure that objects produced by LLVM link with /safeseh

Reid Kleckner rnk at google.com
Mon Sep 16 16:58:25 PDT 2013

Hi Bigcheese,

We indicate that the object files are safe by emitting a @feat.00
absolute address symbol.  The address is presumably interpreted as a
bitfield of features that the compiler would like to enable.  Bit 0 is
documented in the PE COFF spec to opt in to "registered SEH", which is
what /safeseh enables.

LLVM's object files are safe by default because LLVM doesn't know how to
produce SEH handlers.

This change also required changing WinCOFFObjectWriter::ExportSymbol()
to export more symbols, since @feat.00 is a non-external variable symbol
that we actually need to emit.



Index: lib/MC/WinCOFFObjectWriter.cpp
--- lib/MC/WinCOFFObjectWriter.cpp
+++ lib/MC/WinCOFFObjectWriter.cpp
@@ -503,14 +503,7 @@
 bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData,
                                        MCAssembler &Asm) {
-  // This doesn't seem to be right. Strings referred to from the .data section
-  // need symbols so they can be linked to code in the .text section right?
-  // return Asm.isSymbolLinkerVisible (&SymbolData);
-  // For now, all non-variable symbols are exported,
-  // the linker will sort the rest out for us.
-  return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable();
+  return Asm.isSymbolLinkerVisible(SymbolData.getSymbol());
 bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
Index: lib/Target/X86/X86AsmPrinter.cpp
--- lib/Target/X86/X86AsmPrinter.cpp
+++ lib/Target/X86/X86AsmPrinter.cpp
@@ -678,6 +678,23 @@
+    // Emit an absolute @feat.00 symbol.  This appears to be some kind of
+    // compiler features bitfield read by link.exe.
+    if (!Subtarget->is64Bit()) {
+      MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00"));
+      OutStreamer.BeginCOFFSymbolDef(S);
+      OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
+      OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
+      OutStreamer.EndCOFFSymbolDef();
+      // According to the PE-COFF spec, the LSB of this value marks the object
+      // for "registered SEH".  This means that all SEH handler entry points
+      // must be registered in .sxdata.  Use of any unregistered handlers will
+      // cause the process to terminate immediately.  LLVM does not know how to
+      // register any SEH handlers, so its object files should be safe.
+      OutStreamer.EmitAssignment(
+          S, MCConstantExpr::Create(int64_t(1), MMI->getContext()));
+    }
   if (Subtarget->isTargetELF()) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1691.1.patch
Type: text/x-patch
Size: 2125 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130916/ddde781e/attachment.bin>

More information about the llvm-commits mailing list