RSO (File Format)

From Retro Modding Wiki
Revision as of 17:20, 2 October 2016 by >Aruki (→‎Header)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The RSO format is the file format for shared objects for Wii games. This is essentially the Wii's equivalent of a DLL file, allowing for code modules to be dynamically linked at runtime and unlinked when not in use to save memory. It's very similar to the GameCube's REL format, with the main difference being that the RSO format resolves symbol references via runtime symbol lookups rather than having pre-calculated offsets into the game's module files.

RSO files are usually accompanied by a SEL file, which is an RSO file that contains no code or data sections, and instead just has an export table for the DOL file. This is used to resolve module references to symbols in the main executable.

Format

Header

Offset Type Count Name Notes
0x0 u32 1 Next Module Link Pointer to the next module, forming a linked list. Always 0, filled in at runtime.
0x4 u32 1 Previous Module Link Pointer to the previous module, forming a linked list. Always 0, filled in at runtime.
0x8 u32 1 Section Count Number of sections contained in the file.
0xC u32 1 Section Info Offset Offset to the section info table. Always 0x58.
0x10 u32 1 Module Name Offset Offset to the module name. Can be 0, in which case this module doesn't contain a name string.
0x14 u32 1 Module Name Size Size of the module name string.
0x18 u32 1 Module Version Module version number. Always 1.
0x1C u32 1 BSS Size Size of the BSS section, which is allocated at runtime (not included in the file).
0x20 u8 1 Prolog Section Section index of the prolog function, which is called when the module is linked. 0 if this module doesn't contain a prolog function.
0x21 u8 1 Epilog Section Section index of the epilog function, which is called when the module is unlinked. 0 if this module doesn't contain an epilog function.
0x22 u8 1 Unresolved Section Section index of the unresolved function, which is called if the module attempts to call an unlinked function. 0 if this module doesn't contain an unresolved function.
0x23 u8 1 BSS Section Section index of the BSS section. Always 0, filled in at runtime.
0x24 u32 1 Prolog Function Offset Section-relative offset of the prolog function. 0 if this module doesn't contain a prolog function.
0x28 u32 1 Epilog Function Offset Section-relative offset of the epilog function. 0 if this module doesn't contain an epilog function.
0x2C u32 1 Unresolved Function Offset Section-relative offset of the unresolved function. 0 if this module doesn't contain an unresolved function.
0x30 u32 1 Internal Relocation Table Offset Absolute offset of the relocation table for internal relocations (relocations for symbols within this module).
0x34 u32 1 Internal Relocation Table Size Size of the relocation table for internal relocations.
0x38 u32 1 External Relocation Table Offset Absolute offset of the relocation table for external relocations (relocations for symbols within other modules).
0x3C u32 1 External Relocation Table Size Size of the relocation table for external relocations.
0x40 u32 1 Export Symbol Table Offset Absolute offset of the symbol table for exports (symbols within this module).
0x44 u32 1 Export Symbol Table Size Size of the symbol table for exports.
0x48 u32 1 Export Symbol Names Offset Absolute offset of the string table containing export symbol names.
0x4C u32 1 Import Symbol Table Offset Absolute offset of the symbol table for imports (symbols within other modules, referenced by this one).
0x50 u32 1 Import Symbol Table Size Size of the symbol table for imports.
0x54 u32 1 Import Symbol Names Offset Absolute offset of the string table containing import symbol names.
0x58 End of RSO header

Section Info Table

This data is pointed to by the Section Info Offset value in the header. It specifies the layout of the file. The structure loops once for each section in the file, as specified by the Section Count in the header. Any compiler-generated sections that are unused (such as the symbol table or the section name table) are nulled out and listed with a size/offset of 0. The first section is always null. The BSS section is listed with a valid size but an offset of 0 (as the BSS section is not included in the file, but instead has space allocated at runtime).

Offset Type Count Name Notes
0x0 u32 1 Offset Absolute offset of the section.
0x4 u32 1 Size Size of the section.
0x8 End of section info

