如何防止“main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'";创建 aarch64 裸机程序时? [英] How to prevent "main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'" when creating an aarch64 baremetal program?

查看:48
本文介绍了如何防止“main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'";创建 aarch64 裸机程序时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建裸机可执行文件时,我遇到了这个错误:

When playing with creating baremetal executables, I hit this error:

main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'
collect2: error: ld returned 1 exit status

然后我设法创建了一个最小的复制示例:

I then managed to create a minimal reproduction example:

main.c

void _start(void) {}

notmain.S

.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'

其中 aarch64-linux-gnu-gcc 是来自 Ubuntu 19.10 的 gcc-9-aarch64-linux-gnu 包的 GCC 9.2.1 版.

where aarch64-linux-gnu-gcc is GCC version 9.2.1 from Ubuntu 19.10's gcc-9-aarch64-linux-gnu package.

我后来也在 Ubuntu 18.04 GCC 7.5.0 上尝试过,它在那里工作,所以最好了解两者之间的变化.

I later also tried on Ubuntu 18.04 GCC 7.5.0, and there it worked, so it would be good to understand what changed in between.

.skip 16 有效,但 .skip 32 无效.

我知道对裸机内容使用非裸机交叉编译器并不理想,但谁能指出我是否可以进行一些命令行选项或代码修改以使链接正常工作?

I know that it is not ideal to use a non-baremetal cross compiler for baremetal stuff, but can anyone point out if there is some command line option or code modification I could make to make the link work?

如果该工具链无法做到这一点,有人可以澄清原因吗?哪个 GCC 构建配置选项特别使这不可能?

And if this is not possible with that toolchain, can someone clarify why? Which GCC build configuration option in particular makes this impossible?

我实际上有一个 aarch64 crosstool-NG 工具链 此处描述 并且它适用于那个,所以它实际上可能是工具链的问题.

I actually had an aarch64 crosstool-NG toolchain lying around described here and it works with that one, so it could actually be a problem with the toolchain.

我知道 R_AARCH64_PREL32 记录在:https://static.docs.arm.com/ihi0044/g/aaelf32.pdf 我对重定位有一个大致的了解:这个 GCC 错误是什么...重定位被截断以适合..."?是什么意思?但这比我现在想深入研究的要多一些.

I know that R_AARCH64_PREL32 is documented at: https://static.docs.arm.com/ihi0044/g/aaelf32.pdf and I have a general understanding of relocaiton: What does this GCC error "... relocation truncated to fit..." mean? but this one is a bit more than what I'd like to dig into right now.

此外,如果我在更真实的设置中将入口点移动到程序集:

Also, if I move the entry point to assembly in a more realistic setup:

notmain.S

.global _start
_start:
    bl entry

main.c

void entry(void) {}

问题没有发生.

推荐答案

作为一种允许它在我不完全了解情况的情况下进行编译的解决方法,您可以添加:

As a workaround that allows it to compile without me fully understanding the situation, you can add:

-fno-unwind-tables -fno-asynchronous-unwind-tables

它删除了失败的重定位来自的 .eh_frame 框架:为什么GCC编译的C程序需要.eh_frame段?

which removes the .eh_frame frame from which the failing relocation was coming from: Why GCC compiled C program needs .eh_frame section?

然后我注意到二进制文件不起作用,因为 _start 有 C 函数序言并首先接触堆栈,我找不到一个惊人的解决方案:创建一个没有编译器生成的序言/结语&的C函数RET 指令? (-O3? :-) 我们需要发明一个 -fno-stack 选项.

I then noticed the binary doesn't work because _start has the C function prologue and touches stack first thing, and I can't find an amazing solution for that: Creating a C function without compiler generated prologue/epilogue & RET instruction? (-O3? :-) We need to invent a -fno-stack option).

这篇关于如何防止“main.o:(.eh_frame+0x1c): relocation truncated to fit: R_AARCH64_PREL32 against `.text'";创建 aarch64 裸机程序时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