2016-01-03 5 views
5

現在、私は任意のプログラムのグローバル変数とフィールド変数のロードとストアのアクセスを識別するツールを開発中です。さらに、アクセスされた変数は、ソースレベルの名前/識別子によって識別される必要があります。 これを達成するために、診断中のプログラムのソースコードをデバッグ情報付きのLLVM IRにコンパイルします。これまでのところ、生成されたメタデータノードには、望ましいソースレベル識別子が含まれています。ただし、一部のLLVM IR識別子とメタデータの情報との接続を確立できません。例えばLLVM IR:メタデータノードで変数を識別する

、クラスのsaticメンバー考える: "_ZN12TestClass6NumberE @" であることを私は知っている。この制御例では

@_ZN12TestClass6NumberE = external global i32, align 4 

... 
!15 = !DIDerivedType(tag: DW_TAG_member, name: "Number", scope: !"_ZTS12TestClass", file: !12, line: 5, baseType: !16, flags: DIFlagPublic | DIFlagStaticMember) 

:対応LLVM IRは、このようになります

class TestClass { 
    public: 
    static int Number; 
}; 

を「番号」の識別子。しかし、一般的にどのIR識別子がどのメタデータに対応しているかを知ることができません。

誰かが私を助けることができますか?

答えて

1

誰も私の問題に対して良い解決策を持っていないようだから、私はこの問題を処理する独自の方法を教えてくれるでしょう。 LLVMの生成されたMetaDataノードには、コードの定義された型および変数に関する情報が含まれています。しかし、生成されたIR変数がどのソースコード変数に対応するかに関する情報はない。 LLVMは、IR命令のメタデータ情報を、対応するソース位置(行および列)と単にリンクさせるだけである。 LLVMのメタデータの主なタスクは分析ではなくデバッグであるため、これは理にかなっています。

まだ、含まれている情報は役に立たないものではありません。この問題に対する私の解決策は、ソースコードの解析にclang ASTを使用することです。ここでは、どの変数がどのソースの場所でアクセスされているかに関する情報を取得します。したがって、LLVM IR計測中にソース変数のアイデンティティに関する情報を取得するには、clang AST分析中にソースの場所をソース変数の識別名にマップするだけで済みます。 2番目のステップとして、以前に収集した情報を使用してIR計測を実行します。 IRにストア命令またはロード命令が出現すると、この命令のメタデータノード内で対応するソース位置を検索します。ソースの位置をソース変数のアイデンティティにマップしたので、IR命令のソース変数のアイデンティティに簡単にアクセスできるようになりました。

なぜ、変数のストアとロードを識別するためにclang ASTを使用するだけではないのですか? ASTでの読み書きの区別は単純な作業ではないためです。 ASTは、変数がアクセスされたことを簡単に伝えることができますが、アクセスされた変数が読み書きされているかどうかは操作に依存します。だから、私はすべての単一の演算子/演算子が変数が書き込み/読み取りか、またはその両方であるかどうかを判断する必要があります。 LLVMは、この点で非常に簡単で、低レベルであり、エラーが起こりにくい。さらに、実際の計装(話し言葉の挿入)は、LLVMの場合と同じように、ASTではずっと困難です。これらの2つの理由から、私はclang ASTとLLVM IR計装の組み合わせが私の問題にとって最良の解決策であると信じています。

関連する問題