【问题标题】:Doesn't PIC mean no relocations?PIC不是意味着没有搬迁吗?
【发布时间】:2014-02-26 23:38:05
【问题描述】:

我正在使用 GCC 在 ARM 上为 bada 构建一个 ELF SO。编译器选项包括 -fpic。然而在构建的文件中,当我执行readelf -r 时,有很多重定位记录,类型如下:

  • R_ARM_RELATIVE
  • R_ARM_REL32
  • R_ARM_ABS32
  • R_ARM_GLOB_DAT
  • R_ARM_JUMP_SLOT

我在这里误会了什么?

编辑:据我所知,编译器中的 PIC 实现不使用 GOT。相反,它们使用 PC 相对寻址,其中存储的常量是从使用点到符号地址的偏移量;这由链接器解决。像这样,读取一个全局变量:

    ldr r12, OffsetToVar
PointOfUse:
    ldr r0, [r12, pc] 
# r0 now has the value of MyVar

#...

# At function's end...
OffsetToVar:
    .long MyVar-PointOfUse-8
# Compiler can't resolve this, since it doesn't know
# the address of MyVar, but linker can

跨模块函数调用的类似想法。但是,当一个项目混合了 ARM 和 Thumb 代码时,后者可能会失败。但我已经解决了这个问题。

【问题讨论】:

  • 只是猜测,您访问全局数据吗?如果是这样,代码可能是 PIC,但数据仍绑定到可能更改的地址?
  • PIC 表示位置无关代码。选择指令以便该代码块即使加载到未链接的地址空间也能正确执行。
  • 我会猜测你想要什么(但不是问题的答案)。请参阅-fixed-REG、使用-msingle-pic-base-mpic-register,您的调度程序必须将r9 设置为指向全局数据。例如,如果没有 MMU,您可以运行多个代码实例并将 r9 替换为指向该任务/线程/进程的全局变量的指针。这是一种避免数据重定位的机制。此外,编译器/链接器通常会发出通常不需要的重定位。

标签: gcc assembly arm elf


【解决方案1】:

PIC 不是意味着没有搬迁吗?

不,它确实不是

这只是意味着没有针对.text 部分的重定位(因此.text 可以在多个进程之间共享)。

【讨论】:

  • 这是真的吗? “-fpic 生成与位置无关的代码...此类代码通过全局偏移表 (GOT) 访问所有常量地址。” gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
  • -pic-pie。实际上,它将取决于gcc 配置。我认为这个答案对于 ARM Linux glibc 类型的环境是正确的。例如,ARM EABI 中有一个 static base,所有全局变量都可以引用该寄存器。此外,有时 relocation 记录实际上并没有做任何事情。即,编译器/链接器输出一个条目,但在加载时不需要实际修复。
  • 从偏移量来看,文本部分也有一些重定位。有没有办法进一步调查?
  • 在 x86-64 上,至少在 PIE 可执行文件中允许文本重定位。也可能在gcc -shared 实际共享库中。 (例如,movabs rsi, offset symbol 使用 64 位立即绝对值,而不是更有效的 RIP 相对值lea。)
猜你喜欢
  • 2010-09-18
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多