首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LLVM比特码函数参数的错误检测

LLVM比特码函数参数的错误检测
EN

Stack Overflow用户
提问于 2017-04-03 17:41:41
回答 1查看 146关注 0票数 0

我使用LLVM来解析bitcode文件。我有下面的代码片段,我使用这个命令来生成bitcode $CC -emit-llvm -c -g source.c,其中CC被设置为clang路径。

代码语言:javascript
复制
#include <stdio.h>

struct Point {
    int a;
    int b;
};

int func_0(struct Point p, int x) {
    return 0;
}

根据参数的类型,TypeID应该有一个数值。但是,对于整数x和结构Point,我都获得了10的值,它被称为TokenTyID。因此,我决定分别使用函数isIntegerTy()isStructTy(),看看至少在这种情况下,我是否获得了正确的结果。此解决方案适用于整数参数x,但不适用于结构。如何正确识别结构并读取它们的字段?

为了完整起见,为了解析bitcode,我使用了以下代码:

代码语言:javascript
复制
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使用结构执行翻译的为什么Clang要将结构参数强制到ints文章,我很确定这也是我的问题。

EN

回答 1

Stack Overflow用户

发布于 2017-04-04 01:13:09

因为clang更改了IR中的函数签名,所以您必须使用debug信息获取该信息。以下是一些粗略的代码:

代码语言:javascript
复制
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 do\n";
      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();
          }
        }
      }
    }
  }
}

我知道它看起来很难看,但是使用调试信息并不容易。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43191027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档