blob: 1566eec0457fc7e6ede6dd92193c8ff24e7920fb [file] [log] [blame]
//===- CheckInfo.h - Information about SAFECode run-time checks --*- C++ -*---//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements structures containing data about the various run-time
// checks that SAFECode inserts into code.
//
//===----------------------------------------------------------------------===//
#ifndef _SC_CHECKINFO_H_
#define _SC_CHECKINFO_H_
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CallSite.h"
using namespace llvm;
namespace {
enum CheckType {memcheck, gepcheck, funccheck, strcheck};
//
// Structure: CheckInfo
//
// Description:
// This structure describes a run-time check.
//
struct CheckInfo {
// The name of the function implementing the run-time check
const char * name;
// The name of the complete version of the check
const char * completeName;
// The argument of the checked pointer.
unsigned char argno;
// A boolean indicating whether it is a memory check or a bounds check
CheckType checkType;
// The argument of the length (if appropriate)
unsigned char lenArg;
// A boolean indicating whether the check is complete
bool isComplete;
// The argument of the source pointer (if appropriate)
unsigned char srcArg;
bool isMemCheck (void) const {
return checkType == memcheck;
}
bool isGEPCheck (void) const {
return checkType == gepcheck;
}
Value * getCheckedPointer (CallInst * CI) const {
CallSite CS(CI);
return CS.getArgument (argno);
}
Value * getCheckedLength (CallInst * CI) const {
if (lenArg) {
CallSite CS(CI);
return CS.getArgument (lenArg);
}
return 0;
}
Value * getSourcePointer (CallInst * CI) const {
if (srcArg) {
CallSite CS(CI);
return CS.getArgument (srcArg);
}
return NULL;
}
};
//
// Create a table describing all of the SAFECode run-time checks.
//
static const unsigned numChecks = 24;
static const struct CheckInfo RuntimeChecks[numChecks] = {
// Regular checking functions
{"poolcheck", "poolcheck", 1, memcheck, 2, true, 0},
{"poolcheckui", "poolcheck", 1, memcheck, 2, false, 0},
{"poolcheckalign", "poolcheckalign", 1, memcheck, 0, true, 0},
{"poolcheckalignui", "poolcheckalign", 1, memcheck, 0, false, 0},
{"poolcheckstr", "poolcheckstr", 1, strcheck, 0, true, 0},
{"poolcheckstrui", "poolcheckstr", 1, strcheck, 0, false, 0},
{"boundscheck", "boundscheck", 2, gepcheck, 0, true, 1},
{"boundscheckui", "boundscheck", 2, gepcheck, 0, false, 1},
{"exactcheck2", "exactcheck2", 2, gepcheck, 0, true, 1},
{"fastlscheck", "fastlscheck", 1, memcheck, 3, true, 0},
{"funccheck", "funccheck", 0, funccheck, 0, true, 0},
{"funccheckui", "funccheck", 0, funccheck, 0, false, 0},
// Debug versions of the above
{"poolcheck_debug", "poolcheck_debug", 1, memcheck, 2, true, 0},
{"poolcheckui_debug", "poolcheck_debug", 1, memcheck, 2, false, 0},
{"poolcheckalign_debug", "poolcheckalign_debug", 1, memcheck, 0, true, 0},
{"poolcheckalignui_debug", "poolcheckalign_debug", 1, memcheck, 0, false, 0},
{"poolcheckstr_debug", "poolcheckstr_debug", 1, strcheck, 0, true, 0},
{"poolcheckstrui_debug", "poolcheckstr_debug", 1, strcheck, 0, false, 0},
{"boundscheck_debug", "boundscheck_debug", 2, gepcheck, 0, true, 1},
{"boundscheckui_debug", "boundscheck_debug", 2, gepcheck, 0, false, 1},
{"exactcheck2_debug", "exactcheck2_debug", 2, gepcheck, 0, true, 1},
{"fastlscheck_debug", "fastlscheck_debug", 1, memcheck, 3, true, 0},
{"funccheck_debug", "funccheck_debug", 0, funccheck, 0, true, 0},
{"funccheckui_debug", "funccheck_debug", 0, funccheck, 0, false, 0}
};
//
// Function: isRuntimeCheck()
//
// Description:
// Determine whether the function is one of the run-time checking functions.
//
// Return value:
// true - The function is a run-time check.
// false - The function is not a run-time check.
//
static inline bool
isRuntimeCheck (const Function * F) {
if (F->hasName()) {
for (unsigned index = 0; index < numChecks; ++index) {
if (F->getName() == RuntimeChecks[index].name) {
return true;
}
}
}
return false;
}
//
// Function: findRuntimeCheck()
//
// Description:
// Determine if this function is one of the run-time checking functions. If
// so, return the information about the run-time check.
//
// Inputs:
// F - The function to check.
//
// Return value:
// NULL - This is not a call to a run-time check.
// Otherwise, a pointer to the proper run-time check entry is returned.
//
static inline const struct CheckInfo *
findRuntimeCheck (const Function * F) {
if (F->hasName()) {
for (unsigned index = 0; index < numChecks; ++index) {
if (F->getName() == RuntimeChecks[index].name) {
return &(RuntimeChecks[index]);
}
}
}
return 0;
}
}
#endif