mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 22:23:10 +00:00
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
This commit is contained in:
@@ -428,6 +428,26 @@ public:
|
||||
llvm_unreachable("Target didn't implement TargetInstrInfo::getTrap!");
|
||||
}
|
||||
|
||||
/// getJumpInstrTableEntryBound - Get a number of bytes that suffices to hold
|
||||
/// either the instruction returned by getUnconditionalBranch or the
|
||||
/// instruction returned by getTrap. This only makes sense because
|
||||
/// getUnconditionalBranch returns a single, specific instruction. This
|
||||
/// information is needed by the jumptable construction code, since it must
|
||||
/// decide how many bytes to use for a jumptable entry so it can generate the
|
||||
/// right mask.
|
||||
///
|
||||
/// Note that if the jumptable instruction requires alignment, then that
|
||||
/// alignment should be factored into this required bound so that the
|
||||
/// resulting bound gives the right alignment for the instruction.
|
||||
virtual unsigned getJumpInstrTableEntryBound() const {
|
||||
// This method gets called by LLVMTargetMachine always, so it can't fail
|
||||
// just because there happens to be no implementation for this target.
|
||||
// Any code that tries to use a jumptable annotation without defining
|
||||
// getUnconditionalBranch on the appropriate Target will fail anyway, and
|
||||
// the value returned here won't matter in that case.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
|
||||
/// block at the specified instruction (i.e. instruction would be the start
|
||||
/// of a new basic block).
|
||||
|
||||
@@ -57,6 +57,14 @@ namespace llvm {
|
||||
};
|
||||
}
|
||||
|
||||
enum class CFIntegrity {
|
||||
Sub, // Use subtraction-based checks.
|
||||
Ror, // Use rotation-based checks.
|
||||
Add // Use addition-based checks. This depends on having
|
||||
// sufficient alignment in the code and is usually not
|
||||
// feasible.
|
||||
};
|
||||
|
||||
class TargetOptions {
|
||||
public:
|
||||
TargetOptions()
|
||||
@@ -70,10 +78,11 @@ namespace llvm {
|
||||
EnableFastISel(false), PositionIndependentExecutable(false),
|
||||
UseInitArray(false), DisableIntegratedAS(false),
|
||||
CompressDebugSections(false), FunctionSections(false),
|
||||
DataSections(false), TrapUnreachable(false), TrapFuncName(""),
|
||||
DataSections(false), TrapUnreachable(false), TrapFuncName(),
|
||||
FloatABIType(FloatABI::Default),
|
||||
AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single),
|
||||
ThreadModel(ThreadModel::POSIX) {}
|
||||
FCFI(false), ThreadModel(ThreadModel::POSIX),
|
||||
CFIType(CFIntegrity::Sub), CFIEnforcing(false), CFIFuncName() {}
|
||||
|
||||
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
|
||||
/// option is specified on the command line, and should enable debugging
|
||||
@@ -228,10 +237,28 @@ namespace llvm {
|
||||
/// create for functions that have the jumptable attribute.
|
||||
JumpTable::JumpTableType JTType;
|
||||
|
||||
/// FCFI - This flags controls whether or not forward-edge control-flow
|
||||
/// integrity is applied.
|
||||
bool FCFI;
|
||||
|
||||
/// ThreadModel - This flag specifies the type of threading model to assume
|
||||
/// for things like atomics
|
||||
ThreadModel::Model ThreadModel;
|
||||
|
||||
/// CFIType - This flag specifies the type of control-flow integrity check
|
||||
/// to add as a preamble to indirect calls.
|
||||
CFIntegrity CFIType;
|
||||
|
||||
/// CFIEnforcing - This flags controls whether or not CFI violations cause
|
||||
/// the program to halt.
|
||||
bool CFIEnforcing;
|
||||
|
||||
/// getCFIFuncName - If this returns a non-empty string, then this is the
|
||||
/// name of the function that will be called for each CFI violation in
|
||||
/// non-enforcing mode.
|
||||
std::string CFIFuncName;
|
||||
StringRef getCFIFuncName() const;
|
||||
|
||||
/// Machine level options.
|
||||
MCTargetOptions MCOptions;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user