diff options
author | Hans Wennborg <hans@hanshq.net> | 2018-09-19 09:58:30 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2018-09-19 09:58:30 +0000 |
commit | 4195eb1068d54fcdd3e942815bbde27248e81488 (patch) | |
tree | 69f8012ce81e3dd4bce334fb19b6601b33361292 /llvm | |
parent | e2b16389e7cde75996aeba698b9c95adf7e4995e (diff) | |
download | bcm5719-llvm-4195eb1068d54fcdd3e942815bbde27248e81488.tar.gz bcm5719-llvm-4195eb1068d54fcdd3e942815bbde27248e81488.zip |
[COFF] Emit @feat.00 on 64-bit and set the CFG bit when emitting guardcf tables
The 0x800 bit in @feat.00 needs to be set in order to make LLD pick up
the .gfid$y table. I believe this is fine to set even if we don't emit
the instrumentation.
We haven't emitted @feat.00 on 64-bit before. I see that MSVC does emit
it, but I'm not entirely sure what the default value should be. I went
with zero since that seems as safe as not emitting the symbol in the
first place.
Differential Revision: https://reviews.llvm.org/D52235
llvm-svn: 342532
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 23 | ||||
-rw-r--r-- | llvm/test/CodeGen/WinCFGuard/cfguard.ll | 2 |
2 files changed, 17 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index c6026f8378c..74dbdcd2793 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -587,21 +587,28 @@ void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { if (TT.isOSBinFormatCOFF()) { // Emit an absolute @feat.00 symbol. This appears to be some kind of // compiler features bitfield read by link.exe. + 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(); + int64_t Feat00Flags = 0; + if (TT.getArch() == Triple::x86) { - 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->EmitSymbolAttribute(S, MCSA_Global); - OutStreamer->EmitAssignment( - S, MCConstantExpr::create(int64_t(1), MMI->getContext())); + Feat00Flags |= 1; } + + if (M.getModuleFlag("cfguardtable")) + Feat00Flags |= 0x800; // Object is CFG-aware. + + OutStreamer->EmitSymbolAttribute(S, MCSA_Global); + OutStreamer->EmitAssignment( + S, MCConstantExpr::create(Feat00Flags, MMI->getContext())); } OutStreamer->EmitSyntaxDirective(); diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard.ll b/llvm/test/CodeGen/WinCFGuard/cfguard.ll index b0a71936a84..2ddd3463219 100644 --- a/llvm/test/CodeGen/WinCFGuard/cfguard.ll +++ b/llvm/test/CodeGen/WinCFGuard/cfguard.ll @@ -1,5 +1,7 @@ ; RUN: llc < %s | FileCheck %s +; CHECK: .set @feat.00, 2048 + ; CHECK: .section .gfids$y ; CHECK: .symidx "?address_taken@@YAXXZ" ; CHECK: .symidx "?virt_method@Derived@@UEBAHXZ" |