RSO (File Format)

From Wexos's Wiki
Jump to navigationJump to search

RSO format is the file format used for shared objects in some Wii games. Unlike DOL which is not relocatable and statically linked, RSO files are relocatable and are loaded and linked dynamically. It is similar usage to REL, with the difference that REL files uses pre-calculated offsets for linking to the DOL while RSO uses symbol name lookup for linking.

In games using RSO files, there is usually a .sel file stored. This is a RSO file containing no code or data and only contains symbols exported from the DOL file.

File Format

Header

The file starts with the following header:

Offset Type Description
0x00 UInt32 Next module link. Pointer to the next loaded RSO module. Always 0, filled in at runtime.
0x04 UInt32 Previous module link. Pointer to the previous RSO module. Always 0, filled in at runtime.
0x08 UInt32 Section count. Number of sections contained in the file.
0x0C UInt32 Section info offset.
0x10 UInt32 Module name offset. May be 0, meaning no module name.
0x14 UInt32 Module name size.
0x18 UInt32 Module version. Always 1.
0x1C UInt32 BSS size in bytes.
0x20 Byte Prolog section index. Section index of the prolog function, which is called when the module is linked. May be 0 if this module doesn't contain a prolog function.
0x21 Byte Epilog section index. Section index of the epilog function, which is called when the module is unlinked. May be 0 if this module doesn't contain an epilog function.
0x22 Byte Unresolved section index. Section index of the unresolved function, which is called if the module attempts to call an unlinked function. May be 0 if this module doesn't contain an unresolved function.
0x23 Byte BSS section index Section index of the BSS section. Always 0, filled in at runtime.
0x24 UInt32 Prolog function offset. Section-relative offset of the prolog function. May be 0 if this module doesn't contain a prolog function.
0x28 UInt32 Epilog function offset. Section-relative offset of the epilog function. May be 0 if this module doesn't contain an epilog function.
0x2C UInt32 Unresolved function offset. Section-relative offset of the unresolved function. May be 0 if this module doesn't contain an unresolved function.
0x30 UInt32 Internal relocation table offset. Offset to the relocation table used for relocations within this module.
0x34 UInt32 Internal relocation table size in bytes.
0x30 UInt32 External relocation table offset. Offset to the relocation table used for relocations outside this module.
0x34 UInt32 External relocation table size in bytes.
0x40 UInt32 Export symbol table offset. Offset to the symbol table which stores symbols exported from this module.
0x44 UInt32 Export symbol table size in bytes.
0x48 UInt32 Export symbol name table offset.
0x4C UInt32 Import symbol table offset. Offset to the symbol table which stores symbols imported to this module from other modules.
0x50 UInt32 Import symbol table size in bytes.
0x54 UInt32 Import symbol name table offset.

Section Info Table

The header specifies the number of sections stored in the file. Each section has the following structure:

Offset Type Description
0x00 UInt32 Section data offset, relative to the start of the file.
0x04 UInt32 Section data size in bytes.

Relocation Table

Each RSO stores two relocation tables, one for internal relocation and one for external relocation. The relocation table allows code to the loaded into any virtual memory address. Each entry in the relocation table has the following structure:

Offset Type Description
0x00 UInt32 Relocation offset. Offset of this relocation, relative to the start of the file.
0x04 UInt24 Internal relocation: Section index of the symbol.
External relocation: Imported symbol index.
0x07 Byte Relocation type. Specifies how the data located at the offset specified should be transformed.
0x08 UInt32 Internal relocation: Section-relative offset of the symbol being patched to.
External relocation: Unused, always 0.

Symbol Table

The header specifies the offset and size of the symbol table, as well as an offset to the symbol name table, which contains null-terminated strings. To calculate the number of entries, divide the symbol table size by 0x10 and 0x0C for the exported and imported symbol table respectively.

In order to resolve symbols at runtime two symbol tables are stored. This is a big difference compared to REL, which does not relocate by symbols. The export table is used for specifying symbols in the current RSO module. The import symbol table is used for symbols outside this module which are referenced in the current RSO module. The symbol names in the import table is used to find the actual symbol from the export symbol table of another RSO module.

The structure is slightly different between export and import symbols, since import symbols do not store an ELF hash. However, everything else is the same. Each symbol has the following structure:

Offset Type Description
0x00 UInt32 Symbol name offset, relative to the symbol name table specified in the header.
0x04 UInt32 Symbol offset. Section-relative offset to the symbol. Always 0 for import symbols.
0x08 UInt32 Export: Section index which contains this symbol.
Import: Unknown, seems to be an offset.
0x0C UInt32 ELF hash. Only stored for export symbols.

Tools

The following tools can handle RSO files:

  • (none)