Insert a function call in the code

Hello, everyone
I am new to LLVM, now I got a problem

I want to add a function call before sleep(int a, int b)

code below

#include <stdio.h>

int sleep(int a, int b)
{

return a+b;
}
int main(int argc, char **argv)
{
sleep(1,2);

}

after use opt -load …/llvm-2.8/Release+Asserts/lib/bishe_insert.so -bishe_insert <1.bc> 2.bc
I want get the code

#include <stdio.h>

int sleep(int a, int b)
{

return a+b;
}
int main(int argc, char **argv)
{
hook() //void *hook(void )
sleep(1,2);
}

after Using apt…

ERROR Occured

[kain@localhost 4]$ opt -load /home/kain/Documents/bishe/llvm-2.8/Release+Asserts/lib/bishe_insert.so -bishe_insert <1.bc> 2.bc
opt: Type.cpp:456: llvm::FunctionType::FunctionType(const llvm::Type*, const std::vector<const llvm::Type*, std::allocator<const llvm::Type*> >&, bool): Assertion `isValidArgumentType(Params[i]) && “Not a valid type for function argument!”’ failed.
0 opt 0x000000000082f5cf
1 opt 0x000000000083181a
2 libpthread.so.0 0x00000033f460f4c0
3 libc.so.6 0x00000033f42329a5 gsignal + 53
4 libc.so.6 0x00000033f4234185 abort + 373
5 libc.so.6 0x00000033f422b935 __assert_fail + 245
6 opt 0x00000000007cb477 llvm::FunctionType::FunctionType(llvm::Type const*, std::vector<llvm::Type const*, std::allocator<llvm::Type const*> > const&, bool) + 407
7 opt 0x00000000007cdf94 llvm::FunctionType::get(llvm::Type const*, std::vector<llvm::Type const*, std::allocator<llvm::Type const*> > const&, bool) + 324
8 opt 0x00000000007babad llvm::Module::getOrInsertFunction(llvm::StringRef, llvm::Type const*, …) + 253
9 bishe_insert.so 0x00007fb4ec5838b0
10 opt 0x00000000007c47d7 llvm::MPPassManager::runOnModule(llvm::Module&) + 503
11 opt 0x00000000007c4957 llvm::PassManagerImpl::run(llvm::Module&) + 167
12 opt 0x00000000004a43be main + 2734
13 libc.so.6 0x00000033f421ec5d __libc_start_main + 253
14 opt 0x0000000000499d19
Stack dump:
0. Program arguments: opt -load /home/kain/Documents/bishe/llvm-2.8/Release+Asserts/lib/bishe_insert.so -bishe_insert

  1. Running pass ‘test function exist’ on module ‘’.
    Aborted (core dumped)

Below is my PASS code

#include “llvm/Pass.h”
#include “llvm/Module.h”
#include “llvm/Function.h”
#include “llvm/Support/raw_ostream.h”
#include “llvm/Type.h”
#include “llvm/Instructions.h”
#include “llvm/Instruction.h”

#include “llvm/Support/IRBuilder.h”

using namespace llvm;

namespace{
struct bishe_insert : public ModulePass{
static char ID;
Function *hook;

bishe_insert() : ModulePass(ID) {}

virtual bool runOnModule(Module &M)
{
// Function *F = M.getFunction(“sleep”);
// hook = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage, “hook”, F->getParent());
Constant hookFunc;
hookFunc = M.getOrInsertFunction(“hook”, Type::getVoidTy(M.getContext()), Type::getVoidTy(M.getContext()), (Type
)0);

hook= cast(hookFunc);

for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{

for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
bishe_insert::runOnBasicBlock(BB);
}
}

return false;
}
virtual bool runOnBasicBlock(Function::iterator &BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa(&(*BI)) || isa(&(*BI)))
{
CallInst *CI = dyn_cast(BI);

std::vector<Value *> Args;
for(Function::arg_iterator i = hook->arg_begin(), e = hook->arg_end(); i != e; ++i)
{
Args.push_back(i);
}

if(“sleep” == CI->getCalledFunction()->getName())
{

CallInst *NewCall = CallInst::Create(hook,Args.begin(), Args.end(), “hook”, (Instruction *)BI);
}

}

}
return true;
}
};
}
char bishe_insert::ID = 0;
static RegisterPass<bishe_insert> X(“bishe_insert”, “test function exist”, false, false);

I think CallInst *NewCall = CallInst::Create(hook,Args.begin(), Args.end(), “hook”, (Instruction *)BI)
can Insert hook() before sleep(1,2), but the Args may be wrong,
I wirte the PASS code by learning Miscompilation.cpp

Thank you very much

Hi 赵夏,

             hookFunc = M.getOrInsertFunction("hook",
Type::getVoidTy(M.getContext()), Type::getVoidTy(M.getContext()), (Type*)0);

try removing the second Type::getVoidTy. Your function doesn't take any
parameters, so you should simply pass an empty list of parameter types.
Unlike in C++, a function foo(void) taking no parameters shouldn't be
declared as taking one parameter of void type, it takes no parameters.

Ciao, Duncan.

Thank you for your help
I found the problem,
as hook() is a no paramter function,so

for(Function::arg_iterator i = hook->arg_begin(), e = hook->arg_end(); i != e; ++i)
{
Args.push_back(i); /////////////Wong
}

we can add a call by
Instruction newInst = CallInst::Create(hook, “”);
BB->getInstList().insert((Instruction
)BI, newInst);

If you want to insert the function with a paramter, you should add a real value to Args

在 2011年11月20日 下午3:07,Duncan Sands <baldrick@free.fr>写道: