如何防止"main.o :(.eh_frame + 0x1c):重定位被截断以适合:R_AARCH64_PREL32针对".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?

查看:230
本文介绍了如何防止"main.o :(.eh_frame + 0x1c):重定位被截断以适合:R_AARCH64_PREL32针对".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

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 ,而我对重新定位有一个大致的了解:但是这个比我现在想深入了解的要多.

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

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框架:

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函数的序言,并且首先涉及到堆栈,而我找不到一个令人惊奇的解决方案:

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):重定位被截断以适合:R_AARCH64_PREL32针对".text"创建aarch64裸机程序时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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