我想检索用于编译给定可执行文件的 GCC 版本。我试过 readelf,但没有得到信息。有什么想法吗?
readelf
此信息不存储在已编译的对象(c)中。
事实上,对于 C 代码,你完全不走运。但是,对于 C + + 代码,您可以从符号版本中找到一些信息。来自 C + + 运行时库的一些函数是版本特定的,并且在对象文件中标记为版本特定的。试试这个:
readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1
但是,它不会显示所使用的 GCC 版本。它显示的是提供给编译器的运行时中的符号版本。通常运行时是编译器装运的运行时,它的版本是 而不是更少,而不是上面命令所示的版本。
为了完成其他人所说的: 它不存储在对象(或 exe)文件 除非使用调试信息进行编译中!(选项 -g)。如果你用调试信息编译,你可以用 readelf返回:
-g
$ 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)。
GNU C 4.4.3 20100108 (prerelease)
它通常存储在注释部分
strings -a <binary/library> |grep "GCC: ("
报税表 海湾合作委员会: (GNU) X.X.X
strip -R .comment <binary> strings -a <binary/library> |grep "GCC: ("
不返回任何输出
通过以下方法减小大小并不罕见: 删除.comments (以及.note)部分
strip --strip-all -R .note -R .comment <binary> strip --strip-unneeded -R .note -R .comment <library>
注意: busybox 字符串在默认情况下指定-a 选项,该选项对于. comments 部分是必需的
编辑: 与 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 #
注意,没有 any-g (调试)标志,而-s 标志去除了不需要的符号。GCC 信息仍然可用,除非。注释部分被删除。如果需要保持这些信息的完整性,可能需要检查 makefile (或适用的构建脚本) ,以验证-fno-id 不在 $CFLAGS 中,并且 $STRIP 命令缺少-R。评论。- fno-id 防止 gcc 从注释部分开始生成这些符号。
还有另外两种方法(也许更简单一些) ,我刚刚在这里读到过: 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.. ...
您可以使用 Elfinfo实用程序。这还支持检测 Go 和 FPC 的编译器版本,以及 GCC。