我想检索用于编译给定可执行文件的GCC版本。我尝试过readelf但没有得到信息。有什么想法吗?
我想检索用于编译给定可执行文件的GCC版本。我尝试过readelf但没有得到信息。有什么想法吗?
Answers:
它通常存储在注释部分
strings -a <binary/library> |grep "GCC: ("
返回GCC:(GNU)XXX
strip -R .comment <binary>
strings -a <binary/library> |grep "GCC: ("
不返回任何输出
剥离.comment(以及.note)部分以减小尺寸的情况很常见。
strip --strip-all -R .note -R .comment <binary>
strip --strip-unneeded -R .note -R .comment <library>
注意:默认情况下,busybox字符串指定-a选项,.comment部分需要此选项
编辑:与Berendra Tusla的回答相反,它不需要使用任何调试标志进行编译,此方法才能起作用。
二进制示例:
# 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
#
请注意,不存在任何-g(调试)标志,并且存在-s标志,该标志会去除不需要的符号。除非删除.comment部分,否则GCC信息仍然可用。如果需要保持此信息不变,则可能需要检查makefile(或适用的生成脚本)以验证-fno-ident不在$ CFLAGS中,并且$ STRIP命令缺少-R .comment。-fno-ident阻止gcc从注释部分开始生成这些符号。
strings。
                    -a选项指定为strings,因为.comment默认情况下该实用程序不会在该部分中查找。
                    要完成别人说的话:除非您使用调试信息进行编译,否则它不会存储在对象(或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  
看看怎么说GNU C 4.4.3 20100108 (prerelease)。
我在这里刚刚读过的另外两种方式(也许更简单):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
...
和
$ 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..
 ...
-p选项在我的readelf(from binutils 2.14)的古代副本中不存在,因此我不得不找到.comment节的索引,然后像这样十六进制转储它:readelf --hex-dump=$(readelf -S <so_file> | grep .comment | awk '{ print $1 }' | tr -d '[]') <so_file>
                    此信息未存储在已编译的对象(c)中。
实际上,对于C代码,您完全不走运。但是,对于C ++代码,您可能会从符号版本中找到一些信息。C ++运行时库中的某些函数是特定于版本的,并在目标文件中被标记为此类。尝试这个:
readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1
但是,它不会显示使用的GCC版本。它显示的是运行时提供给编译器的符号版本。通常,运行时是编译器出厂的运行时,其版本不少于以上命令显示的运行时。