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函數。
對於-fPIE和-shared同時作用生成可共享的庫時,為什么不允許有全局對外可見的變量,其本質未弄清楚,若有高人看到,請指點小弟一二。