[llvm] r190898 - COFF: Ensure that objects produced by LLVM link with /safeseh
Reid Kleckner
reid at kleckner.net
Tue Sep 17 16:18:05 PDT 2013
Author: rnk
Date: Tue Sep 17 18:18:05 2013
New Revision: 190898
URL: http://llvm.org/viewvc/llvm-project?rev=190898&view=rev
Log:
COFF: Ensure that objects produced by LLVM link with /safeseh
Summary:
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.
Reviewers: Bigcheese
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1691
Added:
llvm/trunk/test/CodeGen/X86/coff-feat00.ll
llvm/trunk/test/MC/COFF/feat00.s
Modified:
llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=190898&r1=190897&r2=190898&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Tue Sep 17 18:18:05 2013
@@ -148,8 +148,8 @@ public:
object_t *createCOFFEntity(StringRef Name, list_t &List);
void DefineSection(MCSectionData const &SectionData);
- void DefineSymbol(MCSymbolData const &SymbolData,
- MCAssembler &Assembler);
+ void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
+ const MCAsmLayout &Layout);
void MakeSymbolReal(COFFSymbol &S, size_t Index);
void MakeSectionReal(COFFSection &S, size_t Number);
@@ -397,7 +397,8 @@ void WinCOFFObjectWriter::DefineSection(
/// This function takes a section data object from the assembler
/// and creates the associated COFF symbol staging object.
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
- MCAssembler &Assembler) {
+ MCAssembler &Assembler,
+ const MCAsmLayout &Layout) {
MCSymbol const &Symbol = SymbolData.getSymbol();
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
SymbolMap[&Symbol] = coff_symbol;
@@ -438,6 +439,12 @@ void WinCOFFObjectWriter::DefineSymbol(M
const MCSymbolData &ResSymData =
Assembler.getSymbolData(Symbol.AliasedSymbol());
+ if (Symbol.isVariable()) {
+ int64_t Addr;
+ if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout))
+ coff_symbol->Data.Value = Addr;
+ }
+
coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0;
coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16;
@@ -449,7 +456,9 @@ void WinCOFFObjectWriter::DefineSymbol(M
external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
}
- if (ResSymData.Fragment != NULL)
+ if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable())
+ coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
+ else if (ResSymData.Fragment != NULL)
coff_symbol->Section =
SectionMap[&ResSymData.Fragment->getParent()->getSection()];
@@ -597,7 +606,7 @@ void WinCOFFObjectWriter::ExecutePostLay
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
e = Asm.symbol_end();
i != e; i++)
- DefineSymbol(*i, Asm);
+ DefineSymbol(*i, Asm, Layout);
}
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=190898&r1=190897&r2=190898&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Tue Sep 17 18:18:05 2013
@@ -518,6 +518,26 @@ bool X86AsmPrinter::PrintAsmMemoryOperan
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget->isTargetEnvMacho())
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
+
+ if (Subtarget->isTargetCOFF()) {
+ // 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.
+ S->setAbsolute();
+ OutStreamer.EmitAssignment(
+ S, MCConstantExpr::Create(int64_t(1), MMI->getContext()));
+ }
+ }
}
Added: llvm/trunk/test/CodeGen/X86/coff-feat00.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/coff-feat00.ll?rev=190898&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/coff-feat00.ll (added)
+++ llvm/trunk/test/CodeGen/X86/coff-feat00.ll Tue Sep 17 18:18:05 2013
@@ -0,0 +1,7 @@
+; RUN: llc -O0 -mtriple=i386-pc-win32 -filetype=asm -o - %s | FileCheck %s
+
+define i32 @foo() {
+ ret i32 0
+}
+
+; CHECK: @feat.00 = 1
Added: llvm/trunk/test/MC/COFF/feat00.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/feat00.s?rev=190898&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/feat00.s (added)
+++ llvm/trunk/test/MC/COFF/feat00.s Tue Sep 17 18:18:05 2013
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s -o - | llvm-readobj -t | FileCheck %s
+
+"@feat.00" = 123
+
+// CHECK: Symbol {
+// CHECK: Name: @feat.00
+// CHECK: Value: 123
+// CHECK: Section: (-1)
+// CHECK: BaseType: Null (0x0)
+// CHECK: ComplexType: Null (0x0)
+// CHECK: StorageClass: External (0x2)
+// CHECK: AuxSymbolCount: 0
+// CHECK: }
More information about the llvm-commits
mailing list