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 a 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:
|
becomes |
|