[llvm] r230780 - Remove the Forward Control Flow Integrity pass and its dependencies.

Kostya Serebryany kcc at google.com
Wed Mar 4 15:47:26 PST 2015


Yep.
clang.llvm.org/docs/ControlFlowIntegrityDesign.html

On Wed, Mar 4, 2015 at 2:12 PM, Eric Christopher <echristo at gmail.com> wrote:

> 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/f0c156fd/attachment.html>


More information about the llvm-commits mailing list