LLVM IR:从中间文件提取struct信息
先放上源代码:
struct demo1 {
long long A;
long long B;
};
struct demo2 {
long long C;
long long D;
float E;
};
int main(){
struct demo1 d1;
struct demo2 d2;
d1.A = 1;
d2.C = 2;
d2.D = d1.A + d2.C;
return 0;
}
LLVM IR:
%struct.demo1 = type { i64, i64 }
%struct.demo2 = type { i64, i64, float }
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca %struct.demo1, align 8
%3 = alloca %struct.demo2, align 8
store i32 0, i32* %1, align 4
%4 = getelementptr inbounds %struct.demo1, %struct.demo1* %2, i32 0, i32 0
store i64 1, i64* %4, align 8
%5 = getelementptr inbounds %struct.demo2, %struct.demo2* %3, i32 0, i32 0
store i64 2, i64* %5, align 8
%6 = getelementptr inbounds %struct.demo1, %struct.demo1* %2, i32 0, i32 0
%7 = load i64, i64* %6, align 8
%8 = getelementptr inbounds %struct.demo2, %struct.demo2* %3, i32 0, i32 0
%9 = load i64, i64* %8, align 8
%10 = add nsw i64 %7, %9
%11 = getelementptr inbounds %struct.demo2, %struct.demo2* %3, i32 0, i32 1
store i64 %10, i64* %11, align 8
ret i32 0
}
想要提取出这个信息:
%struct.demo1 = type { i64, i64 }
%struct.demo2 = type { i64, i64, float }
最开始操作的时候通过遍历Model->Basicblock->Function->Instruction发现没有找到struct的定义信息,其上级属于Model而不属于基本块Basicblock,使用方法getIdentifiedStructTypes()可以直接获取到已经定义好的结构体,返回一个vector< StructType >,然后遍历就可以对结构体进行操作,直接放核心代码(M为LLVM IR问价的Model):
//获取所有定义好的struct
std::vector<StructType*> STy = M->getIdentifiedStructTypes();
int struct_size = 0;
for(auto sty : STy){
struct_size = 0;
errs() << "----------begin----------" << "\n";
errs() << "StructName: " << sty->getName() << "\n";
errs() << "NumElements: " << sty->getNumElements() << "\n";
//获取所有元素
errs() << "ElementsType: ";
ArrayRef<Type*> ty_ary = sty->elements();
for(auto i : ty_ary){
auto element_size_bits = i->getPrimitiveSizeInBits();
struct_size += element_size_bits;
errs() << *i << " " << element_size_bits << "bits;";
}
errs() << "\nStructSize: " << struct_size << "bits\n";
errs() << "-----------end-----------" << "\n";
}
方法说明:
getName():获取结构体名称
getNumElements():获取结构体元素数量
elements():返回一个每一个元素的Type,使用ArrayRef存储
getPrimitiveSizeInBits():获取元素类型的字节宽度
结果如下: