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?

62
demandé sur Daniel Serodio 2010-03-05 16:35:10

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.

64
répondu technosaurus 2015-11-25 19:59:47

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) .

18
répondu 2010-03-06 17:00:38

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..
 ...
8
répondu marcin 2017-04-13 12:36:31

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.

2
répondu P Shved 2010-03-05 13:48:59

Cette information n'est pas stockée dans l'objet compilé.

0
répondu kennytm 2010-03-05 13:36:06

vous pouvez utiliser l'utilitaire elfinfo . Cela permet également de détecter les versions de compilateurs de Go et FPC, en plus de GCC.

0
répondu Alexander 2017-06-06 11:29:51