llvm-6502/include/llvm/CodeGen/JumpInstrTables.h
Tom Roeder 63dea2c952 Add Forward Control-Flow Integrity.
This commit adds a new pass that can inject checks before indirect calls to
make sure that these calls target known locations. It supports three types of
checks and, at compile time, it can take the name of a custom function to call
when an indirect call check fails. The default failure function ignores the
error and continues.

This pass incidentally moves the function JumpInstrTables::transformType from
private to public and makes it static (with a new argument that specifies the
table type to use); this is so that the CFI code can transform function types
at call sites to determine which jump-instruction table to use for the check at
that site.

Also, this removes support for jumptables in ARM, pending further performance
analysis and discussion.

Review: http://reviews.llvm.org/D4167



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221708 91177308-0d34-0410-b5e6-96231b3b80d8
2014-11-11 21:08:02 +00:00

106 lines
3.7 KiB
C++

//===-- 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,@function
/// .align 8,0x90
/// f:
/// jmp f_orig@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 */