llvm 在 C++ 中提取结构元素和结构大小
llvm extract struct elements and struct size in C++
这里是 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;
}
使用 clang++,我可以看到 LLVM IR 包含结构字段,如下所示
%struct.A = type { i32, i32 }
我想使用 LLVM Pass 获取结构元素。我编写了以下程序 - 它遍历了两个全局变量和每个指令操作数,但是其中 none 帮助我提取结构 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 *>>.
我浏览了 doxygen 页面、LLVM 教程并检查了我们是否可以获得结构值,但是我无法在不知道结构值的情况下找到提取结构的方法 - 例如。创建 IRBuilder,插入预定义的 IntTy32 类型变量。在这方面的任何帮助或一些相关教程都会有所帮助
在 LLVM IR 术语中,"global" 是全局变量或全局常量。这一行:
%struct.A = type { i32, i32 }
是标识结构规范,不是全局变量,就像C++中的typedef
不是全局变量一样。 您可以使用 Module::getIdentifiedStructTypes()
.
迭代那些
然而,一些注意事项:
熟悉 dump()
方法。它比 cerr
.
的所有印刷品更容易替代
您在值而不是类型上使用 getName()
- 我认为这不是您的本意。还要记住 LLVM 值不一定有名称。
得到像 <int32, bool, char *>
这样的结果——这是 C++ 类型,而不是 LLVM IR 类型——会很棘手。例如,Clang 可能会将 bool
和 char
都编译为 i8
,并且很难区分它们。您可能还会获得 vptr 字段、填充字段等。如果您确实想要源程序中使用的结构的实际 C++ 结构,则必须依赖 debug info.
这里是 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;
}
使用 clang++,我可以看到 LLVM IR 包含结构字段,如下所示
%struct.A = type { i32, i32 }
我想使用 LLVM Pass 获取结构元素。我编写了以下程序 - 它遍历了两个全局变量和每个指令操作数,但是其中 none 帮助我提取结构 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 *>>.
我浏览了 doxygen 页面、LLVM 教程并检查了我们是否可以获得结构值,但是我无法在不知道结构值的情况下找到提取结构的方法 - 例如。创建 IRBuilder,插入预定义的 IntTy32 类型变量。在这方面的任何帮助或一些相关教程都会有所帮助
在 LLVM IR 术语中,"global" 是全局变量或全局常量。这一行:
%struct.A = type { i32, i32 }
是标识结构规范,不是全局变量,就像C++中的typedef
不是全局变量一样。 您可以使用 Module::getIdentifiedStructTypes()
.
然而,一些注意事项:
熟悉
dump()
方法。它比cerr
. 的所有印刷品更容易替代
您在值而不是类型上使用
getName()
- 我认为这不是您的本意。还要记住 LLVM 值不一定有名称。得到像
<int32, bool, char *>
这样的结果——这是 C++ 类型,而不是 LLVM IR 类型——会很棘手。例如,Clang 可能会将bool
和char
都编译为i8
,并且很难区分它们。您可能还会获得 vptr 字段、填充字段等。如果您确实想要源程序中使用的结构的实际 C++ 结构,则必须依赖 debug info.