Chao Chen via llvm-dev
2017-Sep-22 02:08 UTC
[llvm-dev] Get function implementation for indirect CallInst.
Hi All,
I am using LLVM to analysis some C++ codes. I need to find the related function
implementation for a given indirect CallInst.
To make my question a little bit clear, I construct a simple example here. For “
call void %3(%class.Base* %1)”, I need to figure out
Which implementation is called ( it can be manually figured out that
_ZN1A5helloEv (A::hello() is called,how to figure it out in a pass ?)
My initial thinking is trace back from "call void %3(%class.Base* %1)”
until find %obj1 = alloca %class.A, align 8, but how can I associate %class.A
with @_ZTV1A, so I can get the function from @_ZTV1A ?
Thanks!
;virtual tables
@_ZTV1A = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8*
null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void
(%class.A*)* @_ZN1A5helloEv to i8*)] }, align 8
@_ZTV1B = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8*
null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (void
(%class.B*)* @_ZN1B5helloEv to i8*)] }, align 8
;A::hello()
define linkonce_odr void @_ZN1A5helloEv(%class.A* %this) unnamed_addr #2 align 2
{
entry:
%this.addr = alloca %class.A*, align 8
store %class.A* %this, %class.A** %this.addr, align 8
%this1 = load %class.A*, %class.A** %this.addr, align 8
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x
i8]* @.str, i32 0, i32 0))
ret void
}
;B::hello()
define linkonce_odr void @_ZN1B5helloEv(%class.B* %this) unnamed_addr #2 align 2
{
entry:
%this.addr = alloca %class.B*, align 8
store %class.B* %this, %class.B** %this.addr, align 8
%this1 = load %class.B*, %class.B** %this.addr, align 8
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x
i8]* @.str.1, i32 0, i32 0))
ret void
}
define i32 @main() #0 {
entry:
%obj1 = alloca %class.A, align 8
%obj2 = alloca %class.B, align 8
%C = alloca %class.Base*, align 8
call void @_ZN1AC1Ev(%class.A* %obj1) #4
call void @_ZN1BC1Ev(%class.B* %obj2) #4
%0 = bitcast %class.A* %obj1 to %class.Base*
store %class.Base* %0, %class.Base** %C, align 8
%1 = load %class.Base*, %class.Base** %C, align 8
%2 = bitcast %class.Base* %1 to void (%class.Base*)***
%vtable = load void (%class.Base*)**, void (%class.Base*)*** %2, align 8
%vfn = getelementptr inbounds void (%class.Base*)*, void (%class.Base*)**
%vtable, i64 0
%3 = load void (%class.Base*)*, void (%class.Base*)** %vfn, align 8
call void %3(%class.Base* %1)
ret i32 0
}
Related C++ code
class Base {
public:
virtual void hello();
};
class A: public Base {
public:
void hello() {
printf("hello\n");
};
};
class B: public Base {
public:
void hello() {
printf("world\n");
};
};
int main() {
A obj1;
B obj2;
Base * C = &obj1;
C->hello();
}
Best Regards,
Chao
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20170921/a2e58c5b/attachment.html>
