How to explain this weird phenomenon????????

My friends,

I ran a function pass on a .bc file, intending to insert a CallInst to my self-made check function.

The compilation is successful. BUT after I ran that pass on the .bc file, the size of the file didn’t get any bigger!!
Does this mean my instrumentation work failed??

BTW the opt command I use is "opt -load …/…/…/Debug+Asserts/lib/Hello.so -hello <hello.bc> -o hello.bc"
Does this command mean to run hello pass on hello.bc and send the result to hello.bc???

The source code of the function pass is as follow.
// for each function traverse the instruction in it
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
{
for(BasicBlock::iterator II = BI->begin(),IE = BI->end();II != IE; ++II)
{
// we only care the instruction that call for functions and it can be cast to CallInst
if(CallInst * III = dyn_cast(II))
{
// if the callInst is calling for puts function
if(III->getCalledFunction()!=NULL&&III->getCalledFunction()->getName()==“puts”)
{
errs() <getCalledFunction()->getName()<<" function found!\n";
// declare the extern function(int check()) that I want to instrument in the .bc file
Function *check = cast(III->getCalledFunction()->getParent()->getOrInsertFunction(“check”,
Type::getInt32Ty(III->getCalledFunction()->getParent()->getContext()),
(Type *)0));
// Create the CallInst to call for the check function!
CallInst *callcheck = CallInst::Create(check,“CallCheck”);
// insert the CallInst right before II
callcheck->insertBefore(II);

errs() <<“INSERT SUCCEEDED!!!\n”;
}
else
{
errs() <<“it’s not main function!\n”<<“it is:”<getCalledFunction()->getName()<<’\n’;
}
}
}

I figured that my opt command is wrong! How to specify the output file anyway??
if I want hello.bc to be input file and newhello.bc to be output file, is the opt command go like this?
opt -load …/…/…/Debug+Asserts/lib/Hello.so -hello <hello.bc> -o newhello.bc ??

I 've checked the introduction of the opt-tool on" http://llvm.org/releases/1.0/docs/CommandGuide/opt.html "
And it says

-o
Specify the output filename.

but I tried “opt -load …/…/…/Debug+Asserts/lib/Hello.so -hello <hello.bc> -o newhello.bc” and get
"opt: newhello.bc: error: Could not open input file: No such file or directory"
It’s not output file!
Any help?

Hi,

BTW the opt command I use is *"opt -load ../../../Debug+Asserts/lib/Hello.so
-hello <hello.bc> -o hello.bc"*

just use hello.bc not <hello.bc> otherwise the shell will redirect input and
output.

Ciao, Duncan.

I did it !!!
YOU MADE MY DAY !!!

Hi, my friends

I finally insert the callInst into the hello.bc file.Then I compile the hello.bc to hello.o file and the check.c to check.o file. And I think by link those to .o file togetherI can get the executable ELF file(clang hello.o check.o -o finalfile).

But when I link the two objective file, it said
“hello.o: In function main': hello.bc:(.text+0x69): undefined reference to check’
clang: error: linker command failed with exit code 1 (use -v to see invocation)” What’s wrong??

To make it readable I convert the .bc file into .ll file using llvm-dis. The IR code is as follow, any help?

Before running the pass
; ModuleID = ‘hello.bc’
target datalayout = “e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128”
target triple = “i386-pc-linux-gnu”

@.str = private unnamed_addr constant [18 x i8] c"add result is %d\0A\00", align 1
@.str1 = private unnamed_addr constant [20 x i8] c"minus result is %d\0A\00", align 1
@str = private unnamed_addr constant [13 x i8] c"hello world!\00"

define i32 @add(i32 %a, i32 %b) nounwind readnone {
entry:
%add = add nsw i32 %b, %a
ret i32 %add
}

define i32 @minus(i32 %a, i32 %b) nounwind readnone {
entry:
%sub = sub nsw i32 %a, %b
ret i32 %sub
}

define i32 @main() nounwind {
entry:
%call1 = tail call i32 (i8*, …)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 3) nounwind
%call3 = tail call i32 (i8*, …)* @printf(i8* getelementptr inbounds ([20 x i8]* @.str1, i32 0, i32 0), i32 1) nounwind
%puts = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @str, i32 0, i32 0))
ret i32 0
}

declare i32 @printf(i8* nocapture, …) nounwind

declare i32 @puts(i8* nocapture) nounwind
After running the pass
; ModuleID = ‘newhello.bc’
target datalayout = “e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128”
target triple = “i386-pc-linux-gnu”

@.str = private unnamed_addr constant [18 x i8] c"add result is %d\0A\00", align 1
@.str1 = private unnamed_addr constant [20 x i8] c"minus result is %d\0A\00", align 1
@str = private unnamed_addr constant [13 x i8] c"hello world!\00"

define i32 @add(i32 %a, i32 %b) nounwind readnone {
entry:
%add = add nsw i32 %b, %a
ret i32 %add
}

define i32 @minus(i32 %a, i32 %b) nounwind readnone {
entry:
%sub = sub nsw i32 %a, %b
ret i32 %sub
}

define i32 @main() nounwind {
entry:
%call1 = tail call i32 (i8*, …)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 3) nounwind
%call3 = tail call i32 (i8*, …)* @printf(i8* getelementptr inbounds ([20 x i8]* @.str1, i32 0, i32 0), i32 1) nounwind
%CallCheck = call i32 @check()
%puts = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @str, i32 0, i32 0))
ret i32 0
}

declare i32 @printf(i8* nocapture, …) nounwind

declare i32 @puts(i8* nocapture) nounwind

declare i32 @check()
The original hello.c file
#include <stdio.h>
extern int check();
int add(int a,int b)
{
return a+b;
}

int minus(int a,int b)
{
return a-b;
}
int main()
{
int a=2,b=1;
printf(“add result is %d\n”,add(a,b));
printf(“minus result is %d\n”,minus(a,b));
printf(“hello world!\n”);
return 0;
}
The original check.c file
#include <stdio.h>
void print()
{
printf(“Check function works!\n”);
}

Your files do not appear to implement the check() function.

Hi 15102925731,

But when I link the two objective file, it said
"hello.o: In function `main':
hello.bc:(.text+0x69): undefined reference to `check'
clang: error: linker command failed with exit code 1 (use -v to see invocation)"
What's wrong??

...

declare i32 @check()

...

*The original check.c file*
#include <stdio.h>
void print()

Should be called check not print.

{
printf("Check function works!\n");
}

Ciao, Duncan.

Again, problem solved!
Awesome! Thank you!!!

Yeah, I implemented the check function in another separated file (check.c) and then linked it with hello.o.
It turns out that I made a mistake by naming the function “print” in check.c file. It should be named “check” too, so
that the programme could find it!

Thanks for your information!