mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
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
This commit is contained in:
parent
c61c811621
commit
28860823ad
@ -148,8 +148,8 @@ public:
|
|||||||
object_t *createCOFFEntity(StringRef Name, list_t &List);
|
object_t *createCOFFEntity(StringRef Name, list_t &List);
|
||||||
|
|
||||||
void DefineSection(MCSectionData const &SectionData);
|
void DefineSection(MCSectionData const &SectionData);
|
||||||
void DefineSymbol(MCSymbolData const &SymbolData,
|
void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
|
||||||
MCAssembler &Assembler);
|
const MCAsmLayout &Layout);
|
||||||
|
|
||||||
void MakeSymbolReal(COFFSymbol &S, size_t Index);
|
void MakeSymbolReal(COFFSymbol &S, size_t Index);
|
||||||
void MakeSectionReal(COFFSection &S, size_t Number);
|
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
|
/// This function takes a section data object from the assembler
|
||||||
/// and creates the associated COFF symbol staging object.
|
/// and creates the associated COFF symbol staging object.
|
||||||
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
||||||
MCAssembler &Assembler) {
|
MCAssembler &Assembler,
|
||||||
|
const MCAsmLayout &Layout) {
|
||||||
MCSymbol const &Symbol = SymbolData.getSymbol();
|
MCSymbol const &Symbol = SymbolData.getSymbol();
|
||||||
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
|
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
|
||||||
SymbolMap[&Symbol] = coff_symbol;
|
SymbolMap[&Symbol] = coff_symbol;
|
||||||
@ -438,6 +439,12 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
|||||||
const MCSymbolData &ResSymData =
|
const MCSymbolData &ResSymData =
|
||||||
Assembler.getSymbolData(Symbol.AliasedSymbol());
|
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.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0;
|
||||||
coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16;
|
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;
|
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 =
|
coff_symbol->Section =
|
||||||
SectionMap[&ResSymData.Fragment->getParent()->getSection()];
|
SectionMap[&ResSymData.Fragment->getParent()->getSection()];
|
||||||
|
|
||||||
@ -597,7 +606,7 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
|
|||||||
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
|
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
|
||||||
e = Asm.symbol_end();
|
e = Asm.symbol_end();
|
||||||
i != e; i++)
|
i != e; i++)
|
||||||
DefineSymbol(*i, Asm);
|
DefineSymbol(*i, Asm, Layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
|
||||||
|
@ -518,6 +518,26 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
|||||||
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
|
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||||
if (Subtarget->isTargetEnvMacho())
|
if (Subtarget->isTargetEnvMacho())
|
||||||
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
7
test/CodeGen/X86/coff-feat00.ll
Normal file
7
test/CodeGen/X86/coff-feat00.ll
Normal file
@ -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
|
13
test/MC/COFF/feat00.s
Normal file
13
test/MC/COFF/feat00.s
Normal file
@ -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: }
|
Loading…
Reference in New Issue
Block a user