【发布时间】:2020-09-25 22:56:27
【问题描述】:
关于从用户代码访问共享库函数,我有些不明白。
我不明白为什么在这种情况下需要 PLT。我自己的代码没有共享所以可以改,那为什么不看共享库的函数加载在哪个地址,改代码直接访问,而不是每次都经过PLT。
是因为在我自己的代码加载到内存之前我无法知道那个地址吗?
这究竟是什么原因?
【问题讨论】:
标签: shared-libraries dynamic-linking
关于从用户代码访问共享库函数,我有些不明白。
我不明白为什么在这种情况下需要 PLT。我自己的代码没有共享所以可以改,那为什么不看共享库的函数加载在哪个地址,改代码直接访问,而不是每次都经过PLT。
是因为在我自己的代码加载到内存之前我无法知道那个地址吗?
这究竟是什么原因?
【问题讨论】:
标签: shared-libraries dynamic-linking
我自己的代码没有共享,所以可以更改,
如果您在系统上运行程序的单个副本,则您自己的代码不会共享仅。如果您运行多个副本,那么您的代码在进程之间共享,写入它会阻止这种共享。
注意:这是针对您的可执行文件的独立调用。如果多个进程具有父/子关系,即使修改后的代码仍然可以共享。
对于x86_64 ELF 系统还有一个额外的考虑:在默认内存模型 (-mcmodel=medium) 中根本没有足够的空间,例如CALL 调用任意地址的指令:您只能调用距当前指令 +/-2GiB 的地址。由于调用的目标可能(通常)更远,所以无论如何您都需要通过 PLT 条目。
最后,通过 PLT 调用允许延迟符号解析,这将运行时间成本推迟到调用函数的时间,并且仅为调用 的函数完成.直接重定位代码将使您的代码表现得就像LD_BIND_NOW=1 生效一样,从而使您的二进制文件启动速度变慢(有时明显变慢)。
【讨论】: