了解 GOT(全局偏移 Table)和 PLT?

Understanding GOT (Global Offset Table) and PLT?

在写这个问题之前,我想强调一下,我自己做了 周的研究 阅读了数十篇文章,但这个问题仍然没有解决,我得到的解释也没有'根本没有意义(也许是因为我是连接世界的新手)。所以我希望有人能提供简单但非常详细的答案。

我知道GOT (Global Offset Table) 可以帮助我们解析动态链接中从另一个引用的全局符号。另外我读到:“每个共享库都有自己的 GOT”

  1. 但这是有问题的,如果2个程序使用同一个共享库怎么办?两者都将具有相同的全局变量值,但事实并非如此。

  2. 至于我的 MAIN 问题:如果我不想使用惰性绑定那么为什么我们根本需要 PLT,为什么不直接使用普通 GOT与变量一样?

(2) - 这正是 gcc -fno-plt 所做的;使用 call puts@gotpcrel(%rip) 引用正常的 GOT 条目,.
参见 x86_64: Is it possible to "in-line substitute" PLT/GOT references?


(1) “每个共享库都有自己的 GOT”意思是相对于每个进程有一个 。并不是说每个使用库映射的进程在共享内存中只有一个库的GOT。

请记住,类 Unix 操作系统(与所有现代主流操作系统一样)使用虚拟内存将进程彼此隔离,因此通常不用说每个进程都有自己独立的 read/write 数据副本。

当然,errnoenviron 之类的全局变量不会在使用同一库的进程之间共享,这会破坏事情,因此您可以排除这种解释。 (如果你 strace /bin/ls 也不是动态链接在做什么)