2017-04-03 1 views
0

ビットコードファイルを解析するためにLLVM APIを使用しています。私は以下のスニペットを持っており、このコマンドを使ってビットコード$CC -emit-llvm -c -g source.cを生成します。ここで、CCはclangパスに設定されています。LLVMのビットコード関数のパラメータの誤検出

#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に対して機能しますが、構造体に対しては機能しません。 構造体を正しく識別してフィールドを読み取るにはどうすればよいですか?ただ、私はこのコードを使用ビットコードを解析するために、完全性

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

私は構造体で打ち鳴らすことによって行わ翻訳についてのこの記事Why does Clang coerce struct parameters to intsを読んで、私はそれが私と同じ問題であるかなり確信しています。

+0

'clang -S -emit-llvm'を使用してLLVM IRをダンプしようとしましたか? – arrowd

+0

はい、うまくいきません。 "-S"オプションでIRコードを生成し、 "llvm-as"でビットコードを生成すると、問題は同じになります。 – Surcle

+0

私は、生成されたIRを見て、あなたの構造がどのように変化しているかを調べることを意味します。 – arrowd

答えて

0

IRは機能シグネチャを変更するので、debug情報を使用してその情報を取得する必要があります。ここにいくつかの大まかなコードがあります:

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

ありがとうございます。あなたは私に前の声明の全体のコードを教えてもらえますか? – Surcle

+0

もちろん、コードへのリンクは次のとおりです:https://github.com/jiten-thakkar/DataStructureAnalysis/blob/dsa_llvm3.8/lib/dsaGenerator/DSAGenerator.cpp私は他のいくつかのプロジェクト – deLta

関連する問題