gcc编译参数-fPIC的一些问题
为什么要使用gcc -fPIC
The-fpic option causes the output object modules to be generated using relocatable
addressing. The acronym pic stands for position independent code.
acronym n.缩略词 英[ˈækrənɪm] 美[ˈækrənɪm]
选项-fpic(位置独立代码,position independent code)指示编译程序生成的代码要适合共享库的内容
——这样的代码能够根据载入内存的位置计算内部地址.
-fpic
该选项用于生成位置无关代码(PIC),尤其被用于共享库的创建(如果目标机器架构支持的话)。
使用该选项编译出的代码在访问所有常量地址时,会通过全局偏移表(GOT)进行计算得到。
动态加载器将会在目标程序启动的时候解析 GOT 的入口(动态加载器不是 GCC 的一部分,其属于操作
系统的一部分)。如果对于需要进行链接的可执行程序来说, 使用的 GOT 大小超过了 machine-specific
值指定的最大大小,你将会得到一条来自链接器的错误信息,以表明 -fpic 无法正常工作;在这种情况下,
会使用 -fPIC 选项再重新编译一次。(这个最大大小限制在 SPARC 上为 8k ,在 m68k 和 RS/6000
上为 32k ,而在 x86 上没有限制)
-fPIC
除了可以避免全局偏移表大小限制的问题外,其它方面和上面的一样。
如果编译库的时候没有指定 -fPIC 选项,那么多进程再同时使用该库的时候,将需要在各自的进程空间中
加载一份该库。
真正的问题在于,一个进程会在自己的进程空间中(虚拟地址空间)加载多个共享库,若未采用 -fPIC ,
那么各个共享库内的地址(会采用绝对地址)就可能发生冲突,因为在编译共享库的时候,是不会假设还有
其他共享库存在的。这个问题在传统共享库概念中是无法避免的。虚拟地址空间在这个问题上起不了作用。
-shared
使用 -shared 选项生成共享库时,最好还是带上 -fpic 或 -fPIC 等选项。