Introduction
A module’s code refers to things it does not contain: functions of the main program, functions of other modules, and its own sections whose address is not known until it is loaded. The words of code and data that hold such an address are left as placeholders, and relocation lists say which words to patch and with what. There is one list for each module the code refers to, and the import table names those modules and where their lists are. The layout follows the Mario Kart Wii wiki “REL (File Format)”, read through a page summary (our words).
The import table
| Offset | Size | Field | Meaning |
|---|---|---|---|
0x0 | 4 | Module id | The module the list’s relocations refer to. 0 is the main program (the DOL); a module’s own id refers to itself. |
0x4 | 4 | List offset | The file offset of that module’s relocation list. |
The header gives the table’s offset and size; the header’s relocation offset is the first list, which is the first import’s offset.
A relocation entry
| Offset | Size | Field | Meaning |
|---|---|---|---|
0x0 | 2 | Offset | The distance from the previous relocation. For the first in a section it is from the start of the section. |
0x2 | 1 | Type | What kind of patch; the table below. |
0x3 | 1 | Section | The section the symbol is in; for type 202, the section the following entries patch. |
0x4 | 4 | Addend | The offset of the symbol inside its section; for a target in the main program, an absolute address. |
A list is read in order and ends with a type 203 entry. The symbol’s address is the load address of its section plus the addend when the target is a module (this one included), and the addend alone when the target is the main program.
Relocation types
| Type | Name | What it does |
|---|---|---|
| 0 | R_PPC_NONE | No operation; the entry is skipped. |
| 1 | R_PPC_ADDR32 | Write the 32-bit address of the symbol. |
| 2 | R_PPC_ADDR24 | Write the address divided by 4, shifted up 2 bits, into a branch’s 24-bit field; fails if it does not fit. |
| 3 | R_PPC_ADDR16 | Write the 16-bit address; fails if it does not fit. |
| 4 | R_PPC_ADDR16_LO | Write the low 16 bits of the address. |
| 5 | R_PPC_ADDR16_HI | Write the high 16 bits of the address. |
| 6 | R_PPC_ADDR16_HA | Write the high 16 bits of the address plus 0x8000, so that an addi or a load that adds the signed low half lands on the address. |
| 7 to 9 | R_PPC_ADDR14 | Write 14 bits of the address divided by 4, shifted up 2 bits, into a conditional branch; fails if it does not fit. The page gives the three types one description. |
| 10 | R_PPC_REL24 | Write the symbol’s address minus the address being patched, divided by 4, shifted up 2 bits, as 24 bits; fails if it does not fit. The ordinary bl to another function. |
| 11 to 13 | R_PPC_REL14 | As REL24 but 14 bits, for a conditional relative branch. One description for the three. |
| 201 | R_DOLPHIN_NOP | No relocation. Its offset is added to the next entry’s offset: used for a gap longer than 0xFFFF bytes. |
| 202 | R_DOLPHIN_SECTION | Switch to patching the section in the entry’s section field, and reset the offset to 0. |
| 203 | R_DOLPHIN_END | The end of the list. |
| 204 | R_DOLPHIN_MRKREF | Unknown; the wiki says Mario Kart Wii does not support it. |
The names 201 to 203 are also given on the page as R_RVL_NONE, R_RVL_SECT and R_RVL_STOP. Types 1 to 13 have the numbers of the
ELF PowerPC relocations of the same names, which is how the test modules were built (an object file’s relocations became the entries).
Not described
Known, not yet covered
- Reference: the individual names of types 8, 9, 12 and 13 (the page gives one description for each range), the behaviour of type 204, what the loader does when a patch does not fit, and the order in which the loader handles several modules.
- Viewer: relocations are noted on the instruction they patch and listed; they are not applied, and a relocation on data (type 1 in a data section) is listed but not noted anywhere in a disassembly.
Links
Reference
- Mario Kart Wii wiki: REL (File Format) – the import table, relocation entries and types