如何检索用于编译给定ELF可执行文件的GCC版本?

如何检索用于编译给定ELF可执行文件的GCC版本?,gcc,elf,Gcc,Elf,我想检索用于编译给定可执行文件的GCC版本。我尝试了readelf,但没有得到信息。有什么想法吗?此信息不存储在编译对象(c)中 实际上,对于C代码来说,你完全不走运。但是,对于C++代码,您可以从符号版本中找到一些信息。C++运行库的一些功能是特定于版本的,并且在对象文件中被标记为这样。试试这个: readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1 但是,它不会显示所使用

我想检索用于编译给定可执行文件的GCC版本。我尝试了
readelf
,但没有得到信息。有什么想法吗?

此信息不存储在编译对象(c)中

实际上,对于C代码来说,你完全不走运。但是,对于C++代码,您可以从符号版本中找到一些信息。C++运行库的一些功能是特定于版本的,并且在对象文件中被标记为这样。试试这个:

readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1

但是,它不会显示所使用的GCC版本。它显示的是运行时提供给编译器的符号版本。通常,运行时是编译器装运的运行时,其版本不低于上述命令所示的版本。

要完成其他人所说的:它不存储在对象(或exe)文件中,除非使用调试信息编译。!(选项
-g
)。如果使用调试信息进行编译,则可以使用
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  
$cat空调
int main(void){返回0;}
$gcc空调
$readelf-wi a.out
$gcc a.c-g
$readelf-wi a.out
.debug_info部分的内容:
偏移量0x0处的编译单位:
长度:0x42(32位)
版本:2
Abbrev偏移量:0
指针大小:4
:Abbrev编号:1(DW_标记_编译_单元)
生产商处的DW_:(间接字符串,偏移量:0x0):GNU c 4.4.3 20100108(预发布)
DW_AT_语言:1(ANSI C)
DW_AT_名称:a.c
DW_AT_comp_dir:(间接字符串,偏移量:0x22):/tmp
DW_在_低_pc:0x8048394
DW_在_高_pc:0x804839e
DW_AT_stmt_列表:0x0
:Abbrev编号:2(DW_标记_子程序)
DW_在_外部:1
DW_AT_name:(间接字符串,偏移量:0x27):主
DW_AT_decl_文件:1
德克卢线DW卢:1
DW_AT_原型:1
DW_AT_类型:
DW_在_低_pc:0x8048394
DW_在_高_pc:0x804839e
帧底部的DW_:0x0(位置列表)
:缩写编号:3(DW_标签_基础_类型)
字节大小为4的数据仓库
DW_AT_编码:5(签名)
DW_AT_名称:int

请参见它是如何显示的
GNU C 4.4.3 20100108(预发布)

它通常存储在注释部分

strings -a <binary/library> |grep "GCC: ("
对象示例:

# 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
#
请注意,没有任何-g(调试)标志,并且存在-s标志,用于去除不需要的符号。除非删除.comment部分,否则GCC信息仍然可用。如果需要保持此信息的完整性,则可能需要检查makefile(或适用的构建脚本),以验证-fno ident不在$CFLAGS中,$STRIP命令缺少-R.comment-fno ident阻止gcc在注释部分中首先生成这些符号。

我刚刚在这里读到的另外两种方法(可能更简单一些):


您可以使用该实用程序。除了GCC之外,它还支持检测Go和FPC的编译器版本。

好的,谢谢大家!无法理解为什么如此重要的信息没有进入ELF头。我的目标实际上是一个嵌入式Linux内核。你说的“正常”是什么意思?当使用默认选项完成编译时,我的编译器/版本不会存储此信息。我使用的是在OS X上编译的GCC 4.6.2,但没有应用任何特定于系统的修补程序。这是香草GCC,什么都没有。如果我在源代码中包含文字字符串,则可以通过
字符串
正确找到这些字符串。您需要将
-a
选项指定为
字符串
,由于该实用程序默认情况下不会查看
.comment
部分。objdump-s--section.comment foo.o会将注释部分转储到屏幕上,并在此基础上进行了一点扩展:
-p
选项在我以前的
readelf
(来自
binutils 2.14
)副本中不存在,因此,我必须找到.comment部分的索引,然后以十六进制方式转储它:
readelf--hex dump=$(readelf-S | grep.comment | awk'{print$1}'| tr-d'[])
strip --strip-all -R .note -R .comment <binary>
strip --strip-unneeded -R .note -R .comment <library>
# 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
#
# 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
#
$ 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
...
$ 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..
 ...