matt-kempster / m2c

A MIPS and PowerPC decompiler.
GNU General Public License v3.0
386 stars 46 forks source link

Add `.L` local label compatibility #269

Closed DRGN-DRC closed 5 months ago

DRGN-DRC commented 5 months ago

Some decompilation projects are using conventions such as .L_80112818 for local labels. This should allow decomp.me to understand them.

ribbanya commented 5 months ago

I noticed #204 introduced tests which use this style of label, I wonder what the difference is? https://github.com/matt-kempster/m2c/blob/1c328cab8262728574335289a4f2115a8d937ed9/tests/end_to_end/andor_loops/mwcc-o4p.s#L5-L82

DRGN-DRC commented 5 months ago

I suppose those are identified as global labels, per the line above the one I edited (line 339): re_local_glabel = re.compile("L(_.*_)?[0-9A-F]{8}") Though I don't know why those tests would pass while decomp.me throws an error trying to decompile the functions I've fed it.

simonlindholm commented 5 months ago

This addition shouldn't be necessary, all labels starting with . are already treated as local. Can you give an example of a function that fails to decompile?

ribbanya commented 5 months ago

Ah, it's not with the declarations but their usage it seems.

scratch

.global ftSk_SpecialAirNLoop_IASA
ftSk_SpecialAirNLoop_IASA:
/* 801127A4 0010F384  7C 08 02 A6 */    mflr r0
/* 801127A8 0010F388  90 01 00 04 */    stw r0, 4(r1)
/* 801127AC 0010F38C  94 21 FF E0 */    stwu r1, -0x20(r1)
/* 801127B0 0010F390  93 E1 00 1C */    stw r31, 0x1c(r1)
/* 801127B4 0010F394  93 C1 00 18 */    stw r30, 0x18(r1)
/* 801127B8 0010F398  7C 7E 1B 78 */    mr r30, r3
/* 801127BC 0010F39C  83 E3 00 2C */    lwz r31, 0x2c(r3)
/* 801127C0 0010F3A0  80 1F 06 5C */    lwz r0, 0x65c(r31)
/* 801127C4 0010F3A4  54 00 05 AD */    rlwinm. r0, r0, 0, 0x16, 0x16
/* 801127C8 0010F3A8  40 82 00 50 */    bne .L_80112818
/* 801127CC 0010F3AC  38 00 00 00 */    li r0, 0
/* 801127D0 0010F3B0  90 1F 23 40 */    stw r0, 0x2340(r31)
/* 801127D4 0010F3B4  38 7E 00 00 */    addi r3, r30, 0
/* 801127D8 0010F3B8  38 80 01 5C */    li r4, 0x15c
/* 801127DC 0010F3BC  C0 22 9C 70 */    lfs f1, ftSk_Init_804D9650@sda21(r2)
/* 801127E0 0010F3C0  38 A0 00 00 */    li r5, 0
/* 801127E4 0010F3C4  C0 42 9C 74 */    lfs f2, ftSk_Init_804D9654@sda21(r2)
/* 801127E8 0010F3C8  38 C0 00 00 */    li r6, 0
/* 801127EC 0010F3CC  FC 60 08 90 */    fmr f3, f1
/* 801127F0 0010F3D0  4B F5 6B BD */    bl Fighter_ChangeMotionState
/* 801127F4 0010F3D4  3C 60 80 11 */    lis r3, ftSk_Init_80110198@ha
/* 801127F8 0010F3D8  80 BE 00 2C */    lwz r5, 0x2c(r30)
/* 801127FC 0010F3DC  38 83 01 98 */    addi r4, r3, ftSk_Init_80110198@l
/* 80112800 0010F3E0  90 85 21 DC */    stw r4, 0x21dc(r5)
/* 80112804 0010F3E4  3C 60 80 11 */    lis r3, .L_80112D44@ha
/* 80112808 0010F3E8  38 03 2D 44 */    addi r0, r3, .L_80112D44@l
/* 8011280C 0010F3EC  90 85 21 E4 */    stw r4, 0x21e4(r5)
/* 80112810 0010F3F0  90 1F 21 BC */    stw r0, 0x21bc(r31)
/* 80112814 0010F3F4  48 00 00 44 */    b .L_80112858
.L_80112818:
/* 80112818 0010F3F8  80 1F 06 68 */    lwz r0, 0x668(r31)
/* 8011281C 0010F3FC  54 00 00 01 */    rlwinm. r0, r0, 0, 0, 0
/* 80112820 0010F400  41 82 00 38 */    beq .L_80112858
/* 80112824 0010F404  C0 22 9C 70 */    lfs f1, ftSk_Init_804D9650@sda21(r2)
/* 80112828 0010F408  7F C3 F3 78 */    mr r3, r30
/* 8011282C 0010F40C  C0 42 9C 74 */    lfs f2, ftSk_Init_804D9654@sda21(r2)
/* 80112830 0010F410  38 80 01 5B */    li r4, 0x15b
/* 80112834 0010F414  FC 60 08 90 */    fmr f3, f1
/* 80112838 0010F418  38 A0 00 00 */    li r5, 0
/* 8011283C 0010F41C  38 C0 00 00 */    li r6, 0
/* 80112840 0010F420  4B F5 6B 6D */    bl Fighter_ChangeMotionState
/* 80112844 0010F424  3C 60 80 11 */    lis r3, ftSk_Init_80110198@ha
/* 80112848 0010F428  80 9E 00 2C */    lwz r4, 0x2c(r30)
/* 8011284C 0010F42C  38 03 01 98 */    addi r0, r3, ftSk_Init_80110198@l
/* 80112850 0010F430  90 04 21 DC */    stw r0, 0x21dc(r4)
/* 80112854 0010F434  90 04 21 E4 */    stw r0, 0x21e4(r4)
.L_80112858:
/* 80112858 0010F438  80 01 00 24 */    lwz r0, 0x24(r1)
/* 8011285C 0010F43C  83 E1 00 1C */    lwz r31, 0x1c(r1)
/* 80112860 0010F440  83 C1 00 18 */    lwz r30, 0x18(r1)
/* 80112864 0010F444  38 21 00 20 */    addi r1, r1, 0x20
/* 80112868 0010F448  7C 08 03 A6 */    mtlr r0
/* 8011286C 0010F44C  4E 80 00 20 */    blr
extern ? ftSk_Init_804D9650;
extern ? ftSk_Init_804D9654;

