为什么编译器版本出现在我的 ELF 可执行文件中?
我最近在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 -Qn 来避免这种情况。
use -Qn to avoid that.
这是 ELF 二进制文件的注释部分。你可以把它去掉:
虽然收益很小,但不确定是否值得。
That's in a comment section in the ELF binary. You can strip it out:
The gains are tiny though, not sure it's worth it.
我自己也遇到了同样的问题,但是使用 MinGW 的 GCC 实现 - 剥离可执行文件并传递 -Qn 选项没有任何作用,而且我无法删除“.comment”部分,因为没有。
为了停止编译器包含此信息,无论可执行文件中包含哪些部分,您都可以将 -fno-ident 参数传递给编译器和链接器:
不带参数 (strings -a [filename ]):
使用参数:
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]):
With the parameter:
这是在注释部分中,未加载到内存中(请注意,ELF 文件通常使用填充,以便内存映射它们将保持正确的对齐方式)。如果您想删除此类不需要的部分,请参阅各种 objcopy 选项并找出答案:
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:
如果你不想要的话,你似乎可以“直接”删除它;请参阅此页面以获得详细的说明。
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
您可以使用链接器脚本告知加载程序要在输出中包含哪些部分。您可以使用 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.