arm-none-eabi 的默认链接器脚本中是否有任何对“main”的引用,从命令行链接时可能会干扰

问题描述

当使用 gnu 工具链,特别是 arm-none-eabi 时,是否有任何原因为什么在使用命令行链接器选项时,它会求助于“main”开头的似乎不正确的地址。然而,当“main”是其他任何东西时,正确的起始地址和堆栈被初始化。例如,

.thumb
.Syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl main
        b .




int main ( void )
{
        return(0);
}


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


disassembly of section .text:

08000000 <main>:
  8000000:      2000            movs    r0,#0
  8000002:      4770            bx      lr

08000004 <_start>:
  8000004:      20001000        .word   0x20001000
  8000008:      0800000c        .word   0x0800000c

0800000c <reset>:
  800000c:      f7ff fff8       bl      8000000 <main>
  8000010:      e7fe            b.n     8000010 <reset+0x4>

在反汇编中,上面的输出没有根据我的注意正确初始化堆栈 0x20001000 和 rom 0x08000000 的开始,但是..

.thumb
.Syntax unified

.globl _start
_start:
.word 0x20001000
.word reset

reset:
        bl notmain
        b .




int notmain ( void )
{
        return(0);
}


arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -O2 -c -mthumb main.c -o main.o
arm-none-eabi-ld -Ttext=0x08000000 start.o main.o -o main.elf
arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm


disassembly of section .text:

08000000 <_start>:
  8000000:      20001000        .word   0x20001000
  8000004:      08000008        .word   0x08000008

08000008 <reset>:
  8000008:      f000 f802       bl      8000010 <xmain>
  800000c:      e7fe            b.n     800000c <reset+0x4>
        ...

08000010 <notmain>:
  8000010:      2000            movs    r0,#0
  8000012:      4770            bx      lr

我尝试查看我的文件中的工具链以找到与链接器脚本有关的 main 的任何其他参考,并在此过程中获得了一些其他帮助,但似乎没有明确的解决方案来解释为什么会这样。当然,如果您创建自己的链接器或生成链接器,您就不会遇到这个问题,但我只是好奇,因为我正在尝试更多地学习该工具。

解决方法

..但我只是好奇,因为我正在尝试更多地学习该工具

arm-eabi-none 旨在与 一起使用(作为猜测,因为您没有另外说明)。这可以处理elf 格式的文件,它是一个“库”,但没有操作系统。如果 newlib 机制希望 main() 成为第一个,该工具将设置如下。您不需要 elf 文件,而是二进制文件。如果您想要二进制文件(ihex、srec 等),请使用链接描述文件!这就是它的意义所在。


使用 ld --verbose 查看默认链接器脚本。您在抱怨发出的 .text 的顺序,但您没有做任何事情来定义排序。链接描述文件可能需要 main 为第一个,以便其他一些库功能可以工作。您有一个重置向量和一个 CPU,用于初始化堆栈和“重置向量”或初始代码。

这仍然在“坏情况”中发出,但没有正确放置。您需要有一个自定义链接器脚本,并将其定位为二进制文件中的第一件事。依靠链接器正确放置它很容易出错。工具的升级绝对可以改变顺序。

请参阅:Can _start be a thumb function,您是否有-nostartfiles -static -nostdlib 之类的选项并使用自定义链接器脚本作为 elf 二进制文件不太可能被理解,您需要闪烁/将二进制文件刻录到任何要读取复位向量的引导设备(或内置 CPU)。