You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何彻底移除静态链接二进制中的.dynsym、.dynstr和.dynamic节?

解决静态二进制文件残留动态节的问题

问题根源

你看到的.dynsym、.dynstr、.dynamic等动态节,是因为编译时使用了-fpic/-fPIC参数——这两个参数会强制编译器生成位置无关代码(PIC),而PIC模式下链接器默认会保留动态链接相关的节,哪怕你指定了--no-dynamic-linker也无法完全消除。另外,-fpic/-fPIC并不是用来消除重定位的,它的作用是让代码能在任意地址加载,反而会引入PLT/GOT这类动态重定位机制,这也是你看到残留重定位的原因。

对于同一代码段内的call main,如果用了PIC编译,编译器会把它转换成通过PLT的间接调用,从而产生不必要的重定位;去掉PIC参数后,会生成直接的相对地址调用,不会有重定位问题。

解决方案:调整编译链接参数

修改你的Makefile,移除-fpic/-fPIC,添加-static链接器参数,明确生成完全静态的二进制:

hello: start.s hello.c Makefile
        gcc -o hello -nostartfiles -nostdlib -static -Wl,--no-dynamic-linker -fno-asynchronous-unwind-tables -s start.s hello.c
        strip -R .comment hello

参数说明

  • -static:告诉链接器生成完全静态链接的二进制,不依赖任何动态库,同时会自动抑制动态节的生成。
  • 移除-fpic/-fPIC:既然目标是静态二进制,不需要位置无关代码,这两个参数只会增加冗余。
  • 保留-nostartfiles -nostdlib:继续使用自定义的启动代码,不依赖标准库和启动文件。

验证结果

修改后重新编译,再用objdump -x hello检查,会发现.dynsym、.dynstr、.dynamic这些动态节已经消失,二进制体积也会进一步缩小,同一代码段内的call main也不会有多余的重定位。

内容的提问来源于stack exchange,提问作者Joshua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:24:55