#### 3.10.8 The Section of an Expression

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 Miscellaneous 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:

- Unary operations on an absolute address or number, and binary operations on two absolute addresses or two numbers, or between one absolute address and a number, apply the operator to the value(s).
- Unary operations on a relative address, and binary operations on two relative addresses in the same section or between one relative address and a number, apply the operator to the offset part of the address(es).
- Other binary operations, that is, between two relative addresses not in the same section, or between a relative address and an absolute address, first convert any non-absolute term to an absolute address before applying the operator.

The result section of each sub-expression is as follows:

- An operation involving only numbers results in a number.
- The result of comparisons, ‘`&&`’ and ‘`||`’ is also a number.
- The result of other binary arithmetic and logical operations on two relative addresses in the same section or two absolute addresses (after above conversions) is also a number when `LD_FEATURE ("SANE_EXPR")` or inside an output section definition but an absolute address otherwise.
- The result of other operations on relative addresses or one relative address and a number, is a relative address in the same section as the relative operand(s).
- The result of other operations on absolute addresses (after above conversions) is an absolute address.

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.