【问题标题】:Where is _start symbol likely to be defined_start 符号可能在哪里定义
【发布时间】:2016-11-04 16:17:54
【问题描述】:

我有一些 RISCV 启动程序集,它将 .text 部分定义为从 .globl _start 开始。

我知道这是什么 - 反汇编显示地址,但我看不到它的定义位置。它不在链接器脚本中,构建目录中的 grep 显示它在各种二进制文件中,但我找不到定义。

我猜这作为架构的函数出现在某个文件中,但是谁能告诉我在哪里? (这都是在 Linux 上使用 RISCV GNU 交叉编译器构建的)

【问题讨论】:

  • 这个问题的答案涉及到链接器、加载器和启动代码的内部细节。或者换一种说法,_start的地址会在运行时分配,所以grep没有定义可以找到。
  • 对于我的裸机项目,我将_start 映射到链接描述文件中的固定地址。否则我不能保证_start 是在正确的地方。
  • 在与.globl _start 指令相同的源代码文件中应该有一个_start: 行定义标签_start,否则.globl _start 指令没有任何用处。
  • 有这么一行,但它只是落在 .text 部分的开头,但也许这就是重点!

标签: gcc assembly linker riscv


【解决方案1】:

除非您自己控制它,否则在 gnu 工具世界中通常至少有一个名为 crt0.s 的文件。或者也许是其他名字。应该是每个架构一个,因为它是汇编语言。它是默认的引导程序,零 .bss 根据需要复制 .data 等。

我不记得它是 C 库(glibc、newlib 等)的一部分,还是后来由构建针对某些特定平台的工具链的人添加的。

当然不是必需的,但_start 是二进制文件开头的标签并不罕见,它当然应该是入口点。因此,如果您的操作系统/加载器使用带有标签(elf 等)的二进制文件,那么它可以加载二进制文件,而不是分支到第一个地址,而是分支到入口点。

【讨论】:

  • 确实如此。事实上,我为此编写了自己的 crt.S(通过将其他人的一些代码拼凑在一起)。我现在意识到 _start 只是定义为加载入口代码的位置。
【解决方案2】:

所以_start 仅仅被定义为在.text 部分的开头,而.text 部分的地址在链接描述文件中定义。

【讨论】:

    猜你喜欢
    • 2017-12-17
    • 2017-12-09
    • 2020-04-03
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多