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