arm linux gcc fpic,【待整理】Gcc中编译和链接选项 -fpic -fPIC -fpie -fPIE -pie的含义
【待整理】Gcc中編譯和鏈接選項(xiàng) -fpic -fPIC -fpie -fPIE -pie的含義
-fpic
Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The 386 has no such limit.)
Position-independent code requires special support, and therefore works only on certain machines. For the 386, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent.
When this flag is set, the macros __pic__ and __PIC__ are defined to 1.
-fPIC
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC.
Position-independent code requires special support, and therefore works only on certain machines.
When this flag is set, the macros __pic__ and __PIC__ are defined to 2.
-fpie
-fPIE
These options are similar to -fpic and -fPIC, but generated position independent code can be only linked into executables. Usually these options are used when -pie GCC option will be used during linking.
-fpie and -fPIE both define the macros __pie__ and __PIE__. The macros have the value 1 for -fpie and 2 for -fPIE.
-fno-jump-tables
Do not use jump tables for switch statements even where it would be more efficient than other code generation strategies. This option is of use in conjunction with -fpic or -fPIC for building code which forms part of a dynamic linker and cannot reference the address of a jump table. On some targets, jump tables do not require a GOT and this option is not needed.
————————————————–
Position-Independent-Executable是Binutils,glibc和gcc的一個功能,能用來創(chuàng)建介于共享庫和通常可執(zhí)行代碼之間的代碼–能像共享庫一樣可重分配地址的程序,這種程序必須連接到Scrt1.o。標(biāo)準(zhǔn)的可執(zhí)行程序需要固定的地址,并且只有被裝載到這個地址時,程序才能正確執(zhí)行。PIE能使程序像共享庫一樣在主存任何位置裝載,這需要將程序編譯成位置無關(guān),并鏈接為ELF共享對象。
引入PIE的原因是讓程序能裝載在隨機(jī)的地址,通常情況下,內(nèi)核都在固定的地址運(yùn)行,如果能改用位置無關(guān),那攻擊者就很難借助系統(tǒng)中的可執(zhí)行碼實(shí)施攻擊了。類似緩沖區(qū)溢出之類的攻擊將無法實(shí)施。而且這種安全提升的代價很小
談到PIE就不得不說說Pax和Grsec內(nèi)核。這兩個東西都是為了構(gòu)建堅不可摧到安全系統(tǒng)而準(zhǔn)備的。PaX是Linux內(nèi)核安全增強(qiáng)補(bǔ)丁,它能在兩方面保證安全性,一是ASLR(Address Space Layout Randomization,地址空間分布隨機(jī)化),這是一種將所有數(shù)據(jù)裝載到內(nèi)存時都隨機(jī)化地址的方式,當(dāng)使用PIE選項(xiàng)編譯應(yīng)用時,PaX能將應(yīng)用的地址做隨機(jī)加法;二是能提供不可執(zhí)行的內(nèi)存空間,這樣就能使得攻擊者放入內(nèi)存中的惡意代碼不可執(zhí)行。不過PaX官網(wǎng)上能支持的最新內(nèi)核是2.6.27,已經(jīng)是一年前的更新了。Grsec也時類似的內(nèi)核補(bǔ)丁,更新較為頻繁能支持最新的2.6.32內(nèi)核。這兩種方式都能將內(nèi)核完全位置無關(guān),除了Grub和Glibc中無法位置無關(guān)的匯編碼。
PIE最早由RedHat的人實(shí)現(xiàn),他在連接起上增加了-pie選項(xiàng),這樣使用-fPIE編譯的對象就能通過連接器得到位置無關(guān)可執(zhí)行程序。fPIE和fPIC有些不同。可以參考Gcc和Open64中的-fPIC選項(xiàng).
gcc中的-fpic選項(xiàng),使用于在目標(biāo)機(jī)支持時,編譯共享庫時使用。編譯出的代碼將通過全局偏移表(Global Offset Table)中的常數(shù)地址訪存,動態(tài)裝載器將在程序開始執(zhí)行時解析GOT表項(xiàng)(注意,動態(tài)裝載器操作系統(tǒng)的一部分,連接器是GCC的一部分).而gcc中的-fPIC選項(xiàng)則是針對某些特殊機(jī)型做了特殊處理,比如適合動態(tài)鏈接并能避免超出GOT大小限制之類的錯誤。而Open64僅僅支持不會導(dǎo)致GOT表溢出的PIC編譯。
gcc中的-fpie和-fPIE選項(xiàng)和fpic及fPIC很相似,但不同的是,除了生成為位置無關(guān)代碼外,還能假定代碼是屬于本程序。通常這些選項(xiàng)會和GCC鏈接時的-pie選項(xiàng)一起使用。fPIE選項(xiàng)僅能在編譯可執(zhí)行碼時用,不能用于編譯庫。所以,如果想要PIE的程序,需要你除了在gcc增加-fPIE選項(xiàng)外,還需要在ld時增加-pie選項(xiàng)才能產(chǎn)生這種代碼。即gcc -fpie -pie來編譯程序。單獨(dú)使用哪一個都無法達(dá)到效果。
你可以使用file命令來查看當(dāng)前的可執(zhí)行文件是不是PIE的。
下面是本博編譯helloword的顯示。可以看出,可執(zhí)行文件屬性從executable變成了shared object.
$ gcc? helloworld.c
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ gcc -fpie -pie helloworld.c
$ file a.out
a.out: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
接下來,我們就能實(shí)驗(yàn)了,使用strace命令來查看這兩個a.out執(zhí)行情況了。關(guān)于strace命令,可以參考strace命令介紹
在博主電腦上,有PIE時,執(zhí)行第一個brk(0)系統(tǒng)調(diào)用時,返回的地址一直是變化的。而無PIE時,brk(O)系統(tǒng)調(diào)用返回地址一直不變。內(nèi)容太多,不再貼出。
注:
linux系統(tǒng)調(diào)用brk():
linux系統(tǒng)內(nèi)部分配內(nèi)存的系統(tǒng)調(diào)用,malloc()其實(shí)也是調(diào)用的brk().直接修改堆的大小,返回新內(nèi)存區(qū)域的結(jié)束地址。
————————————————–
說實(shí)話,還是看的不是很懂,似懂非懂的感覺。
總結(jié)
以上是生活随笔為你收集整理的arm linux gcc fpic,【待整理】Gcc中编译和链接选项 -fpic -fPIC -fpie -fPIE -pie的含义的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux调用qt生成静态库文件下载,C
- 下一篇: linux不能到达网关,linux –