Tiny C 二进制文件

主要观点:默认情况下,GCC 生成的 ELF 二进制文件包含冗余数据导致可执行文件较大,通过一系列优化手段可减小文件大小。
关键信息

  • ELF 二进制文件:Linux 上可执行对象代码的标准文件格式,包含 ELF 头和文件数据,64 位的 ELF 头格式各字段有特定含义,如 e_ident 包含魔数等信息,e_type 等字段指定对象类型等。
  • 大小优化步骤

    • 先使用 -Os 优化但文件大小未减,因该标志不考虑所有冗余数据;改为直接调用 Linux 内核打印,避免链接标准库代码。
    • 编写汇编包装器将用户模式参数转换为内核系统调用参数,使用 -nostdlib 阻止链接标准库对象代码,但需自己实现程序启动相关符号。
    • 编写自定义链接脚本(x86_64.ld)指定保留必要的代码段,可大幅减小文件大小。
    • 使用 GCC 其他编译时标志如 -ffunction-sections 等进一步去除无用代码段,配合 -static 可得到更小的静态二进制文件。
    • 使用 sstrip 工具去除动态链接输出可执行文件中的冗余代码和数据段,最终可将文件大小减小到约 830 字节。

    重要细节

  • 示例 hello world 程序经 GCC 编译后约 17KB,objdump 可查看 ELF 节,strip 工具可去除部分冗余节但效果不明显。
  • Linux 系统调用在 x86_64 架构上有特定参数顺序,需编写汇编包装器进行转换。
  • 自定义链接脚本设置输出二进制的虚拟基地址并保留必要代码段。
  • GCC 有多种优化标志,如 -ffunction-sections 等可分别将函数和数据项放入各自节等。
  • sstrip 工具可更激进地去除未使用的代码和数据段,但其需配合手动优化才能得到极小的二进制文件。
  • 源代码可在https://github.com/lunarbin/tinybase获取。
阅读 6
0 条评论