mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Reland "Emit Function IDs table for Control Flow Guard"
Adds option /guard:cf to clang-cl and -cfguard to cc1 to emit function IDs of functions that have their address taken into a section named .gfids$y for compatibility with Microsoft's Control Flow Guard feature. The original patch didn't have the lit.local.cfg file that restricts the new test to x86, thus the new test was failing on the non-x86 bots. Differential Revision: https://reviews.llvm.org/D40531 The reverts r322008, which was a revert of r322005. This reverts commit a05b89f9aca70597dc79fe97bc49b50b51f525ba. llvm-svn: 322136
This commit is contained in:
parent
9c22504bad
commit
de2d0196a2
@ -196,6 +196,7 @@ protected:
|
||||
MCSection *PDataSection;
|
||||
MCSection *XDataSection;
|
||||
MCSection *SXDataSection;
|
||||
MCSection *GFIDsSection;
|
||||
|
||||
public:
|
||||
void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
|
||||
@ -349,6 +350,7 @@ public:
|
||||
MCSection *getPDataSection() const { return PDataSection; }
|
||||
MCSection *getXDataSection() const { return XDataSection; }
|
||||
MCSection *getSXDataSection() const { return SXDataSection; }
|
||||
MCSection *getGFIDsSection() const { return GFIDsSection; }
|
||||
|
||||
MCSection *getEHFrameSection() {
|
||||
return EHFrameSection;
|
||||
|
@ -500,6 +500,9 @@ public:
|
||||
|
||||
virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol);
|
||||
|
||||
/// \brief Emits the symbol table index of a Symbol into the current section.
|
||||
virtual void EmitCOFFSymbolIndex(MCSymbol const *Symbol);
|
||||
|
||||
/// \brief Emits a COFF section index.
|
||||
///
|
||||
/// \param Symbol - Symbol the section number relocation should point to.
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
void EmitCOFFSymbolType(int Type) override;
|
||||
void EndCOFFSymbolDef() override;
|
||||
void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
|
||||
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "CodeViewDebug.h"
|
||||
#include "DwarfDebug.h"
|
||||
#include "DwarfException.h"
|
||||
#include "WinCFGuard.h"
|
||||
#include "WinException.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
@ -130,6 +131,8 @@ static const char *const DbgTimerName = "emit";
|
||||
static const char *const DbgTimerDescription = "Debug Info Emission";
|
||||
static const char *const EHTimerName = "write_exception";
|
||||
static const char *const EHTimerDescription = "DWARF Exception Writer";
|
||||
static const char *const CFGuardName = "Control Flow Guard";
|
||||
static const char *const CFGuardDescription = "Control Flow Guard Tables";
|
||||
static const char *const CodeViewLineTablesGroupName = "linetables";
|
||||
static const char *const CodeViewLineTablesGroupDescription =
|
||||
"CodeView Line Tables";
|
||||
@ -354,6 +357,13 @@ bool AsmPrinter::doInitialization(Module &M) {
|
||||
if (ES)
|
||||
Handlers.push_back(HandlerInfo(ES, EHTimerName, EHTimerDescription,
|
||||
DWARFGroupName, DWARFGroupDescription));
|
||||
|
||||
if (mdconst::extract_or_null<ConstantInt>(
|
||||
MMI->getModule()->getModuleFlag("cfguard")))
|
||||
Handlers.push_back(HandlerInfo(new WinCFGuard(this), CFGuardName,
|
||||
CFGuardDescription, DWARFGroupName,
|
||||
DWARFGroupDescription));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ add_llvm_library(LLVMAsmPrinter
|
||||
EHStreamer.cpp
|
||||
ErlangGCPrinter.cpp
|
||||
OcamlGCPrinter.cpp
|
||||
WinCFGuard.cpp
|
||||
WinException.cpp
|
||||
CodeViewDebug.cpp
|
||||
|
||||
|
45
lib/CodeGen/AsmPrinter/WinCFGuard.cpp
Normal file
45
lib/CodeGen/AsmPrinter/WinCFGuard.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
//===-- CodeGen/AsmPrinter/WinCFGuard.cpp - Control Flow Guard Impl ------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains support for writing Win64 exception info into asm files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WinCFGuard.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCObjectFileInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
WinCFGuard::WinCFGuard(AsmPrinter *A) : AsmPrinterHandler(), Asm(A) {}
|
||||
|
||||
WinCFGuard::~WinCFGuard() {}
|
||||
|
||||
void WinCFGuard::endModule() {
|
||||
const Module *M = Asm->MMI->getModule();
|
||||
std::vector<const Function *> Functions;
|
||||
for (const Function &F : *M)
|
||||
if (F.hasAddressTaken())
|
||||
Functions.push_back(&F);
|
||||
if (Functions.empty())
|
||||
return;
|
||||
auto &OS = *Asm->OutStreamer;
|
||||
OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGFIDsSection());
|
||||
for (const Function *F : Functions)
|
||||
OS.EmitCOFFSymbolIndex(Asm->getSymbol(F));
|
||||
}
|
54
lib/CodeGen/AsmPrinter/WinCFGuard.h
Normal file
54
lib/CodeGen/AsmPrinter/WinCFGuard.h
Normal file
@ -0,0 +1,54 @@
|
||||
//===-- WinCFGuard.h - Windows Control Flow Guard Handling ----*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains support for writing windows exception info into asm files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCFGUARD_H
|
||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_WINCFGUARD_H
|
||||
|
||||
#include "AsmPrinterHandler.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY WinCFGuard : public AsmPrinterHandler {
|
||||
/// Target of directive emission.
|
||||
AsmPrinter *Asm;
|
||||
|
||||
public:
|
||||
WinCFGuard(AsmPrinter *A);
|
||||
~WinCFGuard() override;
|
||||
|
||||
void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
|
||||
|
||||
/// \brief Emit the Control Flow Guard function ID table
|
||||
void endModule() override;
|
||||
|
||||
/// \brief Gather pre-function debug information.
|
||||
/// Every beginFunction(MF) call should be followed by an endFunction(MF)
|
||||
/// call.
|
||||
void beginFunction(const MachineFunction *MF) override {}
|
||||
|
||||
/// \brief Gather post-function debug information.
|
||||
/// Please note that some AsmPrinter implementations may not call
|
||||
/// beginFunction at all.
|
||||
void endFunction(const MachineFunction *MF) override {}
|
||||
|
||||
/// \brief Process beginning of an instruction.
|
||||
void beginInstruction(const MachineInstr *MI) override {}
|
||||
|
||||
/// \brief Process end of an instruction.
|
||||
void endInstruction() override {}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -151,6 +151,7 @@ public:
|
||||
void EmitCOFFSymbolType(int Type) override;
|
||||
void EndCOFFSymbolDef() override;
|
||||
void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
|
||||
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
|
||||
@ -649,6 +650,12 @@ void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {
|
||||
OS << "\t.symidx\t";
|
||||
Symbol->print(OS, MAI);
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
|
||||
OS << "\t.secidx\t";
|
||||
Symbol->print(OS, MAI);
|
||||
|
@ -819,6 +819,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
|
||||
SXDataSection = Ctx->getCOFFSection(".sxdata", COFF::IMAGE_SCN_LNK_INFO,
|
||||
SectionKind::getMetadata());
|
||||
|
||||
GFIDsSection = Ctx->getCOFFSection(".gfids$y",
|
||||
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata());
|
||||
|
||||
TLSDataSection = Ctx->getCOFFSection(
|
||||
".tls$", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
|
||||
COFF::IMAGE_SCN_MEM_WRITE,
|
||||
|
@ -65,8 +65,9 @@ class COFFAsmParser : public MCAsmParserExtension {
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(".symidx");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
|
||||
addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
|
||||
|
||||
// Win64 EH directives.
|
||||
@ -130,6 +131,7 @@ class COFFAsmParser : public MCAsmParserExtension {
|
||||
bool ParseDirectiveSecRel32(StringRef, SMLoc);
|
||||
bool ParseDirectiveSecIdx(StringRef, SMLoc);
|
||||
bool ParseDirectiveSafeSEH(StringRef, SMLoc);
|
||||
bool ParseDirectiveSymIdx(StringRef, SMLoc);
|
||||
bool parseCOMDATType(COFF::COMDATType &Type);
|
||||
bool ParseDirectiveLinkOnce(StringRef, SMLoc);
|
||||
|
||||
@ -520,6 +522,21 @@ bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseDirectiveSymIdx(StringRef, SMLoc) {
|
||||
StringRef SymbolID;
|
||||
if (getParser().parseIdentifier(SymbolID))
|
||||
return TokError("expected identifier in directive");
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitCOFFSymbolIndex(Symbol);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ::= [ identifier ]
|
||||
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
|
||||
StringRef TypeId = getTok().getIdentifier();
|
||||
|
@ -795,6 +795,8 @@ void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
|
||||
void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
|
||||
|
||||
void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
|
||||
}
|
||||
|
||||
|
@ -193,6 +193,17 @@ void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
|
||||
<< COFF::SCT_COMPLEX_TYPE_SHIFT);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {
|
||||
MCSection *Sec = getCurrentSectionOnly();
|
||||
getAssembler().registerSection(*Sec);
|
||||
if (Sec->getAlignment() < 4)
|
||||
Sec->setAlignment(4);
|
||||
|
||||
new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
|
||||
|
||||
getAssembler().registerSymbol(*Symbol);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::EmitCOFFSectionIndex(const MCSymbol *Symbol) {
|
||||
visitUsedSymbol(*Symbol);
|
||||
MCDataFragment *DF = getOrCreateDataFragment();
|
||||
|
162
test/CodeGen/WinCFGuard/cfguard.ll
Normal file
162
test/CodeGen/WinCFGuard/cfguard.ll
Normal file
@ -0,0 +1,162 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
|
||||
; CHECK: .section .gfids$y
|
||||
; CHECK: .symidx "?address_taken@@YAXXZ"
|
||||
; CHECK: .symidx "?virt_method@Derived@@UEBAHXZ"
|
||||
|
||||
; ModuleID = 'cfguard.cpp'
|
||||
source_filename = "cfguard.cpp"
|
||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
%struct.Derived = type { %struct.Base }
|
||||
%struct.Base = type { i32 (...)** }
|
||||
%rtti.CompleteObjectLocator = type { i32, i32, i32, i32, i32, i32 }
|
||||
%rtti.TypeDescriptor13 = type { i8**, i8*, [14 x i8] }
|
||||
%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, i32 }
|
||||
%rtti.BaseClassDescriptor = type { i32, i32, i32, i32, i32, i32, i32 }
|
||||
%rtti.TypeDescriptor10 = type { i8**, i8*, [11 x i8] }
|
||||
|
||||
$"\01??0Derived@@QEAA@XZ" = comdat any
|
||||
|
||||
$"\01??0Base@@QEAA@XZ" = comdat any
|
||||
|
||||
$"\01?virt_method@Derived@@UEBAHXZ" = comdat any
|
||||
|
||||
$"\01??_7Derived@@6B@" = comdat largest
|
||||
|
||||
$"\01??_R4Derived@@6B@" = comdat any
|
||||
|
||||
$"\01??_R0?AUDerived@@@8" = comdat any
|
||||
|
||||
$"\01??_R3Derived@@8" = comdat any
|
||||
|
||||
$"\01??_R2Derived@@8" = comdat any
|
||||
|
||||
$"\01??_R1A@?0A@EA@Derived@@8" = comdat any
|
||||
|
||||
$"\01??_R1A@?0A@EA@Base@@8" = comdat any
|
||||
|
||||
$"\01??_R0?AUBase@@@8" = comdat any
|
||||
|
||||
$"\01??_R3Base@@8" = comdat any
|
||||
|
||||
$"\01??_R2Base@@8" = comdat any
|
||||
|
||||
$"\01??_7Base@@6B@" = comdat largest
|
||||
|
||||
$"\01??_R4Base@@6B@" = comdat any
|
||||
|
||||
@"\01?D@@3UDerived@@A" = global %struct.Derived zeroinitializer, align 8
|
||||
@0 = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4Derived@@6B@" to i8*), i8* bitcast (i32 (%struct.Derived*)* @"\01?virt_method@Derived@@UEBAHXZ" to i8*)] }, comdat($"\01??_7Derived@@6B@")
|
||||
@"\01??_R4Derived@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor13* @"\01??_R0?AUDerived@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Derived@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Derived@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@"\01??_7type_info@@6B@" = external constant i8*
|
||||
@"\01??_R0?AUDerived@@@8" = linkonce_odr global %rtti.TypeDescriptor13 { i8** @"\01??_7type_info@@6B@", i8* null, [14 x i8] c".?AUDerived@@\00" }, comdat
|
||||
@__ImageBase = external constant i8
|
||||
@"\01??_R3Derived@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2Derived@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@"\01??_R2Derived@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Derived@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Base@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
|
||||
@"\01??_R1A@?0A@EA@Derived@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor13* @"\01??_R0?AUDerived@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Derived@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@"\01??_R1A@?0A@EA@Base@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor10* @"\01??_R0?AUBase@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Base@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@"\01??_R0?AUBase@@@8" = linkonce_odr global %rtti.TypeDescriptor10 { i8** @"\01??_7type_info@@6B@", i8* null, [11 x i8] c".?AUBase@@\00" }, comdat
|
||||
@"\01??_R3Base@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Base@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@"\01??_R2Base@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Base@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
|
||||
@1 = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4Base@@6B@" to i8*), i8* bitcast (void ()* @_purecall to i8*)] }, comdat($"\01??_7Base@@6B@")
|
||||
@"\01??_R4Base@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor10* @"\01??_R0?AUBase@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Base@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Base@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
|
||||
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_cfguard.cpp, i8* null }]
|
||||
|
||||
@"\01??_7Derived@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @0, i32 0, i32 0, i32 1)
|
||||
@"\01??_7Base@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @1, i32 0, i32 0, i32 1)
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define internal void @"\01??__ED@@YAXXZ"() #0 {
|
||||
entry:
|
||||
%call = call %struct.Derived* @"\01??0Derived@@QEAA@XZ"(%struct.Derived* @"\01?D@@3UDerived@@A") #2
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define linkonce_odr %struct.Derived* @"\01??0Derived@@QEAA@XZ"(%struct.Derived* returned %this) unnamed_addr #1 comdat align 2 {
|
||||
entry:
|
||||
%this.addr = alloca %struct.Derived*, align 8
|
||||
store %struct.Derived* %this, %struct.Derived** %this.addr, align 8
|
||||
%this1 = load %struct.Derived*, %struct.Derived** %this.addr, align 8
|
||||
%0 = bitcast %struct.Derived* %this1 to %struct.Base*
|
||||
%call = call %struct.Base* @"\01??0Base@@QEAA@XZ"(%struct.Base* %0) #2
|
||||
%1 = bitcast %struct.Derived* %this1 to i32 (...)***
|
||||
store i32 (...)** bitcast (i8** @"\01??_7Derived@@6B@" to i32 (...)**), i32 (...)*** %1, align 8
|
||||
ret %struct.Derived* %this1
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define void @"\01?address_taken@@YAXXZ"() #1 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define void ()* @"\01?foo@@YAP6AXXZPEAUBase@@@Z"(%struct.Base* %B) #1 {
|
||||
entry:
|
||||
%retval = alloca void ()*, align 8
|
||||
%B.addr = alloca %struct.Base*, align 8
|
||||
store %struct.Base* %B, %struct.Base** %B.addr, align 8
|
||||
%0 = load %struct.Base*, %struct.Base** %B.addr, align 8
|
||||
%1 = bitcast %struct.Base* %0 to i32 (%struct.Base*)***
|
||||
%vtable = load i32 (%struct.Base*)**, i32 (%struct.Base*)*** %1, align 8
|
||||
%vfn = getelementptr inbounds i32 (%struct.Base*)*, i32 (%struct.Base*)** %vtable, i64 0
|
||||
%2 = load i32 (%struct.Base*)*, i32 (%struct.Base*)** %vfn, align 8
|
||||
%call = call i32 %2(%struct.Base* %0)
|
||||
%tobool = icmp ne i32 %call, 0
|
||||
br i1 %tobool, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
store void ()* @"\01?address_taken@@YAXXZ", void ()** %retval, align 8
|
||||
br label %return
|
||||
|
||||
if.end: ; preds = %entry
|
||||
store void ()* null, void ()** %retval, align 8
|
||||
br label %return
|
||||
|
||||
return: ; preds = %if.end, %if.then
|
||||
%3 = load void ()*, void ()** %retval, align 8
|
||||
ret void ()* %3
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define linkonce_odr %struct.Base* @"\01??0Base@@QEAA@XZ"(%struct.Base* returned %this) unnamed_addr #1 comdat align 2 {
|
||||
entry:
|
||||
%this.addr = alloca %struct.Base*, align 8
|
||||
store %struct.Base* %this, %struct.Base** %this.addr, align 8
|
||||
%this1 = load %struct.Base*, %struct.Base** %this.addr, align 8
|
||||
%0 = bitcast %struct.Base* %this1 to i32 (...)***
|
||||
store i32 (...)** bitcast (i8** @"\01??_7Base@@6B@" to i32 (...)**), i32 (...)*** %0, align 8
|
||||
ret %struct.Base* %this1
|
||||
}
|
||||
|
||||
; Function Attrs: noinline nounwind optnone
|
||||
define linkonce_odr i32 @"\01?virt_method@Derived@@UEBAHXZ"(%struct.Derived* %this) unnamed_addr #1 comdat align 2 {
|
||||
entry:
|
||||
%this.addr = alloca %struct.Derived*, align 8
|
||||
store %struct.Derived* %this, %struct.Derived** %this.addr, align 8
|
||||
%this1 = load %struct.Derived*, %struct.Derived** %this.addr, align 8
|
||||
ret i32 42
|
||||
}
|
||||
|
||||
declare dllimport void @_purecall() unnamed_addr
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define internal void @_GLOBAL__sub_I_cfguard.cpp() #0 {
|
||||
entry:
|
||||
call void @"\01??__ED@@YAXXZ"()
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.ident = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"cfguard", i32 1}
|
||||
!1 = !{i32 1, !"wchar_size", i32 2}
|
||||
!2 = !{!"clang version 6.0.0 "}
|
2
test/CodeGen/WinCFGuard/lit.local.cfg
Normal file
2
test/CodeGen/WinCFGuard/lit.local.cfg
Normal file
@ -0,0 +1,2 @@
|
||||
if not 'X86' in config.root.targets:
|
||||
config.unsupported = True
|
15
test/MC/COFF/symidx.s
Normal file
15
test/MC/COFF/symidx.s
Normal file
@ -0,0 +1,15 @@
|
||||
// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-objdump -s -t - | FileCheck %s
|
||||
.text
|
||||
foo:
|
||||
ret
|
||||
bar:
|
||||
ret
|
||||
.data
|
||||
.symidx bar
|
||||
.symidx foo
|
||||
|
||||
// CHECK: Contents of section .data:
|
||||
// CHECK-NEXT: 0000 0[[BAR:[1-9]]]000000 0[[FOO:[1-9]]]000000
|
||||
// CHECK: SYMBOL TABLE:
|
||||
// CHECK: [ [[FOO]]](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 foo
|
||||
// CHECK-NEXT: [ [[BAR]]](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000001 bar
|
Loading…
Reference in New Issue
Block a user