J'aimerais récupérer la version de GCC utilisée pour compiler un exécutable donné. J'ai essayé readelf
mais n'a pas obtenu l'information. Des idées ?
Réponses
Trop de publicités?Il est normalement stocké dans la section des commentaires
strings -a <binary/library> |grep "GCC: ("
renvoie à GCC : (GNU) X.X.X
strip -R .comment <binary>
strings -a <binary/library> |grep "GCC: ("
ne renvoie aucune sortie
Il n'est pas rare de retirer la section .comment (ainsi que .note) pour réduire la taille via
strip --strip-all -R .note -R .comment <binary>
strip --strip-unneeded -R .note -R .comment <library>
Note : busybox strings spécifie l'option -a par défaut, qui est nécessaire pour la section .comment.
Edit : Contrairement à la réponse de Berendra Tusla, il n'est pas nécessaire de compiler avec des drapeaux de débogage pour que cette méthode fonctionne.
Exemple binaire :
# echo "int main(void){}">a.c
# gcc -o a a.c -s
# strings -a a |grep GCC
GCC: (GNU) 4.3.4
# strip -R .comment a
# strings -a a |grep GCC
#
Exemple d'objet :
# gcc -c a.c -s
# strings -a a.o |grep GCC
GCC: (GNU) 4.3.4
# strip -R .comment a.o
# strings -a a |grep GCC
#
Notez l'absence de tout drapeau -g (débogage) et la présence du drapeau -s qui supprime les symboles inutiles. L'information GCC est toujours disponible à moins que la section .comment soit supprimée. Si vous avez besoin de garder ces informations intactes, vous devrez peut-être vérifier votre makefile (ou le build script applicable) pour vérifier que -fno-ident n'est pas dans votre $CFLAGS et que la commande $STRIP n'a pas -R .comment. -fno-ident empêche gcc de générer ces symboles dans la section commentaire pour commencer.
Pour compléter ce que d'autres ont dit : il n'est pas stocké dans le fichier objet (ou exe), à moins que vous compiliez avec des informations de débogage ! (option -g
). Si vous compilez avec des infos de débogage, vous pouvez les récupérer avec readelf
:
$ cat a.c
int main(void){ return 0; }
$ gcc a.c
$ readelf -wi a.out
$ gcc a.c -g
$ readelf -wi a.out
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0x42 (32-bit)
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
< c> DW_AT_producer : (indirect string, offset: 0x0): GNU C 4.4.3 20100108 (prerelease)
<10> DW_AT_language : 1 (ANSI C)
<11> DW_AT_name : a.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x22): /tmp
<19> DW_AT_low_pc : 0x8048394
<1d> DW_AT_high_pc : 0x804839e
<21> DW_AT_stmt_list : 0x0
<1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
<26> DW_AT_external : 1
<27> DW_AT_name : (indirect string, offset: 0x27): main
<2b> DW_AT_decl_file : 1
<2c> DW_AT_decl_line : 1
<2d> DW_AT_prototyped : 1
<2e> DW_AT_type : <0x3e>
<32> DW_AT_low_pc : 0x8048394
<36> DW_AT_high_pc : 0x804839e
<3a> DW_AT_frame_base : 0x0 (location list)
<1><3e>: Abbrev Number: 3 (DW_TAG_base_type)
<3f> DW_AT_byte_size : 4
<40> DW_AT_encoding : 5 (signed)
<41> DW_AT_name : int
Voyez comment il est écrit GNU C 4.4.3 20100108 (prerelease)
.
Encore deux autres façons (peut-être un peu plus simples) que je viens de lire ici : https://unix.stackexchange.com/questions/719/can-we-get-compiler-information-from-an-elf-binary
$ readelf -p .comment /usr/lib64/flash-plugin/libflashplayer.so
String dump of section '.comment':
[ 1] GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)
[ 2e] GCC: (GNU) 4.3.2
...
y
$ objdump -s --section .comment /usr/lib64/flash-plugin/libflashplayer.so
/usr/lib64/flash-plugin/libflashplayer.so: file format elf64-x86-64
Contents of section .comment:
0000 00474343 3a202847 4e552920 342e332e .GCC: (GNU) 4.3.
0010 32203230 30383131 30352028 52656420 2 20081105 (Red
0020 48617420 342e332e 322d3729 00004743 Hat 4.3.2-7)..GC
0030 433a2028 474e5529 20342e33 2e320000 C: (GNU) 4.3.2..
...
Cette information n'est pas stockée dans l'objet compilé (c).
En fait, pour le code C, vous n'avez aucune chance. Cependant, pour le code C++, vous pouvez trouver quelques informations à partir des versions des symboles. Certaines fonctions des bibliothèques d'exécution C++ sont spécifiques à une version, et sont marquées comme telles dans les fichiers d'objets. Essayez ceci :
readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1
Il ne vous montrera pas la version de GCC utilisée, cependant. Ce qu'il montre est la version des symboles en runtime fournie au compilateur. Habituellement, le runtime est celui d'une livraison du compilateur, et sa version est pas moins que celle affichée avec la commande ci-dessus.
- Réponses précédentes
- Plus de réponses