在创建裸机可执行文件时,我遇到了以下错误:
main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'
collect2: error: ld returned 1 exit status
然后我设法创建了一个最小的复制示例:
main.c
void _start(void) {}
不是主程序
.skip 32
link.ld
ENTRY(_start)
SECTIONS
{
.text : {
*/bootloader.o(.text)
*(.text)
*(.rodata)
*(.data)
*(COMMON)
}
.bss : { *(.bss) }
heap_low = .;
. = . + 0x1000000;
heap_top = .;
. = . + 0x1000000;
stack_top = .;
}
编译命令:
aarch64-linux-gnu-gcc \
-save-temps \
-T link.ld \
-Wall \
-Werror \
-Wextra \
-Wl,--section-start=.text=0x80000000 \
-Xassembler -march=all \
-fno-pie \
-ggdb3 \
-no-pie \
-nostartfiles \
-nostdlib \
-static \
-o 'main.out' \
-pedantic \
notmain.S \
'main.c'
where aarch64-linux-gnu-gcc
是 Ubuntu 19.10 的 GCC 版本 9.2.1gcc-9-aarch64-linux-gnu
包裹。
后来我也在 Ubuntu 18.04 GCC 7.5.0 上进行了尝试,并且它成功了,所以最好了解一下之间发生了什么变化。
.skip 16
有效,但是.skip 32
才不是。
我知道使用非裸机交叉编译器来处理裸机内容并不理想,但是任何人都可以指出是否可以进行一些命令行选项或代码修改来使链接正常工作?
如果该工具链无法实现这一点,有人可以澄清原因吗?哪个 GCC 构建配置选项特别使这成为不可能?
我实际上有一个aarch64
crosstool-NG 工具链随处可见此处描述它适用于那个,所以这实际上可能是工具链的问题。
我知道R_AARCH64_PREL32
记录于:https://static.docs.arm.com/ihi0044/g/aaelf32.pdf我对搬迁有一个大概的了解:这个 GCC 错误“...重定位被截断以适合...”是什么意思?但这比我现在想深入研究的内容要多一些。
另外,如果我将入口点移至更实际的设置中的程序集:
不是主程序
.global _start
_start:
bl entry
main.c
void entry(void) {}
问题没有发生。