GCC交叉编译i386-pc-coff时__end未定义引用问题求助
解决i386-pc-coff交叉编译中__end未定义引用问题
问题复盘
你已经完成GCC 3.2.3交叉编译器的构建,修复了__EH_FRAME_BEGIN__未定义问题,但当前卡在libc.a(brk.o)报__end未定义的错误。首先要澄清一个关键误解:你看到的brk.o符号表中,__end对应的sec 0在COFF格式中代表未定义的外部符号,而非已定义符号——也就是说brk.o是在引用__end,而不是提供它的定义。
解决思路
1. 通过链接脚本定义__end
COFF目标依赖链接脚本定义程序的内存布局,其中包括__end这类标记段边界的符号。创建一个简单的链接脚本(比如命名为i386-coff.ld):
OUTPUT_FORMAT("coff-i386") ENTRY(_start) SECTIONS { .text 0x00010000 : { *(.text) } .data : { *(.data) } .bss : { __bss_start = .; *(.bss) *(COMMON) __end = .; } }
编译时指定该链接脚本:
i386-pc-coff-gcc -v -D__COHERENT__ helloworld.c -T i386-coff.ld
2. 调整链接库顺序
链接器按从左到右的顺序解析符号,确保libc和libgcc的顺序符合依赖关系。尝试手动指定链接顺序:
i386-pc-coff-gcc -v -D__COHERENT__ helloworld.c -lc -lgcc
或者直接调用链接器明确顺序:
i386-pc-coff-ld ~/opt/i386-pc-coff/lib/crt0.o helloworld.o -L~/opt/i386-pc-coff/lib -lc -L~/opt/lib/gcc-lib/i386-pc-coff/3.2.3 -lgcc
3. 检查crt0.o的完整性
传统COFF环境中,crt0.o通常会定义程序初始化所需的布局符号。如果你的crt0.o缺少__end,可以修改crt0的源码,在.bss段末尾添加__end的定义,重新编译crt0.o:
; 示例crt0.s片段 .section .bss .global __end __end:
4. 验证目标libc的兼容性
确保你复制的目标机libc.a是针对i386-pc-coff平台编译的,且与GCC 3.2.3的ABI兼容。部分旧版libc可能依赖特定的链接脚本符号,需要对应补充。
内容的提问来源于stack exchange,提问作者toejam
相关产品推荐
相关产品推荐

