#!/usr/bin/env python3 """Wrap a raw Tensilica Xtensa firmware image in a minimal ELF32 (EM_XTENSA=94, little-endian). For the Navi31 SMU/MP1 (smu_13_0_0.bin), which is Xtensa windowed-ABI, NOT RS64/RISC-V. Ghidra recognizes EM_XTENSA and offers the Xtensa language (Xtensa:LE:32). Stock IDA has no Xtensa module -> use a community Xtensa processor plugin or Ghidra. usage: mkelf_xtensa.py [entry_hex] """ import struct, sys, os def mkelf_xtensa(raw: bytes, base: int, entry: int|None=None) -> bytes: if entry is None: entry = base EHSIZE, PHENTSIZE = 52, 32 DATA_OFF = 0x1000 e = b'\x7fELF' + bytes([1, 1, 1, 0]) + b'\x00'*8 # ELFCLASS32, LSB e += struct.pack(' 4 else base open(sys.argv[3], 'wb').write(mkelf_xtensa(raw, base, entry)) print(f"{os.path.basename(sys.argv[1])} -> {os.path.basename(sys.argv[3])} " f"EM_XTENSA base={base:#x} entry={entry:#x} size={len(raw):,}")