-
Notifications
You must be signed in to change notification settings - Fork 46
Basic Decompilation
This is a basic guide for using decomp.me to create matching function decompilations. For functions inside map files refer to the map tool guide for information about sharing functions between maps.
Look for the INCLUDE_ASM macro of the function you're interested in:
INCLUDE_ASM("asm/bodyprog/nonmatchings/bodyprog_80070B84", func_80071620)
The first parameter is the folder containing the assembly file, in that folder you should find a file with the function name with a *.s extension, copy the contents of that file and follow the next section.
You can also run ./tools/func_rater.py to see the current unmatched functions ranked by estimated difficulty. Some of the easier ones near the bottom could be good starting points for learning to decompile.
decomp.me allows decompiling functions using m2c, while providing a live diff view that compares the compiled C code against the original assembly, letting you edit C code directly in the browser and see the changes in real time.
Each scratch is also publicly viewable and forkable, making it easy to collaborate on the same function.
Note
If you have a GitHub account you may want to login to it on decomp.me first, so scratches can be credited to you.
Warning
It's recommended to try searching decomp.me for the function you want to work on first, others may have already made some progress on it.
-
On the decomp.me page, head to New scratch > Click PlayStation option > Under Presets, select Silent Hill
-
Ignore the
Diff Labelfield for now. -
Paste the function assembly (
.sfile) into the Target Assembly box.-
.sfiles are generated after runningmake setupin the decomp project. -
Diff Labelfield should auto-fill after pasting it in.
-
-
In the Context box, paste in the
ctx.ccontent for the.cfile that includes the function:- Run
tools/m2ctx.py src/bodyprog/bodyprog.c(change to the .c file that hasINCLUDE_ASMline for the function) - Copy the contents of the generated
ctx.cinto the box
- Run
-
Click Create Scratch
This will try to create a scratch for you with decompiled output using m2c. The result tend to variate, sometimes it can make very closely matching C code, most of the time it create a decently enough result to get an idea to start working from and in case of a large function or one that uses many macros or inlinement it can require too much work.
Note
When working on non-engine overlay functions, add the overlay name to the beginning of the scratch (a comment like // MAP0_S00, or a #define MAP0_S00 define), this will help keep track of each function.
In some cases where the function uses jump tables, decomp.me/m2c may ask for jtbl data before it can decompile:
-
In this case, delete the scratch and start over with a new one.
-
Before the function's assembly, include the jtbl_XXXX data that m2c requested (can usually be found either as a separate
.sfile, or in one of the.rodata.sfile for the.c):.set noat /* allow manual use of $at */ .set noreorder /* don't insert nops after branches */ .section .rodata, "a" ; jump table data here (`dlabel jtbl_XXXX` line through `.size jtbl_XXXX`) .section .text, "a" ; original function code here (`glabel func_XXXX` through `.size func_XXXX`)
The context from m2ctx will also contain function code from the input .c file, this code can cause rodata / code offsets to be mismatched from the original assembly, causing them to appear in blue, and sometimes affecting the match percentage.
This is an easy fix: simply edit the context and remove all function code after the function and struct declarations. Note that static inlines can usually be left in the context, unless those also cause decompilation issues.
Code offsets can also be affected by the same thing, causing branch targets to appear in blue despite pointing to the same code. The same fix can resolve them.