From Fedora Project Wiki
No edit summary
No edit summary
Line 5: Line 5:
'''MUST''': Packages that install static library archives (.a files) must do exactly one of:
'''MUST''': Packages that install static library archives (.a files) must do exactly one of:
* build them as PIC objects
* build them as PIC objects
* document why the static libraries are not built PIC
* document why the static libraries are not built PIC AND receive explicit approval from [http://fedoraproject.org/wiki/Fedora_Engineering_Steering_Committee FESCo].
* build both PIC and non-PIC libraries, with a .pc file for each for dependent packages to use
* build both PIC and non-PIC libraries, with a .pc file for each for dependent packages to use
== Definitions ==
=== PIC ===
In computing, 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 compiled 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. While some systems only run PIC executables, there are other reasons they are used. 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 a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks.


== Rationale ==
== 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.
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.


Line 20: Line 27:
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.
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.
In any case, non-PIC static libraries need explicit approval from [http://fedoraproject.org/wiki/Fedora_Engineering_Steering_Committee FESCo].


Packages that install non-PIC static libraries should be explicitly listed in the wiki somewhere.
Packages that install non-PIC static libraries should be explicitly listed in the wiki somewhere.
Line 30: Line 37:
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.
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.


TODO: Add pc file templates for static and static-nonpic.
== Templates for packaging PIC and non-PIC static libraries ==
 
=== PIC static library ===
 
The library must be renamed to <code>libfoo-pic.a</code>, where <code>libfoo.a</code> is the original name.
 
Here is a template for the necessary libfoo-pic.pc file:
 
<pre>
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
</pre>
 
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 <code>libfoo-nonpic.a</code>, where <code>libfoo.a</code> is the original name.
 
Here is a template for the necessary libfoo-nonpic.pc file:
 
<pre>
prefix=/usr
exec_prefix=/usr
libdir=/usr/lib64
includedir=/usr/include


== Open Issues ==
Name: foo
Description: Does foo type operations
Version: 1.0.0
Requires: xproto
Cflags: -I${includedir}
Libs: -L${libdir} -lfoo
Libs.private: -lfoo-nonpic
</pre>


* Add howto info for common build systems to build static libraries PIC.
Be sure to adjust the variables appropriately, depending on the architecture target (e.g. libdir=).
* Need a little more info for reviewers to be able to apply the Guidelines. Simple definition of PIC and PIE, for instance.
* Can we finish off the TODO in Documentation?


[[Category:Packaging guidelines drafts ]]
[[Category:Packaging guidelines drafts ]]

Revision as of 13:40, 10 May 2010

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

Definitions

PIC

In computing, 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 compiled 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. While some systems only run PIC executables, there are other reasons they are used. 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 a security attack using exploits that rely 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.

Templates for packaging PIC and non-PIC static libraries

PIC static library

The library must be renamed to libfoo-pic.a, where libfoo.a 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 libfoo-nonpic.a, where libfoo.a 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=).