I'm curious how your analyzers handle those tricky MIPS edge cases like split address loads via lui and addiu where you have interleaved instructions in between. If Ghidra fails to collapse those into a single reference, does your math check just flag it as an error and bail, or does it actually try to reconstruct the instruction chain itself?

I wrote an analyzer to do that, you can find it here: https://github.com/boricj/ghidra-delinker-extension/blob/mas...

It uses register dependency graph traversal and code block flow analysis to try and find which two instructions are the likely targets of a HI16/LO16 for a given reference. It also uses an unhealthy amount of recursion and has been rewritten multiple times in order to deal with all these edge cases.

Unfortunately, my extension is only set up for one HI16 relocation having one or many LO16 child relocations. There's an undocumented GNU extension that allows multiple HI16 relocations to be shared by a single LO16 relocation, and I have a really ugly hack that shifts branch targets to "normalize" this into the standard pattern. I don't know why this hack works (I didn't even know about the GNU extension, I thought it was an assembler peephole optimization), but with it my extension can delink the whole of Tenchu: Stealth Assassins without any manual annotations, just the regular references from the cleaned-up Ghidra database.