Relocation Table

Since modules have space allocated at runtime and therefore do not have a fixed memory address, the relocations table is needed to ensure all data and function addresses in the RSO are correct; this includes both symbols within the RSO itself, which don't have a fixed address until the RSO is linked in, and symbols within the DOL, which need corrections due to the usage of relative offsets in branch instructions. The relocation table describes the location of every instruction that needs to be patched, and how to patch it.

There are two relocation tables in the file; one for internal relocations (relocations for addresses pointing to symbols within this RSO), and one for external relocations (relocations for addresses pointing to symbols within the main DOL executable). These tables are pointed to by the Internal Relocation Table Offset and External Relocation Table Offset values in the header. You can calculate the number of relocation entries by dividing the size of the table by 0xC (the size of one relocation entry).

Offset Type Count Name Notes
0x0 u32 1 Offset Absolute offset of this relocation (relative to the start of the RSO file).
0x4 u24 1 Symbol ID For internal relocations, this is the section index of the symbol being patched to. For external relocations, this is the index of the symbol within the import symbol table.
0x7 u8 1 Relocation Type Type of the relocation. See the below table for a list of possible types.
0x8 u32 1 Symbol Offset For internal relocations, this is the section-relative offset of the symbol being patched to. For external relocations, this is unused and always 0 (the offset is calculated using the import symbol table).
0xC End of relocation

These are the possible relocation types. The "used" column indicates whether this relocation type is used by any of the modules in any of Retro's games.

Value Name Description Used?
0 R_PPC_NONE Do nothing.
1 R_PPC_ADDR32 Write the full, 32-bit address of the symbol.
2 R_PPC_ADDR24 Write the 24-bit address of the symbol. Leave the existing value of the bottom two bits intact.
3 R_PPC_ADDR16 Write the 16-bit address of the symbol.
4 R_PPC_ADDR16_LO Write the low 16 bits of the symbol address.
5 R_PPC_ADDR16_HI Write the high 16 bits of the symbol address.
6 R_PPC_ADDR16_HA Write the high 16 bits of the symbol address, plus 0x10000. This is used for cases where the bottom half is >= 0x8000, in which case a subtract operation is used to load the lower half of the address.
7 R_PPC_ADDR14 Write the 14-bit address of the symbol. Leave the existing value of the bottom two bits intact. This is used for conditional branch instructions.
8 R_PPC_ADDR14_BRTAKEN Write the 14-bit address of the symbol. Leave the existing value of the bottom two bits intact. Note: Needs a proper check on differences between this and ADDR14
9 R_PPC_ADDR14_BRNTAKEN Write the 14-bit address of the symbol. Leave the existing value of the bottom two bits intact. Note: Needs a proper check on differences between this and ADDR14
10 R_PPC_REL24 Write a 24-bit offset from the address of this instruction to the address of the symbol. This is used for branch instructions.
11 R_PPC_REL14 Write a 14-bit offset from the address of this instruction to the address of the symbol.

Symbol Table

RSO modules resolve references to symbols at runtime, rather than using precalculated offsets into the module files like REL does. To accomplish this, there's two symbol tables in the file; one for exports (symbols that are included in this RSO), and imports (symbols that are included in other modules but are referenced from this module). The name of the symbol in the import table is used to locate the same symbol in another module's export table, from which the address of the symbol can be calculated. Note that although the main DOL file doesn't contain an export table, there is a DOL export table in the SEL file, which can usually be found alongside the RSOs.

Offset Type Count Name Notes
0x0 u32 1 Symbol Name Offset Relative offset into the name table pointed to in the header, which points to the name of this symbol.
0x4 u32 1 Symbol Offset The section-relative offset to the symbol. This is always 0 for imports.
0x8 u32 1 Symbol Section Index For exports, index of the section that contains this symbol. For imports, appears to be an offset?
0xC u32 1 ELF Hash A hash. Exact details unknown, but isn't required to link to the symbol. This field is omitted for imports.
0x10 End of symbol