Функции выделения памяти в llvm
Как обнаружить malloc и свободные вызовы функций в проходе llvm и заменить его вызовами новой функции, получив аргументы и тип возврата в llvm?
т.е. есть ли способ создавать новые функции (Malloc и free), а затем создавать вызовы функций всякий раз, когда Malloc и free обнаруживаются?
1.Create malloc and free
Type *BPTy = PointerType::getUnqual(Type::getInt8Ty(M.getContext()));
FunctionType *malloc_Fty = FunctionType::get(BPTy, llvm::ArrayRef<Type*>(), true);
Function *malloc_func = cast<Function>(M.getOrInsertFunction("malloc", malloc_Fty));
FunctionType *free_Fty = FunctionType::get(Type::getVoidTy(M.getContext()), BPTy, false);
Function *free_func = cast<Function>(M.getOrInsertFunction("free",free_Fty));
2. Detect malloc and free and replace it with new malloc and free function calls
if(CallInst *CI = dyn_cast<CallInst>(I)) {
Function *Callee = CI->getCalledFunction();
if (Callee->getName() == "malloc") {
FunctionType *Ty = Callee->getFunctionType();
PointerType *PtrTy = dyn_cast<PointerType>(Ty);
Type *AllocTy = PtrTy->getElementType();
const DataLayout &DL = M.getDataLayout();
Type *IntPtrTy = DL.getIntPtrType(M.getContext());
Value *mallocArgs;
mallocArgs = ConstantExpr::getSizeOf(AllocTy);
mallocArgs = ConstantExpr::getTruncOrBitCast(cast<Constant>(mallocArgs), IntPtrTy);
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&*I)) {
if (AI->isArrayAllocation()) {
if (isa<ConstantInt>(mallocArgs) && cast<ConstantInt>(mallocArgs)->isOne()) {
mallocArgs = I->getOperand(0);
} else if (Constant *CO = dyn_cast<Constant>(I->getOperand(0))) {
CO = ConstantExpr::getIntegerCast(CO, IntPtrTy, false );
mallocArgs = ConstantExpr::getMul(CO, cast<Constant>(mallocArgs));
} else {
Value *Scale = I->getOperand(0);
if (Scale->getType() != IntPtrTy)
Scale = CastInst::CreateIntegerCast(Scale, IntPtrTy, false,"", &*I);
// Multiply it by the array size if necessary...
mallocArgs =BinaryOperator::Create(Instruction::Mul, Scale, mallocArgs, "", &*I);
}
}
}
// Create the call to malloc
CallInst *malloc_Call = CallInst::Create(malloc_func, mallocArgs, "", &*I);
// Cast the instruction to convert to the correct type
Value *malloc_PtrCast;
Type * voidty=Type::getVoidTy (M.getContext());
if (malloc_Call->getType() !=voidty )
malloc_PtrCast = new BitCastInst(malloc_Call, I->getType(), "", &*I);
else
malloc_PtrCast = Constant::getNullValue(I->getType());
Instruction *II=dyn_cast<Instruction>(&*I);
II->replaceAllUsesWith(malloc_PtrCast);
}
if (Callee->getName() == "free") {
Value *free_PtrCast =
new BitCastInst(I->getOperand(0), PointerType::getUnqual(Type::getInt8Ty(M.getContext())), "", &*I);
// Create the call to free function
CallInst::Create(free_func, free_PtrCast, "", &*I);
Instruction *II=dyn_cast<Instruction>(&*I);
II->replaceAllUsesWith(free_PtrCast);
}
}
3. Example on which I am testing
void* ptr;
void malloc_func()
{
ptr = malloc(512);
}
void free_func()
{
free(ptr);
}
Но, я получаю ошибку сегментации, это правильный способ заменить malloc и вызовы свободных функций новыми функциями?