matt-kempster / m2c

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

Add `.L` local label compatibility #269

Closed DRGN-DRC closed 10 months ago

DRGN-DRC commented 10 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 10 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 10 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 10 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 10 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 10 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 10 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 10 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 10 months ago

Excellent! Will close this then.