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

时间:2010-03-05 13:35:11

标签: gcc elf

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

5 个答案:

答案 0 :(得分:71)

通常存储在评论部分

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

返回 GCC:(GNU)X.X.X

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

不返回任何输出

通过<。p>删除.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在注释部分生成这些符号。

答案 1 :(得分:18)

要完成其他人所说的内容:它不会存储在对象(或exe)文件中,除非您使用调试信息进行编译! (选项1}})。如果使用调试信息进行编译,则可以使用-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

答案 2 :(得分:8)

我刚读到的另外两种方式(可能更简单一点):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..
 ...

答案 3 :(得分:2)

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

实际上,对于C代码,你完全没有运气。但是,对于C ++代码,您可以从符号版本中找到一些信息。 C ++运行时库中的某些函数是特定于版本的,并在对象文件中标记为这些函数。试试这个:

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

但是,它不会向您显示使用的GCC版本。它显示的是提供给编译器的运行时符号的版本。通常运行时是编译器出货的运行时,其版本不小于,而不是上面命令所示的版本。

答案 4 :(得分:0)

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