llvm在C++中提取struct元素和struct size

She*_*fer 5 c++ struct static-analysis llvm

LLVM新手在这里.我有以下C++程序

using namespace std;
struct A{
  int i;
  int j;
};

int main()
{
   struct A obj;
   obj.i = 10;
   obj.j = obj.i;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用clang ++,我可以看到LLVM IR包含struct字段,如下所示

%struct.A = type { i32, i32 }
Run Code Online (Sandbox Code Playgroud)

我想使用LLVM Pass获取结构元素.我编写了以下程序 - 遍历全局变量和每个指令操作数,但它们都没有帮助我提取结构A或Ai或Aj

    #include "llvm/Pass.h"
    #include "llvm/IR/Function.h"
    #include "llvm/Support/raw_ostream.h"

    #include <llvm/IR/Constants.h>
    #include <llvm/IR/DerivedTypes.h>
    #include <llvm/IR/Instructions.h>
    #include <llvm/IR/IntrinsicInst.h>
    #include <llvm/IR/LLVMContext.h>
    #include <llvm/IR/Module.h>

    #include <iostream>
    #include <map>
    #include <vector>


    using namespace llvm;

    namespace {

    class StructModulePass: public ModulePass {
    public:
    static char ID;
    StructModulePass() : ModulePass(ID) {}
    virtual bool runOnModule(Module &M1) override {
    // iterate over global structures
    M = &M1;
    int i;
    for(auto G = M->global_begin(); G!= M->global_end() ; G++, i++){
    errs() << i << " == > " ;
    errs().write_escaped(G->getName()) << "\n";
  }

// iterate through each instruction. module->function->BB->Inst
  for(auto &F_ : M->functions()){
    F = &F_;
    for(auto &B_ : *F)
      B = &B_;
      for(auto &I : *B) {
        for (unsigned i = 0; i < I.getNumOperands(); i++)
          std::cerr << I.getOperand(i)->getName().data() << std::endl;
      }
  }
  return true;
  }
private:
  Module *M;
  Function *F;
  BasicBlock *B;
};
  }


char StructModulePass:: ID = 0;
static RegisterPass<StructModulePass> X("getstructnamesize", "Get All Struct Names and Sizes",
                             false /* Only looks at CFG */ ,
                             false /* Analysis Pass */);
Run Code Online (Sandbox Code Playgroud)

我想创建一个包含所有结构(全局和本地)的数据库,并在我的程序中使用.例如.< A , <int32, int32> , B , <int32, bool , char *>>.

我已经通过了doxygen页面,LLVM教程并检查了我们是否可以获取结构值,但是我无法找到一种方法来提取结构而不必知道结构值 - 例如.创建一个IRBuilder,插入预定义的IntTy32类型变量.在这方面的任何帮助或一些相关的教程将有所帮助

Oak*_*Oak 4

在 LLVM IR 术语中,“全局”是全局变量或全局常量。这行:

%struct.A = type { i32, i32 }
Run Code Online (Sandbox Code Playgroud)

是一个确定的结构规范,而不是全局变量,就像typedef在C++中不是全局变量一样。您可以使用 迭代那些Module::getIdentifiedStructTypes()

不过,有一些注意事项:

  1. 熟悉该dump()方法。这是比所有打印到cerr.

  2. 您使用getName()的是值,而不是类型 - 我不认为这就是您的意图。另请记住,LLVM 值不一定有名称。

  3. 获得像<int32, bool, char *>C++ 类型,而不是 LLVM IR 类型这样的结果将很棘手。例如,Clang 可能会将bool和编译chari8,并且不容易区分两者。您还可能获得 vptr 字段、填充字段等。如果您确实想要源程序中使用的实际 C++ 结构体,则必须依赖debug info