7.7. Symbolic Relocations

The assembler treats each section as if it began at address 0. Of course, all sections cannot actually begin at address 0 in memory, so the linker must relocate sections. Relocations are symbol-relative rather than section-relative.

The linker can relocate sections by:

  • Allocating them into the memory map so that they begin at the appropriate address as defined with the linker’s MEMORY directive

  • Adjusting symbol values to correspond to the new section addresses

  • Adjusting references to relocated symbols to reflect the adjusted symbol values

The linker uses relocation entries to adjust references to symbol values. The assembler creates a relocation entry each time a relocatable symbol is referenced. The linker then uses these entries to patch the references after the symbols are relocated. The following example contains a code fragment for an Arm device for which the assembler generates relocation entries.

Example: Code That Generates Relocation Entries

 1                    *********************************************
 2                    **      Generating Relocation Entries      **
 3                    *********************************************
 4                            .ref X
 5                            .def Y
 6 00000000                   .text
 7 00000000 E0921003          ADDS   R1, R2, R3
 8 00000004 0A000001          BEQ    Y
 9 00000008 E1C410BE          STRH   R1, [R4, #14]
10 0000000c EAFFFFFB!         B      X   ; generates a relocation entry
11 00000010 E0821003  Y:      ADD    R1, R2, R3

In this example, both symbols X and Y are relocatable. Y is defined in the .text section of this module; X is defined in another module. When the code is assembled, X has a value of 0 (the assembler assumes all undefined external symbols have values of 0), and Y has a value of 16 (relative to address 0 in the .text section). The assembler generates two relocation entries: one for X and one for Y. The reference to X is an external reference (indicated by the ! character in the listing). The reference to Y is to an internally defined relocatable symbol (indicated by the character in the listing).

After the code is linked, suppose that X is relocated to address 0x10014. Suppose also that the .text section is relocated to begin at address 0x10000; Y now has a relocated value of 0x10010. The linker uses the relocation entry for the reference to X to patch the branch instruction in the object code:

EAFFFFFB!   B     X

becomes

EA000000