4 votes

Comment extraire des informations des métadonnées llvm

J'ai le morceau de code suivant :

 int main(int argc, char *argv[])
    {
        int a = 2;
        int b = 5;
        int soma = a + b;
  //...}

Le bitcode llvm résultant est :

       define i32 @main(i32 %argc, i8** %argv) #0 {
        entrée :
          ...
          % a = allouer i32, aligner 4
          % b = allouer i32, aligner 4
          % soma = allouer i32, aligner 4
          ...
          appel vide @ llvm.dbg.declare (métadonnées ! {i32* % a}, métadonnées ! 15), ! dbg ! 16
          magasin i32 2, i32* % a, aligner 4, ! dbg ! 16
          appel vide @ llvm.dbg.declare (métadonnées ! {i32* % b}, métadonnées ! 17), ! dbg ! 18
          magasin i32 5, i32* % b, aligner 4, ! dbg ! 18
          appel vide @ llvm.dbg.declare (métadonnées ! {i32* % soma}, métadonnées ! 19), ! dbg ! 20
          % 0 = charge i32* % a, aligner 4, ! dbg ! 20
          % 1 = charge i32* % b, aligner 4, ! dbg ! 20
          % add = ajouter nsw i32 % 0, % 1, ! dbg ! 20
          magasin i32 % add, i32* % soma, aligner 4, ! dbg ! 20
          ...      
          ! 1 = métadonnées ! {i32 0}
          ! 2 = métadonnées ! {métadonnées ! 3}
          ...
          ! 15 = métadonnées ! {i32 786688, métadonnées ! 3, métadonnées !"a", métadonnées ! 4, i32 6, métadonnées ! 7, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [ligne 6]
! 16 = métadonnées ! {i32 6, i32 0, métadonnées ! 3, nul}
! 17 = métadonnées ! {i32 786688, métadonnées ! 3, métadonnées !"b", métadonnées ! 4, i32 7, métadonnées ! 7, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [b] [ligne 7]
! 18 = métadonnées ! {i32 7, i32 0, métadonnées ! 3, nul}
! 19 = métadonnées ! {i32 786688, métadonnées ! 3, métadonnées !"soma", métadonnées ! 4, i32 8, métadonnées ! 7, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [soma] [ligne 8]
! 20 = métadonnées ! {i32 8, i32 0, métadonnées ! 3, nul}

À partir du bitcode, j'ai besoin d'obtenir le texte suivant :

a = 2
b = 5
soma = a + b

Ma question est comment extraire l'information dont j'ai besoin à partir des métadonnées (dgb) ?? En ce moment, je n'ai que le nom des instructions I-> getName () et le nom des opérandes avec valueOp Value * = I-> getOperand (i); valueOp-> getName (). Str (); Les métadonnées sont très étendues. Comment puis-je obtenir cette information à partir des métadonnées ?

3voto

Oak Points 10667

S'appuyer sur I->getName() pour trouver le nom de la variable n'est pas une bonne idée - vous avez les informations de débogage pour cela. La bonne approche pour connaître les noms de toutes les variables locales en C/C++ consiste à parcourir l'IR et à rechercher tous les appels à @llvm.dbg.declare, puis aller à leur 2ème opérande (les métadonnées de débogage), et récupérer le nom de la variable à partir de là.

Utilisez le guide de débogage au niveau source pour découvrir comment les métadonnées de débogage sont agencées. En particulier, pour les variables locales, le 3ème argument sera une chaîne de métadonnées avec le nom de la variable dans le code source C/C++.

La prochaine étape est donc de savoir à quoi les variables sont initialisées. Pour cela, suivez le 1er argument de @llvm.dbg.declare pour obtenir la valeur LLVM réelle utilisée, puis localisez la 1ère instruction store dans celle-ci, et vérifiez quelles données y sont utilisées.

S'il s'agit d'une constante, vous avez désormais tout ce dont vous avez besoin pour afficher les informations de style a = 5. S'il s'agit d'une autre instruction, vous devez la suivre vous-même et la "décoder" - par exemple, s'il s'agit d'une "addition", vous devez imprimer ses deux opérandes avec un "+" entre eux, etc. Et bien sûr, les impressions doivent être récursives... pas simple. Mais cela vous fournira la valeur d'initialisation précise.

Si vous cherchez quelque chose de beaucoup plus général et que vous avez accès au code source d'origine, vous pouvez simplement obtenir le numéro de ligne dans laquelle la variable est déclarée (le 5ème opérande dans les métadonnées de débogage, en supposant que l'étiquette (1er opérande) est effectivement DW_TAG_auto_variable et non DW_TAG_arg_variable, ce qui indique un paramètre). Ensuite, imprimez cette ligne à partir du code source d'origine. Cependant, cela n'affichera pas toutes les informations pertinentes (si la valeur d'initialisation est construite à partir de plusieurs lignes) et peut afficher des informations non pertinentes (s'il y a plusieurs instructions dans cette ligne, par exemple).

Enfin, rappelez-vous que l'optimisation peut sérieusement perturber les informations de débogage. Si obtenir ces sorties est important, faites attention à votre option -O, peut-être restez à -O0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X