5.0 KiB
Getting Started
See Dependencies first.
Clone this template repository.
Rename orig/GAMEID
to the game's ID. (For example, GLZE01
for The Legend of Zelda: The Wind Waker.)
Extract your game to orig/[GAMEID]
. In Dolphin, use "Extract Entire Disc" for GameCube games, or use "Data Partition" -> "Extract Entire Partition" for Wii games.
Rename config/GAMEID
to the game's ID and modify config/[GAMEID]/config.yml
appropriately, using config.example.yml
as a reference. If the game doesn't use RELs, the modules
list in config.yml
can be removed.
Generate a config/[GAMEID]/build.sha1
file for verification. This file is a list of SHA-1 hashes for each build artifact. One possible way:
$ dtk shasum orig/[GAMEID]/sys/main.dol orig/[GAMEID]/files/*.rel > config/[GAMEID]/build.sha1
Then, modify the paths in config/[GAMEID]/build.sha1
to point to the build
directory instead of orig
. The DOL will be built at build/[GAMEID]/main.dol
, and modules will be built at build/[GAMEID]/[module_name]/[module_name].rel
.
Update VERSIONS
in configure.py
with the game ID.
Run python configure.py
to generate the initial build.ninja
.
Run ninja
to perform initial analysis.
If all goes well, the initial symbols.txt
and splits.txt
should be automatically generated. Though it's likely it won't build yet. See Post-analysis for next steps.
Using a .map
If the game has .map
files matching the DOL (and RELs, if applicable), they can be used to fill out symbols.txt
and splits.txt
automatically during the initial analysis.
Add the map
key to config.yml
, pointing to the .map
file from the game disc. (For example, orig/[GAMEID]/files/main.map
.) For RELs, add a map
key to each module in config.yml
.
If the game uses common BSS, be sure to set common_start
as well. (See config.example.yml
.) Otherwise, the final link order may fail to be determined.
Once the initial analysis is completed, symbols.txt
and splits.txt
will be generated from the map information. Remove the map
fields from config.yml
to avoid conflicts.
Post-analysis
After the initial analysis, symbols.txt
and splits.txt
will be generated. These files can be modified to adjust symbols and split points.
If the game uses C++ exceptions, it's required to set up a split for the __init_cpp_exceptions.cpp
file. This differs between linker versions.
Often indicated by the following error:
# runtime sources 'global_destructor_chain.c' and
# '__init_cpp_exceptions.cpp' both need to be updated to latest version.
GC 1.0 - 2.6 linkers:
# splits.txt
Runtime.PPCEABI.H/__init_cpp_exceptions.cpp:
.text start:0x803294EC end:0x80329568
.ctors start:0x80338680 end:0x80338684
.dtors start:0x80338820 end:0x80338828
.sdata start:0x803F67F0 end:0x803F67F8
.text
:
Find the following symbols in symbols.txt
:
GetR2__Fv = .text:0x803294EC; // type:function size:0x8 scope:local align:4
__fini_cpp_exceptions = .text:0x803294F4; // type:function size:0x34 scope:global align:4
__init_cpp_exceptions = .text:0x80329528; // type:function size:0x40 scope:global align:4
The split end is the address of __init_cpp_exceptions
+ size.
.ctors
:
Find the address of __init_cpp_exception_reference
or _ctors
in symbols.txt.
Always size 4.
.dtors
:
Look for the address of __destroy_global_chain_reference
or _dtors
in symbols.txt.
If __fini_cpp_exceptions_reference
is present, it's size 8, otherwise size 4
.sdata
:
Find the following symbol in symbols.txt
:
fragmentID = .sdata:0x803F67F0; // type:object size:0x4 scope:local align:4 data:4byte
The split end includes any inter-TU padding, so it's usually size 8.
GC 2.7+ and Wii linkers:
# splits.txt
Runtime.PPCEABI.H/__init_cpp_exceptions.cpp:
.text start:0x80345C34 end:0x80345CA4
.ctors start:0x803A54A0 end:0x803A54A4 rename:.ctors$10
.dtors start:0x803A56A0 end:0x803A56A4 rename:.dtors$10
.dtors start:0x803A56A4 end:0x803A56A8 rename:.dtors$15
.sdata start:0x80418CA8 end:0x80418CB0
.text
:
Find the following symbols in symbols.txt
:
__fini_cpp_exceptions = .text:0x80345C34; // type:function size:0x34 scope:global
__init_cpp_exceptions = .text:0x80345C68; // type:function size:0x3C scope:global
The split end is the address of __init_cpp_exceptions
+ size.
.ctors$10
:
Find the address of __init_cpp_exception_reference
or _ctors
in symbols.txt.
Always size 4.
.dtors$10
:
Look for the address of __destroy_global_chain_reference
or _dtors
in symbols.txt.
Always size 4.
.dtors$15
:
Look for the address of __fini_cpp_exceptions_reference
in symbols.txt.
Always size 4.
.sdata
:
Find the following symbol in symbols.txt
:
fragmentID = .sdata:0x80418CA8; // type:object size:0x4 scope:local data:4byte
The split end includes any inter-TU padding, so it's usually size 8.