From 4195eb1068d54fcdd3e942815bbde27248e81488 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 19 Sep 2018 09:58:30 +0000 Subject: [PATCH] [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 --- llvm/lib/Target/X86/X86AsmPrinter.cpp | 23 +++++++++++++++-------- 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 c6026f8..74dbdcd 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 b0a7193..2ddd346 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" -- 2.7.4