lab313ru / ghidra_psx_ldr

Sony Playstation PSX executables loader for GHIDRA
231 stars 31 forks source link

reg-getter macros: if given an offset, decompiler doesn't produce an assignment statement #61

Open ghost opened 2 years ago

ghost commented 2 years ago

Hello, I noticed that some reg-getter macros are not shown with an assignment statement in the decompiler. This seems to happen when the offset is given. Without an offset it looks fine. Below is an example.

Let me know what you think. Thanks for sharing the project.

Listing:

      f8 ff ac e8     gte_stSXY0 -0x8(a1)
      fc ff ad e8     gte_stSXY1 -0x4(a1)
      00 88 08 48     gte_stSZ1  t0
      00 90 09 48     gte_stSZ2  t1

Decompiler:

      gte_stSXY0();           // Expecting a return value to be assigned.
      gte_stSXY1();           // Expecting a return value to be assigned.
      iVar3 = gte_stSZ1();    // Looks good.
      iVar4 = gte_stSZ2();    // Looks good.
ghost commented 2 years ago

I'm not sure if this fixes the underlying problem, but redefining the OFF_BASE versions of the macros in cop2_regs.inc seems to help. E.g., from

:gte_stSXY0 OFF_BASE is swc2_x_12 & OFF_BASE {
    OFF_BASE = gte_stSXY0();
}

:gte_stSXY1 OFF_BASE is swc2_x_13 & OFF_BASE {
    OFF_BASE = gte_stSXY1();
}

to

:gte_stSXY0 OFF_BASE is swc2_x_12 & OFF_BASE {
    *[ram]:4 OFF_BASE = gte_stSXY0();
}

:gte_stSXY1 OFF_BASE is swc2_x_13 & OFF_BASE {
    *[ram]:4 OFF_BASE = gte_stSXY1();
}

changes the decompiled code from

      gte_stSXY0();
      gte_stSXY1();
      iVar3 = gte_stSZ1();
      iVar4 = gte_stSZ2();

to

      uVar2 = gte_stSXY0();
      *(undefined4 *)param_2 = uVar2;
      uVar2 = gte_stSXY1();
      *(undefined4 *)((int)param_2 + 4) = uVar2;
      iVar5 = gte_stSZ1();
      iVar6 = gte_stSZ2();

This is the correct output for this example.