2010-03-05 5 views

Répondre

0

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

+0

Voulez-vous dire, qu'il n'est pas du tout possible de l'avoir à partir d'un objet ELF, étant l'objet compilé ou l'exécutable final lié? –

+0

Tous. (Sauf si vous ajoutez manuellement la version dans le code.) – kennytm

2

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

En fait, pour le code C, vous n'avez absolument 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ée, cependant. Qu'est-ce qu'il montre est la version des symboles dans l'exécution fournie au compilateur. Habituellement, le temps d'exécution est celui d'un envoi de compilateur, et sa version est pas moins que celle montrée avec la commande ci-dessus.

+0

Très bien, merci les gars! Impossible de comprendre pourquoi une information si importante ne fait pas dans l'en-tête ELF. Ma cible est en fait un noyau Linux intégré. –

16

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 les informations de débogage! (option -g). Si vous compilez avec les informations de débogage, vous pouvez l'obtenir en arrière 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 dit GNU C 4.4.3 20100108 (prerelease).

55

Il est normalement stocké dans la section de commentaire

strings -a <binary/library> |grep "GCC: (" 

retours CCG: (GNU) XXX

strip -R .comment <binary> 
strings -a <binary/library> |grep "GCC: (" 

rendements sans sortie

Il est courant pour dépouiller les .comment (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> 

Note: les chaînes busybox spécifie l'option -a par défaut, ce qui est nécessaire pour la section .comment

Edit: Contrairement à la réponse de Berendra Tusla, il n'a pas besoin d'être compilé avec des indicateurs de débogage pour cette méthode travailler.

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 de l'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 drapeaux -g (débogage) et la présence du drapeau -s qui déshabille les symboles non nécessaires. Les informations de GCC sont toujours disponibles sauf si la section .comment est supprimée. Si vous devez conserver cette information intacte, vous devrez peut-être vérifier votre makefile (ou le script de construction applicable) pour vérifier que -fno-ident n'est pas dans votre $ CFLAGS et que la commande $ STRIP ne contient pas -R .comment. -fno-ident empêche gcc de générer ces symboles dans la section des commentaires pour commencer.

+1

Que voulez-vous dire par "normalement"? Mon compilateur/version ne stocke pas ces informations lorsque la compilation est effectuée en utilisant les options par défaut. –

+0

J'utilise GCC 4.6.2 compilé sur OS X mais sans aucun correctif spécifique au système. C'est un GCC vanillé. –

+0

Rien du tout. Si j'insère des chaînes littérales dans le code source, celles-ci sont correctement trouvées par 'strings'. –

7

Encore une autre deux façons (peut-être un peu plus simple) que je viens de lire au sujet 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.. 
... 
+0

Expansion un peu: l'option '-p' n'existe pas dans ma copie ancienne de' readelf' (from 'binutils 2.14'), donc je devais trouver l'index de la section .comment, puis le vider comme ceci: 'readelf --hex-dump = $ (lire -S | grep .comment | awk '{print $ 1}' | tr -d '[]') ' – tkocmathla

0

Vous pouvez utiliser l'utilitaire elfinfo. Cela prend également en charge la détection des versions du compilateur Go et FPC, en plus de GCC.

Questions connexes