mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
63dea2c952
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
106 lines
3.7 KiB
C++
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 */
|