Trace calls to memcpy

Hello,

I’m trying to use an LLVM Pass to trace calls to memcpy via instrumentation, but finding it quite difficult without having much knowledge of sound IR structure. Here’s my FunctionPass thus far:

// at the beginning of runOnFunction
FunctionCallee hookFunc = M->getOrInsertFunction(“_Z12trace_memcpyPvS_m”, Type::getVoidTy(M->getContext()));

// further in the same function
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
if (isa(&I)) {
CallInst CI = dyn_cast(&I);
Function
FC = CI->getCalledFunction();
StringRef SR = FC->getName();
if (SR == “llvm.memcpy.p0i8.p0i8.i64”) {
CallInst* newInstr = dyn_cast(CI->clone());
newInstr->setCalledFunction(hookFunc);
newInstr->insertBefore(CI);
}
}
}
}

The issue arises when using setCalledFunction. If I remove that, it runs successfully and I end up with duplicate calls to memcpy - as expected.

But when I leave it in, and run the pass with opt, I get the following error:

LLVM ERROR: Broken function found, compilation aborted!

Looking for any clues on how to fix… and would also appreciate pointers in general about how I might learn the general concepts at play here.

Thanks all,.

Hi Matt,

It looks to me that at least the function type doesn’t match.
You have defined a type of _Z12trace_memcpyPvS_m as () -> void but memcpy doesn’t have that type.

You need to pass the same function type as llvm.memcpy to getOrInsertFunction.

Regards,
Hideto

2020年3月12日(木) 22:15 Matt Fysh via llvm-dev <llvm-dev@lists.llvm.org>: