aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-09-17 23:18:05 +0000
committerReid Kleckner <reid@kleckner.net>2013-09-17 23:18:05 +0000
commit28860823ad34d41d4f58561dc14a982fb0843fdd (patch)
treec9accba4573b7a3d6dad99873d16f283411b017a /lib/MC/WinCOFFObjectWriter.cpp
parentc61c8116212c68ebc81a9dc06327d6cc806b1f08 (diff)
downloadexternal_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.cpp19
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,