/*
Internal error in function ftSk_SpecialAirNLoop_IASA:

Traceback (most recent call last):
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/instruction.py", line 215, in set_current_instr
    yield
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 2157, in set_current_instr
    yield
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 3596, in translate_node_body
    evaluate_instruction(instr_ref, state)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 3582, in evaluate_instruction
    eval_fn(state, args)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/arch_ppc.py", line 968, in <lambda>
    a.reg_ref(0), cls.instrs_destination_first[mnemonic](a)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/arch_ppc.py", line 1233, in <lambda>
    "lis": lambda a: load_upper(a),
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/evaluate.py", line 168, in load_upper
    ref = args.hi_imm(1)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 2373, in hi_imm
    raise DecompFailure(f"Invalid macro argument {arg.argument}")
m2c.error.DecompFailure: Invalid macro argument .L_80112D44

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/main.py", line 226, in run
    raise function_info
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/main.py", line 183, in run
    info = translate_to_ast(function, flow_graph, options, global_info)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 4390, in translate_to_ast
    translate_all_blocks(state, used_naive_phis, return_blocks, options)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 3793, in translate_all_blocks
    block_info = translate_block(state, options)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 3630, in translate_block
    block_info = translate_node_body(state)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 3595, in translate_node_body
    with state.regs.set_current_instr(instr_ref):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/translate.py", line 2156, in set_current_instr
    with set_current_instr(instr_ref.instruction):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ethteck/.cache/pypoetry/virtualenvs/backend-xRJ-wtRq-py3.10/lib/python3.10/site-packages/m2c/instruction.py", line 217, in set_current_instr
    raise InstrProcessingFailure(instr) from e
m2c.instruction.InstrProcessingFailure: Error while processing instruction:
lis $r3, %ha(.L_80112D44)
*/
/* Warning: struct HSD_Spline is not defined (only forward-declared) */
/* Warning: struct _HSD_Rvalue is not defined (only forward-declared) */
/* Warning: struct _HSD_RObjDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_ExpDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_ByteCodeExpDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_IKHintDesc is not defined (only forward-declared) */
/* Warning: struct UnkFloat6_Camera is not defined (only forward-declared) */

