Difference between revisions of "REL (File Format)"
(New research into this format changes a lot of things.) |
m (nameOffset and nameSize are the official field names (verified from the RVL SDK)) |
||
(20 intermediate revisions by 7 users not shown) | |||
Line 17: | Line 17: | ||
| 4 | | 4 | ||
| <code>id</code> | | <code>id</code> | ||
− | | Arbitrary identification number. Must be unique amongst all RELs used by a game. | + | | Arbitrary identification number. Must be unique amongst all RELs used by a game. Must not be 0. |
|- | |- | ||
| 0x04 | | 0x04 | ||
− | | | + | | 4 |
− | | | + | | <code>next</code> |
− | | | + | | Pointer to next module, filled at runtime. |
+ | |- | ||
+ | | 0x08 | ||
+ | | 4 | ||
+ | | <code>prev</code> | ||
+ | | Pointer to previous module, filled at runtime. | ||
|- | |- | ||
| 0x0c | | 0x0c | ||
Line 37: | Line 42: | ||
| 4 | | 4 | ||
| <code>nameOffset</code> | | <code>nameOffset</code> | ||
− | | Offset to ASCII string containing | + | | Offset to the ASCII string containing the path of this module's <code>.plf</code> file. Relative to the start of the <code>.str</code> file. |
|- | |- | ||
| 0x18 | | 0x18 | ||
| 4 | | 4 | ||
| <code>nameSize</code> | | <code>nameSize</code> | ||
− | | | + | | Length of the path of this module's <code>.plf</code> file. |
|- | |- | ||
| 0x1c | | 0x1c | ||
Line 57: | Line 62: | ||
| 4 | | 4 | ||
| <code>relOffset</code> | | <code>relOffset</code> | ||
− | | Offset to the [[#Relocation Data|relocation table]]. | + | | Offset to the first [[#Relocation Data|relocation list]] (same as the first offset in [[#imp|imp table]]). |
|- | |- | ||
| 0x28 | | 0x28 | ||
Line 71: | Line 76: | ||
| 0x30 | | 0x30 | ||
| 1 | | 1 | ||
− | | | + | | <code>prologSection</code> |
| Index into [[#Section Info Table|section table]] which <code>prolog</code> is relative to. Skip if this field is 0. | | Index into [[#Section Info Table|section table]] which <code>prolog</code> is relative to. Skip if this field is 0. | ||
|- | |- | ||
| 0x31 | | 0x31 | ||
| 1 | | 1 | ||
− | | | + | | <code>epilogSection</code> |
| Index into [[#Section Info Table|section table]] which <code>epilog</code> is relative to. Skip if this field is 0. | | Index into [[#Section Info Table|section table]] which <code>epilog</code> is relative to. Skip if this field is 0. | ||
|- | |- | ||
| 0x32 | | 0x32 | ||
| 1 | | 1 | ||
− | | | + | | <code>unresolvedSection</code> |
| Index into [[#Section Info Table|section table]] which <code>unresolved</code> is relative to. Skip if this field is 0. | | Index into [[#Section Info Table|section table]] which <code>unresolved</code> is relative to. Skip if this field is 0. | ||
|- | |- | ||
| 0x33 | | 0x33 | ||
| 1 | | 1 | ||
− | | | + | | <code>bssSection</code> |
− | | | + | | Index into [[#Section Info Table|section table]] which <code>bss</code> is relative to. Filled at runtime! |
|- | |- | ||
| 0x34 | | 0x34 | ||
Line 107: | Line 112: | ||
| 4 | | 4 | ||
| <code>align</code> | | <code>align</code> | ||
− | | Version ≥ 2 only. Alignment constraint | + | | Version ≥ 2 only. Alignment constraint of the load address of the REL, expressed as power of 2. |
|- | |- | ||
| 0x44 | | 0x44 | ||
Line 117: | Line 122: | ||
| 4 | | 4 | ||
| <code>fixSize</code> | | <code>fixSize</code> | ||
− | + | | Version ≥ 3 only. If REL is linked with OSLinkFixed (instead of OSLink), the space after this address can be used for other purposes (like BSS). | |
|- | |- | ||
| 0x4c or 0x48 or 0x40 | | 0x4c or 0x48 or 0x40 | ||
Line 134: | Line 139: | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | 4 |
− | | Offset from the beginning of the REL to the section. If this is zero, the section is an uninitialized section (i.e. <code>.bss</code>). | + | | Offset from the beginning of the REL to the section. If this is zero, the section is an uninitialized section (i.e. <code>.bss</code>). The least significant bit of this value is 1 if the section is executable and 0 otherwise, but the OS always zeroes out that bit for the offset calculation. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
| 0x4 | | 0x4 | ||
Line 153: | Line 150: | ||
|- | |- | ||
|} | |} | ||
+ | |||
+ | The very first entry in this list is always empty (size = 0). | ||
== imp == | == imp == | ||
− | The '''imp''' acts as a directory for the relocation information. It | + | The '''imp''' acts as a directory for the relocation information. It specifies the offset of each relocation list and which module it refers to. Each entry has the form: |
{| class="wikitable" | {| class="wikitable" | ||
|+ imp table entry | |+ imp table entry | ||
Line 179: | Line 178: | ||
The relocation data seems to be heavily based on the ELF relocation format. It is one or more lists of 0x8 byte structures, and must be parsed in order. The [[#imp|imp table]] gives the start of each list. The end of each list is marked by the special type code 203. Each entry has the form: | The relocation data seems to be heavily based on the ELF relocation format. It is one or more lists of 0x8 byte structures, and must be parsed in order. The [[#imp|imp table]] gives the start of each list. The end of each list is marked by the special type code 203. Each entry has the form: | ||
{| class="wikitable" | {| class="wikitable" | ||
− | |+ Relocation | + | |+ Relocation entry |
|- | |- | ||
! Offset | ! Offset | ||
+ | ! Name | ||
! Size | ! Size | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
+ | | <code>offset</code> | ||
| 2 | | 2 | ||
| Offset in bytes from the previous relocation to this one. If this is the first relocation in the section, this is relative to the section start. | | Offset in bytes from the previous relocation to this one. If this is the first relocation in the section, this is relative to the section start. | ||
|- | |- | ||
| 0x2 | | 0x2 | ||
+ | | <code>type</code> | ||
| 1 | | 1 | ||
| The relocation type. Described below. | | The relocation type. Described below. | ||
|- | |- | ||
| 0x3 | | 0x3 | ||
+ | | <code>section</code> | ||
| 1 | | 1 | ||
| The section of the symbol to relocate against. For the special relocation type 202, this is instead the number of the section in this file which the following relocation entries apply to. | | The section of the symbol to relocate against. For the special relocation type 202, this is instead the number of the section in this file which the following relocation entries apply to. | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
+ | | <code>addend</code> | ||
| 4 | | 4 | ||
| Offset in bytes of the symbol to relocate against, relative to the start of its section. This is an absolute address instead for relocations against [[main.dol]]. | | Offset in bytes of the symbol to relocate against, relative to the start of its section. This is an absolute address instead for relocations against [[main.dol]]. | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | colspan= | + | | colspan=3 {{unknown|Next entry}} |
|- | |- | ||
|} | |} | ||
Line 255: | Line 259: | ||
|- | |- | ||
| 201 | | 201 | ||
− | | R_RVL_NONE | + | | R_RVL_NONE<br/>R_DOLPHIN_NOP |
− | | Do | + | | Do not relocate anything, but accumulate the <code>offset</code> field for the next relocation offset calculation. These types are used for referring to relocations that are more than <code>0xffff</code> apart from each other. |
|- | |- | ||
| 202 | | 202 | ||
− | | R_RVL_SECT | + | | R_RVL_SECT<br/>R_DOLPHIN_SECTION |
| Change which section relocations are being applied to. Set the offset into the section to 0. | | Change which section relocations are being applied to. Set the offset into the section to 0. | ||
|- | |- | ||
| 203 | | 203 | ||
− | | R_RVL_STOP | + | | R_RVL_STOP<br/>R_DOLPHIN_END |
− | | Stop parsing the relocation | + | | Stop parsing the relocation list. |
+ | |- | ||
+ | | 204 | ||
+ | | R_DOLPHIN_MRKREF | ||
+ | | {{unknown-left|Unknown. Unsupported by Mario Kart Wii.}} | ||
|- | |- | ||
|} | |} | ||
Line 273: | Line 281: | ||
The following tools can handle REL files: | The following tools can handle REL files: | ||
− | * [[BrawlBox]], by | + | * [[BrawlBox]], by Kryal and BlackJax96 |
− | * '''wstrt''' (see [[Wiimms SZS Tools]]) is able to patch data in the [[Mario Kart Wii]] file [[ | + | * '''wstrt''' (see [[Wiimms SZS Tools]]) is able to patch data in the [[Mario Kart Wii]] file [[StaticR.rel]]. |
− | * [[StaticR.rel Tool]], by [[Atlas]], can edit the region number, plus HUD, region line, Mii suit and layout | + | * [[StaticR.rel Tool]], by [[Atlas]], can edit the region number, plus HUD, region line, Mii suit and layout button colors from the same file. |
[[Category:File Format/Wii]] | [[Category:File Format/Wii]] |
Latest revision as of 13:55, 4 September 2023
REL files are relocatable object files used by Nintendo. Mario Kart Wii features one such file: StaticR.rel. In general these files allow extra code to be loaded as needed by games, especially when the memory footprint becomes a concern. In Mario Kart, the REL code contains much of the Mario Kart specific logic, such as gameplay, and, once loaded during the health and safety screen, remains loaded for the entire run of the application. Information about specific alteration that can be made to the Mario Kart Wii file can be found here.
File Format
Like many object formats, the file is divided into sections, grouped by like access. For example, all executable code is placed in one section, read only data in another, etc. The file begins with a header, followed by the section info table, followed by the section data, followed by the relocation information.
File Header
The file begins with a header of up to 0x4C bytes:
Offset | Size | Field Name | Description |
---|---|---|---|
0x00 | 4 | id
|
Arbitrary identification number. Must be unique amongst all RELs used by a game. Must not be 0. |
0x04 | 4 | next
|
Pointer to next module, filled at runtime. |
0x08 | 4 | prev
|
Pointer to previous module, filled at runtime. |
0x0c | 4 | numSections
|
Number of sections in the file. |
0x10 | 4 | sectionInfoOffset
|
Offset to the start of the section table. |
0x14 | 4 | nameOffset
|
Offset to the ASCII string containing the path of this module's .plf file. Relative to the start of the .str file.
|
0x18 | 4 | nameSize
|
Length of the path of this module's .plf file.
|
0x1c | 4 | version
|
Version number of the REL file format. |
0x20 | 4 | bssSize
|
Size of the '.bss ' section.
|
0x24 | 4 | relOffset
|
Offset to the first relocation list (same as the first offset in imp table). |
0x28 | 4 | impOffset
|
Offset to imp table. |
0x2c | 4 | impSize
|
Size of imp table in bytes. |
0x30 | 1 | prologSection
|
Index into section table which prolog is relative to. Skip if this field is 0.
|
0x31 | 1 | epilogSection
|
Index into section table which epilog is relative to. Skip if this field is 0.
|
0x32 | 1 | unresolvedSection
|
Index into section table which unresolved is relative to. Skip if this field is 0.
|
0x33 | 1 | bssSection
|
Index into section table which bss is relative to. Filled at runtime!
|
0x34 | 4 | prolog
|
Offset into specified section of the _prolog function.
|
0x38 | 4 | epilog
|
Offset into specified section of the _epilog function.
|
0x3c | 4 | unresolved
|
Offset into specified section of the _unresolved function.
|
0x40 | 4 | align
|
Version ≥ 2 only. Alignment constraint of the load address of the REL, expressed as power of 2. |
0x44 | 4 | bssAlign
|
Version ≥ 2 only. Alignment constraint on all '.bss ' section, expressed as power of 2.
|
0x48 | 4 | fixSize
|
Version ≥ 3 only. If REL is linked with OSLinkFixed (instead of OSLink), the space after this address can be used for other purposes (like BSS). |
0x4c or 0x48 or 0x40 | End of header |
Section Info Table
The section info table comprises of numSections entries each 0x8 bytes long, of the following form:
Offset | Size | Description |
---|---|---|
0x0 | 4 | Offset from the beginning of the REL to the section. If this is zero, the section is an uninitialized section (i.e. .bss ). The least significant bit of this value is 1 if the section is executable and 0 otherwise, but the OS always zeroes out that bit for the offset calculation.
|
0x4 | 4 | Length in bytes of the section. If this is zero, this entry is skipped. |
0x8 | Next entry |
The very first entry in this list is always empty (size = 0).
imp
The imp acts as a directory for the relocation information. It specifies the offset of each relocation list and which module it refers to. Each entry has the form:
Offset | Size | Description |
---|---|---|
0x0 | 4 | Module number (id ) that these relocations refer to. 0 means these refer to main.dol instead.
|
0x4 | 4 | Offset from the beginning of the REL to the relocation data. |
0x8 | Next entry |
Relocation Data
The relocation data seems to be heavily based on the ELF relocation format. It is one or more lists of 0x8 byte structures, and must be parsed in order. The imp table gives the start of each list. The end of each list is marked by the special type code 203. Each entry has the form:
Offset | Name | Size | Description |
---|---|---|---|
0x0 | offset
|
2 | Offset in bytes from the previous relocation to this one. If this is the first relocation in the section, this is relative to the section start. |
0x2 | type
|
1 | The relocation type. Described below. |
0x3 | section
|
1 | The section of the symbol to relocate against. For the special relocation type 202, this is instead the number of the section in this file which the following relocation entries apply to. |
0x4 | addend
|
4 | Offset in bytes of the symbol to relocate against, relative to the start of its section. This is an absolute address instead for relocations against main.dol. |
0x8 | Next entry |
The following relocation types are known[1]:
Type | Name | Description |
---|---|---|
0 | R_PPC_NONE | Do nothing. Skip this entry. |
1 | R_PPC_ADDR32 | Write the 32 bit address of the symbol. |
2 | R_PPC_ADDR24 | Write the 24 bit address of the symbol divided by four shifted up 2 bits to the 32 bit value (for relocating branch instructions). Fail if address won't fit. |
3 | R_PPC_ADDR16 | Write the 16 bit address of the symbol. Fail if address more than 16 bits. |
4 | R_PPC_ADDR16_LO | Write the low 16 bits of the address of the symbol. |
5 | R_PPC_ADDR16_HI | Write the high 16 bits of the address of the symbol. |
6 | R_PPC_ADDR16_HA | Write the high 16 bits of the address of the symbol plus 0x8000. |
7 - 9 | R_PPC_ADDR14 | Write the 14 bits of the address of the symbol divided by four shifted up 2 bits to the 32 bit value (for relocating conditional branch instructions). Fail if address won't fit. |
10 | R_PPC_REL24 | Write the 24 bit address of the symbol minus the address of the relocation divided by four shifted up 2 bits to the 32 bit value (for relocating relative branch instructions). Fail if address won't fit. |
11 - 13 | R_PPC_REL14 | Write the 14 bit address of the symbol minus the address of the relocation divided by four shifted up 2 bits to the 32 bit value (for relocating conditional relative branch instructions). Fail if address won't fit. |
201 | R_RVL_NONE R_DOLPHIN_NOP |
Do not relocate anything, but accumulate the offset field for the next relocation offset calculation. These types are used for referring to relocations that are more than 0xffff apart from each other.
|
202 | R_RVL_SECT R_DOLPHIN_SECTION |
Change which section relocations are being applied to. Set the offset into the section to 0. |
203 | R_RVL_STOP R_DOLPHIN_END |
Stop parsing the relocation list. |
204 | R_DOLPHIN_MRKREF | Unknown. Unsupported by Mario Kart Wii. |
The loader walks this table obeying each command until it encounters R_RVL_STOP. When relocation against a REL file (including against this file itself), the symbol address is calculated by taking the load address of the section section and adding the offset address. For relocation again main.dol, the symbol address is just address with no adjustment.
Tools
The following tools can handle REL files:
- BrawlBox, by Kryal and BlackJax96
- wstrt (see Wiimms SZS Tools) is able to patch data in the Mario Kart Wii file StaticR.rel.
- StaticR.rel Tool, by Atlas, can edit the region number, plus HUD, region line, Mii suit and layout button colors from the same file.