为什么编译器版本出现在我的 ELF 可执行文件中?

发布于 2024-11-14 02:05:51 字数 540 浏览 1 评论 0原文

我最近在 Debian Linux 下使用 gcc 编译了一个简单的 hello world C 程序:

gcc -mtune=native -march=native -m32 -s -Wunused -O2 -o hello hello.c

文件大小为 2980 字节。我在十六进制编辑器中打开它,看到以下几行:

GCC: (Debian 4.4.5-8) 4.4.5 GCC: (Debian 4.4.5-10) 4.4.5 .shstrtab .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .text .fini .rodata .eh_frame .ctors .dtors .jcr .dynamic .got .got.plt data.data .bss .comment

它们真的需要吗?没有办法减少可执行文件的大小吗?

I've recently compiled a simple hello world C program under Debian Linux using gcc:

gcc -mtune=native -march=native -m32 -s -Wunused -O2 -o hello hello.c

The file size was 2980 bytes. I opened it in a hex editor and i saw the following lines:

GCC: (Debian 4.4.5-8) 4.4.5 GCC: (Debian 4.4.5-10) 4.4.5 .shstrtab .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .text .fini .rodata .eh_frame .ctors .dtors .jcr .dynamic .got .got.plt data.data .bss .comment

Are they really needed? No way to reduce executable size?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏有森光若流苏 2024-11-21 02:05:51

使用 -Qn 来避免这种情况。

aa$ touch hello.c
aa$ gcc -c hello.c 
aa$ objdump -s hello.o 

hello.o:     file format elf32-i386

Contents of section .comment:
 0000 00474343 3a202844 65626961 6e20342e  .GCC: (Debian 4.
 0010 372e322d 35292034 2e372e32 00        7.2-5) 4.7.2.   
aa$ gcc -Qn -c hello.c 
aa$ objdump -s hello.o 

hello.o:     file format elf32-i386

aa$ gcc -v 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i486-linux-gnu/4.7/lto-wrapper
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5) 
aa$ 

use -Qn to avoid that.

aa$ touch hello.c
aa$ gcc -c hello.c 
aa$ objdump -s hello.o 

hello.o:     file format elf32-i386

Contents of section .comment:
 0000 00474343 3a202844 65626961 6e20342e  .GCC: (Debian 4.
 0010 372e322d 35292034 2e372e32 00        7.2-5) 4.7.2.   
aa$ gcc -Qn -c hello.c 
aa$ objdump -s hello.o 

hello.o:     file format elf32-i386

aa$ gcc -v 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i486-linux-gnu/4.7/lto-wrapper
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5) 
aa$ 
遗忘曾经 2024-11-21 02:05:51

这是 ELF 二进制文件的注释部分。你可以把它去掉:

$ gcc -m32 -O2 -s -o t t.c
$ ls -l t
-rwxr-xr-x 1 me users 5488 Jun  7 11:58 t
$ readelf -p .comment t

String dump of section '.comment':
  [     0]  GCC: (Gentoo 4.5.1-r1 p1.4, pie-0.4.5) 4.5.1
  [    2d]  GCC: (Gentoo 4.5.2 p1.1, pie-0.4.5) 4.5.2


$ strip -R .comment t


$ readelf -p .comment t
readelf: Warning: Section '.comment' was not dumped because it does not exist!
$ ls -l t
-rwxr-xr-x 1 me users 5352 Jun  7 11:58 t

虽然收益很小,但不确定是否值得。

That's in a comment section in the ELF binary. You can strip it out:

$ gcc -m32 -O2 -s -o t t.c
$ ls -l t
-rwxr-xr-x 1 me users 5488 Jun  7 11:58 t
$ readelf -p .comment t

String dump of section '.comment':
  [     0]  GCC: (Gentoo 4.5.1-r1 p1.4, pie-0.4.5) 4.5.1
  [    2d]  GCC: (Gentoo 4.5.2 p1.1, pie-0.4.5) 4.5.2


$ strip -R .comment t


$ readelf -p .comment t
readelf: Warning: Section '.comment' was not dumped because it does not exist!
$ ls -l t
-rwxr-xr-x 1 me users 5352 Jun  7 11:58 t

The gains are tiny though, not sure it's worth it.

梦初启 2024-11-21 02:05:51

我自己也遇到了同样的问题,但是使用 MinGW 的 GCC 实现 - 剥离可执行文件并传递 -Qn 选项没有任何作用,而且我无法删除“.comment”部分,因为没有。

为了停止编译器包含此信息,无论可执行文件中包含哪些部分,您都可以将 -fno-ident 参数传递给编译器和链接器:

不带参数 (strings -a [filename ]):

!This program cannot be run in DOS mode.
.text
0`.rdata
[email protected]
GCC: (tdm64-2) 4.8.1

使用参数:

!This program cannot be run in DOS mode.
.text
0`.idata

I had the same issue myself, but using MinGW's GCC implementation - stripping the executable and passing the -Qn option did nothing, and I couldn't remove the ".comment" section as there wasn't one.

In order to stop the compiler including this information, regardless of which sections are in your executable, you can pass the -fno-ident parameter to the compiler and linker:

Without the parameter (strings -a [filename]):

!This program cannot be run in DOS mode.
.text
0`.rdata
[email protected]
GCC: (tdm64-2) 4.8.1

With the parameter:

!This program cannot be run in DOS mode.
.text
0`.idata
狂之美人 2024-11-21 02:05:51

这是在注释部分中,未加载到内存中(请注意,ELF 文件通常使用填充,以便内存映射它们将保持正确的对齐方式)。如果您想删除此类不需要的部分,请参阅各种 objcopy 选项并找出答案:

objcopy --remove-section .comment a.o b.o

This is in a comment section which isn't loaded in memory (and note that ELF files usually use padding so that memory mapping them will keep a correct alignment). If you want to get rid of such unneeded sections, see the various objcopy options and find out:

objcopy --remove-section .comment a.o b.o
绻影浮沉 2024-11-21 02:05:51

如果你不想要的话,你似乎可以“直接”删除它;请参阅此页面以获得详细的说明。

http://timelessname.com/elfbin/

请注意,该页面(当然)也诉诸于使用程序集,您可能不想这样做,但一般要点适用

It appears that you'd be able to 'just' strip that if you don't want it; See this page for a nice run-down.

http://timelessname.com/elfbin/

Note that the page (of course) also resorts to using assembly, which you may not want to do, but the general gist applies

丶情人眼里出诗心の 2024-11-21 02:05:51

您可以使用链接器脚本告知加载程序要在输出中包含哪些部分。您可以使用 objdump 命令查看文件中包含哪些部分。正如您所注意到的,精灵垃圾中含有很多“垃圾”,直到您希望拥有它为止。

但请注意,elf 可执行文件的大小并不表示在内存中实现的图像的内存占用量。许多“垃圾”不在内存映像中,并且映像可以调用 sbreak 和/或 mmap 来获取更多内存,elf 文件不考虑堆栈使用情况 - 本质上所有自动变量都没有考虑在内。这只是三个例子,其他例子还有很多。

You can inform the loader which sections to include in your output with a linker script. You can see what sections are included in the file using the objdump command. As you've noticed there's a good bit of 'junk' in an elf - junk that is until you wish you had it.

Note though, that the size of an elf executable file is not indicative of the memory foot print of the image as realized in memory. A lot of the 'junk' isn't in the memory image and the image can call sbreak and or mmap to acquire more memory, the elf file takes no account of stack usage - essentially all of your automatic variables are unaccounted for. These are only three examples others abound.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文