2

如何通过获取 llvm 中的参数和返回类型来检测 llvm 传递中的 malloc 和 free 函数调用并用新的函数调用替换它?

即有没有办法创建新函数(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 和 free 函数调用的正确方法吗?

4

0 回答 0