码迷,mamicode.com
首页 > 其他好文 > 详细

PIC和PIE

时间:2018-04-17 19:56:51      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:错误   www.   html   期望   情况   相对   http   编译   lin   

PIC指的是位置无关代码,用于生成位置无关的共享库,所谓位置无关,指的是共享库的代码断是只读的,存放在代码段,多个进程可同时公用这份代码段而不需要拷贝副本。库中的变量(全局变量和静态变量)通过GOT表访问,而库中的函数,通过PLT->GOT->函数位置进行访问。Linux下编译共享库时,必须加上-fPIC参数,否则在链接时会有错误提示(有资料说AMD64的机器才会出现这种错误,但我在Inter的机器上也出现了)。这篇资料不错:http://ixuan.org/2015/01/%E5%8A%A8%E6%80%81%E5%BA%93%E4%B8%AD%E7%9A%84%E4%BD%8D%E7%BD%AE%E6%97%A0%E5%85%B3%E4%BB%A3%E7%A0%81-position-independent-code-pic-in-shared-libraries/

 

  PIE指的是位置无关的可执行程序,用于生成位置无关的可执行程序,所谓位置无关的可执行程序,指的是,可执行程序的代码指令集可以被加载到任意位置,进程通过相对地址获取指令操作和数据,如果不是位置无关的可执行程序,则该可执行程序的代码指令集必须放到特定的位置才可运行进程。(可执行程序和进程的区别,简单来说,可执行程序就是一堆指令集,而进程是系统分配资源之后利用该指令集进行的一次工作)。在Linux下,使用-fPIE时需要注意:

 

  1.如果-fPIE和-shared同时使用,生成的结果即可作为动态库,也可作为可执行程序:

1)作为动态库时,必须满足:不存在main函数且模块中不存在对外输出的全局变量。这是因为-fPIE默认总是将生成的位置无关代码看作是属于程序本身(http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/),如果有一个对外输出的变量且结果又是作为共享的动态库,这个时候对外输出的变量就会和fPIC的作用产生矛盾,因此,这种情况下,不允许有对外可见的变量。这种情况下,编译生成的可执行程序可作为动态库被调用。

2)如果是作为可执行程序,必须有main函数,此时模块中可以有全局变量,是一个可执行程序。

  2.如果-fPIE不和-shared一起使用,那么生成的结果只能作为可执行程序,其中必须包含main函数。

PIC生成的共享库是会被其它程序调用的,所以可以在调用时对GOT中的变量地址重定位来确定全局变量地址。
而PIE本身的目的不是生成共享库,而是生成位置无关的可执行程序,所以在连接时所有的变量都已经确定好了,包括全局的对外可见变量也默认视为程序内部变量。因此,如果用PIE生成共享库,一旦存在全局对外可见的变量,一方面,作为共享库,该变量地址被期望是可重定位的,另一方面,作为PIE,该变量地址被期望是固定的,就会产生矛盾。
根本原因在于变量地址是否应该可以被重定位。

原文链接:https://www.cnblogs.com/yanqi0124/p/4816343.html

PIC和PIE

标签:错误   www.   html   期望   情况   相对   http   编译   lin   

原文地址:https://www.cnblogs.com/Spider-spiders/p/8868535.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!