Note: This document assumes general familiarity with object files, executables, and the concept of a linker
The GNU linker (ld
) is an incredibly powerful tool that you can generally avoid messing with. Sometimes you do need to intervene and manually describe the link, this document acts as a quick, but not exhasutive, reference for those situations.
- Linker scripts describe the memory layout and the mapping of input sections to an executable
- Every link is described by a linker script
- If you don't explicitly write one, a default script will be used
- Linker scripts are a series of commands written in "Linker Command Language"
- Linker Command Langauge is compact, weird, and C-like
- Comments are written like C block comments (
/* Comment Here */
) - Semicolons are ignored after commands but required after expressions
- Syntax:
symbol = expression;
- After definition, you can use C-like assignment operators:
+=
,-=
,*=
,/=
,<<=
,>>=
,&=
, and|=
- After definition, you can use C-like assignment operators:
- Expression syntax is just like C
- This includes the ternary if (
expression ? if_nonzero : if_zero
)
- This includes the ternary if (
- Constants are assumed to be 32 or 64 bits and can be prefixed with
0x
(hex) and0
(octal) - ❗ User defined symbols are visible to the programs being linked ❗
- The most important, and only required command in a linker script
SECTIONS
describes the mapping of input sections to output sections in the executable- Syntax:
SECTIONS { /* * Populated with one or more of any of the following: * - Output section description * - Symbol assignment * - ENTRY command * - Overlay description [not covered] */ ... }
- The magic symbol
.
is defined inside of aSECTIONS
command to mean the current output location counter- Assigning to this symbol moves where the next input section will be linked
- Syntax:
/* * Output Section Description Parameters: * - section_name : required, the name of the output section (ex: .text, .data, ...) * - [address] : optional, the VMA (Virtual Memory Address) of the section * - [(type)] : optional, if "NOLOAD" the section won't be loaded into memory * - [AT(lma)] : optional, the LMA (Load Memory Address) where the section will be loaded * into memory. It's up to you to copy this data from the LMA to the VMA at runtime * - [>region] : optional, assigns the section to a region of memory (MEMORY command) * - [:phdr ...] : optional, assigns the section to a program segment (PHDRS command [not covered]) * - [=fillexp] : optional, sets fill pattern for the etnire section */ section_name [address] [(type)] : [AT(lma)] { /* * Populated with one or more of any of the following: * - Input section description * - Literal values * - Symbol assignment * - Output section keywords [not covered] */ ... } [>region] [:phdr ...] [=fillexp]
- The section name
'/DISCARD/'
is magic and will discard any input sections in it
- Directs the linker on which sections to include
- Syntax:
filename(.section_name ...)
- Will include
.section_name
fromfilename
- The filename and section name can contain unix-style patterns:
*
,?
,[char set]
- ex:
*(.text)
includes the.text
section from all linked files
- Will include
- The linker will link sections to the first matching pattern and won't repeat any sections
- The following functions can be used to include literal values in an output section:
Function Size (bytes) BYTE(expression)
1 SHORT(expression)
2 LONG(expression)
4 QUAD(expression)
8
- Sets the entry point of the code, can be overrided with the
-e
command line flag - Syntax:
ENTRY(symbol)
- If not used, will default to the magic symbol
start
if defined, otherwise the first byte of.text
- Optional, if not included the linker will assume all memory is usable
- Syntax:
MEMORY { /* * One or more memory descriptions (format following): * region_name : ORIGIN = literal_constant, LENGTH = literal_constant */ ... }
- Regions defined in the
MEMORY
command can be used in theSECTIONS
command
ADDR(section)
: Returns the VMA ofsection
ALIGN(expression)
: Returns the location counter (.
) aligned to the nextexpression
byte boundaryDEFINED(symbol)
: Returns 1 if the symbol is definedLOADADDR(section)
: Returns the LMA ofsection
MAX(expression_1, expression_2)
: Returns the max ofexpression_1
andexpression_2
MIN(expression_1, expression_2)
: Returns the min ofexpression_1
andexpression_2
SIZEOF(section)
: Returns the size ofsection
in bytes
INCLUDE filename
: Includes the linker scriptfilename
in this linker script- Can be nested up to 10 levels
INPUT(filename, ....)
: Includesfilename
in the linkOUTPUT(filename)
: Names the output fileSTARTUP(filename)
: Specifiesfilename
as the first file linkedASSERT(expression, message)
: Assertsexpression != 0
PROVIDE(symbol = expression)
: Definessymbol
only if it is referenced and not defined by the code being linked