mirror of
https://github.com/encounter/decomp.me.git
synced 2026-03-30 11:06:27 -07:00
86b9dfdf8d
* Add has_decompiler for arm32 platforms * Handle missing '.syntax unified' for gba * allow fallback to default compiler if arch is supported
274 lines
7.5 KiB
Python
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,
|
|
}
|
|
)
|