LLVM как обнаруживать и игнорировать библиотечные (встроенные) функции? - PullRequest
1 голос
/ 07 января 2020

Я пытаюсь написать простой проход LLVM со следующей целью:

  • Найти все call инструкции.
  • Вставить внешнюю функцию, написанную мной, в вызываемую функция.

В качестве примера рассмотрим, что у меня есть следующий пример программы:

#include <stdio.h>
#include <stdlib.h>

int times_two(int val);

int main(int argc, char** argv) {
    int arg_1 = atoi(argv[1]);
    char test_str[] = "Test String";
    int res = times_two(arg_1);
    printf("%d", res);
    return 0;
}

int times_two(int val) {
    // ----> INSERT SOME EXTERNAL FUNCTION HERE <---- 
    return val * 2;     
}

Вот часть моего инструментария LLVM:

/* Begin instrumentation 
   --------------------- */
for (auto &F : M)
{       
    for (auto &B : F)
    {
        for (auto &I : B)
        {
             IRBuilder<> builder(&I);
             // Now we have reached a 'call' instruction
             if (auto *CallInstr = dyn_cast<CallInst>(&I))
             {
                // Cast into Function pointer
                Function *called_func = CallInstr->getCalledFunction();
                errs() << called_func->getName() << "\n";  

                // loop into the function, getFirstInstruction, do stuff and break.
                for (auto &bb_in_func : *called_func)
                    {
                        // Set an Insert point at the first
                        // line of the external function
                        BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
                        builder.SetInsertPoint(&bb_in_func, insert_point);
                        // Make an external call
                        builder.CreateCall(extern1);
                        break;
                    }
               }
          }
    }
}        

Однако, так как я oop через все функции в модуле, этот список функций также, кажется, состоит из встроенных функций. В приведенном выше случае я получаю следующее:

atoi
llvm.memcpy.p0i8.p0i8.i64
times_two
printf

Как мне игнорировать эти встроенные функции и учитывать только times_two?

1 Ответ

0 голосов
/ 07 января 2020

Я думаю, я понял это. Мы хотим использовать getLibFunc(). Этот пример делает нечто очень похожее.

В моем случае мне пришлось обновить инструментарий LLVM следующим образом:

/* Include this:
#include "llvm/Analysis/TargetLibraryInfo.h"
#include <bits/stdc++.h>
*/

bool Example::runOnModule(Module &M)
{
  const TargetLibraryInfo *TLI; 
  LibFunc inbuilt_func;
  std::set<StringRef> builtins;

  /* Gather all built-in functions 
     --------------------- */
  for (auto &F : M)
  {
     if (TLI->getLibFunc(F, inbuilt_func))
        builtins.insert(F.getFunction().getName());
  }       

  /* Begin instrumentation 
     --------------------- */
  for (auto &F : M)
  {       
    for (auto &B : F)
    {
      for (auto &I : B)
      {
         IRBuilder<> builder(&I);
         // Now we have reached a 'call' instruction
         if (auto *CallInstr = dyn_cast<CallInst>(&I))
         {
           // Cast into Function pointer
           Function *called_func = CallInstr->getCalledFunction();
           StringRef func_name = called_func->getName();
           // This line checks to see if the function is not a builtin-function
           if (builtins.count(func_name)==0)
           {
             // loop into the function, getFirstInstruction, do stuff and break.
             for (auto &bb_in_func : *called_func)
             {
               // Set an Insert point at the first
               // line of the external function
               BasicBlock::iterator insert_point = bb_in_func.getFirstInsertionPt();
               builder.SetInsertPoint(&bb_in_func, insert_point);
               // Make an external call
               builder.CreateCall(extern1);
               break;
             }
           }
         }
      }
    }
  }        
} 
...