Addresses and symbols may be section relative, or absolute. A section relative symbol is relocatable. If you request relocatable output using the ‘-r’ option, a further link operation may change the value of a section relative symbol. On the other hand, an absolute symbol will retain the same value throughout any further link operations.
Some terms in linker expressions are addresses. This is true of
section relative symbols and for builtin functions that return an
address, such as ADDR
, LOADADDR
, ORIGIN
and
SEGMENT_START
. Other terms are simply numbers, or are builtin
functions that return a non-address value, such as LENGTH
.
One complication is that unless you set LD_FEATURE ("SANE_EXPR")
(see Other Linker Script Commands), numbers and absolute symbols are treated
differently depending on their location, for compatibility with older
versions of ld
. Expressions appearing outside an output
section definition treat all numbers as absolute addresses.
Expressions appearing inside an output section definition treat
absolute symbols as numbers. If LD_FEATURE ("SANE_EXPR")
is
given, then absolute symbols and numbers are simply treated as numbers
everywhere.
In the following simple example,
SECTIONS { . = 0x100; __executable_start = 0x100; .data : { . = 0x10; __data_start = 0x10; *(.data) } … }
both .
and __executable_start
are set to the absolute
address 0x100 in the first two assignments, then both .
and
__data_start
are set to 0x10 relative to the .data
section in the second two assignments.
For expressions involving numbers, relative addresses and absolute addresses, ld follows these rules to evaluate terms:
The result section of each sub-expression is as follows:
LD_FEATURE ("SANE_EXPR")
or inside an output section definition
but an absolute address otherwise.
You can use the builtin function ABSOLUTE
to force an expression
to be absolute when it would otherwise be relative. For example, to
create an absolute symbol set to the address of the end of the output
section ‘.data’:
SECTIONS { .data : { *(.data) _edata = ABSOLUTE(.); } }
If ‘ABSOLUTE’ were not used, ‘_edata’ would be relative to the ‘.data’ section.
Using LOADADDR
also forces an expression absolute, since this
particular builtin function returns an absolute address.