PIE is to support address space layout randomization (ASLR) in executable files.
Before the PIE mode was created, the program's executable could not be placed at a random address in memory, only position independent code (PIC) dynamic libraries could be relocated to a random offset. It works very much like what PIC does for dynamic libraries, the difference is that a Procedure Linkage Table (PLT) is not created, instead PC-relative relocation is used.
After enabling PIE support in gcc/linkers, the body of program is compiled and linked as position-independent code. A dynamic linker does full relocation processing on the program module, just like dynamic libraries. Any usage of global data is converted to access via the Global Offsets Table (GOT) and GOT relocations are added.
PIE is well described in this OpenBSD PIE presentation.
Changes to functions are shown in this slide (PIE vs PIC).
x86 pic vs pie
Local global variables and functions are optimized in pie
External global variables and functions are same as pic
and in this slide (PIE vs old-style linking)
x86 pie vs no-flags (fixed)
Local global variables and functions are similar to fixed
External global variables and functions are same as pic
Note, that PIE may be incompatible with -static
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…