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

如何将编译器生成的32位与64位代码链接为单个二进制文件?

解决混合32/64位ELF代码的链接难题

Michael Petch 曾提到:“64位ELF格式支持32位代码段。”

你遇到的链接器错误,本质上是没给链接器足够的信息来处理两种不同字长的代码段,以及跨模式调用的符号兼容性问题——毕竟编译器默认不会生成能直接和异字长代码链接的目标文件,这也是你之前只能用手写汇编绕开问题的原因。下面给你几个具体的解决方向:

  • 明确编译目标字长,生成正确的ELF目标文件
    用GCC这类编译器时,必须给32位代码加上-m32参数,64位代码用-m64,这样编译器会生成对应字长的目标文件,并且在ELF段中标记正确的属性(比如32位代码段的e_ident[EI_CLASS]会设为ELFCLASS32)。如果编译时参数混乱,目标文件的字长不匹配,链接器直接就会抛出错误。

  • 自定义链接脚本,告诉链接器如何处理32位代码段
    默认的链接器脚本不会处理混合32/64位的场景,你需要手动定义32位代码的专属段,并标记其32位属性。举个简单的链接脚本示例:

    SECTIONS {
      . = 0x100000;  /* 64位代码起始地址 */
      .text : { *(.text) } :text
      .text32 : { *(.text32) } :text32  /* 32位代码段 */
      .data : { *(.data) } :data
      .bss : { *(.bss) } :bss
    }
    PHDRS {
      text PT_LOAD FLAGS(5);        /* 64位可执行段(R+E) */
      text32 PT_LOAD FLAGS(5) PHDRS_FLAGS(0x40000000);  /* 标记为32位可执行段 */
      data PT_LOAD FLAGS(6);        /* 数据段(R+W) */
    }
    

    编译32位代码时,还要用-ffunction-sections把函数放到.text32段,比如:

    gcc -m32 -c my32code.c -ffunction-sections -Wl,--section-start=.text32=0x200000
    

    这样链接器就能正确识别并放置32位代码段了。

  • 处理跨模式调用的符号转换
    32位和64位代码之间的调用不能直接进行,必须做模式切换和调用约定适配。比如从64位代码跳转到32位代码时,需要先保存64位寄存器状态,用ljmp指令切换到32位代码段,调用完成后再切回64位模式并恢复寄存器;反过来也是同理。这部分逻辑可能需要你写少量汇编胶水代码,因为编译器不会自动生成跨模式的调用代码。

  • 验证目标文件属性,排除基础错误
    用readelf -h命令检查每个目标文件的头部信息,确认32位文件的Class字段是ELF32,64位文件是ELF64。如果有文件的属性不符合预期,那肯定是编译参数出了问题,先修正这一点再尝试链接。

按照这些步骤调整后,你应该能顺利链接编译器生成的32位和64位代码,不用再全靠手写汇编来维护,降低项目复杂度带来的维护压力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:04:24