ld: Location Counter

1 
1 3.10.5 The Location Counter
1 ---------------------------
1 
1 The special linker variable "dot" '.' always contains the current output
1 location counter.  Since the '.' always refers to a location in an
1 output section, it may only appear in an expression within a 'SECTIONS'
1 command.  The '.' symbol may appear anywhere that an ordinary symbol is
1 allowed in an expression.
1 
1    Assigning a value to '.' will cause the location counter to be moved.
1 This may be used to create holes in the output section.  The location
1 counter may not be moved backwards inside an output section, and may not
1 be moved backwards outside of an output section if so doing creates
1 areas with overlapping LMAs.
1 
1      SECTIONS
1      {
1        output :
1          {
1            file1(.text)
1            . = . + 1000;
1            file2(.text)
1            . += 1000;
1            file3(.text)
1          } = 0x12345678;
1      }
1 In the previous example, the '.text' section from 'file1' is located at
1 the beginning of the output section 'output'.  It is followed by a 1000
1 byte gap.  Then the '.text' section from 'file2' appears, also with a
1 1000 byte gap following before the '.text' section from 'file3'.  The
11 notation '= 0x12345678' specifies what data to write in the gaps (⇒
 Output Section Fill).
1 
1    Note: '.' actually refers to the byte offset from the start of the
1 current containing object.  Normally this is the 'SECTIONS' statement,
1 whose start address is 0, hence '.' can be used as an absolute address.
1 If '.' is used inside a section description however, it refers to the
1 byte offset from the start of that section, not an absolute address.
1 Thus in a script like this:
1 
1      SECTIONS
1      {
1          . = 0x100
1          .text: {
1            *(.text)
1            . = 0x200
1          }
1          . = 0x500
1          .data: {
1            *(.data)
1            . += 0x600
1          }
1      }
1 
1    The '.text' section will be assigned a starting address of 0x100 and
1 a size of exactly 0x200 bytes, even if there is not enough data in the
1 '.text' input sections to fill this area.  (If there is too much data,
1 an error will be produced because this would be an attempt to move '.'
1 backwards).  The '.data' section will start at 0x500 and it will have an
1 extra 0x600 bytes worth of space after the end of the values from the
1 '.data' input sections and before the end of the '.data' output section
1 itself.
1 
1    Setting symbols to the value of the location counter outside of an
1 output section statement can result in unexpected values if the linker
1 needs to place orphan sections.  For example, given the following:
1 
1      SECTIONS
1      {
1          start_of_text = . ;
1          .text: { *(.text) }
1          end_of_text = . ;
1 
1          start_of_data = . ;
1          .data: { *(.data) }
1          end_of_data = . ;
1      }
1 
1    If the linker needs to place some input section, e.g.  '.rodata', not
1 mentioned in the script, it might choose to place that section between
1 '.text' and '.data'.  You might think the linker should place '.rodata'
1 on the blank line in the above script, but blank lines are of no
1 particular significance to the linker.  As well, the linker doesn't
1 associate the above symbol names with their sections.  Instead, it
1 assumes that all assignments or other statements belong to the previous
1 output section, except for the special case of an assignment to '.'.
1 I.e., the linker will place the orphan '.rodata' section as if the
1 script was written as follows:
1 
1      SECTIONS
1      {
1          start_of_text = . ;
1          .text: { *(.text) }
1          end_of_text = . ;
1 
1          start_of_data = . ;
1          .rodata: { *(.rodata) }
1          .data: { *(.data) }
1          end_of_data = . ;
1      }
1 
1    This may or may not be the script author's intention for the value of
1 'start_of_data'.  One way to influence the orphan section placement is
1 to assign the location counter to itself, as the linker assumes that an
1 assignment to '.' is setting the start address of a following output
1 section and thus should be grouped with that section.  So you could
1 write:
1 
1      SECTIONS
1      {
1          start_of_text = . ;
1          .text: { *(.text) }
1          end_of_text = . ;
1 
1          . = . ;
1          start_of_data = . ;
1          .data: { *(.data) }
1          end_of_data = . ;
1      }
1 
1    Now, the orphan '.rodata' section will be placed between
1 'end_of_text' and 'start_of_data'.
1