2016-03-28 2 views
3

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; 
} 

Используя лязг ++ можно видеть, что LLVM ИК содержит поле структуры, как показано ниже

%struct.A = type { i32, i32 } 

Я хотел бы получить элементы конструкции с использованием LLVM Pass. Я пишу следующую программу - итерацию через как глобальные переменные, так и каждый операнд инструкции, но ни один из них не помогает мне в извлечении структур A или A.i или A.j.

#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 */); 

Я хочу создать базу данных всех структур (глобальных и локальных), определенных и используемых в моей программе. Например. < A , <int32, int32> , B , <int32, bool , char *>>.

Я прошел через доксигенные страницы, учебники LLVM и проверил, можем ли мы получить значения структуры, но я не могу найти способ извлечь структуры, не зная значения struct - например. создавая IRBuilder, вставляя предопределенные переменные типа IntTy32. Любая помощь в этом отношении или некоторые соответствующие учебные пособия помогут

ответ

3

В терминологии LLVM IR глобальная переменная или глобальная константа. Эта линия:

%struct.A = type { i32, i32 } 

Является идентифицированный спецификация структуры, а не глобальная переменная, так же, как, как typedef в C++ не является глобальной переменной. Вы можете перебирать те, которые используют Module::getIdentifiedStructTypes().

Некоторые замечания, однако:

  1. ознакомятся с методом dump(). Это намного проще для всех ваших отпечатков до cerr.

  2. Вы используете getName() по значениям, а не по типам - я не думаю, что это то, что вы хотели сделать. Также имейте в виду, что значения LLVM не обязательно имеют имена.

  3. Получение результатов, таких как <int32, bool, char *> - которые являются типами C++, а не типами LLVM IR - будет хитро. Например, Clang, вероятно, скомпилирует как bool, так и char до i8, и будет нелегко сказать разницу. Вы также можете получить поле vptr, поля заполнения и т. Д. Если вам действительно нужна фактическая структура структур C++, используемая в исходной программе, вы должны полагаться на debug info.