Difference between revisions of "REL (File Format)"

From Custom Mario Kart
Jump to navigation Jump to search
(Fix wrong numbering, document fields, typos.)
(New research into this format changes a lot of things.)
Line 1: Line 1:
 
'''REL files''' are relocatable object files used by Nintendo. [[Mario Kart Wii]] features one such file: '''[[Filesystem/rel/StaticR.rel|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 '''[[Filesystem/rel/StaticR.rel|here]]'''.
 
'''REL files''' are relocatable object files used by Nintendo. [[Mario Kart Wii]] features one such file: '''[[Filesystem/rel/StaticR.rel|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 '''[[Filesystem/rel/StaticR.rel|here]]'''.
__TOC__
+
 
 
= File Format =
 
= 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.
 
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 ==
 
== File Header ==
 
The file begins with a header of up to 0x4C bytes:
 
The file begins with a header of up to 0x4C bytes:
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+ REL file header
 
|-
 
|-
 
! Offset
 
! Offset
 
! Size
 
! Size
 +
! Field Name
 
! Description
 
! Description
 
|-
 
|-
 
| 0x00
 
| 0x00
 
| 4
 
| 4
| id: Arbitrary identification number for game use.
+
| <code>id</code>
 +
| Arbitrary identification number. Must be unique amongst all RELs used by a game.
 
|-
 
|-
 
| 0x04
 
| 0x04
 
| 8
 
| 8
| {{unknown|padding? ignored by [[Mario Kart Wii|MKW]]}}
+
| {{unknown}}
 +
| Padding.
 
|-
 
|-
 
| 0x0c
 
| 0x0c
 
| 4
 
| 4
| numSections: Number of sections in the file.
+
| <code>numSections</code>
 +
| Number of sections in the file.
 
|-
 
|-
 
| 0x10
 
| 0x10
 
| 4
 
| 4
| sectionInfoOffset: Offset to the start of the '''section table'''.
+
| <code>sectionInfoOffset</code>
 +
| Offset to the start of the [[#Section Info Table|section table]].
 
|-
 
|-
 
| 0x14
 
| 0x14
 
| 4
 
| 4
| nameOffset: Offset to ASCII string containing name of module. May be NULL. Unclear what it is relative to.
+
| <code>nameOffset</code>
 +
| Offset to ASCII string containing name of module. May be NULL. Unclear what it is relative to.
 
|-
 
|-
 
| 0x18
 
| 0x18
 
| 4
 
| 4
| nameSize: Size of the module name in bytes.
+
| <code>nameSize</code>
 +
| Size of the module name in bytes.
 
|-
 
|-
 
| 0x1c
 
| 0x1c
 
| 4
 
| 4
| version: Version number of the REL file format.
+
| <code>version</code>
 +
| Version number of the REL file format.
 
|-
 
|-
 
| 0x20
 
| 0x20
 
| 4
 
| 4
| bssSize: Size of the 'bss' section.
+
| <code>bssSize</code>
 +
| Size of the '<code>.bss</code>' section.
 
|-
 
|-
 
| 0x24
 
| 0x24
 
| 4
 
| 4
| relOffset: Offset to the relocation table.
+
| <code>relOffset</code>
 +
| Offset to the [[#Relocation Data|relocation table]].
 
|-
 
|-
 
| 0x28
 
| 0x28
 
| 4
 
| 4
| impOffset: Offset to imp(?).
+
| <code>impOffset</code>
 +
| Offset to [[#imp|imp table]].
 
|-
 
|-
 
| 0x2c
 
| 0x2c
 
| 4
 
| 4
| impSize: Size of imp(?).
+
| <code>impSize</code>
 +
| Size of [[#imp|imp table]] in bytes.
 
|-
 
|-
 
| 0x30
 
| 0x30
| 4
+
| 1
| {{unknown|flags of some sort? ignored by [[Mario Kart Wii|MKW]]}}
+
| {{unknown}}
 +
| Index into [[#Section Info Table|section table]] which <code>prolog</code> is relative to. Skip if this field is 0.
 +
|-
 +
| 0x31
 +
| 1
 +
| {{unknown}}
 +
| Index into [[#Section Info Table|section table]] which <code>epilog</code> is relative to. Skip if this field is 0.
 +
|-
 +
| 0x32
 +
| 1
 +
| {{unknown}}
 +
| Index into [[#Section Info Table|section table]] which <code>unresolved</code> is relative to. Skip if this field is 0.
 +
|-
 +
| 0x33
 +
| 1
 +
| {{unknown}}
 +
| Padding.
 
|-
 
|-
 
| 0x34
 
| 0x34
 
| 4
 
| 4
| prolog: Offset into first executable section of the <code>_prolog</code> function.
+
| <code>prolog</code>
 +
| Offset into specified section of the <code>_prolog</code> function.
 
|-
 
|-
 
| 0x38
 
| 0x38
 
| 4
 
| 4
| epilog: Offset into first executable section of the <code>_epilog</code> function.
+
| <code>epilog</code>
 +
| Offset into specified section of the <code>_epilog</code> function.
 
|-
 
|-
 
| 0x3c
 
| 0x3c
 
| 4
 
| 4
| unresolved: Offset into first executable section of the <code>_unresolved</code> function.
+
| <code>unresolved</code>
 +
| Offset into specified section of the <code>_unresolved</code> function.
 
|-
 
|-
 
| 0x40
 
| 0x40
 
| 4
 
| 4
| Version &ge; 2 only. align: Alignment constraint on all sections.
+
| <code>align</code>
 +
| Version &ge; 2 only. Alignment constraint on all sections, expressed as power of 2.
 
|-
 
|-
 
| 0x44
 
| 0x44
 
| 4
 
| 4
| Version &ge; 2 only. bssAlign: Alignment constraint on all 'bss' section.
+
| <code>bssAlign</code>
 +
| Version &ge; 2 only. Alignment constraint on all '<code>.bss</code>' section, expressed as power of 2.
 
|-
 
|-
 
| 0x48
 
| 0x48
 
| 4
 
| 4
| Version &ge; 3 only. fixSize: ?
+
| <code>fixSize</code>
 +
| {{unknown|Version &ge; 3 only. Unknown.}}
 
|-
 
|-
 
| 0x4c or 0x48 or 0x40
 
| 0x4c or 0x48 or 0x40
| colspan=2 {{unknown|End of header}}
+
| colspan=3 {{unknown|End of header}}
 
|-
 
|-
 
|}
 
|}
 +
 
== Section Info Table ==
 
== Section Info Table ==
 
The section info table comprises of ''numSections'' entries each 0x8 bytes long, of the following form:
 
The section info table comprises of ''numSections'' entries each 0x8 bytes long, of the following form:
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+ Section table entry
 
|-
 
|-
 
! Offset
 
! Offset
Line 96: Line 134:
 
|-
 
|-
 
| 0x0
 
| 0x0
| 4
+
| 30 bits
| offset: Location in file of the section information. The last bit determines if this section is executable or not. If this is zero, the section is an uninitialized section.
+
| 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>).
 +
|-
 +
| 0x3.6
 +
| 1 bit
 +
| {{Unknown}}
 +
|-
 +
| 0x3.7
 +
| 1 bit
 +
| Executable flag; if this is 1 the section is executable.
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| 4
 
| 4
| length: Length in bytes of the section.
+
| Length in bytes of the section. If this is zero, this entry is skipped.
 
|-
 
|-
 
| 0x8
 
| 0x8
Line 107: Line 153:
 
|-
 
|-
 
|}
 
|}
 +
 
== imp ==
 
== imp ==
The imp information may be a table. It seems to contain pointers into the relocation information, potentially to allow it to be done in phases. If so, the table contains 0x8 byte entries of the form:
+
The '''imp''' acts as a directory for the relocation information. It controls which entries in the relocation table refer to. Each entry has the form:
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+ imp table entry
 
|-
 
|-
 
! Offset
 
! Offset
Line 117: Line 165:
 
| 0x0
 
| 0x0
 
| 4
 
| 4
| type: Type of the relocation entries. 1 for internal, 0 for external.
+
| Module number (<code>id</code>) that these relocations refer to. 0 means these refer to [[main.dol]] instead.
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| 4
 
| 4
| offset: Offset from the beginning of the REL to the relocation data.
+
| Offset from the beginning of the REL to the relocation data.
 
|-
 
|-
 
| 0x8
 
| 0x8
Line 127: Line 175:
 
|-
 
|-
 
|}
 
|}
 +
 
== Relocation Data ==
 
== Relocation Data ==
The relocation data seems to be heavily based on the ELF relocation format. It is a list of 0x8 byte structures, and must be parsed in order. 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 table entry
 
|-
 
|-
 
! Offset
 
! Offset
Line 137: Line 187:
 
| 0x0
 
| 0x0
 
| 2
 
| 2
| offset: Number of bytes to skip before this relocation.
+
| 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
 
| 1
 
| 1
| type: The relocation type. Described below.
+
| The relocation type. Described below.
 
|-
 
|-
 
| 0x3
 
| 0x3
 
| 1
 
| 1
| section: The section of the symbol to locate.
+
| 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
 
| 4
 
| 4
| address: Address of the symbol in the section.
+
| 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
Line 155: Line 205:
 
|-
 
|-
 
|}
 
|}
The followng relocation types are known[https://www.power.org/wp-content/uploads/2012/07/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf <sup>[1&#93;</sup>]:
+
 
 +
The following relocation types are known[https://www.power.org/wp-content/uploads/2012/07/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf <sup>[1&#93;</sup>]:
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+ Relocation entry type
 
|-
 
|-
 
! Type
 
! Type
Line 215: Line 267:
 
|-
 
|-
 
|}
 
|}
The loader walks this table obeying each command until it encounters R_RVL_STOP. In the case of internal relocations, the symbol address is calculated by taking the load address of the section ''section'' and adding the offset ''address''. For external relocation, the symbol address is just ''address''. The purpose of ''section'' in such instances is unknown.
+
 
 +
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 =
 
= Tools =

Revision as of 12:57, 6 September 2017

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:

REL file header
Offset Size Field Name Description
0x00 4 id Arbitrary identification number. Must be unique amongst all RELs used by a game.
0x04 8 Unknown Padding.
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 ASCII string containing name of module. May be NULL. Unclear what it is relative to.
0x18 4 nameSize Size of the module name in bytes.
0x1c 4 version Version number of the REL file format.
0x20 4 bssSize Size of the '.bss' section.
0x24 4 relOffset Offset to the relocation table.
0x28 4 impOffset Offset to imp table.
0x2c 4 impSize Size of imp table in bytes.
0x30 1 Unknown Index into section table which prolog is relative to. Skip if this field is 0.
0x31 1 Unknown Index into section table which epilog is relative to. Skip if this field is 0.
0x32 1 Unknown Index into section table which unresolved is relative to. Skip if this field is 0.
0x33 1 Unknown Padding.
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 on all sections, 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. Unknown.
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:

Section table entry
Offset Size Description
0x0 30 bits Offset from the beginning of the REL to the section. If this is zero, the section is an uninitialized section (i.e. .bss).
0x3.6 1 bit Unknown
0x3.7 1 bit Executable flag; if this is 1 the section is executable.
0x4 4 Length in bytes of the section. If this is zero, this entry is skipped.
0x8 Next entry

imp

The imp acts as a directory for the relocation information. It controls which entries in the relocation table refer to. Each entry has the form:

imp table entry
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:

Relocation table entry
Offset Size Description
0x0 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 1 The relocation type. Described below.
0x3 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 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]:

Relocation entry type
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 Do nothing. Skip this entry. Carry the address of the symbol to the next entry.
202 R_RVL_SECT Change which section relocations are being applied to. Set the offset into the section to 0.
203 R_RVL_STOP Stop parsing the relocation table.

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: