Search code examples
llvmllvm-clangllvm-ir

llvm: How to get the call graph for a module of external node


I am having a program lets consider myProgram.c which uses some library (user created library) lets say myLibrary.

#include "myLibrary.h"'

int main()
{
    //call some function in myLibrary lets say foo
    foo();
}

Now when I have created a module pass. And I am generating call graph. Now in the call graph generated there is a node for the function foo() as follows:

Call graph node for function: 'foo'<<0x951d300>> #uses=3 CS<0x0> calls external node.

Now I want all the functions which will be called by this foo in the "myLibrary".

Is it possible? Can I get the call graph of myLibrary through the call graph node of the function foo in myProgram.c


Solution

  • I tried this with the following steps, and was able to get all functions from call graph.

    First my_program.c looks like

    #include "my_library.h"
    int main()
    {
        foo();
    }
    

    my_library.c is

    #include "my_library.h"
    void boo() {}
    
    void foo()
    {
        boo();
    }
    
    clang++ my_program.c -c -emit-llvm
    clang++ my_library.c -c -emit-llvm
    llvm-link my_program.bc my_library.bc -o linked.bc
    

    Then I used a custom ModulePass to traverse call graph. To get the call graph the ModulePass uses llvm CallGraphWrapperPass pass.

    If I use clang instead of clang++, CallGraph does not capture main calling foo, which is strange, but i don't have any explanation for this.