Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the list of function calls that are performed in each function of a program, from the intermediate representation of LLVM?

Tags:

c++

llvm

I am trying to build a simple version of a code analysis tool with LLVM.

I have a few .ll files which contain the intermediate LLVM representation of certain programs.

How can I get the list of function calls that are performed in each function of a program, from the intermediate representation of LLVM?

The input parameter I have is an instance of the LLVM: Module class which represents the program. Then, I get the list of functions present in the program with the function getFunctionList ().

void getFunctionCalls(const Module *M)
{

  // Iterate functions in program
  for (auto curFref = M->getFunctionList().begin(), endFref = M->getFunctionList().end();
 curFref != endFref; ++curFref) {

        // For each function
        // Get list of function calls

  }

}
like image 804
Kroka Avatar asked Apr 01 '17 18:04

Kroka


People also ask

What is a function call?

A function call is an expression that passes control and arguments (if any) to a function and has the form: expression (expression-list opt) where expression is a function name or evaluates to a function address and expression-list is a list of expressions (separated by commas).

What are the requirements for a function to be called?

The only requirement in any function call is that the expression before the parentheses must evaluate to a function address. This means that a function can be called through any function-pointer expression. This example illustrates function calls called from a switch statement:

Which functions are commonly used to manipulate lists in Python?

We have functions that are commonly used to manipulate lists. For example: len (), sum (), max (), range () and many more. We also have some functions that are not commonly used like any (), all (), etc.

How do I find all functions defined in an application?

You can find out all functions defined (but not necessarily called) in an application with the nm command, e.g. You can also use GDB to set a breakpoint on each function: Once you continue, you'll hit a breakpoint for each function called.


1 Answers

This is a fragment from our working code here:

for (auto &module : Ctx.getModules()) {
  auto &functionList = module->getModule()->getFunctionList();
  for (auto &function : functionList) {
    for (auto &bb : function) {
      for (auto &instruction : bb) {
        if (CallInst *callInst = dyn_cast<CallInst>(&instruction)) {
          if (Function *calledFunction = callInst->getCalledFunction()) {
            if (calledFunction->getName().startswith("llvm.dbg.declare")) {

Also keep in mind that there are also invoke instructions InvokeInst which may be obtained in a similar way.

Google CallInst vs InvokeInst and also learn about the functions with or without a called function. If a function does not have a called function this is indirect call. Indirect calls appear in LLVM IR when the source code instead of calling a function directly, calls a function pointer. In C++ this often happens when some class operates through an abstract interface (polymorphism). So keep in mind that it is not 100% always possible to trace a called function even though you have a call instruction in place.

like image 169
Stanislav Pankevich Avatar answered Oct 29 '22 01:10

Stanislav Pankevich