How to instrument a this function using insertBefore instruction???

Hi all,
Im trying to instrument this hello function right before the instruction that call the “puts” function(the source code is as follow).

Now I can compile the pass without errors, but when run the pass with opt tool, it broke down. The diagnose is something like

Referencing function in another module!
%CallCheck = call i32 @fib()
Broken module found, compilation aborted!

Does it mean I fail to wrap the function into a module?? How to actually insert the the “hello function” before the calling instruction ?? Im waiting for your help.
Thank you!!

//=========================================================================================================================================//
//=========================================================================================================================================//// FPSFI: a Function Pass Based Idea for Software Fault Isolation
//
//
//This file involves the main work of SFI. It will source the certain point in any programme(mainly modules in our context)and insert our manully made//
//check function to provide API integrity. Thanks to the pass mechanism that LLVM provide, we can wrap our fix and optimization idea into a function pass
// and act it on every function the clang has analysed.
//
//=========================================================================================================================================//
//=========================================================================================================================================//
#include “llvm/Pass.h”
#include “llvm/Function.h”
#include “llvm/Support/raw_ostream.h”
#include “llvm/Instruction.h”
#include “llvm/Transforms/Utils/UnrollLoop.h”
#include “llvm/BasicBlock.h”
#include “llvm/ADT/Statistic.h”
#include “llvm/Analysis/LoopIterator.h”
#include “llvm/Analysis/LoopPass.h”
#include “llvm/Analysis/ScalarEvolution.h”
#include “llvm/Analysis/ScalarEvolutionExpander.h”
#include “llvm/Support/Debug.h”
#include “llvm/Transforms/Utils/BasicBlockUtils.h”
#include “llvm/Transforms/Utils/Cloning.h”
#include “llvm/Type.h”
#include “llvm/LLVMContext.h”
#include “llvm/Support/Casting.h”
#include “stdio.h”

#include “llvm/Module.h”
using namespace llvm;

int check()
{
printf(“Hello me!!\n”);
return 0;
}

Module * M;
LLVMContext Context;
FunctionType *STy=FunctionType::get(Type::getInt32Ty(Context), false);
Function *check = Function::Create(STy, Function::InternalLinkage, “check” ,&M);

CallInst *callcheck = CallInst::Create(FibF,“CallCheck”);

namespace {

struct Hello : public FunctionPass
{

static char ID;
Hello() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &F)
{
errs() << "Hello: ";
errs().write_escaped(F.getName()) <<‘\n’;
// run through all the instruction and convert all the callinst to …
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
{
for(BasicBlock::iterator II = BI->begin(),IE = BI->end();II != IE; ++II)
{
// errs() <<“between instructions! \n”;
// CallInst * III = CallInst::Create(&F,“InsttoCallInst”,II);
if(CallInst * III = dyn_cast(II))
{

if(III->getCalledFunction()!=NULL&&III->getCalledFunction()->getName()==“puts”)
{
errs() <getCalledFunction()->getName()<<" function found!\n";
callcheck->insertBefore(II);
errs() <<“INSERT SUCCEEDED!!!\n”;
}
else
{
errs() <<“it’s not main function!\n”<<“it is:”<getCalledFunction()->getName()<<‘\n’;
}
}/**/
}

}

}
return true;
}
};
}

char Hello::ID = 0;
static RegisterPass X(“hello”, “ZHello Korld Pass”, false, false);

Hi,
I got upset… What does “Broken module found, compilation aborted!” mean really?? what‘s “broken module“??

Hi,

I don’t think the code you pasted can be the correct code, where does FibF come from?

Anyway, the problem is that you’re calling the FibF from Module A, however you defined it for Module B.

You need to insert the FibF function into the Module that you’re running. To do this override “virtual bool doInitialization(Module &M);” and insert FibF into M.

Joey

2012/4/9 15102925731 <zhenkaixd@126.com>

You'll need to declare the function in a separate module, not in the
function pass.
That module needs to be compiled independently and linked to the
program instrumented by your pass.
In order to add a function declaration to the program, use getOrInsertFunction()
You may want to have a look at how AddressSanitizer works
(http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp),
it does essentially the same.

HTH,
Alex

Thank you very much!

To make it simpler, I may as well just implement the self-written “check function” in C language instead of wrapping it in LLVM module. According to the hint you give me, all I need to do is as follow(?)

  1. Implement the “Check function” in the check.c file;
  2. Add the check function into the module(the Hello1.bc file which I will run the functionPass on) in the functionPass file.
  3. Determine the exact position and insert the CallInst instruction to call that check function. (already done as is shown in the source code).
  4. gmake and use the opt tool to generate the instrumented module(Hello2.bc).
  5. Link the check.c file and Hello2.bc file together to generate ELF file.

does that make sense?

That sounds like a good general plan, yes!

Joey

2012/4/9 15102925731 <zhenkaixd@126.com>

I do appreciate your patience. I will try out that idea to see what may bring about~ Thank you!

在 2012-04-09 17:56:05,“Joey Gouly” joel.gouly@gmail.com 写道: