Skip to content

Fix qdb support for ARM Cortex-M #1574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion qiling/debugger/qdb/arch/arch_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from typing import Dict, Optional
from typing import ClassVar, Dict, Optional

from .arch import Arch


class ArchARM(Arch):
_flags_reg: ClassVar[str] = 'cpsr'

def __init__(self) -> None:
regs = (
'r0', 'r1', 'r2', 'r3',
Expand Down Expand Up @@ -134,6 +136,8 @@ def read_insn(self, address: int) -> Optional[bytearray]:


class ArchCORTEX_M(ArchARM):
_flags_reg: ClassVar[str] = 'xpsr'

def __init__(self):
super().__init__()

Expand Down
14 changes: 7 additions & 7 deletions qiling/debugger/qdb/branch_predictor/branch_predictor_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ class BranchPredictorARM(BranchPredictor, ArchARM):

stop = 'udf'

def get_cpsr(self) -> Tuple[bool, bool, bool, bool]:
"""Get flags map of CPSR.
def get_cond_flags(self) -> Tuple[bool, bool, bool, bool]:
"""Get condition status flags from CPSR / xPSR.
"""

cpsr = self.read_reg('cpsr')
cpsr = self.read_reg(self._flags_reg)

return (
(cpsr & (0b1 << 28)) != 0, # V, overflow flag
Expand Down Expand Up @@ -122,9 +122,9 @@ def __parse_op(op: ArmOp, *args, **kwargs) -> Optional[int]:

def __is_taken(cc: int) -> Tuple[bool, Tuple[bool, ...]]:
pred = predicate[cc]
cpsr = self.get_cpsr()
flags = self.get_cond_flags()

return pred(*cpsr), cpsr
return pred(*flags), flags

# conditions predicate selector
predicate: Dict[int, Callable[..., bool]] = {
Expand Down Expand Up @@ -215,13 +215,13 @@ def __is_taken(cc: int) -> Tuple[bool, Tuple[bool, ...]]:
where = __parse_op(operands[1], **msize[suffix])

elif iname in binop:
going, cpsr = __is_taken(insn.cc)
going, flags = __is_taken(insn.cc)

if going:
operator = binop[iname]
op1 = __parse_op(operands[1])
op2 = __parse_op(operands[2])
carry = int(cpsr[1])
carry = int(flags[1])

where = (op1 and op2) and operator(op1, op2, carry)

Expand Down
4 changes: 2 additions & 2 deletions qiling/debugger/qdb/render/render_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from typing import Iterator, Optional
from typing import Iterator

from .render import Render, ContextRender
from ..arch import ArchARM, ArchCORTEX_M
Expand All @@ -15,7 +15,7 @@ class ContextRenderARM(ContextRender, ArchARM):
"""

def print_mode_info(self) -> None:
cpsr = self.read_reg('cpsr')
cpsr = self.read_reg(self._flags_reg)

flags = ArchARM.get_flags(cpsr)
mode = ArchARM.get_mode(cpsr)
Expand Down