4.10. Expressions in Linker Scripts

The syntax for expressions in the linker script language is identical to that of C expressions. All expressions are evaluated as integers. All expressions are evaluated in the same size, which is 32 bits if both the host and target are 32 bits, and is otherwise 64 bits.

You can use and set symbol values in expressions.

The linker defines several special purpose builtin functions for use in expressions.

4.10.1. Constants

All constants are integers.

As in C, the linker considers an integer beginning with 0 to be octal, and an integer beginning with 0x or 0X to be hexadecimal. The linker considers other integers to be decimal.

In addition, you can use the suffixes K and M to scale a constant by 1024 or 1024*1024 respectively. For example, the following all refer to the same quantity:
_fourk_1 = 4K;
_fourk_2 = 4096;
_fourk_3 = 0x1000;

4.10.2. Symbol Names

Unless quoted, symbol names start with a letter, underscore, or period and may include letters, digits, underscores, periods, and hyphens. Unquoted symbol names must not conflict with any keywords. You can specify a symbol which contains odd characters or has the same name as a keyword by surrounding the symbol name in double quotes:
"SECTION" = 9;
"with a space" = "also with a space" + 10;

Since symbols can contain many non-alphabetic characters, it is safest to delimit symbols with spaces. For example, A-B is one symbol, whereas A - B is an expression involving subtraction.

4.10.3. The Location Counter

The special linker variable dot . always contains the current output location counter. Since the . always refers to a location in an output section, it may only appear in an expression within a SECTIONS command. The . symbol may appear anywhere that an ordinary symbol is allowed in an expression.

Assigning a value to . will cause the location counter to be moved. This may be used to create holes in the output section. The location counter may never be moved backwards.

  output :
      . = . + 1000;
      . += 1000;
    } = 0x12345678;

In the previous example, the .text section from file1 is located at the beginning of the output section output. It is followed by a 1000 byte gap. Then the .text section from file2 appears, also with a 1000 byte gap following before the .text section from file3. The notation = 0x12345678 specifies what data to write in the gaps (refer to Section Output Section Fill).

