|
在生成动态库时,常常习惯性的加上 fPIC 选项,fPIC 有什么作用和意义,加不加有什么区别,这里做下小结。
fPIC 的全称是 Position Independent Code, 用于生成位置无关代码。什么是位置无关代码,个人理解是代码无绝对跳转,跳转都为相对跳转。
编译将报错
/usr/bin/ld: /tmp/ccCViivC.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccCViivC.o: could not read symbols: Bad value
2、加 fPIC 选项
加上 fPIC 选项生成的动态库,显然是位置无关的,这样的代码本身就能被放到线性地址空间的任意位置,无需修改就能正确执行。通常的方法是获取指令指针的值,加上一个偏移得到全局变量 / 函数的地址。
加 fPIC 选项的源文件对于它引用的函数头文件编写有很宽松的尺度。比如只需要包含个声明的函数的头文件,即使没有相应的 C 文件来实现,编译成 so 库照样可以通过。
3、在内存引用上,加不加 fPIC 的异同
加了 fPIC 实现真正意义上的多个进程共享 so 文件。
多个进程引用同一个 PIC 动态库时,可以共用内存。这一个库在不同进程中的虚拟地址不同,但操作系统显然会把它们映射到同一块物理内存上。
对于不加 fPIC,则加载 so 文件时,需要对代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个 .so 文件代码段的进程在内核里都会生成这个 .so 文件代码段的 copy。每个 copy 都不一样,取决于这个 .so 文件代码段和数据段内存映射的位置。
可见,这种方式更消耗内存。
但是不加 fPIC 编译的 so 文件的优点是加载速度比较快。
|
+10
|