[llvm] r230780 - Remove the Forward Control Flow Integrity pass and its dependencies.
Eric Christopher
echristo at gmail.com
Wed Mar 4 14:12:26 PST 2015
I can't, but Kostya and Peter can :)
-eric
On Wed, Mar 4, 2015 at 2:09 PM Chad Rosier <mcrosier at codeaurora.org> wrote:
> Hi Eric,
> We (Qualcomm) are very interested in compiler-based mitigations and we’d
> like to learn more about the new direction. Could you share the thought
> process?
>
> Chad
>
> > Author: echristo
> > Date: Fri Feb 27 13:03:38 2015
> > New Revision: 230780
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=230780&view=rev
> > Log:
> > Remove the Forward Control Flow Integrity pass and its dependencies.
> >
> > This work is currently being rethought along different lines and
> > if this work is needed it can be resurrected out of svn. Remove it
> > for now as no current work in ongoing on it and it's unused. Verified
> > with the authors before removal.
> >
> > Removed:
> > llvm/trunk/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
> > llvm/trunk/include/llvm/CodeGen/JumpInstrTables.h
> > llvm/trunk/lib/Analysis/JumpInstrTableInfo.cpp
> > llvm/trunk/lib/CodeGen/ForwardControlFlowIntegrity.cpp
> > llvm/trunk/lib/CodeGen/JumpInstrTables.cpp
> > llvm/trunk/test/CodeGen/X86/cfi_enforcing.ll
> > llvm/trunk/test/CodeGen/X86/cfi_invoke.ll
> > llvm/trunk/test/CodeGen/X86/cfi_non_default_function.ll
> > llvm/trunk/test/CodeGen/X86/cfi_simple_indirect_call.ll
> > llvm/trunk/test/CodeGen/X86/jump_table_alias.ll
> > llvm/trunk/test/CodeGen/X86/jump_table_align.ll
> > llvm/trunk/test/CodeGen/X86/jump_table_bitcast.ll
> > llvm/trunk/test/CodeGen/X86/jump_tables.ll
> > llvm/trunk/test/LTO/X86/jump-table-type.ll
> > Modified:
> > llvm/trunk/include/llvm/Analysis/Passes.h
> > llvm/trunk/include/llvm/InitializePasses.h
> > llvm/trunk/include/llvm/LinkAllPasses.h
> > llvm/trunk/lib/Analysis/Analysis.cpp
> > llvm/trunk/lib/Analysis/CMakeLists.txt
> > llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
> > llvm/trunk/lib/CodeGen/CMakeLists.txt
> > llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> > llvm/trunk/test/CodeGen/Generic/stop-after.ll
> >
> > Modified: llvm/trunk/include/llvm/Analysis/Passes.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/Analysis/Passes.h?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/include/llvm/Analysis/Passes.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/Passes.h Fri Feb 27 13:03:38 2015
> > @@ -159,10 +159,6 @@ namespace llvm {
> > //
> > FunctionPass *createMemDepPrinter();
> >
> > - // createJumpInstrTableInfoPass - This creates a pass that stores
> > information
> > - // about the jump tables created by JumpInstrTables
> > - ImmutablePass *createJumpInstrTableInfoPass();
> > -
> > //===-------------------------------------------------------
> -------------===//
> > //
> > // createMemDerefPrinter - This pass collects memory
> dereferenceability
> >
> > Removed: llvm/trunk/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/
> ForwardControlFlowIntegrity.h?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
> > (original)
> > +++ llvm/trunk/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
> > (removed)
> > @@ -1,122 +0,0 @@
> > -//===-- ForwardControlFlowIntegrity.h: Forward-Edge CFI ---------*- C++
> > -*-===//
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -//
> > -// This pass instruments indirect calls with checks to ensure that these
> > calls
> > -// pass through the appropriate jump-instruction table generated by
> > -// JumpInstrTables.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -
> > -#ifndef LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
> > -#define LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
> > -
> > -#include "llvm/ADT/DenseMap.h"
> > -#include "llvm/ADT/SmallVector.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Target/TargetOptions.h"
> > -#include <string>
> > -
> > -namespace llvm {
> > -
> > -class AnalysisUsage;
> > -class BasicBlock;
> > -class Constant;
> > -class Function;
> > -class Instruction;
> > -class Module;
> > -class Value;
> > -
> > -/// ForwardControlFlowIntegrity uses the information from
> > JumpInstrTableInfo to
> > -/// prepend checks to indirect calls to make sure that these calls
> target
> > valid
> > -/// locations.
> > -class ForwardControlFlowIntegrity : public ModulePass {
> > -public:
> > - static char ID;
> > -
> > - ForwardControlFlowIntegrity();
> > - ForwardControlFlowIntegrity(JumpTable::JumpTableType JTT,
> > - CFIntegrity CFIType,
> > - bool CFIEnforcing, std::string
> > CFIFuncName);
> > - ~ForwardControlFlowIntegrity() override;
> > -
> > - /// Runs the CFI pass on a given module. This works best if the module
> > in
> > - /// question is the result of link-time optimization (see lib/LTO).
> > - bool runOnModule(Module &M) override;
> > - const char *getPassName() const override {
> > - return "Forward Control-Flow Integrity";
> > - }
> > - void getAnalysisUsage(AnalysisUsage &AU) const override;
> > -
> > -private:
> > - typedef SmallVector<Instruction *, 64> CallSet;
> > -
> > - /// A structure that is used to keep track of constant table
> > information.
> > - struct CFIConstants {
> > - Constant *StartValue;
> > - Constant *MaskValue;
> > - Constant *Size;
> > - };
> > -
> > - /// A map from function type to the base of the table for this type
> and
> > a mask
> > - /// for the table
> > - typedef DenseMap<FunctionType *, CFIConstants> CFITables;
> > -
> > - CallSet IndirectCalls;
> > -
> > - /// The type of jumptable implementation.
> > - JumpTable::JumpTableType JTType;
> > -
> > - /// The type of CFI check to add before each indirect call.
> > - CFIntegrity CFIType;
> > -
> > - /// A value that controls whether or not CFI violations cause a halt.
> > - bool CFIEnforcing;
> > -
> > - /// The name of the function to call in case of a CFI violation when
> > - /// CFIEnforcing is false. There is a default function that ignores
> > - /// violations.
> > - std::string CFIFuncName;
> > -
> > - /// The alignment of each entry in the table, from JumpInstrTableInfo.
> > The
> > - /// JumpInstrTableInfo class always makes this a power of two.
> > - uint64_t ByteAlignment;
> > -
> > - /// The base-2 logarithm of ByteAlignment, needed for some of the
> > transforms
> > - /// (like CFIntegrity::Ror)
> > - unsigned LogByteAlignment;
> > -
> > - /// Adds checks to each indirect call site to make sure that it is
> > calling a
> > - /// function in our jump table.
> > - void updateIndirectCalls(Module &M, CFITables &CFIT);
> > -
> > - /// Walks the instructions to find all the indirect calls.
> > - void getIndirectCalls(Module &M);
> > -
> > - /// Adds a function that handles violations in non-enforcing mode
> > - /// (!CFIEnforcing). The default warning function simply returns,
> since
> > the
> > - /// exact details of how to handle CFI violations depend on the
> > application.
> > - void addWarningFunction(Module &M);
> > -
> > - /// Rewrites a function pointer in a call/invoke instruction to force
> > it into
> > - /// a table.
> > - void rewriteFunctionPointer(Module &M, Instruction *I, Value *FunPtr,
> > - Constant *JumpTableStart, Constant
> > *JumpTableMask,
> > - Constant *JumpTableSize);
> > -
> > - /// Inserts a check and a call to a warning function at a given
> > instruction
> > - /// that must be an indirect call.
> > - void insertWarning(Module &M, BasicBlock *Block, Instruction *I,
> > - Value *FunPtr);
> > -};
> > -
> > -ModulePass *
> > -createForwardControlFlowIntegrityPass(JumpTable::JumpTableType JTT,
> > - CFIntegrity CFIType,
> > - bool CFIEnforcing, StringRef
> > CFIFuncName);
> > -}
> > -
> > -#endif // LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
> >
> > Removed: llvm/trunk/include/llvm/CodeGen/JumpInstrTables.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/CodeGen/JumpInstrTables.h?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/include/llvm/CodeGen/JumpInstrTables.h (original)
> > +++ llvm/trunk/include/llvm/CodeGen/JumpInstrTables.h (removed)
> > @@ -1,105 +0,0 @@
> > -//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++
> > -*-===//
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -///
> > -/// \file
> > -/// \brief An implementation of tables consisting of jump instructions
> > -///
> > -//===------------------------------------------------------
> ----------------===//
> > -
> > -#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H
> > -#define LLVM_CODEGEN_JUMPINSTRTABLES_H
> > -
> > -#include "llvm/ADT/DenseMap.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Target/TargetOptions.h"
> > -
> > -namespace llvm {
> > -class Constant;
> > -class Function;
> > -class FunctionType;
> > -class JumpInstrTableInfo;
> > -class Module;
> > -
> > -/// A class to manage a set of jump tables indexed on function type. It
> > looks at
> > -/// each function in the module to find all the functions that have the
> > -/// jumptable attribute set. For each such function, it creates a new
> > -/// jump-instruction-table function and stores the mapping in the
> > ImmutablePass
> > -/// JumpInstrTableInfo.
> > -///
> > -/// These special functions get lowered in AsmPrinter to assembly of the
> > form:
> > -/// \verbatim
> > -/// .globl f
> > -/// .type f, at function
> > -/// .align 8,0x90
> > -/// f:
> > -/// jmp f_orig at PLT
> > -/// \endverbatim
> > -///
> > -/// Support for an architecture depends on three functions in
> > TargetInstrInfo:
> > -/// getUnconditionalBranch, getTrap, and getJumpInstrTableEntryBound.
> > AsmPrinter
> > -/// uses these to generate the appropriate instructions for the jump
> > statement
> > -/// (an unconditional branch) and for padding to make the table have a
> > size that
> > -/// is a power of two. This padding uses a trap instruction to ensure
> > that calls
> > -/// to this area halt the program. The default implementations of these
> > -/// functions call llvm_unreachable, except for
> > getJumpInstrTableEntryBound,
> > -/// which returns 0 by default.
> > -class JumpInstrTables : public ModulePass {
> > -public:
> > - static char ID;
> > -
> > - JumpInstrTables();
> > - JumpInstrTables(JumpTable::JumpTableType JTT);
> > - virtual ~JumpInstrTables();
> > - bool runOnModule(Module &M) override;
> > - const char *getPassName() const override { return "Jump-Instruction
> > Tables"; }
> > - void getAnalysisUsage(AnalysisUsage &AU) const override;
> > -
> > - /// Creates a jump-instruction table function for the Target and adds
> > it to
> > - /// the tables.
> > - Function *insertEntry(Module &M, Function *Target);
> > -
> > - /// Checks to see if there is already a table for the given
> > FunctionType.
> > - bool hasTable(FunctionType *FunTy);
> > -
> > - /// Maps the function into a subset of function types, depending on
> the
> > - /// jump-instruction table style selected from JumpTableTypes in
> > - /// JumpInstrTables.cpp. The choice of mapping determines the number
> of
> > - /// jump-instruction tables generated by this pass. E.g., the simplest
> > mapping
> > - /// converts every function type into void f(); so, all functions end
> > up in a
> > - /// single table.
> > - static FunctionType *transformType(JumpTable::JumpTableType JTT,
> > - FunctionType *FunTy);
> > -private:
> > - /// The metadata used while a jump table is being built
> > - struct TableMeta {
> > - /// The number of this table
> > - unsigned TableNum;
> > -
> > - /// The current number of jump entries in the table.
> > - unsigned Count;
> > - };
> > -
> > - typedef DenseMap<FunctionType *, struct TableMeta> JumpMap;
> > -
> > - /// The current state of functions and jump entries in the table(s).
> > - JumpMap Metadata;
> > -
> > - /// The ImmutablePass that stores information about the generated
> > tables.
> > - JumpInstrTableInfo *JITI;
> > -
> > - /// The total number of tables.
> > - unsigned TableCount;
> > -
> > - /// The type of tables to build.
> > - JumpTable::JumpTableType JTType;
> > -};
> > -
> > -/// Creates a JumpInstrTables pass for the given type of jump table.
> > -ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT);
> > -}
> > -
> > -#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */
> >
> > Modified: llvm/trunk/include/llvm/InitializePasses.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/InitializePasses.h?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)
> > +++ llvm/trunk/include/llvm/InitializePasses.h Fri Feb 27 13:03:38 2015
> > @@ -150,8 +150,6 @@ void initializeInstCountPass(PassRegistr
> > void initializeInstNamerPass(PassRegistry&);
> > void initializeInternalizePassPass(PassRegistry&);
> > void initializeIntervalPartitionPass(PassRegistry&);
> > -void initializeJumpInstrTableInfoPass(PassRegistry&);
> > -void initializeJumpInstrTablesPass(PassRegistry&);
> > void initializeJumpThreadingPass(PassRegistry&);
> > void initializeLCSSAPass(PassRegistry&);
> > void initializeLICMPass(PassRegistry&);
> >
> > Modified: llvm/trunk/include/llvm/LinkAllPasses.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/LinkAllPasses.h?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
> > +++ llvm/trunk/include/llvm/LinkAllPasses.h Fri Feb 27 13:03:38 2015
> > @@ -91,8 +91,6 @@ namespace {
> > (void) llvm::createIndVarSimplifyPass();
> > (void) llvm::createInstructionCombiningPass();
> > (void) llvm::createInternalizePass();
> > - (void) llvm::createJumpInstrTableInfoPass();
> > - (void) llvm::createJumpInstrTablesPass();
> > (void) llvm::createLCSSAPass();
> > (void) llvm::createLICMPass();
> > (void) llvm::createLazyValueInfoPass();
> >
> > Modified: llvm/trunk/lib/Analysis/Analysis.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Analysis/Analysis.cpp?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/lib/Analysis/Analysis.cpp (original)
> > +++ llvm/trunk/lib/Analysis/Analysis.cpp Fri Feb 27 13:03:38 2015
> > @@ -49,7 +49,6 @@ void llvm::initializeAnalysis(PassRegist
> > initializeIVUsersPass(Registry);
> > initializeInstCountPass(Registry);
> > initializeIntervalPartitionPass(Registry);
> > - initializeJumpInstrTableInfoPass(Registry);
> > initializeLazyValueInfoPass(Registry);
> > initializeLibCallAliasAnalysisPass(Registry);
> > initializeLintPass(Registry);
> >
> > Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Analysis/CMakeLists.txt?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Analysis/CMakeLists.txt Fri Feb 27 13:03:38 2015
> > @@ -27,7 +27,6 @@ add_llvm_library(LLVMAnalysis
> > InstructionSimplify.cpp
> > Interval.cpp
> > IntervalPartition.cpp
> > - JumpInstrTableInfo.cpp
> > LazyCallGraph.cpp
> > LazyValueInfo.cpp
> > LibCallAliasAnalysis.cpp
> >
> > Removed: llvm/trunk/lib/Analysis/JumpInstrTableInfo.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Analysis/JumpInstrTableInfo.cpp?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/lib/Analysis/JumpInstrTableInfo.cpp (original)
> > +++ llvm/trunk/lib/Analysis/JumpInstrTableInfo.cpp (removed)
> > @@ -1,55 +0,0 @@
> > -//===-- JumpInstrTableInfo.cpp: Info for Jump-Instruction Tables
> > ----------===//
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -///
> > -/// \file
> > -/// \brief Information about jump-instruction tables that have been
> > created by
> > -/// JumpInstrTables pass.
> > -///
> > -//===------------------------------------------------------
> ----------------===//
> > -
> > -#define DEBUG_TYPE "jiti"
> > -
> > -#include "llvm/Analysis/JumpInstrTableInfo.h"
> > -#include "llvm/Analysis/Passes.h"
> > -#include "llvm/IR/Function.h"
> > -#include "llvm/IR/Type.h"
> > -#include "llvm/Support/MathExtras.h"
> > -
> > -using namespace llvm;
> > -
> > -INITIALIZE_PASS(JumpInstrTableInfo, "jump-instr-table-info",
> > - "Jump-Instruction Table Info", true, true)
> > -char JumpInstrTableInfo::ID = 0;
> > -
> > -ImmutablePass *llvm::createJumpInstrTableInfoPass() {
> > - return new JumpInstrTableInfo();
> > -}
> > -
> > -ModulePass *llvm::createJumpInstrTableInfoPass(unsigned Bound) {
> > - // This cast is always safe, since Bound is always in a subset of
> > uint64_t.
> > - uint64_t B = static_cast<uint64_t>(Bound);
> > - return new JumpInstrTableInfo(B);
> > -}
> > -
> > -JumpInstrTableInfo::JumpInstrTableInfo(uint64_t ByteAlign)
> > - : ImmutablePass(ID), Tables(), ByteAlignment(ByteAlign) {
> > - if (!llvm::isPowerOf2_64(ByteAlign)) {
> > - // Note that we don't explicitly handle overflow here, since we
> > handle the 0
> > - // case explicitly when a caller actually tries to create jumptable
> > entries,
> > - // and this is the return value on overflow.
> > - ByteAlignment = llvm::NextPowerOf2(ByteAlign);
> > - }
> > -
> > - initializeJumpInstrTableInfoPass(*PassRegistry::getPassRegistry());
> > -}
> > -
> > -JumpInstrTableInfo::~JumpInstrTableInfo() {}
> > -
> > -void JumpInstrTableInfo::insertEntry(FunctionType *TableFunTy, Function
> > *Target,
> > - Function *Jump) {
> > - Tables[TableFunTy].push_back(JumpPair(Target, Jump));
> > -}
> >
> > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/AsmPrinter/AsmPrinter.cpp?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
> > +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri Feb 27 13:03:38
> > 2015
> > @@ -1018,59 +1018,6 @@ bool AsmPrinter::doFinalization(Module &
> > EmitVisibility(Name, V, false);
> > }
> >
> > - // Get information about jump-instruction tables to print.
> > - JumpInstrTableInfo *JITI =
> > getAnalysisIfAvailable<JumpInstrTableInfo>();
> > -
> > - if (JITI && !JITI->getTables().empty()) {
> > - // Since we're at the module level we can't use a function specific
> > - // MCSubtargetInfo - instead create one with the module defaults.
> > - std::unique_ptr<MCSubtargetInfo>
> > STI(TM.getTarget().createMCSubtargetInfo(
> > - TM.getTargetTriple(), TM.getTargetCPU(),
> > TM.getTargetFeatureString()));
> > - unsigned Arch = Triple(getTargetTriple()).getArch();
> > - bool IsThumb = (Arch == Triple::thumb || Arch == Triple::thumbeb);
> > - const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo();
> > - MCInst TrapInst;
> > - TII->getTrap(TrapInst);
> > - unsigned LogAlignment = llvm::Log2_64(JITI->entryByteAlignment());
> > -
> > - // Emit the right section for these functions.
> > -
> > OutStreamer.SwitchSection(OutContext.getObjectFileInfo()
> ->getTextSection());
> > - for (const auto &KV : JITI->getTables()) {
> > - uint64_t Count = 0;
> > - for (const auto &FunPair : KV.second) {
> > - // Emit the function labels to make this be a function entry
> > point.
> > - MCSymbol *FunSym =
> > - OutContext.GetOrCreateSymbol(FunPair.second->getName());
> > - EmitAlignment(LogAlignment);
> > - if (IsThumb)
> > - OutStreamer.EmitThumbFunc(FunSym);
> > - if (MAI->hasDotTypeDotSizeDirective())
> > - OutStreamer.EmitSymbolAttribute(FunSym,
> MCSA_ELF_TypeFunction);
> > - OutStreamer.EmitLabel(FunSym);
> > -
> > - // Emit the jump instruction to transfer control to the original
> > - // function.
> > - MCInst JumpToFun;
> > - MCSymbol *TargetSymbol =
> > - OutContext.GetOrCreateSymbol(FunPair.first->getName());
> > - const MCSymbolRefExpr *TargetSymRef =
> > - MCSymbolRefExpr::Create(TargetSymbol,
> MCSymbolRefExpr::VK_PLT,
> > - OutContext);
> > - TII->getUnconditionalBranch(JumpToFun, TargetSymRef);
> > - OutStreamer.EmitInstruction(JumpToFun, *STI);
> > - ++Count;
> > - }
> > -
> > - // Emit enough padding instructions to fill up to the next power
> of
> > two.
> > - uint64_t Remaining = NextPowerOf2(Count) - Count;
> > - for (uint64_t C = 0; C < Remaining; ++C) {
> > - EmitAlignment(LogAlignment);
> > - OutStreamer.EmitInstruction(TrapInst, *STI);
> > - }
> > -
> > - }
> > - }
> > -
> > // Emit module flags.
> > SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
> > M.getModuleFlagsMetadata(ModuleFlags);
> >
> > Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/CMakeLists.txt?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/CodeGen/CMakeLists.txt Fri Feb 27 13:03:38 2015
> > @@ -19,7 +19,6 @@ add_llvm_library(LLVMCodeGen
> > ExecutionDepsFix.cpp
> > ExpandISelPseudos.cpp
> > ExpandPostRAPseudos.cpp
> > - ForwardControlFlowIntegrity.cpp
> > GCMetadata.cpp
> > GCMetadataPrinter.cpp
> > GCRootLowering.cpp
> > @@ -29,7 +28,6 @@ add_llvm_library(LLVMCodeGen
> > InlineSpiller.cpp
> > InterferenceCache.cpp
> > IntrinsicLowering.cpp
> > - JumpInstrTables.cpp
> > LLVMTargetMachine.cpp
> > LatencyPriorityQueue.cpp
> > LexicalScopes.cpp
> >
> > Removed: llvm/trunk/lib/CodeGen/ForwardControlFlowIntegrity.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
> ForwardControlFlowIntegrity.cpp?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/lib/CodeGen/ForwardControlFlowIntegrity.cpp (original)
> > +++ llvm/trunk/lib/CodeGen/ForwardControlFlowIntegrity.cpp (removed)
> > @@ -1,374 +0,0 @@
> > -//===-- ForwardControlFlowIntegrity.cpp: Forward-Edge CFI
> > -----------------===//
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -///
> > -/// \file
> > -/// \brief A pass that instruments code with fast checks for indirect
> > calls and
> > -/// hooks for a function to check violations.
> > -///
> > -//===------------------------------------------------------
> ----------------===//
> > -
> > -#define DEBUG_TYPE "cfi"
> > -
> > -#include "llvm/ADT/SmallVector.h"
> > -#include "llvm/ADT/Statistic.h"
> > -#include "llvm/Analysis/JumpInstrTableInfo.h"
> > -#include "llvm/CodeGen/ForwardControlFlowIntegrity.h"
> > -#include "llvm/CodeGen/JumpInstrTables.h"
> > -#include "llvm/CodeGen/Passes.h"
> > -#include "llvm/IR/Attributes.h"
> > -#include "llvm/IR/CallSite.h"
> > -#include "llvm/IR/Constants.h"
> > -#include "llvm/IR/DerivedTypes.h"
> > -#include "llvm/IR/Function.h"
> > -#include "llvm/IR/GlobalValue.h"
> > -#include "llvm/IR/IRBuilder.h"
> > -#include "llvm/IR/InlineAsm.h"
> > -#include "llvm/IR/Instructions.h"
> > -#include "llvm/IR/LLVMContext.h"
> > -#include "llvm/IR/Module.h"
> > -#include "llvm/IR/Operator.h"
> > -#include "llvm/IR/Type.h"
> > -#include "llvm/IR/Verifier.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Support/CommandLine.h"
> > -#include "llvm/Support/Debug.h"
> > -#include "llvm/Support/raw_ostream.h"
> > -
> > -using namespace llvm;
> > -
> > -STATISTIC(NumCFIIndirectCalls,
> > - "Number of indirect call sites rewritten by the CFI pass");
> > -
> > -char ForwardControlFlowIntegrity::ID = 0;
> > -INITIALIZE_PASS_BEGIN(ForwardControlFlowIntegrity, "forward-cfi",
> > - "Control-Flow Integrity", true, true)
> > -INITIALIZE_PASS_DEPENDENCY(JumpInstrTableInfo);
> > -INITIALIZE_PASS_DEPENDENCY(JumpInstrTables);
> > -INITIALIZE_PASS_END(ForwardControlFlowIntegrity, "forward-cfi",
> > - "Control-Flow Integrity", true, true)
> > -
> > -ModulePass *llvm::createForwardControlFlowIntegrityPass() {
> > - return new ForwardControlFlowIntegrity();
> > -}
> > -
> > -ModulePass *llvm::createForwardControlFlowIntegrityPass(
> > - JumpTable::JumpTableType JTT, CFIntegrity CFIType, bool
> CFIEnforcing,
> > - StringRef CFIFuncName) {
> > - return new ForwardControlFlowIntegrity(JTT, CFIType, CFIEnforcing,
> > - CFIFuncName);
> > -}
> > -
> > -// Checks to see if a given CallSite is making an indirect call,
> > including
> > -// cases where the indirect call is made through a bitcast.
> > -static bool isIndirectCall(CallSite &CS) {
> > - if (CS.getCalledFunction())
> > - return false;
> > -
> > - // Check the value to see if it is merely a bitcast of a function. In
> > - // this case, it will translate to a direct function call in the
> > resulting
> > - // assembly, so we won't treat it as an indirect call here.
> > - const Value *V = CS.getCalledValue();
> > - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
> > - return !(CE->isCast() && isa<Function>(CE->getOperand(0)));
> > - }
> > -
> > - // Otherwise, since we know it's a call, it must be an indirect call
> > - return true;
> > -}
> > -
> > -static const char cfi_failure_func_name[] =
> "__llvm_cfi_pointer_warning";
> > -
> > -ForwardControlFlowIntegrity::ForwardControlFlowIntegrity()
> > - : ModulePass(ID), IndirectCalls(), JTType(JumpTable::Single),
> > - CFIType(CFIntegrity::Sub), CFIEnforcing(false), CFIFuncName("") {
> > -
> > initializeForwardControlFlowIntegrityPass(*PassRegistry::
> getPassRegistry());
> > -}
> > -
> > -ForwardControlFlowIntegrity::ForwardControlFlowIntegrity(
> > - JumpTable::JumpTableType JTT, CFIntegrity CFIType, bool
> CFIEnforcing,
> > - std::string CFIFuncName)
> > - : ModulePass(ID), IndirectCalls(), JTType(JTT), CFIType(CFIType),
> > - CFIEnforcing(CFIEnforcing), CFIFuncName(CFIFuncName) {
> > -
> > initializeForwardControlFlowIntegrityPass(*PassRegistry::
> getPassRegistry());
> > -}
> > -
> > -ForwardControlFlowIntegrity::~ForwardControlFlowIntegrity() {}
> > -
> > -void ForwardControlFlowIntegrity::getAnalysisUsage(AnalysisUsage &AU)
> > const {
> > - AU.addRequired<JumpInstrTableInfo>();
> > - AU.addRequired<JumpInstrTables>();
> > -}
> > -
> > -void ForwardControlFlowIntegrity::getIndirectCalls(Module &M) {
> > - // To get the indirect calls, we iterate over all functions and
> iterate
> > over
> > - // the list of basic blocks in each. We extract a total list of
> > indirect calls
> > - // before modifying any of them, since our modifications will modify
> > the list
> > - // of basic blocks.
> > - for (Function &F : M) {
> > - for (BasicBlock &BB : F) {
> > - for (Instruction &I : BB) {
> > - CallSite CS(&I);
> > - if (!(CS && isIndirectCall(CS)))
> > - continue;
> > -
> > - Value *CalledValue = CS.getCalledValue();
> > -
> > - // Don't rewrite this instruction if the indirect call is
> > actually just
> > - // inline assembly, since our transformation will generate an
> > invalid
> > - // module in that case.
> > - if (isa<InlineAsm>(CalledValue))
> > - continue;
> > -
> > - IndirectCalls.push_back(&I);
> > - }
> > - }
> > - }
> > -}
> > -
> > -void ForwardControlFlowIntegrity::updateIndirectCalls(Module &M,
> > - CFITables &CFIT) {
> > - Type *Int64Ty = Type::getInt64Ty(M.getContext());
> > - for (Instruction *I : IndirectCalls) {
> > - CallSite CS(I);
> > - Value *CalledValue = CS.getCalledValue();
> > -
> > - // Get the function type for this call and look it up in the tables.
> > - Type *VTy = CalledValue->getType();
> > - PointerType *PTy = dyn_cast<PointerType>(VTy);
> > - Type *EltTy = PTy->getElementType();
> > - FunctionType *FunTy = dyn_cast<FunctionType>(EltTy);
> > - FunctionType *TransformedTy = JumpInstrTables::
> transformType(JTType,
> > FunTy);
> > - ++NumCFIIndirectCalls;
> > - Constant *JumpTableStart = nullptr;
> > - Constant *JumpTableMask = nullptr;
> > - Constant *JumpTableSize = nullptr;
> > -
> > - // Some call sites have function types that don't correspond to any
> > - // address-taken function in the module. This happens when function
> > pointers
> > - // are passed in from external code.
> > - auto it = CFIT.find(TransformedTy);
> > - if (it == CFIT.end()) {
> > - // In this case, make sure that the function pointer will change
> by
> > - // setting the mask and the start to be 0 so that the transformed
> > - // function is 0.
> > - JumpTableStart = ConstantInt::get(Int64Ty, 0);
> > - JumpTableMask = ConstantInt::get(Int64Ty, 0);
> > - JumpTableSize = ConstantInt::get(Int64Ty, 0);
> > - } else {
> > - JumpTableStart = it->second.StartValue;
> > - JumpTableMask = it->second.MaskValue;
> > - JumpTableSize = it->second.Size;
> > - }
> > -
> > - rewriteFunctionPointer(M, I, CalledValue, JumpTableStart,
> > JumpTableMask,
> > - JumpTableSize);
> > - }
> > -
> > - return;
> > -}
> > -
> > -bool ForwardControlFlowIntegrity::runOnModule(Module &M) {
> > - JumpInstrTableInfo *JITI = &getAnalysis<JumpInstrTableInfo>();
> > - Type *Int64Ty = Type::getInt64Ty(M.getContext());
> > - Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext());
> > -
> > - // JumpInstrTableInfo stores information about the alignment of each
> > entry.
> > - // The alignment returned by JumpInstrTableInfo is alignment in bytes,
> > not
> > - // in the exponent.
> > - ByteAlignment = JITI->entryByteAlignment();
> > - LogByteAlignment = llvm::Log2_64(ByteAlignment);
> > -
> > - // Set up tables for control-flow integrity based on information about
> > the
> > - // jump-instruction tables.
> > - CFITables CFIT;
> > - for (const auto &KV : JITI->getTables()) {
> > - uint64_t Size = static_cast<uint64_t>(KV.second.size());
> > - uint64_t TableSize = NextPowerOf2(Size);
> > -
> > - int64_t MaskValue = ((TableSize << LogByteAlignment) - 1) &
> > -ByteAlignment;
> > - Constant *JumpTableMaskValue = ConstantInt::get(Int64Ty, MaskValue);
> > - Constant *JumpTableSize = ConstantInt::get(Int64Ty, Size);
> > -
> > - // The base of the table is defined to be the first jumptable
> > function in
> > - // the table.
> > - Function *First = KV.second.begin()->second;
> > - Constant *JumpTableStartValue = ConstantExpr::getBitCast(First,
> > VoidPtrTy);
> > - CFIT[KV.first].StartValue = JumpTableStartValue;
> > - CFIT[KV.first].MaskValue = JumpTableMaskValue;
> > - CFIT[KV.first].Size = JumpTableSize;
> > - }
> > -
> > - if (CFIT.empty())
> > - return false;
> > -
> > - getIndirectCalls(M);
> > -
> > - if (!CFIEnforcing) {
> > - addWarningFunction(M);
> > - }
> > -
> > - // Update the instructions with the check and the indirect jump
> through
> > our
> > - // table.
> > - updateIndirectCalls(M, CFIT);
> > -
> > - return true;
> > -}
> > -
> > -void ForwardControlFlowIntegrity::addWarningFunction(Module &M) {
> > - PointerType *CharPtrTy = Type::getInt8PtrTy(M.getContext());
> > -
> > - // Get the type of the Warning Function: void (i8*, i8*),
> > - // where the first argument is the name of the function in which the
> > violation
> > - // occurs, and the second is the function pointer that violates CFI.
> > - SmallVector<Type *, 2> WarningFunArgs;
> > - WarningFunArgs.push_back(CharPtrTy);
> > - WarningFunArgs.push_back(CharPtrTy);
> > - FunctionType *WarningFunTy =
> > - FunctionType::get(Type::getVoidTy(M.getContext()),
> WarningFunArgs,
> > false);
> > -
> > - if (!CFIFuncName.empty()) {
> > - Constant *FailureFun = M.getOrInsertFunction(CFIFuncName,
> > WarningFunTy);
> > - if (!FailureFun)
> > - report_fatal_error("Could not get or insert the function specified
> > by"
> > - " -cfi-func-name");
> > - } else {
> > - // The default warning function swallows the warning and lets the
> > call
> > - // continue, since there's no generic way for it to print out this
> > - // information.
> > - Function *WarningFun = M.getFunction(cfi_failure_func_name);
> > - if (!WarningFun) {
> > - WarningFun =
> > - Function::Create(WarningFunTy, GlobalValue::
> LinkOnceAnyLinkage,
> > - cfi_failure_func_name, &M);
> > - }
> > -
> > - BasicBlock *Entry =
> > - BasicBlock::Create(M.getContext(), "entry", WarningFun, 0);
> > - ReturnInst::Create(M.getContext(), Entry);
> > - }
> > -}
> > -
> > -void ForwardControlFlowIntegrity::rewriteFunctionPointer(
> > - Module &M, Instruction *I, Value *FunPtr, Constant *JumpTableStart,
> > - Constant *JumpTableMask, Constant *JumpTableSize) {
> > - IRBuilder<> TempBuilder(I);
> > -
> > - Type *OrigFunType = FunPtr->getType();
> > -
> > - BasicBlock *CurBB = cast<BasicBlock>(I->getParent());
> > - Function *CurF = cast<Function>(CurBB->getParent());
> > - Type *Int64Ty = Type::getInt64Ty(M.getContext());
> > -
> > - Value *TI = TempBuilder.CreatePtrToInt(FunPtr, Int64Ty);
> > - Value *TStartInt = TempBuilder.CreatePtrToInt(JumpTableStart,
> Int64Ty);
> > -
> > - Value *NewFunPtr = nullptr;
> > - Value *Check = nullptr;
> > - switch (CFIType) {
> > - case CFIntegrity::Sub: {
> > - // This is the subtract, mask, and add version.
> > - // Subtract from the base.
> > - Value *Sub = TempBuilder.CreateSub(TI, TStartInt);
> > -
> > - // Mask the difference to force this to be a table offset.
> > - Value *And = TempBuilder.CreateAnd(Sub, JumpTableMask);
> > -
> > - // Add it back to the base.
> > - Value *Result = TempBuilder.CreateAdd(And, TStartInt);
> > -
> > - // Convert it back into a function pointer that we can call.
> > - NewFunPtr = TempBuilder.CreateIntToPtr(Result, OrigFunType);
> > - break;
> > - }
> > - case CFIntegrity::Ror: {
> > - // This is the subtract and rotate version.
> > - // Rotate right by the alignment value. The optimizer should
> > recognize
> > - // this sequence as a rotation.
> > -
> > - // This cast is safe, since unsigned is always a subset of uint64_t.
> > - uint64_t LogByteAlignment64 =
> > static_cast<uint64_t>(LogByteAlignment);
> > - Constant *RightShift = ConstantInt::get(Int64Ty,
> LogByteAlignment64);
> > - Constant *LeftShift = ConstantInt::get(Int64Ty, 64 -
> > LogByteAlignment64);
> > -
> > - // Subtract from the base.
> > - Value *Sub = TempBuilder.CreateSub(TI, TStartInt);
> > -
> > - // Create the equivalent of a rotate-right instruction.
> > - Value *Shr = TempBuilder.CreateLShr(Sub, RightShift);
> > - Value *Shl = TempBuilder.CreateShl(Sub, LeftShift);
> > - Value *Or = TempBuilder.CreateOr(Shr, Shl);
> > -
> > - // Perform unsigned comparison to check for inclusion in the table.
> > - Check = TempBuilder.CreateICmpULT(Or, JumpTableSize);
> > - NewFunPtr = FunPtr;
> > - break;
> > - }
> > - case CFIntegrity::Add: {
> > - // This is the mask and add version.
> > - // Mask the function pointer to turn it into an offset into the
> > table.
> > - Value *And = TempBuilder.CreateAnd(TI, JumpTableMask);
> > -
> > - // Then or this offset to the base and get the pointer value.
> > - Value *Result = TempBuilder.CreateAdd(And, TStartInt);
> > -
> > - // Convert it back into a function pointer that we can call.
> > - NewFunPtr = TempBuilder.CreateIntToPtr(Result, OrigFunType);
> > - break;
> > - }
> > - }
> > -
> > - if (!CFIEnforcing) {
> > - // If a check hasn't been added (in the rotation version), then
> check
> > to see
> > - // if it's the same as the original function. This check determines
> > whether
> > - // or not we call the CFI failure function.
> > - if (!Check)
> > - Check = TempBuilder.CreateICmpEQ(NewFunPtr, FunPtr);
> > - BasicBlock *InvalidPtrBlock =
> > - BasicBlock::Create(M.getContext(), "invalid.ptr", CurF, 0);
> > - BasicBlock *ContinuationBB = CurBB->splitBasicBlock(I);
> > -
> > - // Remove the unconditional branch that connects the two blocks.
> > - TerminatorInst *TermInst = CurBB->getTerminator();
> > - TermInst->eraseFromParent();
> > -
> > - // Add a conditional branch that depends on the Check above.
> > - BranchInst::Create(ContinuationBB, InvalidPtrBlock, Check, CurBB);
> > -
> > - // Call the warning function for this pointer, then continue.
> > - Instruction *BI = BranchInst::Create(ContinuationBB,
> > InvalidPtrBlock);
> > - insertWarning(M, InvalidPtrBlock, BI, FunPtr);
> > - } else {
> > - // Modify the instruction to call this value.
> > - CallSite CS(I);
> > - CS.setCalledFunction(NewFunPtr);
> > - }
> > -}
> > -
> > -void ForwardControlFlowIntegrity::insertWarning(Module &M, BasicBlock
> > *Block,
> > - Instruction *I, Value
> > *FunPtr) {
> > - Function *ParentFun = cast<Function>(Block->getParent());
> > -
> > - // Get the function to call right before the instruction.
> > - Function *WarningFun = nullptr;
> > - if (CFIFuncName.empty()) {
> > - WarningFun = M.getFunction(cfi_failure_func_name);
> > - } else {
> > - WarningFun = M.getFunction(CFIFuncName);
> > - }
> > -
> > - assert(WarningFun && "Could not find the CFI failure function");
> > -
> > - Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext());
> > -
> > - IRBuilder<> WarningInserter(I);
> > - // Create a mergeable GlobalVariable containing the name of the
> > function.
> > - Value *ParentNameGV =
> > - WarningInserter.CreateGlobalString(ParentFun->getName());
> > - Value *ParentNamePtr = WarningInserter.CreateBitCast(ParentNameGV,
> > VoidPtrTy);
> > - Value *FunVoidPtr = WarningInserter.CreateBitCast(FunPtr, VoidPtrTy);
> > - WarningInserter.CreateCall2(WarningFun, ParentNamePtr, FunVoidPtr);
> > -}
> >
> > Removed: llvm/trunk/lib/CodeGen/JumpInstrTables.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/JumpInstrTables.cpp?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/lib/CodeGen/JumpInstrTables.cpp (original)
> > +++ llvm/trunk/lib/CodeGen/JumpInstrTables.cpp (removed)
> > @@ -1,296 +0,0 @@
> > -//===-- JumpInstrTables.cpp: Jump-Instruction Tables
> > ----------------------===//
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> > -//===------------------------------------------------------
> ----------------===//
> > -///
> > -/// \file
> > -/// \brief An implementation of jump-instruction tables.
> > -///
> > -//===------------------------------------------------------
> ----------------===//
> > -
> > -#define DEBUG_TYPE "jt"
> > -
> > -#include "llvm/CodeGen/JumpInstrTables.h"
> > -#include "llvm/ADT/Statistic.h"
> > -#include "llvm/Analysis/JumpInstrTableInfo.h"
> > -#include "llvm/CodeGen/Passes.h"
> > -#include "llvm/IR/Attributes.h"
> > -#include "llvm/IR/CallSite.h"
> > -#include "llvm/IR/Constants.h"
> > -#include "llvm/IR/DerivedTypes.h"
> > -#include "llvm/IR/Function.h"
> > -#include "llvm/IR/LLVMContext.h"
> > -#include "llvm/IR/Module.h"
> > -#include "llvm/IR/Operator.h"
> > -#include "llvm/IR/Type.h"
> > -#include "llvm/IR/Verifier.h"
> > -#include "llvm/Support/CommandLine.h"
> > -#include "llvm/Support/Debug.h"
> > -#include "llvm/Support/raw_ostream.h"
> > -#include <vector>
> > -
> > -using namespace llvm;
> > -
> > -char JumpInstrTables::ID = 0;
> > -
> > -INITIALIZE_PASS_BEGIN(JumpInstrTables, "jump-instr-tables",
> > - "Jump-Instruction Tables", true, true)
> > -INITIALIZE_PASS_DEPENDENCY(JumpInstrTableInfo);
> > -INITIALIZE_PASS_END(JumpInstrTables, "jump-instr-tables",
> > - "Jump-Instruction Tables", true, true)
> > -
> > -STATISTIC(NumJumpTables, "Number of indirect call tables generated");
> > -STATISTIC(NumFuncsInJumpTables, "Number of functions in the jump
> > tables");
> > -
> > -ModulePass *llvm::createJumpInstrTablesPass() {
> > - // The default implementation uses a single table for all functions.
> > - return new JumpInstrTables(JumpTable::Single);
> > -}
> > -
> > -ModulePass *llvm::createJumpInstrTablesPass(JumpTable::JumpTableType
> JTT)
> > {
> > - return new JumpInstrTables(JTT);
> > -}
> > -
> > -namespace {
> > -static const char jump_func_prefix[] = "__llvm_jump_instr_table_";
> > -static const char jump_section_prefix[] = ".jump.instr.table.text.";
> > -
> > -// Checks to see if a given CallSite is making an indirect call,
> > including
> > -// cases where the indirect call is made through a bitcast.
> > -bool isIndirectCall(CallSite &CS) {
> > - if (CS.getCalledFunction())
> > - return false;
> > -
> > - // Check the value to see if it is merely a bitcast of a function. In
> > - // this case, it will translate to a direct function call in the
> > resulting
> > - // assembly, so we won't treat it as an indirect call here.
> > - const Value *V = CS.getCalledValue();
> > - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
> > - return !(CE->isCast() && isa<Function>(CE->getOperand(0)));
> > - }
> > -
> > - // Otherwise, since we know it's a call, it must be an indirect call
> > - return true;
> > -}
> > -
> > -// Replaces Functions and GlobalAliases with a different Value.
> > -bool replaceGlobalValueIndirectUse(GlobalValue *GV, Value *V, Use *U) {
> > - User *Us = U->getUser();
> > - if (!Us)
> > - return false;
> > - if (Instruction *I = dyn_cast<Instruction>(Us)) {
> > - CallSite CS(I);
> > -
> > - // Don't do the replacement if this use is a direct call to this
> > function.
> > - // If the use is not the called value, then replace it.
> > - if (CS && (isIndirectCall(CS) || CS.isCallee(U))) {
> > - return false;
> > - }
> > -
> > - U->set(V);
> > - } else if (Constant *C = dyn_cast<Constant>(Us)) {
> > - // Don't replace calls to bitcasts of function symbols, since they
> > get
> > - // translated to direct calls.
> > - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Us)) {
> > - if (CE->getOpcode() == Instruction::BitCast) {
> > - // This bitcast must have exactly one user.
> > - if (CE->user_begin() != CE->user_end()) {
> > - User *ParentUs = *CE->user_begin();
> > - if (CallInst *CI = dyn_cast<CallInst>(ParentUs)) {
> > - CallSite CS(CI);
> > - Use &CEU = *CE->use_begin();
> > - if (CS.isCallee(&CEU)) {
> > - return false;
> > - }
> > - }
> > - }
> > - }
> > - }
> > -
> > - // GlobalAlias doesn't support replaceUsesOfWithOnConstant. And the
> > verifier
> > - // requires alias to point to a defined function. So, GlobalAlias is
> > handled
> > - // as a separate case in runOnModule.
> > - if (!isa<GlobalAlias>(C))
> > - C->replaceUsesOfWithOnConstant(GV, V, U);
> > - } else {
> > - llvm_unreachable("The Use of a Function symbol is neither an
> > instruction "
> > - "nor a constant");
> > - }
> > -
> > - return true;
> > -}
> > -
> > -// Replaces all replaceable address-taken uses of GV with a pointer to a
> > -// jump-instruction table entry.
> > -void replaceValueWithFunction(GlobalValue *GV, Function *F) {
> > - // Go through all uses of this function and replace the uses of GV
> with
> > the
> > - // jump-table version of the function. Get the uses as a vector before
> > - // replacing them, since replacing them changes the use list and
> > invalidates
> > - // the iterator otherwise.
> > - for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I !=
> > E;) {
> > - Use &U = *I++;
> > -
> > - // Replacement of constants replaces all instances in the constant.
> > So, some
> > - // uses might have already been handled by the time we reach them
> > here.
> > - if (U.get() == GV)
> > - replaceGlobalValueIndirectUse(GV, F, &U);
> > - }
> > -
> > - return;
> > -}
> > -} // end anonymous namespace
> > -
> > -JumpInstrTables::JumpInstrTables()
> > - : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0),
> > - JTType(JumpTable::Single) {
> > - initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
> > -}
> > -
> > -JumpInstrTables::JumpInstrTables(JumpTable::JumpTableType JTT)
> > - : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0),
> > JTType(JTT) {
> > - initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
> > -}
> > -
> > -JumpInstrTables::~JumpInstrTables() {}
> > -
> > -void JumpInstrTables::getAnalysisUsage(AnalysisUsage &AU) const {
> > - AU.addRequired<JumpInstrTableInfo>();
> > -}
> > -
> > -Function *JumpInstrTables::insertEntry(Module &M, Function *Target) {
> > - FunctionType *OrigFunTy = Target->getFunctionType();
> > - FunctionType *FunTy = transformType(JTType, OrigFunTy);
> > -
> > - JumpMap::iterator it = Metadata.find(FunTy);
> > - if (Metadata.end() == it) {
> > - struct TableMeta Meta;
> > - Meta.TableNum = TableCount;
> > - Meta.Count = 0;
> > - Metadata[FunTy] = Meta;
> > - it = Metadata.find(FunTy);
> > - ++NumJumpTables;
> > - ++TableCount;
> > - }
> > -
> > - it->second.Count++;
> > -
> > - std::string NewName(jump_func_prefix);
> > - NewName += (Twine(it->second.TableNum) + "_" +
> > Twine(it->second.Count)).str();
> > - Function *JumpFun =
> > - Function::Create(OrigFunTy, GlobalValue::ExternalLinkage, NewName,
> > &M);
> > - // The section for this table
> > - JumpFun->setSection((jump_section_prefix +
> > Twine(it->second.TableNum)).str());
> > - JITI->insertEntry(FunTy, Target, JumpFun);
> > -
> > - ++NumFuncsInJumpTables;
> > - return JumpFun;
> > -}
> > -
> > -bool JumpInstrTables::hasTable(FunctionType *FunTy) {
> > - FunctionType *TransTy = transformType(JTType, FunTy);
> > - return Metadata.end() != Metadata.find(TransTy);
> > -}
> > -
> > -FunctionType *JumpInstrTables::transformType(JumpTable::JumpTableType
> > JTT,
> > - FunctionType *FunTy) {
> > - // Returning nullptr forces all types into the same table, since all
> > types map
> > - // to the same type
> > - Type *VoidPtrTy = Type::getInt8PtrTy(FunTy->getContext());
> > -
> > - // Ignore the return type.
> > - Type *RetTy = VoidPtrTy;
> > - bool IsVarArg = FunTy->isVarArg();
> > - std::vector<Type *> ParamTys(FunTy->getNumParams());
> > - FunctionType::param_iterator PI, PE;
> > - int i = 0;
> > -
> > - std::vector<Type *> EmptyParams;
> > - Type *Int32Ty = Type::getInt32Ty(FunTy->getContext());
> > - FunctionType *VoidFnTy = FunctionType::get(
> > - Type::getVoidTy(FunTy->getContext()), EmptyParams, false);
> > - switch (JTT) {
> > - case JumpTable::Single:
> > -
> > - return FunctionType::get(RetTy, EmptyParams, false);
> > - case JumpTable::Arity:
> > - // Transform all types to void* so that all functions with the same
> > arity
> > - // end up in the same table.
> > - for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
> > - PI++, i++) {
> > - ParamTys[i] = VoidPtrTy;
> > - }
> > -
> > - return FunctionType::get(RetTy, ParamTys, IsVarArg);
> > - case JumpTable::Simplified:
> > - // Project all parameters types to one of 3 types: composite,
> > integer, and
> > - // function, matching the three subclasses of Type.
> > - for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
> > - ++PI, ++i) {
> > - assert((isa<IntegerType>(*PI) || isa<FunctionType>(*PI) ||
> > - isa<CompositeType>(*PI)) &&
> > - "This type is not an Integer or a Composite or a
> Function");
> > - if (isa<CompositeType>(*PI)) {
> > - ParamTys[i] = VoidPtrTy;
> > - } else if (isa<FunctionType>(*PI)) {
> > - ParamTys[i] = VoidFnTy;
> > - } else if (isa<IntegerType>(*PI)) {
> > - ParamTys[i] = Int32Ty;
> > - }
> > - }
> > -
> > - return FunctionType::get(RetTy, ParamTys, IsVarArg);
> > - case JumpTable::Full:
> > - // Don't transform this type at all.
> > - return FunTy;
> > - }
> > -
> > - return nullptr;
> > -}
> > -
> > -bool JumpInstrTables::runOnModule(Module &M) {
> > - JITI = &getAnalysis<JumpInstrTableInfo>();
> > -
> > - // Get the set of jumptable-annotated functions that have their
> address
> > taken.
> > - DenseMap<Function *, Function *> Functions;
> > - for (Function &F : M) {
> > - if (F.hasFnAttribute(Attribute::JumpTable) && F.hasAddressTaken())
> {
> > - assert(F.hasUnnamedAddr() &&
> > - "Attribute 'jumptable' requires 'unnamed_addr'");
> > - Functions[&F] = nullptr;
> > - }
> > - }
> > -
> > - // Create the jump-table functions.
> > - for (auto &KV : Functions) {
> > - Function *F = KV.first;
> > - KV.second = insertEntry(M, F);
> > - }
> > -
> > - // GlobalAlias is a special case, because the target of an alias
> > statement
> > - // must be a defined function. So, instead of replacing a given
> > function in
> > - // the alias, we replace all uses of aliases that target jumptable
> > functions.
> > - // Note that there's no need to create these functions, since only
> > aliases
> > - // that target known jumptable functions are replaced, and there's no
> > way to
> > - // put the jumptable annotation on a global alias.
> > - DenseMap<GlobalAlias *, Function *> Aliases;
> > - for (GlobalAlias &GA : M.aliases()) {
> > - Constant *Aliasee = GA.getAliasee();
> > - if (Function *F = dyn_cast<Function>(Aliasee)) {
> > - auto it = Functions.find(F);
> > - if (it != Functions.end()) {
> > - Aliases[&GA] = it->second;
> > - }
> > - }
> > - }
> > -
> > - // Replace each address taken function with its jump-instruction table
> > entry.
> > - for (auto &KV : Functions)
> > - replaceValueWithFunction(KV.first, KV.second);
> > -
> > - for (auto &KV : Aliases)
> > - replaceValueWithFunction(KV.first, KV.second);
> > -
> > - return !Functions.empty();
> > -}
> >
> > Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/LLVMTargetMachine.cpp?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
> > +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Fri Feb 27 13:03:38
> 2015
> > @@ -12,12 +12,9 @@
> > //===-------------------------------------------------------
> ---------------===//
> >
> > #include "llvm/Target/TargetMachine.h"
> > -#include "llvm/Analysis/JumpInstrTableInfo.h"
> > #include "llvm/Analysis/Passes.h"
> > #include "llvm/CodeGen/AsmPrinter.h"
> > #include "llvm/CodeGen/BasicTTIImpl.h"
> > -#include "llvm/CodeGen/ForwardControlFlowIntegrity.h"
> > -#include "llvm/CodeGen/JumpInstrTables.h"
> > #include "llvm/CodeGen/MachineFunctionAnalysis.h"
> > #include "llvm/CodeGen/MachineModuleInfo.h"
> > #include "llvm/CodeGen/Passes.h"
> > @@ -145,16 +142,6 @@ bool LLVMTargetMachine::addPassesToEmitF
> > bool DisableVerify,
> > AnalysisID StartAfter,
> > AnalysisID StopAfter) {
> > - // Passes to handle jumptable function annotations. These can't be
> > handled at
> > - // JIT time, so we don't add them directly to addPassesToGenerateCode.
> > - PM.add(createJumpInstrTableInfoPass(
> > -
> > getSubtargetImpl()->getInstrInfo()->getJumpInstrTableEntryBound()));
> > - PM.add(createJumpInstrTablesPass(Options.JTType));
> > - if (Options.FCFI)
> > - PM.add(createForwardControlFlowIntegrityPass(
> > - Options.JTType, Options.CFIType, Options.CFIEnforcing,
> > - Options.getCFIFuncName()));
> > -
> > // Add common CodeGen passes.
> > MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
> > StartAfter, StopAfter);
> >
> > Modified: llvm/trunk/test/CodeGen/Generic/stop-after.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/Generic/stop-after.ll?rev=230780&r1=230779&r2=230780&view=diff
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/Generic/stop-after.ll (original)
> > +++ llvm/trunk/test/CodeGen/Generic/stop-after.ll Fri Feb 27 13:03:38
> 2015
> > @@ -5,6 +5,6 @@
> > ; STOP: Loop Strength Reduction
> > ; STOP-NEXT: Machine Function Analysis
> >
> > -; START: -machine-branch-prob -jump-instr-tables -gc-lowering
> > +; START: -machine-branch-prob -gc-lowering
> > ; START: FunctionPass Manager
> > ; START-NEXT: Lower Garbage Collection Instructions
> >
> > Removed: llvm/trunk/test/CodeGen/X86/cfi_enforcing.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/cfi_enforcing.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/cfi_enforcing.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/cfi_enforcing.ll (removed)
> > @@ -1,34 +0,0 @@
> > -; RUN: llc -mtriple=i386-unknown-linux-gnu -fcfi -cfi-enforcing <%s |
> > FileCheck --check-prefix=X86 %s
> > -; RUN: llc -mtriple=x86_64-unknown-linux-gnu -fcfi -cfi-enforcing <%s |
> > FileCheck --check-prefix=X86-64 %s
> > -
> > -define void @indirect_fun() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @m(void ()* %fun) {
> > - call void ()* %fun()
> > -; CHECK: subl
> > -; X86-64: andq $8,
> > -; X86-64: leaq __llvm_jump_instr_table_0_1({{%[a-z0-9]+}}),
> > [[REG:%[a-z0-9]+]]
> > -; X86-64-NOT: callq __llvm_cfi_pointer_warning
> > -; X86-64: callq *[[REG]]
> > -; X86: andl $8,
> > -; X86: leal __llvm_jump_instr_table_0_1({{%[a-z0-9]+}}),
> > [[REG:%[a-z0-9]+]]
> > -; X86-NOT: calll __llvm_cfi_pointer_warning
> > -; X86: calll *[[REG]]
> > - ret i32 0
> > -}
> > -
> > -define void ()* @get_fun() {
> > - ret void ()* @indirect_fun
> > -}
> > -
> > -define i32 @main(i32 %argc, i8** %argv) {
> > - %f = call void ()* ()* @get_fun()
> > - %a = call i32 @m(void ()* %f)
> > - ret i32 %a
> > -}
> > -
> > -; CHECK: .align 8
> > -; CHECK: __llvm_jump_instr_table_0_1:
> > -; CHECK: jmp indirect_fun at PLT
> >
> > Removed: llvm/trunk/test/CodeGen/X86/cfi_invoke.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/cfi_invoke.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/cfi_invoke.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/cfi_invoke.ll (removed)
> > @@ -1,35 +0,0 @@
> > -; RUN: llc <%s -fcfi -cfi-type=sub | FileCheck %s
> > -; ModuleID = 'test.cc'
> > -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> > -target triple = "x86_64-unknown-linux-gnu"
> > -
> > -declare i32 @__gxx_personality_v0(...)
> > -
> > - at _ZTIPKc = external constant i8*
> > - at _ZTIi = external constant i8*
> > -
> > -define void @f() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > - at a = global void ()* @f
> > -
> > -; Make sure invoke gets targeted as well as regular calls
> > -define void @_Z3foov(void ()* %f) uwtable ssp {
> > -; CHECK-LABEL: _Z3foov:
> > - entry:
> > - invoke void %f()
> > - to label %try.cont unwind label %lpad
> > -; CHECK: callq __llvm_cfi_pointer_warning
> > -; CHECK: callq *%rbx
> > -
> > - lpad:
> > - %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)*
> > @__gxx_personality_v0 to i8*)
> > - catch i8* bitcast (i8** @_ZTIi to i8*)
> > - filter [1 x i8*] [i8* bitcast (i8**
> > @_ZTIPKc to i8*)]
> > - ret void
> > -
> > - try.cont:
> > - ret void
> > -}
> > -
> >
> > Removed: llvm/trunk/test/CodeGen/X86/cfi_non_default_function.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/cfi_non_default_function.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/cfi_non_default_function.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/cfi_non_default_function.ll (removed)
> > @@ -1,27 +0,0 @@
> > -; RUN: llc -fcfi -cfi-func-name=cfi_new_failure <%s | FileCheck %s
> > -
> > -target triple = "x86_64-unknown-linux-gnu"
> > -define void @indirect_fun() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @m(void ()* %fun) {
> > -; CHECK-LABEL: @m
> > - call void ()* %fun()
> > -; CHECK: callq cfi_new_failure
> > - ret i32 0
> > -}
> > -
> > -define void ()* @get_fun() {
> > - ret void ()* @indirect_fun
> > -}
> > -
> > -define i32 @main(i32 %argc, i8** %argv) {
> > - %f = call void ()* ()* @get_fun()
> > - %a = call i32 @m(void ()* %f)
> > - ret i32 %a
> > -}
> > -
> > -; CHECK: .align 8
> > -; CHECK: __llvm_jump_instr_table_0_1:
> > -; CHECK: jmp indirect_fun at PLT
> >
> > Removed: llvm/trunk/test/CodeGen/X86/cfi_simple_indirect_call.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/cfi_simple_indirect_call.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/cfi_simple_indirect_call.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/cfi_simple_indirect_call.ll (removed)
> > @@ -1,43 +0,0 @@
> > -; RUN: llc -fcfi -cfi-type=sub <%s | FileCheck --check-prefix=SUB %s
> > -; RUN: llc -fcfi -cfi-type=add <%s | FileCheck --check-prefix=ADD %s
> > -; RUN: llc -fcfi -cfi-type=ror <%s | FileCheck --check-prefix=ROR %s
> > -
> > -target triple = "x86_64-unknown-linux-gnu"
> > -
> > -define void @indirect_fun() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @m(void ()* %fun) {
> > - call void ()* %fun()
> > -; SUB: subl
> > -; SUB: andq $8
> > -; SUB-LABEL: leaq __llvm_jump_instr_table_0_1
> > -; SUB-LABEL: callq __llvm_cfi_pointer_warning
> > -
> > -; ROR: subq
> > -; ROR: rolq $61
> > -; ROR: testq
> > -; ROR-LABEL: callq __llvm_cfi_pointer_warning
> > -
> > -; ADD: andq $8
> > -; ADD-LABEL: leaq __llvm_jump_instr_table_0_1
> > -; ADD: cmpq
> > -; ADD-LABEL: callq __llvm_cfi_pointer_warning
> > -ret i32 0
> > -}
> > -
> > -define void ()* @get_fun() {
> > - ret void ()* @indirect_fun
> > -}
> > -
> > -define i32 @main(i32 %argc, i8** %argv) {
> > - %f = call void ()* ()* @get_fun()
> > - %a = call i32 @m(void ()* %f)
> > - ret i32 %a
> > -}
> > -; SUB: .text
> > -; SUB: .align 8
> > -; SUB-LABEL: .type __llvm_jump_instr_table_0_1, at function
> > -; SUB-LABEL:__llvm_jump_instr_table_0_1:
> > -; SUB-LABEL: jmp indirect_fun at PLT
> >
> > Removed: llvm/trunk/test/CodeGen/X86/jump_table_alias.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/jump_table_alias.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/jump_table_alias.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/jump_table_alias.ll (removed)
> > @@ -1,32 +0,0 @@
> > -; RUN: llc <%s -jump-table-type=single | FileCheck %s
> > -target triple = "x86_64-unknown-linux-gnu"
> > -define i32 @f() unnamed_addr jumptable {
> > -entry:
> > - ret i32 0
> > -}
> > -
> > - at i = internal alias i32 ()* @f
> > - at j = alias i32 ()* @f
> > -
> > -define i32 @main(i32 %argc, i8** %argv) {
> > - %temp = alloca i32 ()*, align 8
> > - store i32 ()* @i, i32()** %temp, align 8
> > -; CHECK: movq $__llvm_jump_instr_table_0_1
> > - %1 = load i32 ()** %temp, align 8
> > -; CHECK: movl $__llvm_jump_instr_table_0_1
> > - %2 = call i32 ()* %1()
> > - %3 = call i32 ()* @i()
> > -; CHECK: callq i
> > - %4 = call i32 ()* @j()
> > -; CHECK: callq j
> > - ret i32 %3
> > -}
> > -
> > -; There should only be one table, even though there are two
> > GlobalAliases,
> > -; because they both alias the same value.
> > -
> > -; CHECK: .align 8, 0x90
> > -; CHECK: .type __llvm_jump_instr_table_0_1, at function
> > -; CHECK: __llvm_jump_instr_table_0_1:
> > -; CHECK: jmp f at PLT
> > -
> >
> > Removed: llvm/trunk/test/CodeGen/X86/jump_table_align.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/jump_table_align.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/jump_table_align.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/jump_table_align.ll (removed)
> > @@ -1,29 +0,0 @@
> > -; RUN: llc -filetype=obj <%s -jump-table-type=single -o %t1
> > -; RUN: llvm-objdump -triple=x86_64-unknown-linux-gnu -d %t1 | FileCheck
> > %s
> > -target triple = "x86_64-unknown-linux-gnu"
> > -define i32 @f() unnamed_addr jumptable {
> > - ret i32 0
> > -}
> > -
> > -define i32 @g(i8* %a) unnamed_addr jumptable {
> > - ret i32 0
> > -}
> > -
> > -define void @h(void ()* %func) unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @main() {
> > - %g = alloca i32 (...)*, align 8
> > - store i32 (...)* bitcast (i32 ()* @f to i32 (...)*), i32 (...)** %g,
> > align 8
> > - %1 = load i32 (...)** %g, align 8
> > - %call = call i32 (...)* %1()
> > - call void (void ()*)* @h(void ()* bitcast (void (void ()*)* @h to void
> > ()*))
> > - %a = call i32 (i32*)* bitcast (i32 (i8*)* @g to i32(i32*)*)(i32* null)
> > - ret i32 %a
> > -}
> > -
> > -; Make sure that the padding from getJumpInstrTableEntryBound is right.
> > -; CHECK: __llvm_jump_instr_table_0_1:
> > -; CHECK-NEXT: e9 00 00 00 00 jmp 0
> > -; CHECK-NEXT: 0f 1f 00 nopl
> > (%rax)
> >
> > Removed: llvm/trunk/test/CodeGen/X86/jump_table_bitcast.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/jump_table_bitcast.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/jump_table_bitcast.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/jump_table_bitcast.ll (removed)
> > @@ -1,43 +0,0 @@
> > -; RUN: llc <%s -jump-table-type=single | FileCheck %s
> > -target triple = "x86_64-unknown-linux-gnu"
> > -define i32 @f() unnamed_addr jumptable {
> > - ret i32 0
> > -}
> > -
> > -define i32 @g(i8* %a) unnamed_addr jumptable {
> > - ret i32 0
> > -}
> > -
> > -define void @h(void ()* %func) unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @main() {
> > - %g = alloca i32 (...)*, align 8
> > - store i32 (...)* bitcast (i32 ()* @f to i32 (...)*), i32 (...)** %g,
> > align 8
> > -; CHECK: movq $__llvm_jump_instr_table_0_[[ENTRY:1|2|3]],
> > -; CHECK: movl $__llvm_jump_instr_table_0_[[ENTRY]],
> > - %1 = load i32 (...)** %g, align 8
> > - %call = call i32 (...)* %1()
> > - call void (void ()*)* @h(void ()* bitcast (void (void ()*)* @h to void
> > ()*))
> > -; CHECK: movl $__llvm_jump_instr_table_0_{{1|2|3}},
> > -; CHECK: callq h
> > -
> > - %a = call i32 (i32*)* bitcast (i32 (i8*)* @g to i32(i32*)*)(i32* null)
> > -; CHECK: callq g
> > - ret i32 %a
> > -}
> > -
> > -; CHECK: .align 8, 0x90
> > -; CHECK: .type __llvm_jump_instr_table_0_1, at function
> > -; CHECK: __llvm_jump_instr_table_0_1:
> > -; CHECK: jmp {{f|g|h}}@PLT
> > -; CHECK: .align 8, 0x90
> > -; CHECK: .type __llvm_jump_instr_table_0_2, at function
> > -; CHECK: __llvm_jump_instr_table_0_2:
> > -; CHECK: jmp {{f|g|h}}@PLT
> > -; CHECK: .align 8, 0x90
> > -; CHECK: .type __llvm_jump_instr_table_0_3, at function
> > -; CHECK: __llvm_jump_instr_table_0_3:
> > -; CHECK: jmp {{f|g|h}}@PLT
> > -
> >
> > Removed: llvm/trunk/test/CodeGen/X86/jump_tables.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/jump_tables.ll?rev=230779&view=auto
> > ============================================================
> ==================
> > --- llvm/trunk/test/CodeGen/X86/jump_tables.ll (original)
> > +++ llvm/trunk/test/CodeGen/X86/jump_tables.ll (removed)
> > @@ -1,255 +0,0 @@
> > -; RUN: llc <%s -jump-table-type=single | FileCheck --check-prefix=SINGLE
> > %s
> > -; RUN: llc <%s -jump-table-type=arity | FileCheck --check-prefix=ARITY
> %s
> > -; RUN: llc <%s -jump-table-type=simplified | FileCheck
> > --check-prefix=SIMPL %s
> > -; RUN: llc <%s -jump-table-type=full | FileCheck --check-prefix=FULL %s
> > -
> > -target triple = "x86_64-unknown-linux-gnu"
> > -
> > -%struct.fun_struct = type { i32 (...)* }
> > -
> > - at a = global [12 x i32 () *] [ i32 ()* bitcast (void ()* @indirect_fun to
> > i32 ()*),
> > - i32 ()* bitcast (void ()*
> @indirect_fun_match to i32 ()*),
> > - i32 ()* bitcast (i32 ()* @indirect_fun_i32
> to i32 ()*),
> > - i32 ()* bitcast (i32 (i32)*
> @indirect_fun_i32_1 to i32 ()*),
> > - i32 ()* bitcast (i32 (i32, i32)*
> @indirect_fun_i32_2 to i32
> > ()*),
> > - i32 ()* bitcast (i32* (i32*, i32)*
> @indirect_fun_i32S_2 to i32
> > ()*),
> > - i32 ()* bitcast (void (%struct.fun_struct)*
> @indirect_fun_struct
> > to i32 ()*),
> > - i32 ()* bitcast (void (i32 (...)*, i32)*
> @indirect_fun_fun to
> > i32 ()*),
> > - i32 ()* bitcast (i32 (i32 (...)*, i32)*
> @indirect_fun_fun_ret to
> > i32 ()*),
> > - i32 ()* bitcast (void ([19 x i8])*
> @indirect_fun_array to i32
> > ()*),
> > - i32 ()* bitcast (void (<3 x i32>)*
> @indirect_fun_vec to i32
> > ()*),
> > - i32 ()* bitcast (void (<4 x float>)*
> @indirect_fun_vec_2 to i32
> > ()*)
> > - ]
> > -
> > -define void @indirect_fun() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define void @indirect_fun_match() unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @indirect_fun_i32() unnamed_addr jumptable {
> > - ret i32 0
> > -}
> > -
> > -define i32 @indirect_fun_i32_1(i32 %a) unnamed_addr jumptable {
> > - ret i32 %a
> > -}
> > -
> > -define i32 @indirect_fun_i32_2(i32 %a, i32 %b) unnamed_addr jumptable {
> > - ret i32 %a
> > -}
> > -
> > -define i32* @indirect_fun_i32S_2(i32* %a, i32 %b) unnamed_addr jumptable
> > {
> > - ret i32* %a
> > -}
> > -
> > -define void @indirect_fun_struct(%struct.fun_struct %fs) unnamed_addr
> > jumptable {
> > - ret void
> > -}
> > -
> > -define void @indirect_fun_fun(i32 (...)* %fun, i32 %a) unnamed_addr
> > jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @indirect_fun_fun_ret(i32 (...)* %fun, i32 %a) unnamed_addr
> > jumptable {
> > - ret i32 %a
> > -}
> > -
> > -define void @indirect_fun_array([19 x i8] %a) unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define void @indirect_fun_vec(<3 x i32> %a) unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define void @indirect_fun_vec_2(<4 x float> %a) unnamed_addr jumptable {
> > - ret void
> > -}
> > -
> > -define i32 @m(void ()* %fun) {
> > - call void ()* %fun()
> > - ret i32 0
> > -}
> > -
> > -define void ()* @get_fun() {
> > - ret void ()* @indirect_fun
> > -; SINGLE: movl $__llvm_jump_instr_table_0_
> > -; ARITY: movl $__llvm_jump_instr_table_
> > -; SIMPL: movl $__llvm_jump_instr_table_
> > -; FULL: movl $__llvm_jump_instr_table_
> > -}
> > -
> > -define i32 @main(i32 %argc, i8** %argv) {
> > - %f = call void ()* ()* @get_fun()
> > - %a = call i32 @m(void ()* %f)
> > - ret i32 %a
> > -}
> > -
> > -; SINGLE-DAG: .align 8, 0x90
> > -; SINGLE-DAG: .type __llvm_jump_instr_table_0_1, at function
> > -; SINGLE-DAG: __llvm_jump_instr_table_0_1:
> > -; SINGLE-DAG: jmp indirect_fun_array at PLT
> > -; SINGLE-DAG: .align 8, 0x90
> > -; SINGLE-DAG: .type __llvm_jump_instr_table_0_2, at function
> > -; SINGLE-DAG: __llvm_jump
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150304/08fec5b8/attachment.html>
More information about the llvm-commits
mailing list