blob: 1149f84aa74393dd484962b85000f878c40830f6 [file] [log] [blame]
//===- Terminate.cpp --------------------------------------------*- 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.
//
//===----------------------------------------------------------------------===//
//
// Pass to modify SAFECode's initialization in the program to terminate on the
// first memory safety error.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
class Terminate : public llvm::ModulePass {
public:
static char ID;
Terminate () : llvm::ModulePass(ID) {
}
virtual bool runOnModule(llvm::Module & M);
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
};
ModulePass * createSCTerminatePass (void);
}
using namespace llvm;
// ID for the Terminate pass
char Terminate::ID = 0;
//
// Method: runOnModule()
//
// Description:
// This method is the entry point for this LLVM pass. We look for calls to
// the pool_init_runtime() function in the program and modify them to tell the
// run-time to terminate the program when a memory error is detected.
//
// Return value:
// true - The program was modified in some way.
// false - This pass did not modify the program.
//
bool
Terminate::runOnModule (Module & M) {
//
// Find the pool_init_runtime() function. If it does not exit, then there
// is nothing to do.
//
Function * F = M.getFunction ("pool_init_runtime");
if (!F)
return false;
//
// Scan through all uses of the function looking for calls to it. If we
// find them, modify the last argument (the terminate argument) to be true.
//
bool modified = false;
Type * Int32Type = IntegerType::getInt32Ty(M.getContext());
Function::use_iterator i, e;
for (i = F->use_begin(), e = F->use_end(); i != e; ++i) {
if (CallInst * CI = dyn_cast<CallInst>(*i)) {
CallSite CS(CI);
CS.setArgument(2, ConstantInt::get(Int32Type, 1));
modified = true;
}
}
return modified;
}
// Function to allow external code to create objects of this pass
ModulePass *
llvm::createSCTerminatePass (void) {
return new Terminate();
}