Add basic support for s390x (#2873)

* Add basic support for s390x

---------

Co-authored-by: intrigus <abc123zeus@live.de>
Co-authored-by: patryk4815 <bux.patryk@gmail.com>
pull/2876/head^2
intrigus-lgtm 8 months ago committed by GitHub
parent 12116a82c5
commit 0e15e5c9a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -46,6 +46,7 @@ CapstoneArch = {
"sparc": CS_ARCH_SPARC,
"rv32": CS_ARCH_RISCV,
"rv64": CS_ARCH_RISCV,
"s390x": CS_ARCH_SYSZ,
}
CapstoneEndian = {
@ -69,6 +70,7 @@ VariableInstructionSizeMax = {
"mips": 8,
"rv32": 22,
"rv64": 22,
"s390x": 6,
}
@ -180,7 +182,9 @@ def get_disassembler(address):
extra = CS_MODE_RISCV32 | CS_MODE_RISCVC # novermin
elif pwndbg.aglib.arch.name == "rv64":
extra = CS_MODE_RISCV64 | CS_MODE_RISCVC # novermin
elif pwndbg.aglib.arch.name == "s390x":
# The ptrsize base modes cause capstone.CsError: Invalid mode (CS_ERR_MODE)
extra = 0
else:
extra = None

@ -39,6 +39,9 @@ from capstone.riscv import RISCV_INS_JAL
from capstone.riscv import RISCV_INS_JALR
from capstone.sparc import SPARC_INS_JMP
from capstone.sparc import SPARC_INS_JMPL
from capstone.systemz import SYSZ_INS_B
from capstone.systemz import SYSZ_INS_BAL
from capstone.systemz import SYSZ_INS_BALR
from capstone.x86 import X86_INS_JMP
from capstone.x86 import X86Op
from typing_extensions import override
@ -67,6 +70,7 @@ UNCONDITIONAL_JUMP_INSTRUCTIONS: Dict[int, Set[int]] = {
RISCV_INS_C_JR,
},
CS_ARCH_PPC: {PPC_INS_B, PPC_INS_BA, PPC_INS_BL, PPC_INS_BLA},
CS_ARCH_SYSZ: {SYSZ_INS_B, SYSZ_INS_BAL, SYSZ_INS_BALR},
}
# See: https://github.com/capstone-engine/capstone/issues/2448

@ -55,6 +55,7 @@ gdb_architecture_name_fixup_list = (
"riscv:rv64",
"riscv",
"loongarch64",
"s390:64-bit",
)
@ -762,6 +763,8 @@ class GDBProcess(pwndbg.dbg_mod.Process):
elif match == "rs6000":
# The RS/6000 architecture is compatible with the PowerPC common
match = "powerpc"
elif match == "s390:64-bit":
match = "s390x"
return GDBArch(endian, match, ptrsize) # type: ignore[arg-type]
if not_exactly_arch:

@ -91,6 +91,7 @@ arch_to_UC = {
# 'powerpc': U.UC_ARCH_PPC,
"rv32": U.UC_ARCH_RISCV,
"rv64": U.UC_ARCH_RISCV,
"s390x": U.UC_ARCH_S390X,
}
# Architecture specific maps: Map<"UC_*_REG_*",constant>
@ -104,6 +105,7 @@ arch_to_UC_consts = {
"aarch64": parse_consts(U.arm64_const),
"rv32": parse_consts(U.riscv_const),
"rv64": parse_consts(U.riscv_const),
"s390x": parse_consts(U.s390x_const),
}
# Architecture specific maps: Map<reg_name, Unicorn constant>
@ -122,8 +124,13 @@ arch_to_reg_const_map = {
),
"rv32": create_reg_to_const_map(arch_to_UC_consts["rv32"]),
"rv64": create_reg_to_const_map(arch_to_UC_consts["rv64"]),
"s390x": create_reg_to_const_map(arch_to_UC_consts["s390x"]),
}
# Architectures for which we want to enable virtual TLB mode
enable_virtual_tlb = {
"s390x": True,
}
# combine the flags with | operator. -1 for all
(
@ -224,6 +231,10 @@ class Emulator:
debug(DEBUG_INIT, "uc = U.Uc(%r, %r)", (arch_to_UC[self.arch], self.uc_mode))
self.uc = U.Uc(arch_to_UC[self.arch], self.uc_mode)
if enable_virtual_tlb.get(self.arch, False):
debug(DEBUG_INIT, "# Setting TLB mode to virtual")
self.uc.ctl_set_tlb_mode(U.UC_TLB_VIRTUAL) # type: ignore[attr-defined]
self.regs: pwndbg.lib.regs.RegisterSet = pwndbg.aglib.regs.current
# Whether the emulator is allowed to emulate instructions
@ -592,6 +603,8 @@ class Emulator:
and "isa32r6" in gdb.newest_frame().architecture().name()
):
mode |= U.UC_MODE_MIPS32R6
elif arch == "s390x":
pass # fails with invalid mode error otherwise
else:
mode |= {4: U.UC_MODE_32, 8: U.UC_MODE_64}[pwndbg.aglib.arch.ptrsize]

@ -20,6 +20,7 @@ PWNDBG_SUPPORTED_ARCHITECTURES_TYPE = Literal[
"sparc",
"powerpc",
"loongarch64",
"s390x",
]
PWNDBG_SUPPORTED_ARCHITECTURES: list[PWNDBG_SUPPORTED_ARCHITECTURES_TYPE] = list(
@ -40,6 +41,7 @@ PWNLIB_ARCH_MAPPINGS = {
"powerpc": "powerpc",
"sparc": "sparc",
"loongarch64": "none",
"s390x": "s390", # FIXME: I believe this should be s390x, but that's not supported
}

@ -668,6 +668,46 @@ loongarch64 = RegisterSet(
misc=("tp", "r21"),
)
# https://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_zSeries/x410.html
# Register name | Usage | Call effect
# --------------|--------------------------------|----------------
# r0 | General purpose | Volatile
# r1 | General purpose | Volatile
# r2 | Parameter passing and return | Volatile
# r3, r4, r5 | Parameter passing | Volatile
# r6 | Parameter passing | Saved
# r7 - r11 | Local variables | Saved
# r12 | Local variable, commonly used | Saved
# | as GOT pointer |
# r13 | Local variable, commonly used | Saved
# | as Literal Pool pointer |
# r14 | Return address | Volatile
# r15 | Stack pointer | Saved
s390x = RegisterSet(
pc="pc",
retaddr=("r14",),
stack="r15",
flags={"pswm": BitFlags()},
gpr=(
"r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
),
args=("r2", "r3", "r4", "r5", "r6"),
retval="r2",
)
reg_sets: Dict[PWNDBG_SUPPORTED_ARCHITECTURES_TYPE, RegisterSet] = {
"i386": i386,
"i8086": i386,
@ -681,4 +721,5 @@ reg_sets: Dict[PWNDBG_SUPPORTED_ARCHITECTURES_TYPE, RegisterSet] = {
"aarch64": aarch64,
"powerpc": powerpc,
"loongarch64": loongarch64,
"s390x": s390x,
}

Loading…
Cancel
Save