33.2. Expressions

Many useful commands involve arithmetic expressions. The syntax for expressions in the command language is identical to that of C expressions, with the following features:

33.2.1. Integers

An octal integer is “0” followed by zero or more of the octal digits (“01234567”).

_as_octal = 0157255;

A decimal integer starts with a non-zero digit followed by zero or more digits (“0123456789”).

_as_decimal = 57005;

A hexadecimal integer is “0x” or “0X” followed by one or more hexadecimal digits chosen from “0123456789abcdefABCDEF”.

_as_hex = 0xdead;

To write a negative integer, use the prefix operator “-” (see Section 33.2.4.).

_as_neg = -57005;

Additionally the suffixes K and M may be used to scale a constant by respectively. For example, the following all refer to the same quantity:

        _fourk_1 = 4K;
        _fourk_2 = 4096;
        _fourk_3 = 0x1000;

33.2.2. Symbol Names

Unless quoted, symbol names start with a letter, underscore, or point and may include any letters, underscores, digits, points, and hyphens. Unquoted symbol names must not conflict with any keywords. You can specify a symbol that 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.

33.2.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 must always appear in an expression within a SECTIONS command. The . symbol may appear anywhere that an ordinary symbol is allowed in an expression, but its assignments have a side effect. Assigning a value to the . symbol 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.

SECTIONS
{
  output :
  {
  file1(.text)
  . = . + 1000;
  file2(.text)
  . += 1000;
  file3(.text)
  } = 0x1234;
}

In the previous example, file1 is located at the beginning of the output section, then there is a 1000 byte gap. Then file2 appears, also with a 1000 byte gap following before file3 is loaded. The notation “= 0x1234” specifies what data to write in the gaps (see Section 33.4.4.).

33.2.4. Operators

The linker recognizes the standard C set of arithmetic operators, with the standard bindings and precedence levels:

     precedence      associativity   Operators                Notes
     (highest)
     1               left            !  -  ~                  (1)
     2               left            *  /  %
     3               left            +  -
     4               left            >>  <<
     5               left            ==  !=  >  <  <=  >=
     6               left            &
     7               left            |
     8               left            &&
     9               left            ||
     10              right           ? :
     11              right           &=  +=  -=  *=  /=       (2)
     (lowest)
   Notes: (1) Prefix operators (2) See Section 33.2.6.

33.2.5. Evaluation

The linker uses lazy evaluation for expressions; it only calculates an expression when absolutely necessary. The linker needs the value of the start address, and the 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 command file. 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.

33.2.6. Assignment: Defining Symbols

You may create global symbols, and assign values (addresses) to global symbols, using any of the C assignment operators:

symbol = expression ;
symbol &= expression ;
symbol += expression ;
symbol -= expression ;
symbol *= expression ;
symbol /= expression ;

Two things distinguish assignment from other operators in linker expressions.

Assignment statements may appear:

The first two cases are equivalent in effect — both define a symbol with an absolute address. The last case defines a symbol whose address is relative to a particular section (see Section 33.4.).

When a linker expression is evaluated and assigned to a variable, it is given either an absolute or a relocatable type. An absolute expression type is one in which the symbol contains the value that it will have in the output file; a relocatable expression type is one in which the value is expressed as a fixed offset from the base of a section.

The type of the expression is controlled by its position in the script file. A symbol assigned within a section definition is created relative to the base of the section; a symbol assigned in any other place is created as an absolute symbol. Since a symbol created within a section definition is relative to the base of the section, it will remain relocatable if relocatable output is requested. A symbol may be created with an absolute value even when assigned to within a section definition by using the absolute assignment function ABSOLUTE. For example, to create an absolute symbol whose address is the last byte of an output section named .data:

SECTIONS{ ...
  .data :
    {
      *(.data)
      _edata = ABSOLUTE(.) ;
    }
... }

The linker tries to put off the evaluation of an assignment until all the terms in the source expression are known (see Section 33.2.5.). For instance, 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 dot, “.” must be evaluated during 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

SECTIONS { ...
  text 9+this_isnt_constant :
    { ...
    }
... }

will cause the error message “Non constant expression for initial address”.

In some cases, it is desirable for a linker script to define a symbol only if it is referenced, and only if it is not defined by any object included in the link. For example, traditional linkers defined the symbol “etext”. However, ANSI C requires that the user be able to use “etext” as a function name without encountering an error. The PROVIDE keyword may be used to define a symbol, such as “etext”, only if it is referenced but not defined. The syntax is PROVIDE(symbol = expression).

33.2.7. Arithmetic Functions

The command language includes a number of built-in functions for use in link script expressions.

ABSOLUTE(exp)

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.

ADDR(section)

Return the absolute address 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:

SECTIONS{ ...
  .output1 :
    {
    start_of_output_1 = ABSOLUTE(.);
    ...
    }
  .output :
    {
    symbol_1 = ADDR(.output1);
    symbol_2 = start_of_output_1;
    }
... }
LOADADDR(section)

Return the absolute load address of the named section. This is normally the same as ADDR, but it may be different if the AT keyword is used in the section definition (see Section 33.4.4.).

ALIGN(exp)

Return the result of the current location counter (.) aligned to the next exp boundary. exp must be an expression whose value is a power of two. This is equivalent to

(. + exp - 1) & ~(exp - 1)

ALIGN doesn't change the value of the location counter — it just does arithmetic on it. As an example, to align the output .data section to the next 0x2000 byte boundary after the preceding section and to set a variable within the section to the next 0x8000 boundary after the input sections:

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

The first use of ALIGN in this example specifies the location of a section because it is used as the optional start attribute of a section definition (see Section 33.4.4.). The second use simply defines the value of a variable.

The built-in NEXT is closely related to ALIGN.

DEFINED(symbol)

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 command-file 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:

SECTIONS{ ...
  .text : {
    begin = DEFINED(begin) ? begin : . ;
    ...
  }
... }
NEXT(exp)

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.

SIZEOF(section)

Return the size in bytes of the named section, if that section has been allocated. In the following example, symbol_1 and symbol_2 are assigned identical values:

SECTIONS{ ...
  .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. You can use this number as the start address of the first section, if you choose, to facilitate paging.

MAX(exp1, exp2)

Returns the maximum of exp1 and exp2.

MIN(exp1, exp2)

Returns the minimum of exp1 and exp2.

33.2.8. Semicolons

Semicolons (;) are required in the following places. In all other places they can appear for aesthetic reasons but are otherwise ignored.

Assignment

Semicolons must appear at the end of assignment expressions. See Section 33.2.6.