void ftSk_SpecialAirNLoop_IASA(void) {
    // ...
}
ribbanya commented 5 months ago

In this case it's being used as a callback, I believe. So the function really shouldn't be anonymous, but the assembler is able to handle it just fine.

.L_80112D44:
/* 80112D44 0010F924  7C 08 02 A6 */    mflr r0
/* 80112D48 0010F928  90 01 00 04 */    stw r0, 4(r1)
/* 80112D4C 0010F92C  94 21 FF D0 */    stwu r1, -0x30(r1)
/* 80112D50 0010F930  93 E1 00 2C */    stw r31, 0x2c(r1)
/* 80112D54 0010F934  93 C1 00 28 */    stw r30, 0x28(r1)
/* 80112D58 0010F938  7C 7E 1B 78 */    mr r30, r3
/* 80112D5C 0010F93C  93 A1 00 24 */    stw r29, 0x24(r1)
/* 80112D60 0010F940  83 E3 00 2C */    lwz r31, 0x2c(r3)
/* 80112D64 0010F944  80 1F 23 44 */    lwz r0, 0x2344(r31)
/* 80112D68 0010F948  83 BF 02 D4 */    lwz r29, 0x2d4(r31)
/* 80112D6C 0010F94C  2C 00 00 00 */    cmpwi r0, 0
/* 80112D70 0010F950  41 82 01 4C */    beq .L_80112EBC
/* 80112D74 0010F954  38 00 00 00 */    li r0, 0
/* 80112D78 0010F958  90 1F 23 44 */    stw r0, 0x2344(r31)
/* 80112D7C 0010F95C  80 1F 22 2C */    lwz r0, 0x222c(r31)
/* 80112D80 0010F960  2C 00 00 00 */    cmpwi r0, 0
/* 80112D84 0010F964  40 81 01 38 */    ble .L_80112EBC
/* 80112D88 0010F968  80 7F 00 B0 */    lwz r3, 0xb0(r31)
/* 80112D8C 0010F96C  80 1F 00 B4 */    lwz r0, 0xb4(r31)
/* 80112D90 0010F970  90 61 00 14 */    stw r3, 0x14(r1)
/* 80112D94 0010F974  90 01 00 18 */    stw r0, 0x18(r1)
/* 80112D98 0010F978  80 1F 00 B8 */    lwz r0, 0xb8(r31)
/* 80112D9C 0010F97C  90 01 00 1C */    stw r0, 0x1c(r1)
/* 80112DA0 0010F980  80 1F 00 E0 */    lwz r0, 0xe0(r31)
/* 80112DA4 0010F984  2C 00 00 00 */    cmpwi r0, 0
/* 80112DA8 0010F988  40 82 00 58 */    bne .L_80112E00
/* 80112DAC 0010F98C  C0 3D 00 00 */    lfs f1, 0(r29)
/* 80112DB0 0010F990  38 60 00 09 */    li r3, 9
/* 80112DB4 0010F994  C0 1F 00 2C */    lfs f0, 0x2c(r31)
/* 80112DB8 0010F998  C0 5F 00 38 */    lfs f2, 0x38(r31)
/* 80112DBC 0010F99C  EC 21 00 32 */    fmuls f1, f1, f0
/* 80112DC0 0010F9A0  C0 01 00 14 */    lfs f0, 0x14(r1)
/* 80112DC4 0010F9A4  EC 02 00 7A */    fmadds f0, f2, f1, f0
/* 80112DC8 0010F9A8  D0 01 00 14 */    stfs f0, 0x14(r1)
/* 80112DCC 0010F9AC  48 26 D7 B5 */    bl HSD_Randi
/* 80112DD0 0010F9B0  3C 80 80 3D */    lis r4, ftSk_SpecialN_803CC598@ha
/* 80112DD4 0010F9B4  C0 5D 00 04 */    lfs f2, 4(r29)
/* 80112DD8 0010F9B8  54 63 10 3A */    slwi r3, r3, 2
/* 80112DDC 0010F9BC  C0 7F 00 38 */    lfs f3, 0x38(r31)
/* 80112DE0 0010F9C0  38 04 C5 98 */    addi r0, r4, ftSk_SpecialN_803CC598@l
/* 80112DE4 0010F9C4  C0 01 00 18 */    lfs f0, 0x18(r1)
/* 80112DE8 0010F9C8  7C 60 1A 14 */    add r3, r0, r3
/* 80112DEC 0010F9CC  C0 23 00 00 */    lfs f1, 0(r3)
/* 80112DF0 0010F9D0  EC 22 08 2A */    fadds f1, f2, f1
/* 80112DF4 0010F9D4  EC 03 00 7A */    fmadds f0, f3, f1, f0
/* 80112DF8 0010F9D8  D0 01 00 18 */    stfs f0, 0x18(r1)
/* 80112DFC 0010F9DC  48 00 00 58 */    b .L_80112E54
.L_80112E00:
/* 80112E00 0010F9E0  C0 3D 00 08 */    lfs f1, 8(r29)
/* 80112E04 0010F9E4  38 60 00 09 */    li r3, 9
/* 80112E08 0010F9E8  C0 1F 00 2C */    lfs f0, 0x2c(r31)
/* 80112E0C 0010F9EC  C0 5F 00 38 */    lfs f2, 0x38(r31)
/* 80112E10 0010F9F0  EC 21 00 32 */    fmuls f1, f1, f0
/* 80112E14 0010F9F4  C0 01 00 14 */    lfs f0, 0x14(r1)
/* 80112E18 0010F9F8  EC 02 00 7A */    fmadds f0, f2, f1, f0
/* 80112E1C 0010F9FC  D0 01 00 14 */    stfs f0, 0x14(r1)
/* 80112E20 0010FA00  48 26 D7 61 */    bl HSD_Randi
/* 80112E24 0010FA04  3C 80 80 3D */    lis r4, ftSk_SpecialN_803CC598@ha
/* 80112E28 0010FA08  C0 62 9C 78 */    lfs f3, ftSk_Init_804D9658@sda21(r2)
/* 80112E2C 0010FA0C  54 63 10 3A */    slwi r3, r3, 2
/* 80112E30 0010FA10  C0 3D 00 0C */    lfs f1, 0xc(r29)
/* 80112E34 0010FA14  38 04 C5 98 */    addi r0, r4, ftSk_SpecialN_803CC598@l
/* 80112E38 0010FA18  C0 9F 00 38 */    lfs f4, 0x38(r31)
/* 80112E3C 0010FA1C  7C 60 1A 14 */    add r3, r0, r3
/* 80112E40 0010FA20  C0 01 00 18 */    lfs f0, 0x18(r1)
/* 80112E44 0010FA24  C0 43 00 00 */    lfs f2, 0(r3)
/* 80112E48 0010FA28  EC 23 08 BA */    fmadds f1, f3, f2, f1
/* 80112E4C 0010FA2C  EC 04 00 7A */    fmadds f0, f4, f1, f0
/* 80112E50 0010FA30  D0 01 00 18 */    stfs f0, 0x18(r1)
.L_80112E54:
/* 80112E54 0010FA34  C0 02 9C 70 */    lfs f0, ftSk_Init_804D9650@sda21(r2)
/* 80112E58 0010FA38  38 7E 00 00 */    addi r3, r30, 0
/* 80112E5C 0010FA3C  38 81 00 14 */    addi r4, r1, 0x14
/* 80112E60 0010FA40  D0 01 00 1C */    stfs f0, 0x1c(r1)
/* 80112E64 0010FA44  38 A0 00 4F */    li r5, 0x4f
/* 80112E68 0010FA48  C0 3F 00 2C */    lfs f1, 0x2c(r31)
/* 80112E6C 0010FA4C  48 19 CF 21 */    bl it_802AFD8C
/* 80112E70 0010FA50  28 03 00 00 */    cmplwi r3, 0
/* 80112E74 0010FA54  41 82 00 10 */    beq .L_80112E84
/* 80112E78 0010FA58  38 9E 00 00 */    addi r4, r30, 0
/* 80112E7C 0010FA5C  38 A0 00 00 */    li r5, 0
/* 80112E80 0010FA60  48 19 D0 29 */    bl it_802AFEA8
.L_80112E84:
/* 80112E84 0010FA64  80 7F 22 2C */    lwz r3, 0x222c(r31)
/* 80112E88 0010FA68  38 9E 00 00 */    addi r4, r30, 0
/* 80112E8C 0010FA6C  38 A1 00 14 */    addi r5, r1, 0x14
/* 80112E90 0010FA70  4C C6 31 82 */    crclr 6
/* 80112E94 0010FA74  38 03 FF FF */    addi r0, r3, -1
/* 80112E98 0010FA78  90 1F 22 2C */    stw r0, 0x222c(r31)
/* 80112E9C 0010FA7C  38 60 05 03 */    li r3, 0x503
/* 80112EA0 0010FA80  4B F4 CF 3D */    bl efSync_Spawn
/* 80112EA4 0010FA84  3C 80 00 04 */    lis r4, 0x00041F3C@ha
/* 80112EA8 0010FA88  38 7F 00 00 */    addi r3, r31, 0
/* 80112EAC 0010FA8C  38 84 1F 3C */    addi r4, r4, 0x00041F3C@l
/* 80112EB0 0010FA90  38 A0 00 7F */    li r5, 0x7f
/* 80112EB4 0010FA94  38 C0 00 40 */    li r6, 0x40
/* 80112EB8 0010FA98  4B F7 52 91 */    bl ft_80088148
.L_80112EBC:
/* 80112EBC 0010FA9C  80 01 00 34 */    lwz r0, 0x34(r1)
/* 80112EC0 0010FAA0  83 E1 00 2C */    lwz r31, 0x2c(r1)
/* 80112EC4 0010FAA4  83 C1 00 28 */    lwz r30, 0x28(r1)
/* 80112EC8 0010FAA8  83 A1 00 24 */    lwz r29, 0x24(r1)
/* 80112ECC 0010FAAC  38 21 00 30 */    addi r1, r1, 0x30
/* 80112ED0 0010FAB0  7C 08 03 A6 */    mtlr r0
/* 80112ED4 0010FAB4  4E 80 00 20 */    blr
simonlindholm commented 5 months ago

