繁体   English   中英

全局偏移表:“指向指针的指针”? 这是由加载程序处理的吗?

[英]Global Offset Table: "Pointers to Pointers"? Is this handled by the loader?

这个问题是关于 Linux (Ubuntu) 可执行文件的。

我会按照我的理解详细说明,以便更清楚地了解是否有任何问题(因此请在适用的地方纠正我):

GOT 充当额外的间接级别以允许从需要与位置无关的文本部分访问数据,例如因为文本部分可能是只读的并且数据的实际地址在(静态)链接时可能是未知的。
GOT 然后保存实际数据位置的地址,这在加载时是已知的,因此动态 linker(由加载程序调用)能够修改适当的 GOT 条目并使它们指向实际数据。

让我感到困惑的主要事情——不是目前唯一的事情,请注意:-)——这意味着文本部分中的地址现在指向“不同类型”的值:
如果没有 GOT,我会期望这个地址(例如在 RIP 相对寻址模式下)指向我所追求的实际值。 但是,对于 GOT,我希望它指向适当的 GOT 条目,该条目又将地址保存为我所追求的值。 在这种情况下,这里需要额外的“取消引用”。

我是否以某种方式误解了这一点? 如果我使用 RIP 相对寻址,计算出的地址(RIP+偏移量)不应该是指令中使用的实际地址吗? 所以(在 AT&T 语法中):

mov $fun_data(%rip), %rax

据我了解,如果没有 GOT,这应该是“ rax = *(rip + (fun_data - rip)) ”,或者简而言之: rax = *fun_data
但是,对于 GOT,我希望这等同于rax = **fun_data ,因为*fun_data只是真正fun_data 的 GOT 条目。

我是不是错了,或者只是如果指针进入 GOT,加载程序就知道如何访问真实数据? (换句话说:我想在 PIE 中,一些指针实际上变成了指向指针的指针?)

我错了吗

不。

或者如果指针指向 GOT,加载程序是否知道访问真实数据?

编译器知道需要双重解引用。

使用和不-fPIC编译此源代码并自行观察:

extern int dddd;
int fn() { return dddd; }

没有-fPIC ,你会得到(预期):

movl    dddd(%rip), %eax

使用-fPIC你会得到“双重取消引用”:

movq    dddd@GOTPCREL(%rip), %rax   # move pointer to dddd into RAX
movl    (%rax), %eax                # dereference it

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM