Comment récupérer la version GCC utilisée pour compiler un exécutable ELF donné?
j'aimerais récupérer la version GCC utilisée pour compiler un exécutable donné. J'ai essayé readelf
mais je n'ai pas eu l'information. Toutes les pensées?
6 réponses
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: ("
renvoie aucune sortie
il n'est pas rare de rayer le .commentaire (ainsi que .note) section pour réduire la taille via
strip --strip-all -R .note -R .comment <binary>
strip --strip-unneeded -R .note -R .comment <library>
Remarque: busybox chaînes spécifie l'option par défaut, qui est nécessaire pour le .comment section
modifier: contrairement à Réponse de Berendra Tusla, il n'est pas nécessaire de compiler avec des options 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
#
noter l'absence de tout drapeau-g (Débogage) et la présence du drapeau-s qui bande les symboles inutiles. Les informations du GCC sont toujours disponibles à moins que le .la section commentaires est supprimée. Si vous avez besoin de garder cette information intacte, vous pourriez avoir besoin de vérifier votre makefile (ou script de compilation applicable) pour vérifier que-fno-ident n'est pas dans votre $CFLAGS et la commande $STRIP manque-r.commentaire. -fno-ident empêche gcc de générer ces symboles dans la section commentaires pour commencer.
pour compléter ce que d'autres ont dit: il n'est pas stocké dans le fichier objet (ou exe), sauf si vous compilez avec des informations de débogage ! (option -g
). Si vous compilez avec debug info, vous pouvez le 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
voir comment il est dit GNU C 4.4.3 20100108 (prerelease)
.
encore deux autres façons (peut-être un peu plus simple) 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
...
et
$ 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, tu n'as pas de chance. Cependant, pour le code C++ vous pouvez trouver des informations à partir des versions de symboles. Certaines fonctions des bibliothèques d'exécution C++ sont spécifiques à la version et sont marquées comme telles dans les fichiers 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é, cependant. Ce qu'il montre est la version des symboles dans l'exécution fournie à compilateur. Habituellement, la durée d'exécution est celle d'un envoi de compilateur, et sa version est pas moins que celle montrée avec la commande ci-dessus.