User:Ajax/Static Library PICness Guidelines

= Packaging Static Libraries =

Summary
MUST: Packages that install static library archives (.a files) must do exactly one of:
 * build them as PIC objects
 * document why the static libraries are not built PIC AND receive explicit approval from FESCo.
 * build both PIC and non-PIC libraries, with a .pc file for each for dependent packages to use

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.

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 they are included in.

Exceptions
Non-PIE applications may legitimately include non-PIC code with no performance penalty. If a static library is only included in non-PIE applications, it need not be built PIC. This case is expected to be rare, limited mostly to numeric computation libraries like atlas or fftw where performance is critical.

In any case, non-PIC static libraries need explicit approval from FESCo.

Packages that install non-PIC static libraries should be explicitly listed in the wiki somewhere.

Documentation
Typically all that's needed to build a library PIC is to add -fPIC to CFLAGS. If a library contains assembly code, adding -fPIC won't make the assembly magically become PIC; code changes will be necessary in this case.

Autotools-based projects can usually disable static library creation by configuring with --disable-static, and can force PIC static libraries by configuring with --with-pic.

PIC static library
The library must be renamed to, where   is the original name.

Here is a template for the necessary libfoo-pic.pc file:

prefix=/usr exec_prefix=/usr libdir=/usr/lib64 includedir=/usr/include

Name: foo Description: Does foo type operations Version: 1.0.0 Requires: xproto Cflags: -I${includedir} Libs: -L${libdir} -lfoo Libs.private: -lfoo-pic

Be sure to adjust the variables appropriately, depending on the architecture target (e.g. libdir=).

non-PIC static library
The library must be renamed to, where   is the original name.

Here is a template for the necessary libfoo-nonpic.pc file:

prefix=/usr exec_prefix=/usr libdir=/usr/lib64 includedir=/usr/include

Name: foo Description: Does foo type operations Version: 1.0.0 Requires: xproto Cflags: -I${includedir} Libs: -L${libdir} -lfoo Libs.private: -lfoo-nonpic

Be sure to adjust the variables appropriately, depending on the architecture target (e.g. libdir=).