Analyzer does not output toml
I tried to use the XenonAnalyze.exe to output Minecraft: Xbox 360 Edition's jump tables to a toml, but it does not seem to create any toml in the path I specified. Nothing shows up in the terminal either
Looking to start a static recomp project of Minecraft so any help would be nice
Right so apparently I was building in Release rather than Debug, and also not specifying a toml output. Now it creates the toml, but doesn't actually get the jump tables
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.
The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253
See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.
The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253
See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is:
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.
The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253
See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
Hello, I have found many such patterns inside of Tetris The Grand Master: Ace, but for some reason XenonAnalyse doesn't output any .toml after running for a little while. I tried it on other games and it did give out either empty or filled tmls, so this behaviour is quite intriguing.
Also, is XenonRecomp supposed to Decompile the game's executable even if it doesn't happen to find any jumptables ? I made a .toml file that doesn't have much information but should still give some basic information to the tool I think
[main]
file_path = "tgma.xex"
out_directory_path = "../tgma"
skip_lr = false
skip_msr = false
ctr_as_local = false
xer_as_local = false
reserved_as_local = false
cr_as_local = false
non_argument_as_local = false
non_volatile_as_local = false
restgprlr_14_address = 0x823100F0
savegprlr_14_address = 0x823100A0
restfpr_14_address = 0x8231019C
savefpr_14_address = 0x82310150
restvmx_14_address = 0x823170F8
savevmx_14_address = 0x82316E60
restvmx_64_address = 0x8231718C
savevmx_64_address = 0x82316EF4
longjmp_address = 0x823191E0
setjmp_address = 0x82319300
invalid_instructions = [
{ data = 0x00000000, size = 4 }, # Padding
{ data = 0x8233ba2c, size = 8 } # C Specific Frame Handler
]
Sorry, I'm not really looking to get all the work chewed and have a step by step tutorial brought on the table to me, but I don't think I left anything out in what was written for the README
Also, if it can help, I compiled the tool with MSYS2 CLANG64 and Ninja, as a Debug project.
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.
The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253
See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
The PVZ 360 port also seems to be different than unleashed, giving an empty toml file. Building debug on CLang MSVC with Ninja.
Edit: either way i'm looking forward to any progress being made on other games, to look at how this kind of stuff can be fixed. I know its super early on in development.
When attempting to run XenonAnalyze on default.xex, it complains about compression type.
PS ...\XenonRecomp\build\XenonAnalyse> .\XenonAnalyse.exe ...\nfsmw\default.xex ...\mwrecomp\jumplist.toml Assertion failed: fileFormatInfo->compressionType <= XEX_COMPRESSION_BASIC, file ...\XenonRecomp\XenonUtils\xex.cpp, line 138
After decompressing the xex with xextool, process finishes without any errors;
PS ...\XenonRecomp\build\XenonAnalyse> .\XenonAnalyse.exe ...\nfsmw\uncompressed.xex ...\mwrecomp\jumplist.toml PS ...\XenonRecomp\build\XenonAnalyse>
However, the toml is never written. Issue does not occur with other games such as WWE 2007.
@koffiato I seem to have a similar issue with Outrun: Online Arcade!
The raw default.xex I extracted from the Xbox Live Arcade container using wxPirs, the result reports as:
Xex Info
Retail
Compressed
Encrypted
Title Module
No ODD Mapping
Uses Game Voice Channel
Pal50 Incompatible
Xbox360 Logo Data Present
on XexTool and when I run XenonAnalyze on it it segfaults similarly to #15, when debugging the segfault with GDB I get a:
Program received signal SIGSEGV, Segmentation fault.
0x000055555557ac39 in Xex2LoadImage(unsigned char const*, unsigned long) ()
which looking at the sources, specifically this part, looks to me as if this is an issue with processing the compression or encryption of my Xex file.
After seeing issue #10 I tried to use XexTool to uncompress and decrypt my default.xex with the following command xextool -o decunc.xex -c b -e u default.xex.
However after running ./XenonAnalyse decunc.xex test.toml which runs for some time and looks as if it is working, my test.toml outputs empty with only comments being present (on GDB I get a [Inferior 1 (process 12767) exited normally] as if everything went well).
Just in case this is a concern, my decrypted and uncompressed binary (decunc.xex) works just fine on xenia when paired up with other game assets so the XexTool output is valid for sure.
used .\xenonanalyse.exe E:\xenonrecomp\artifacts\dah\default.xex E:\xenonrecomp\artifacts\dah default.toml and do not get a default.toml file for destroy all humans path of the furon. had 0 problems getting the file yesterday
Edit 03/05/2025: i figured it out, it works if i dont put the output directory and just do .\xenonanalyse.exe E:\xenonrecomp\artifacts\dah\default.xex default.toml, it then spits the toml file into the xenonanalyse folder
There is a pattern that can be used for some games that is:
PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_SUBI, PPC_INST_LWZX, PPC_INST_MTSPR
OR
PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_ADDI, PPC_INST_LWZX, PPC_INST_MTSPR
I believe there is currently a parsing error when reading in the opcodes where PPC_INST_MTSPR is not being properly parsed as I know that instruction is in the binary in the order that I am passing in, but I never hit my breakpoint that says we found any of them in the binary. Commenting the PPC_INST_MTSPR out makes it catch these switch cases, but it would be ideal if PPC_INST_MTSPR could properly get parsed.
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has. The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253 See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is:
Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please
Looking to start a static recomp project of Minecraft so any help would be nice
i was also wanting to do this, i can help with it
Right so apparently I was building in Release rather than Debug, and also not specifying a toml output. Now it creates the toml, but doesn't actually get the jump tables
I am also getting an empty TOML using the xex from The Fancy Pants Adventures with XenonAnalyze, had to change compression with xextool since the compression level was above XEX_COMPRESSION_BASIC
Same as @Fancy2209 with Skate 3
From some reading, I believe Recompiler's analyzer is more robust than Xenon's, at least in the sense it doesn't depend on a Specific MSVC version
From some reading, I believe Recompiler's analyzer is more robust than Xenon's, at least in the sense it doesn't depend on a Specific MSVC version
Would there be any way to use that analyser then use the result from that in XenonRecomp?
Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has. The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253 See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.
i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is:
Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please
I also dont understand how you make this detemination. Could you please explain. Also, how can you get the jump table to detect ori and subi instructions. Ive been trying for a while but with no luck.
There is a pattern that can be used for some games that is:
PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_SUBI, PPC_INST_LWZX, PPC_INST_MTSPR
OR
PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_ADDI, PPC_INST_LWZX, PPC_INST_MTSPR
I believe there is currently a parsing error when reading in the opcodes where PPC_INST_MTSPR is not being properly parsed as I know that instruction is in the binary in the order that I am passing in, but I never hit my breakpoint that says we found any of them in the binary. Commenting the PPC_INST_MTSPR out makes it catch these switch cases, but it would be ideal if PPC_INST_MTSPR could properly get parsed.
(Sorry if this is reviving an old issue but seems to be still referenced) It looks like those using Ghidra will see the opcodes without simplified mnemonics - meaning that if you're using another tool such as IDA, you may see the opcodes in their simplified form instead. For instance, two of them I've come across for Dance Central:
In Ghidra:
In IDA Pro:
In this example, IDA shows the instructions slwi and mtctr, however Ghidra shows rlwinm and mtspr respectively. It appears that XenonAnalyse will parse the opcodes using their simplified forms, so swapping those out from original to simplified should help pick up the jump tables properly once identified. (There are other differences too as to how IDA and Ghidra parse out other instructions, but this should at least explain simplified ones.)
For those interested, doing a quick search on "ppc simplified mnemonics" should bring up a document that explains all of the variations you may come across.
Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please
Not sure how everyone else is doing it but sharing my method in case someone has a better one:
Context: C++ code has often switch/case code flows, to the way those are translated to machine code depends on the compiler/version/options. So you need to adjust XenonAnalyse to match what your xex is using.
Step 0: Extract default.xex from your iso with XGDTool, decrypt and unpack the xex with xextool. Make sure you have the xex plugin installed in Ghidra (https://github.com/zeroKilo/XEXLoaderWV), load the xex and analyze it.
Step 1: When analysis is finished, go to Search menu and pick "Decompiled text..." then search text "switch(" without quotes but with open parenthesis. Inspect all the instances one by one until you find all the different patterns below.
Pattern 1: Value for mtspr loaded from memory => Absolute lwzx r0, r12 mtspr CTR, r0
Pattern 2: Value loaded and then rlwin before added => Computed lbzx r0, r12, r10 rlwinm r0, r0, 0x2, 0x0, 0x1d ... add r12, r12, r0 mtspr CTR, r12
Pattern 3: Byte loaded and added as is => offsetSwitch lbzx r0, r12 ... add r12, r12, r0 mtspr CTR, r12
Pattern 4: Half loaded and added as is => wordOffsetSwitch lhzx r0, r12 ... add r12, r12, r0 mtspr CTR, r12
Step 2: When you found the code patterns, you need to edit the switch tables of main.cpp for XenonAnalyse. Things to keep in mind if you use Ghidra to pick the right op code.
-
Ghidra shows subi but you should use addi. Example: 39 8c b0 0c subi r12, r12, 0x4ff4 Since the first two bytes are 39 8c, use PPC_INST_ADDI in the search pattern
-
Ghidra shows ori but you should use nop. Example: 60 00 00 00 ori r0, r0, 0x0 Since the code is the same as nop, use PPC_INST_NOP in the search pattern
-
Ghidra shows mtspr CTR, r12 but you should use PPC_INST_MTCTR in the search pattern
Step 3: Fix ReadTable function in main.cpp of XenonAnalyse to match the pattern offsets you found.
ppc::Disassemble(code + 4, table.base + 0x10, insn); base = insn.operands[1] << 16;
ppc::Disassemble(code + 5, table.base + 0x14, insn); base += insn.operands[2];
For example SWITCH_SHORTOFFSET got the value loaded in R12 from the original pattern from the 4th and 5th code lines in the pattern. Which might be something like this in the xex lis r12, -0x7dd4 addi r12, r12, 0x3870
Step 4: If any of your tables does has anything between the very first lis and addi, make sure you edit the computation of pOffset in ReadTable to match your pattern.