ethteck / splat

A binary splitting tool to assist with decompilation and modding projects
MIT License
159 stars 42 forks source link

Splat generates negative BSS segment start address #365

Closed Tmcg2 closed 5 months ago

Tmcg2 commented 5 months ago

Apologies if this issue is too game specific

Using splat version 0.23.1 on the US version of Star Wars Rogue Squadron generates a config with a negative address for the start of the BSS segment.

  - name: main
    type: code
    start: 0x1050
    vram: 0x80000450
    follows_vram: entry
    bss_size: 0xE
    subsegments:
      - [0x1050, asm]
      - [0x1040, data]
      - { start: 0x-7FFFF3F0, type: bss, vram: 0x00000010 }

I am 99% certain that the segment immediately after the entry point (0x1040) is rodata rather than code. That appears to be highly non-standard when compared to the games listed in the wiki. I would speculate then that its the source of the issue.

  - name: main
    type: code
    start: 0x01040
    vram: 0x80000440
    follows_vram: entry
    subsegments:
      - [0x01040, rodata] # Part of rodata for main?
      - [0x01070, rodata]
      - [0x01100, rodata]
      - [0x01120, rodata]
      - [0x013D0, rodata]
      - [0x01720, asm] # main code, part of it at least
AngheloAlf commented 5 months ago

This is a known issue. As you say the Star Wars games are highly non-standard (it does some very weird stuff on the entrypoint, going back and forth with the rest of the code), so splat chokes trying to parse the ROM.

Sadly there's no much we can do about it. Maybe we could add some checks to ensure the parsed values make sense.

Tmcg2 commented 5 months ago

Cool, thank you for the information.

Is there any guidance on how to figure out the bss size manually? I've been able to identify most (all?) of the bss segements for the libultra code, but my understanding is that they won't get split out 100% correctly without the bss size being set.

AngheloAlf commented 5 months ago

Usually the games set the bss range of the first segment (aka the boot segment) to zero on the entrypoint function, but this doesn't seem to be the case for this game.

The game may be clearing the bss somewhere else, but you would need to read the assembly and try to figure out where it clears the bss. Knowing the address of the first bss variable may help to do this, because you could search for all the references to it and you may find where it clears the bss. This routine usually has the bss size hardcoded.

If the game does not clear the bss anywhere then you would be in a Paper Mario situation, which is annoying to deal with. In this case your best bet is to just set the bss_size to some number big enough to hold the bss that you have identified. If you realize the bss may be larger then you would need to increase this number. This can be tricky because you may inadvertently mark as bss something from the next segment. Be cautious.

I hope this help.

Tmcg2 commented 5 months ago

Yes that is very helpful, thank you again.

I'm going to go ahead and close this issue then as its a known issue with no clear resolution, no need to have it cluttering up your issues page.