关于从用户代码访问共享库功能,我有些不了解。
我不知道为什么在这种情况下需要PLT。我自己的代码没有共享,因此可以更改,所以为什么我们看不到共享库的功能在哪个地址加载,而是更改代码以直接访问它,而不是每次都通过PLT进行访问。
是因为在将我自己的代码加载到内存之前,我才知道该地址吗?
确切的原因是什么?
我自己的代码未共享,因此可以更改,
如果没有在系统上运行程序的单个副本,则不会共享您自己的代码。如果您运行多个副本,那么您的代码is在进程之间共享,并且对其进行写入操作将阻止此类共享。注意:这是针对可执行文件的 独立x86_64
ELF系统还有一个额外的考虑因素:在默认的内存模型(-mcmodel=medium
)中,例如,内存不足。 CALL
指令调用任意地址:您只能调用当前指令+/- 2GiB的地址。由于呼叫的目标可能(通常是)很远,因此无论如何您都需要通过PLT输入。
最后,通过PLT进行调用可以实现惰性符号解析,这将运行时成本推迟到调用函数的时间,对于
are
调用的函数<< only >>完成。直接重定位代码将使您的代码表现为好像LD_BIND_NOW=1
生效,从而使二进制文件的启动速度变慢(有时明显地变慢)。