diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-09-17 23:18:05 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-09-17 23:18:05 +0000 |
commit | 28860823ad34d41d4f58561dc14a982fb0843fdd (patch) | |
tree | c9accba4573b7a3d6dad99873d16f283411b017a /lib/MC/WinCOFFObjectWriter.cpp | |
parent | c61c8116212c68ebc81a9dc06327d6cc806b1f08 (diff) | |
download | external_llvm-28860823ad34d41d4f58561dc14a982fb0843fdd.zip external_llvm-28860823ad34d41d4f58561dc14a982fb0843fdd.tar.gz external_llvm-28860823ad34d41d4f58561dc14a982fb0843fdd.tar.bz2 |
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 263151c..3252317 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -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(MCSectionData const &SectionData) { /// 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(MCSymbolData const &SymbolData, 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(MCSymbolData const &SymbolData, 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::ExecutePostLayoutBinding(MCAssembler &Asm, 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, |