LLVM 的位码错误检测函数参数
LLVM's bitcode wrong detections of function's parameters
我正在使用LLVM api来解析位码文件。我有以下代码片段,我正在使用此命令生成位码$CC -emit-llvm -c -g source.c
其中 CC 设置为clang
路径。
#include <stdio.h>
struct Point {
int a;
int b;
};
int func_0(struct Point p, int x) {
return 0;
}
类型ID 应该有一个基于参数类型的数值。但是,对于整数x
和结构Point
我都获得了10
的值,这称为TokenTyID
。因此,我决定分别使用函数isIntegerTy()
和isStructTy()
,看看至少在这种情况下,我是否获得了正确的结果。此解决方案适用于整数参数 x
,但不适用于结构。如何正确识别结构并读取其字段?
为了完整起见,为了解析位码,我使用以下代码:
using namespace llvm;
int main(int argc, char** argv) {
LLVMContext context;
OwningPtr<MemoryBuffer> mb;
MemoryBuffer::getFile(FileName, mb);
Module *m = ParseBitcodeFile(mb.get(), context);
for (Module::const_iterator i = m->getFunctionList().begin(), e = m->getFunctionList().end(); i != e; ++i) {
if (i->isDeclaration() || i->getName().str() == "main")
continue;
std::cout << i->getName().str() << std::endl;
Type* ret_type = i->getReturnType();
std::cout << "t(ret) " << ret_type->getTypeID() << std::endl;
Function::const_arg_iterator ai;
Function::const_arg_iterator ae;
for (ai = i->arg_begin(), ae = i->arg_end(); ai != ae; ++ai) {
Type* t = ai->getType();
std::cout << "t" << ai->getName().str() << " " << t->getTypeID()
<< "(" << t->getFunctionNumParams() << ")"
<< " is struct? " << (t->isStructTy() ? "Y" : "N")
<< " is int? " << (t->isIntegerTy() ? "Y" : "N")
<< "n";
}
}
return 0;
}
我读了这篇文章 为什么 Clang 将结构参数强制为 ints 关于 clang 与结构体执行的翻译,我很确定这是我的相同问题。
由于 clang 更改了 IR 中的函数签名,因此您必须使用调试信息获取该信息。下面是一些粗略的代码:
DITypeIdentifierMap TypeIdentifierMap;
DIType* getLowestDINode(DIType* Ty) {
if (Ty->getTag() == dwarf::DW_TAG_pointer_type ||
Ty->getTag() == dwarf::DW_TAG_member) {
DIType *baseTy =
dyn_cast<DIDerivedType>(Ty)->getBaseType().resolve(TypeIdentifierMap);
if (!baseTy) {
errs() << "Type : NULL - Nothing more to don";
return NULL;
}
//Skip all the DINodes with DW_TAG_typedef tag
while ((baseTy->getTag() == dwarf::DW_TAG_typedef || baseTy->getTag() == dwarf::DW_TAG_const_type
|| baseTy->getTag() == dwarf::DW_TAG_pointer_type)) {
if (DITypeRef temp = dyn_cast<DIDerivedType>(baseTy)->getBaseType())
baseTy = temp.resolve(TypeIdentifierMap);
else
break;
}
return baseTy;
}
return Ty;
}
int main(int argc, char** argv) {
LLVMContext context;
OwningPtr<MemoryBuffer> mb;
MemoryBuffer::getFile(FileName, mb);
Module *m = ParseBitcodeFile(mb.get(), context);
if (NamedMDNode *CU_Nodes = m.getNamedMetadata("llvm.dbg.cu")) {
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
}
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
for (auto &MD : MDs) {
if (MDNode *N = MD.second) {
if (auto *subRoutine = dyn_cast<DISubprogram>(N)->getType()) {
if (!subRoutine->getTypeArray()[0]) {
errs() << "return type "void" for Function : " << F.getName().str()
<< "n";
}
const auto &TypeRef = subRoutine->getTypeArray();
for (int i=0; i<TypeRef.size(); i++) {
// Resolve the type
DIType *Ty = ArgTypeRef.resolve(TypeIdentifierMap);
DIType* baseTy = getLowestDINode(Ty);
if (!baseTy)
return;
// If that pointer is a struct
if (baseTy->getTag() == dwarf::DW_TAG_structure_type) {
std::cout << "structure type name: " << baseTy->getName().str() << std::endl();
}
}
}
}
}
}
我知道它看起来很丑,但使用调试信息并不容易。
相关文章:
- 检测使用 CRTP 的类中的成员函数
- 用于检测函数类型是否为否的特征
- 如何检测除整数以外的任何内容是否传递给我的类构造函数?
- 检测是否存在具有给定签名的函数
- 如何检测 Clang AST C++中的静态函数
- 主函数体未检测到对重载可变变量模板化函数C++的调用
- 如何在C++17中使用type_traits检测具有特定名称和签名的函数(NOT类成员)的存在
- 使用SFINAE来检测void返回类型函数的存在
- 如何检测构造函数是否与抛出的析构函数无关
- 如何检测函数是否执行IO操作
- 用于检测函数是否存在的C++元函数的问题
- C++检测函数是否已挂接(32 位计算机)
- LLVM 的位码错误检测函数参数
- std::clamp - 检测函数返回值是否绑定到 const T&
- 检测函数范围之外的未使用变量
- 有没有办法检测函数是否存在并且可以在编译时使用
- 为什么自动不检测函数的引用类型
- 使用堆栈跟踪检测函数
- 检测函数对象(函子)和lambda特征
- 如何检测函数,只有从未使用的函数调用使用cppcheck