Files
Mark Street 86b9dfdf8d Add has_decompiler for arm32 platforms (#1741)
* Add has_decompiler for arm32 platforms

* Handle missing '.syntax unified' for gba

* allow fallback to default compiler if arch is supported
2025-11-15 12:12:12 +00:00

274 lines
7.5 KiB
Python

import logging
from dataclasses import dataclass, field
from typing import Any, Dict, OrderedDict
from pathlib import Path
import functools
from coreapp import compilers
from coreapp.flags import (
COMMON_DIFF_FLAGS,
COMMON_MIPS_DIFF_FLAGS,
COMMON_MSDOS_DIFF_FLAGS,
Flags,
)
from coreapp.models.scratch import Scratch
from rest_framework.exceptions import APIException
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class Platform:
id: str
name: str
description: str
arch: str
assemble_cmd: str
objdump_cmd: str
nm_cmd: str
diff_flags: Flags = field(default_factory=lambda: COMMON_DIFF_FLAGS, hash=False)
supports_objdump_disassemble: bool = False # TODO turn into objdump flag
has_decompiler: bool = False
@property
@functools.lru_cache()
def asm_prelude(self) -> str:
asm_prelude_path: Path = Path(__file__).parent / "asm_preludes" / f"{self.id}.s"
if asm_prelude_path.is_file():
return asm_prelude_path.read_text()
return ""
def get_num_scratches(self) -> int:
return Scratch.objects.filter(platform=self.id).count()
def to_json(
self,
include_compilers: bool = False,
include_num_scratches: bool = False,
) -> Dict[str, Any]:
ret: Dict[str, Any] = {
"id": self.id,
"name": self.name,
"description": self.description,
"arch": self.arch,
"has_decompiler": self.has_decompiler,
}
if include_compilers:
ret["compilers"] = [
x.id
for x in compilers.available_compilers()
if x.platform.id == self.id
]
if include_num_scratches:
ret["num_scratches"] = self.get_num_scratches()
return ret
def from_id(platform_id: str) -> Platform:
if platform_id not in _platforms:
raise APIException(f"Unknown platform: {platform_id}")
return _platforms[platform_id]
DUMMY = Platform(
id="dummy",
name="Dummy System",
description="DMY",
arch="dummy",
assemble_cmd='echo "assembled("$INPUT")" > "$OUTPUT"',
objdump_cmd="echo",
nm_cmd="echo",
)
MSDOS = Platform(
id="msdos",
name="Microsoft DOS",
description="x86",
arch="x86",
assemble_cmd='jwasm -c -Fo"$OUTPUT" -Fi"$PRELUDE" "$INPUT"',
objdump_cmd="omf-objdump --no-objects",
nm_cmd="omf-nm",
supports_objdump_disassemble=True,
diff_flags=COMMON_DIFF_FLAGS + COMMON_MSDOS_DIFF_FLAGS,
)
WIN32 = Platform(
id="win32",
name="Windows (9x/NT)",
description="x86 (32bit)",
arch="i686",
assemble_cmd='i686-w64-mingw32-as --32 -mmnemonic=intel -msyntax=intel -mnaked-reg -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="i686-w64-mingw32-objdump",
nm_cmd="i686-w64-mingw32-nm",
)
SWITCH = Platform(
id="switch",
name="Nintendo Switch",
description="ARMv8-A",
arch="aarch64",
assemble_cmd='aarch64-linux-gnu-as -mcpu=cortex-a57+fp+simd+crypto+crc -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="aarch64-linux-gnu-objdump",
nm_cmd="aarch64-linux-gnu-nm",
supports_objdump_disassemble=True,
)
N64 = Platform(
id="n64",
name="Nintendo 64",
description="MIPS (big-endian)",
arch="mips",
assemble_cmd='mips-linux-gnu-as -march=vr4300 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="mips-linux-gnu-objdump",
nm_cmd="mips-linux-gnu-nm",
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
has_decompiler=True,
)
IRIX = Platform(
id="irix",
name="IRIX",
description="MIPS (big-endian, PIC)",
arch="mips",
assemble_cmd='mips-linux-gnu-as -march=vr4300 -mabi=32 -KPIC -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="mips-linux-gnu-objdump",
nm_cmd="mips-linux-gnu-nm",
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
has_decompiler=True,
)
PS1 = Platform(
id="ps1",
name="PlayStation",
description="MIPS (little-endian)",
arch="mipsel",
assemble_cmd='mips-linux-gnu-as -EL -march=r3000 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="mips-linux-gnu-objdump",
nm_cmd="mips-linux-gnu-nm",
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
has_decompiler=True,
)
PSP = Platform(
id="psp",
name="PlayStation Portable",
description="MIPS (little-endian)",
arch="mipsel:4000",
assemble_cmd='mips-ps2-decompals-as -EL -march=gs464 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="mips-ps2-decompals-objdump",
nm_cmd="mips-ps2-decompals-nm",
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
has_decompiler=True,
)
SATURN = Platform(
id="saturn",
name="Saturn",
description="SH2 (big-endian)",
arch="sh2",
assemble_cmd='sh-elf-as --isa=sh2 --big -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="sh-elf-objdump",
nm_cmd="sh-elf-nm",
diff_flags=COMMON_DIFF_FLAGS,
)
DREAMCAST = Platform(
id="dreamcast",
name="Dreamcast",
description="SH4 (little-endian)",
arch="sh4",
assemble_cmd='sh-elf-as --isa=sh4 --little --relax -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="sh-elf-objdump",
nm_cmd="sh-elf-nm",
diff_flags=COMMON_DIFF_FLAGS,
has_decompiler=False,
)
PS2 = Platform(
id="ps2",
name="PlayStation 2",
description="MIPS (little-endian)",
arch="mipsee",
assemble_cmd='mips-ps2-decompals-as -EL -march=r5900 -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="mips-ps2-decompals-objdump",
nm_cmd="mips-ps2-decompals-nm",
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
has_decompiler=True,
)
MACOSX = Platform(
id="macosx",
name="Mac OS X",
description="PowerPC",
arch="ppc",
assemble_cmd='powerpc-linux-gnu-as -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="powerpc-linux-gnu-objdump",
nm_cmd="powerpc-linux-gnu-nm",
)
GC_WII = Platform(
id="gc_wii",
name="GameCube / Wii",
description="PowerPC",
arch="ppc",
assemble_cmd='powerpc-eabi-as -mgekko -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="powerpc-eabi-objdump -M broadway",
nm_cmd="powerpc-eabi-nm",
has_decompiler=True,
)
NDS_ARM9 = Platform(
id="nds_arm9",
name="Nintendo DS",
description="ARMv5TE",
arch="arm32",
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -march=armv5te -mthumb -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="arm-none-eabi-objdump",
nm_cmd="arm-none-eabi-nm",
has_decompiler=True,
)
GBA = Platform(
id="gba",
name="Game Boy Advance",
description="ARMv4T",
arch="arm32",
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -mcpu=arm7tdmi -mthumb -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="arm-none-eabi-objdump",
nm_cmd="arm-none-eabi-nm",
has_decompiler=True,
)
N3DS = Platform(
id="n3ds",
name="Nintendo 3DS",
description="ARMv6K",
arch="arm32",
assemble_cmd='sed -i -e "s/;/;@/" "$INPUT" && arm-none-eabi-as -mfpu=vfpv2 -march=armv6k -o "$OUTPUT" "$PRELUDE" "$INPUT"',
objdump_cmd="arm-none-eabi-objdump",
nm_cmd="arm-none-eabi-nm",
has_decompiler=True,
)
_platforms: OrderedDict[str, Platform] = OrderedDict(
{
"dummy": DUMMY,
"irix": IRIX,
"n64": N64,
"gc_wii": GC_WII,
"switch": SWITCH,
"gba": GBA,
"nds_arm9": NDS_ARM9,
"n3ds": N3DS,
"ps1": PS1,
"ps2": PS2,
"psp": PSP,
"saturn": SATURN,
"dreamcast": DREAMCAST,
"macosx": MACOSX,
"msdos": MSDOS,
"win32": WIN32,
}
)