为什么共享库必须是位置独立的而静态库不是?
Why must shared libraries be position independent while static libraries don't?
我理解位置无关代码使用当前位置的偏移量,而位置相关代码使用绝对地址。
但是,我不明白为什么共享库必须被视为与位置无关,而静态库却不能?
一般来说,如今的程序只有一个线性地址 - space 用于所有内容,由虚拟内存(硬件和 os 子系统)支持。而且所有使用的东西都必须以某种方式安装进去。
为此,我们必须区分 PIC 代码(任何 position 都很好)、可重定位代码(首选 position)和固定代码(只有一个 position os迁移有效)。
由于可执行文件本身是特权的,因为它是第一个加载的用户代码(除了某些系统中的加载程序,尽管通常可以无缝地复制os自身),它可以放在任何地方你要。但是使用它会限制 ASLR。
可执行文件的静态库中的代码可以利用,但会限制包含的代码。
另一方面,共享库的加载顺序远没有明确规定,因此虽然加载器可以尝试将其放在首选位置os,但通常必须是可以放在别处。
因此,共享库和它们包含的代码必须是 PIC 或至少是可重定位的。
PIC 代码通常稍慢,但需要较少的修复,这意味着 most 可以根据需要从源二进制文件重新加载,而不必重新定位(这发生在 Windows 95 和后代)或在需要 space 时交换到磁盘。
实际上"static libraries"也有位置独立代码。不同之处在于链接器在构建静态可执行文件时将这些相对地址解析为绝对地址。静态库一旦被链接,就不能在其他地址执行了。
共享库能够被共享意味着代码大部分不能更改。因此,代码已准备好在 运行 时间的任何位置工作。
上面使用的所有 "addresses" 表示有 "virtual addresses" 天。静态库仍然可以在不同的物理地址加载和执行,而虚拟地址保持不变...
我理解位置无关代码使用当前位置的偏移量,而位置相关代码使用绝对地址。
但是,我不明白为什么共享库必须被视为与位置无关,而静态库却不能?
一般来说,如今的程序只有一个线性地址 - space 用于所有内容,由虚拟内存(硬件和 os 子系统)支持。而且所有使用的东西都必须以某种方式安装进去。
为此,我们必须区分 PIC 代码(任何 position 都很好)、可重定位代码(首选 position)和固定代码(只有一个 position os迁移有效)。
由于可执行文件本身是特权的,因为它是第一个加载的用户代码(除了某些系统中的加载程序,尽管通常可以无缝地复制os自身),它可以放在任何地方你要。但是使用它会限制 ASLR。
可执行文件的静态库中的代码可以利用,但会限制包含的代码。
另一方面,共享库的加载顺序远没有明确规定,因此虽然加载器可以尝试将其放在首选位置os,但通常必须是可以放在别处。
因此,共享库和它们包含的代码必须是 PIC 或至少是可重定位的。
PIC 代码通常稍慢,但需要较少的修复,这意味着 most 可以根据需要从源二进制文件重新加载,而不必重新定位(这发生在 Windows 95 和后代)或在需要 space 时交换到磁盘。
实际上"static libraries"也有位置独立代码。不同之处在于链接器在构建静态可执行文件时将这些相对地址解析为绝对地址。静态库一旦被链接,就不能在其他地址执行了。
共享库能够被共享意味着代码大部分不能更改。因此,代码已准备好在 运行 时间的任何位置工作。
上面使用的所有 "addresses" 表示有 "virtual addresses" 天。静态库仍然可以在不同的物理地址加载和执行,而虚拟地址保持不变...