User:Tibbs/Text Relocation Guidelines

= Static Library guideline changes =

Summary
Add the following as a new section before Packaging:Guidelines:

Executables and libraries must not have text relocations
Executables and libraries (both dynamic and static) must not contain text relocations. This implies that (GCC-built) binaries must be built with -fPIC and must not contain position-dependent assembler sections.

The eu-findtextrel program, included in the elfutils package, can be run on executables and libraries to locate any text relocations.

A separate document of rationale and further detail on using eu-findtextrel is probably warranted; it can crib liberally from and include examples of eu-findtextrel usage.

PIC
Position-independent code (PIC) is machine instruction code that executes properly regardless of where in memory it resides. PIC is commonly used for shared libraries, so that the same library code can be loaded in a location in each program address space where it won't overlap any other uses of memory (for example, other shared libraries). Position-independent code can be copied to any memory location and executed without modification. This differs from relocatable code, which requires special processing by a link editor or program loader to make it suitable for execution at a given location. Position independent code must adhere to a specific set of semantics in the source code, and compiler support is required. Instructions that refer to specific memory addresses, such as absolute branches, must be replaced with equivalent program counter relative instructions.

PIE
Position-independent executables (PIE) are executable binaries made entirely from position-independent code. PIE binaries are used in Fedora to allow Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during an exploit that relies on knowing the offset of the executable code in the binary, such as return-to-libc attacks.

Text relocation
When code is not position-independent, the binaries must be fixed up at runtime so that the absolute address references are correct after loading. This requires rewriting the the code in memory, takes some time, prevents the memory occupied by the executable from being shared and interferes with selinux protections.

Rationale
Some architectures (including i386, but not including x86_64) permit non-position-independent code. A static library may, through subsequent linking, be included in any of another static library, an application, or a shared library.

On architectures that permit it, non-PIC code comes with a tradeoff. Since the load address is assumed, the compiler has an additional register to use, which can be a - usually small - performance benefit. However, any otherwise relocatable object (shared library or PIE executable) that the non-PIC code is linked into will require text relocations. Text relocations impose a performance penalty on executable startup, and effectively make the code unshareable, thus negating the benefits of making the code into a shared library in the first place.

In general, it is preferable to err on the side of PIC. Text relocations are incompatible with some of the security measures in Fedora, and the performance benefit of actually being able to share your shared library code in memory outweighs any performance benefit from the additional register. Static libraries in particular should be built PIC, since if not their non-PIC-ness effectively poisons any shared libraries in which they are included.