Note: . actually refers to the byte offset from the start of the current containing object. Normally this is the SECTIONS statement, whose start address is 0, hence . can be used as an absolute address. If . is used inside a section description however, it refers to the byte offset from the start of that section, not an absolute address. Thus in a script like this:

    . = 0x100
    .text: {
      . = 0x200
    . = 0x500
    .data: {
      . += 0x600

The .text section will be assigned a starting address of 0x100 and a size of exactly 0x200 bytes, even if there is not enough data in the .text input sections to fill this area. (If there is too much data, an error will be produced because this would be an attempt to move . backwards). The .data section will start at 0x500 and it will have an extra 0x600 bytes worth of space after the end of the values from the .data input sections and before the end of the .data output section itself.

4.10.4. Operators

The linker recognizes the standard C set of arithmetic operators, with the standard bindings and precedence levels:
precedence      associativity   Operators                Notes
1               left            !  -  ~                  (1)
2               left            *  /  %
3               left            +  -
4               left            >>  <<
5               left            ==  !=  >  <  <=  >=
6               left            &
7               left            |
8               left            &&
9               left            ||
10              right           ? :
11              right           &=  +=  -=  *=  /=       (2)
Notes: (1) Prefix operators (2) Refer to Section 4.5 Assigning Values to Symbols.

4.10.5. Evaluation

The linker evaluates expressions lazily. It only computes the value of an expression when absolutely necessary.

The linker needs some information, such as the value of the start address of the first section, and the origins and lengths of memory regions, in order to do any linking at all. These values are computed as soon as possible when the linker reads in the linker script.

However, other values (such as symbol values) are not known or needed until after storage allocation. Such values are evaluated later, when other information (such as the sizes of output sections) is available for use in the symbol assignment expression.

The sizes of sections cannot be known until after allocation, so assignments dependent upon these are not performed until after allocation.

Some expressions, such as those depending upon the location counter ., must be evaluated during section allocation.

If the result of an expression is required, but the value is not available, then an error results. For example, a script like the following
    .text 9+this_isnt_constant :
      { *(.text) }

will cause the error message non constant expression for initial address.

4.10.6. The Section of an Expression

When the linker evaluates an expression, the result is either absolute or relative to some section. A relative expression is expressed as a fixed offset from the base of a section.

The position of the expression within the linker script determines whether it is absolute or relative. An expression which appears within an output section definition is relative to the base of the output section. An expression which appears elsewhere will be absolute.

A symbol set to a relative expression will be relocatable if you request relocatable output using the -r option. That means that a further link operation may change the value of the symbol. The symbol's section will be the section of the relative expression.

A symbol set to an absolute expression will retain the same value through any further link operation. The symbol will be absolute, and will not have any particular associated section.

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:
    .data : { *(.data) _edata = ABSOLUTE(.); }

If ABSOLUTE were not used, _edata would be relative to the .data section.

4.10.7. Builtin Functions

The linker script language includes a number of builtin functions for use in linker script expressions.


Return the absolute (non-relocatable, as opposed to non-negative) value of the expression exp. Primarily useful to assign an absolute value to a symbol within a section definition, where symbol values are normally section relative. Refer to Section 4.10.6 The Section of an Expression.


Return the absolute address (the VMA) of the named section. Your script must previously have defined the location of that section. In the following example, symbol_1 and symbol_2 are assigned identical values:

  .output1 :
    start_of_output_1 = ABSOLUTE(.);
  .output :
    symbol_1 = ADDR(.output1);
    symbol_2 = start_of_output_1;
… }

Return the location counter (.) aligned to the next exp boundary. ALIGN doesn't change the value of the location counter--it just does arithmetic on it. Here is an example which aligns the output .data section to the next 0x2000 byte boundary after the preceding section and sets a variable within the section to the next 0x8000 boundary after the input sections:

  .data ALIGN(0x2000): {
    variable = ALIGN(0x8000);
… }

The first use of ALIGN in this example specifies the location of a section because it is used as the optional address attribute of a section definition (refer to Section 4.6.3 Output Section Description). The second use of ALIGN is used to defines the value of a symbol.

The builtin function NEXT is closely related to ALIGN.


This is a synonym for ALIGN, for compatibility with older linker scripts. It is most often seen when setting the address of an output section.

DATA_SEGMENT_ALIGN(maxpagesize, commonpagesize)

This is equivalent to either

(ALIGN(maxpagesize) + (. & (maxpagesize - 1)))


(ALIGN(maxpagesize) + (. & (maxpagesize - commonpagesize)))

depending on whether the latter uses fewer commonpagesize sized pages for the data segment (area between the result of this expression and DATA_SEGMENT_END) than the former or not. If the latter form is used, it means commonpagesize bytes of runtime memory will be saved at the expense of up to commonpagesize wasted bytes in the on-disk file.

This expression can only be used directly in SECTIONS commands, not in any output section descriptions and only once in the linker script. commonpagesize should be less or equal to maxpagesize and should be the system page size the object wants to be optimized for (while still working on system page sizes up to maxpagesize).


  . = DATA_SEGMENT_ALIGN(0x10000, 0x2000);

This defines the end of data segment for DATA_SEGMENT_ALIGN evaluation purposes.


Return 1 if symbol is in the linker global symbol table and is defined, otherwise return 0. You can use this function to provide default values for symbols. For example, the following script fragment shows how to set a global symbol begin to the first location in the .text section--but if a symbol called begin already existed, its value is preserved:

  .text : {
    begin = DEFINED(begin) ? begin : . ;

Return the absolute LMA of the named section. This is normally the same as ADDR, but it may be different if the AT attribute is used in the output section definition (refer to Section Output Section LMA).

MAX(exp1, exp2)

Returns the maximum of exp1 and exp2.

MIN(exp1, exp2)

Returns the minimum of exp1 and exp2.


Return the next unallocated address that is a multiple of exp. This function is closely related to ALIGN(exp); unless you use the MEMORY command to define discontinuous memory for the output file, the two functions are equivalent.


Return the size in bytes of the named section, if that section has been allocated. If the section has not been allocated when this is evaluated, the linker will report an error. In the following example, symbol_1 and symbol_2 are assigned identical values:

  .output {
    .start = . ;
    .end = . ;
  symbol_1 = .end - .start ;
  symbol_2 = SIZEOF(.output);
… }
SIZEOF_HEADERS, sizeof_headers

Return the size in bytes of the output file's headers. This is information which appears at the start of the output file. You can use this number when setting the start address of the first section, if you choose, to facilitate paging.

When producing an ELF output file, if the linker script uses the SIZEOF_HEADERS builtin function, the linker must compute the number of program headers before it has determined all the section addresses and sizes. If the linker later discovers that it needs additional program headers, it will report an error not enough room for program headers. To avoid this error, you must avoid using the SIZEOF_HEADERS function, or you must rework your linker script to avoid forcing the linker to use additional program headers, or you must define the program headers yourself using the PHDRS command (refer to Section 4.8 PHDRS Command).