[llvm-dev] Get function implementation for indirect CallInst. (original) (raw)

Chao Chen via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 21 19:08:18 PDT 2017


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>



More information about the llvm-dev mailing list