Coincidentally I think this should have been fixed by 0514701ef53ce46e91e4e675455c44647714d014 just a few weeks ago, but decomp.me has yet to bump their m2c dep to that version.

ribbanya commented 5 months ago

Confirmed locally that it works with this function on 0514701ef53ce46e91e4e675455c44647714d014.

extern ? .L_80112D44;
extern f32 ftSk_Init_804D9650;
extern f32 ftSk_Init_804D9654;

void ftSk_SpecialAirNLoop_IASA(HSD_GObj *gobj) {
    void *temp_r31;
    void *temp_r4;
    void *temp_r5;

    temp_r31 = gobj->user_data;
    if (!(temp_r31->unk65C & 0x200)) {
        temp_r31->unk2340 = 0;
        Fighter_ChangeMotionState((Fighter_GObj *) gobj, 0x15C, 0U, ftSk_Init_804D9650, ftSk_Init_804D9654, ftSk_Init_804D9650, NULL);
        temp_r5 = gobj->user_data;
        temp_r5->unk21DC = ftSk_Init_80110198;
        temp_r5->unk21E4 = ftSk_Init_80110198;
        temp_r31->unk21BC = &.L_80112D44;
        return;
    }
    if (temp_r31->unk668 & 0x80000000) {
        Fighter_ChangeMotionState((Fighter_GObj *) gobj, 0x15B, 0U, ftSk_Init_804D9650, ftSk_Init_804D9654, ftSk_Init_804D9650, NULL);
        temp_r4 = gobj->user_data;
        temp_r4->unk21DC = ftSk_Init_80110198;
        temp_r4->unk21E4 = ftSk_Init_80110198;
    }
}
/* Warning: struct HSD_Spline is not defined (only forward-declared) */
/* Warning: struct _HSD_Rvalue is not defined (only forward-declared) */
/* Warning: struct _HSD_RObjDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_ExpDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_ByteCodeExpDesc is not defined (only forward-declared) */
/* Warning: struct _HSD_IKHintDesc is not defined (only forward-declared) */
/* Warning: struct UnkFloat6_Camera is not defined (only forward-declared) */
simonlindholm commented 5 months ago

Excellent! Will close this then.