本文整理汇总了C++中module::iterator::use_end方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::use_end方法的具体用法?C++ iterator::use_end怎么用?C++ iterator::use_end使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类module::iterator
的用法示例。
在下文中一共展示了iterator::use_end方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: checkFeatures
// Check the assumptions we made.
void CheckInserter::checkFeatures(Module &M) {
// Assume no function name starts with Loom.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
assert(!F->getName().startswith("Loom") &&
"Loom update engine seems already instrumented");
}
// We do not support the situation where some important functions are called
// via a function pointer, e.g. pthread_create, pthread_join and fork.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (F->getName() == "pthread_create" ||
F->getName() == "pthread_join" ||
F->getName() == "fork") {
for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
User *Usr = *UI;
assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
CallSite CS(cast<Instruction>(Usr));
for (unsigned i = 0; i < CS.arg_size(); ++i)
assert(CS.getArgument(i) != F);
}
}
}
// pthread_cancel provides another way of terminating a thread, which we have
// not supported yet.
assert(M.getFunction("pthread_cancel") == NULL);
}
示例2: checkFeatures
void MemoryInstrumenter::checkFeatures(Module &M) {
// Check whether any memory allocation function can
// potentially be pointed by function pointers.
// Also, all intrinsic functions will be called directly,
// i.e. not via function pointers.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
User *Usr = *UI;
assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
CallSite CS(cast<Instruction>(Usr));
for (unsigned i = 0; i < CS.arg_size(); ++i)
assert(CS.getArgument(i) != F);
}
}
}
// Check whether memory allocation functions are captured.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
// 0 is the return, 1 is the first parameter.
if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << "'s return value is marked noalias, ";
errs() << "but the function is not treated as malloc.\n";
errs().resetColor();
}
}
// Global variables shouldn't be of the array type.
for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
GI != E; ++GI) {
assert(!GI->getType()->isArrayTy());
}
// A function parameter or an instruction can be an array, but we don't
// instrument such constructs for now. Issue a warning on such cases.
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
if (AI->getType()->isArrayTy()) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << ":" << *AI << " is an array\n";
errs().resetColor();
}
}
}
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
if (Ins->getType()->isArrayTy()) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << ":" << *Ins << " is an array\n";
errs().resetColor();
}
}
}
}
}
示例3: checkFeatures
void MemoryInstrumenter::checkFeatures(Module &M) {
// Check whether any memory allocation function can
// potentially be pointed by function pointers.
// Also, all intrinsic functions will be called directly,
// i.e. not via function pointers.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) {
for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) {
User *Usr = *UI;
assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr));
CallSite CS(cast<Instruction>(Usr));
for (unsigned i = 0; i < CS.arg_size(); ++i)
assert(CS.getArgument(i) != F);
}
}
}
// Check whether memory allocation functions are captured.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
// 0 is the return, 1 is the first parameter.
if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) {
errs().changeColor(raw_ostream::RED);
errs() << F->getName() << "'s return value is marked noalias, ";
errs() << "but the function is not treated as malloc.\n";
errs().resetColor();
}
}
// Sequential types except pointer types shouldn't be used as the type of
// an instruction, a function parameter, or a global variable.
for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
GI != E; ++GI) {
if (isa<SequentialType>(GI->getType()))
assert(GI->getType()->isPointerTy());
}
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) {
if (isa<SequentialType>(AI->getType()))
assert(AI->getType()->isPointerTy());
}
}
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
if (isa<SequentialType>(Ins->getType()))
assert(Ins->getType()->isPointerTy());
}
}
}
// We don't support multi-process programs for now.
if (!HookFork)
assert(M.getFunction("fork") == NULL);
}
示例4: CloneFunction
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass. Search for functions which could be called
// indirectly and create clones for them which are only called by direct
// calls.
//
// Inputs:
// M - A reference to the LLVM module to transform.
//
// Outputs:
// M - The transformed LLVM module.
//
// Return value:
// true - The module was modified.
// false - The module was not modified.
//
bool
IndClone::runOnModule(Module& M) {
// Set of functions to clone
std::vector<Function*> toClone;
//
// Check all of the functions in the module. If the function could be called
// by an indirect function call, add it to our worklist of functions to
// clone.
//
for (Module::iterator I = M.begin(); I != M.end(); ++I) {
// Flag whether the function should be cloned
bool pleaseCloneTheFunction = false;
//
// Only clone functions which are defined and cannot be replaced by another
// function by the linker.
//
if (!I->isDeclaration() && !I->mayBeOverridden()) {
for (Value::use_iterator ui = I->use_begin(), ue = I->use_end();
ui != ue; ++ui) {
if (!isa<CallInst>(*ui) && !isa<InvokeInst>(*ui)) {
if(!ui->use_empty())
//
// If this function is used for anything other than a direct function
// call, then we want to clone it.
//
pleaseCloneTheFunction = true;
} else {
//
// This is a call instruction, but hold up ranger! We need to make
// sure that the function isn't passed as an argument to *another*
// function. That would make the function usable in an indirect
// function call.
//
for (unsigned index = 1; index < ui->getNumOperands(); ++index) {
if (ui->getOperand(index)->stripPointerCasts() == I) {
pleaseCloneTheFunction = true;
break;
}
}
}
//
// If we've discovered that the function could be used by an indirect
// call site, schedule it for cloning.
//
if (pleaseCloneTheFunction) {
toClone.push_back(I);
break;
}
}
}
}
//
// Update the statistics on the number of functions we'll be cloning.
// We only update the statistic if we want to clone one or more functions;
// due to the magic of how statistics work, avoiding assignment prevents it
// from needlessly showing up.
//
if (toClone.size())
numCloned += toClone.size();
//
// Go through the worklist and clone each function. After cloning a
// function, change all direct calls to use the clone instead of using the
// original function.
//
for (unsigned index = 0; index < toClone.size(); ++index) {
//
// Clone the function and give it a name indicating that it is a clone to
// be used for direct function calls.
//
Function * Original = toClone[index];
Function* DirectF = CloneFunction(Original);
DirectF->setName(Original->getName() + "_DIRECT");
//
// Make the clone internal; external code can use the original function.
//
DirectF->setLinkage(GlobalValue::InternalLinkage);
//.........这里部分代码省略.........
示例5: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Search for all call sites to casted functions.
// Check if they only differ in an argument type
// Cast the argument, and call the original function
//
// Inputs:
// M - A reference to the LLVM module to transform
//
// Outputs:
// M - The transformed LLVM module.
//
// Return value:
// true - The module was modified.
// false - The module was not modified.
//
bool ArgCast::runOnModule(Module& M) {
std::vector<CallInst*> worklist;
for (Module::iterator I = M.begin(); I != M.end(); ++I) {
if (I->mayBeOverridden())
continue;
// Find all uses of this function
for(Value::use_iterator ui = I->use_begin(), ue = I->use_end(); ui != ue; ) {
// check if is ever casted to a different function type
ConstantExpr *CE = dyn_cast<ConstantExpr>(*ui++);
if(!CE)
continue;
if (CE->getOpcode() != Instruction::BitCast)
continue;
if(CE->getOperand(0) != I)
continue;
const PointerType *PTy = dyn_cast<PointerType>(CE->getType());
if (!PTy)
continue;
const Type *ETy = PTy->getElementType();
const FunctionType *FTy = dyn_cast<FunctionType>(ETy);
if(!FTy)
continue;
// casting to a varargs funtion
// or function with same number of arguments
// possibly varying types of arguments
if(FTy->getNumParams() != I->arg_size() && !FTy->isVarArg())
continue;
for(Value::use_iterator uii = CE->use_begin(),
uee = CE->use_end(); uii != uee; ++uii) {
// Find all uses of the casted value, and check if it is
// used in a Call Instruction
if (CallInst* CI = dyn_cast<CallInst>(*uii)) {
// Check that it is the called value, and not an argument
if(CI->getCalledValue() != CE)
continue;
// Check that the number of arguments passed, and expected
// by the function are the same.
if(!I->isVarArg()) {
if(CI->getNumOperands() != I->arg_size() + 1)
continue;
} else {
if(CI->getNumOperands() < I->arg_size() + 1)
continue;
}
// If so, add to worklist
worklist.push_back(CI);
}
}
}
}
// Proces the worklist of potential call sites to transform
while(!worklist.empty()) {
CallInst *CI = worklist.back();
worklist.pop_back();
// Get the called Function
Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
const FunctionType *FTy = F->getFunctionType();
SmallVector<Value*, 8> Args;
unsigned i =0;
for(i =0; i< FTy->getNumParams(); ++i) {
Type *ArgType = CI->getOperand(i+1)->getType();
Type *FormalType = FTy->getParamType(i);
// If the types for this argument match, just add it to the
// parameter list. No cast needs to be inserted.
if(ArgType == FormalType) {
Args.push_back(CI->getOperand(i+1));
}
else if(ArgType->isPointerTy() && FormalType->isPointerTy()) {
CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1),
FormalType, "", CI);
Args.push_back(CastI);
} else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) {
unsigned SrcBits = ArgType->getScalarSizeInBits();
unsigned DstBits = FormalType->getScalarSizeInBits();
if(SrcBits > DstBits) {
CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
FormalType, true, "", CI);
//.........这里部分代码省略.........