【问题标题】:Position Dependent, Independent Code, and Global Variables in PowerPC AssemblyPowerPC 汇编中的位置相关、独立代码和全局变量
【发布时间】:2016-03-31 17:23:33
【问题描述】:

我对组装比较陌生,并且正在使用 powerpc 芯片。我正在使用 gcc 交叉编译器并使用 buildroot 环境(仅用于背景)。

我正在向一些代码的 .head 部分添加代码,这些代码将创建一个 .elf 对象(为了参数,我们将其称为 target.elf),该对象将通过 buildroot 引入一个更大的二进制文件。 target.elf 被定义为从代码和本地链接器中的地址 0x0 开始,但稍后将移动到不同的地址位置。我希望从汇编代码中引用一个在汇编代码和 c 文件之间共享的全局变量。当我使用与位置无关的方式这样做时,我会遇到问题。当我使用 GOT 作为参考时(例如,symbol@got@h),我能够正确引用该符号。

这是一个问题,因为我希望创建一个中断处理程序,它不依赖于在进入时具有指向堆栈或 TOC 的有效指针,并且我需要 TOC 才能使用 GOT。

有没有办法在没有 TOC 的情况下做到这一点?

下面是一些示例代码:

不正确的结果(%r3 不包含“符号”包含的内容):

.global symbol
symbol:
    .long 0

.global irq_handler
irq_handler:
    addi    %r3, 0, 0
    ori     %r3, %r3, symbol@l
    ld      %r3, 0(%r3)
    b       .

In global area of C-file:
extern uint64_t symbol;

我还尝试在 c 文件中定义符号(因此没有 extern 但仍然是全局的)并省略了 asm 文件中的定义。这也失败了。

我也采取了捷径,只加载地址的@l 部分,因为前 32 位是 0x0。

正确的结果(%r3 确实包含“符号”所包含的内容):

.global irq_handler
irq_handler:
  ld      %r3, symbol@got(%r2)
  ld      %r3, 0(%r3)
  b       .

请注意,在正确的示例中,TOC 在 %r2 中可用。

提前谢谢你。

【问题讨论】:

  • 我不明白你怎么能拥有“不依赖于指向堆栈的有效指针的中断处理程序”
  • 中断处理程序提供了一种分支到不同上下文的方法。对于这种情况,我将在分支到新上下文之前将当前上下文(寄存器)备份到已知位置。当我返回时,寄存器将处于未定义状态。当 irq 再次触发时,我将恢复原始上下文,但希望在恢复 TOC 之前引用“符号”。中断处理程序也处理其他功能,但不涉及太多细节。
  • 对上述评论的澄清:再次调用相同的中断处理程序有助于从其他上下文返回。再次调用时,寄存器处于未知状态,检查“符号”后将恢复。
  • 中断例程需要用自己的 TOC 库加载 R2。通常,ELF PowerPC ABI 要求函数的调用者将 R2 设置为被调用函数的 TOC 基值。显然,中断不会发生这种情况。用于设置 R2 的代码使用调用函数的 TOC,因此您不能只复制该代码,因为通常中断例程无法知道其“调用者”正在使用什么 TOC(如果有)。您可以查看 Linux 或其他 PowerPC 内核在其中断例程中的作用。
  • 谢谢。我手头有一个内核供参考,并且一直在使用它。我有一些解决方法的想法,但我想我希望如果我遗漏了一些东西并且我不需要这里的 TOC,我可以做一些更清洁的事情。但听起来对于会移动的代码,我需要 TOC 来定位“符号”。非常感谢。

标签: assembly powerpc


【解决方案1】:

似乎答案是位置无关代码需要TOC

【讨论】:

    猜你喜欢
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    相关资源
    最近更新 更多