Location Counter - Untitled
Description: Untitled

Next: Operators, Previous: Orphan Sections, Up: Expressions

#### 3.10.5 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 not be moved backwards inside an output section, and may not be moved backwards outside of an output section if so doing creates areas with overlapping LMAs.

         SECTIONS
         {
           output :
             {
               file1(.text)
               . = . + 1000;
               file2(.text)
               . += 1000;
               file3(.text)
             } = 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 (see 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:

         SECTIONS
         {
             . = 0x100
             .text: {
               *(.text)
               . = 0x200
             }
             . = 0x500
             .data: {
               *(.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.

Setting symbols to the value of the location counter outside of an output section statement can result in unexpected values if the linker needs to place orphan sections. For example, given the following:

         SECTIONS
         {
             start_of_text = . ;
             .text: { *(.text) }
             end_of_text = . ;

             start_of_data = . ;
             .data: { *(.data) }
             end_of_data = . ;
         }

If the linker needs to place some input section, e.g. `.rodata`, not mentioned in the script, it might choose to place that section between `.text` and `.data`. You might think the linker should place `.rodata` on the blank line in the above script, but blank lines are of no particular significance to the linker. As well, the linker doesn't associate the above symbol names with their sections. Instead, it assumes that all assignments or other statements belong to the previous output section, except for the special case of an assignment to `.`. I.e., the linker will place the orphan `.rodata` section as if the script was written as follows:

         SECTIONS
         {
             start_of_text = . ;
             .text: { *(.text) }
             end_of_text = . ;

             start_of_data = . ;
             .rodata: { *(.rodata) }
             .data: { *(.data) }
             end_of_data = . ;
         }

This may or may not be the script author's intention for the value of `start_of_data`. One way to influence the orphan section placement is to assign the location counter to itself, as the linker assumes that an assignment to `.` is setting the start address of a following output section and thus should be grouped with that section. So you could write:

         SECTIONS
         {
             start_of_text = . ;
             .text: { *(.text) }
             end_of_text = . ;

             . = . ;
             start_of_data = . ;
             .data: { *(.data) }
             end_of_data = . ;
         }

Now, the orphan `.rodata` section will be placed between `end_of_text` and `start_of_data`.