blob: 34de0d6dee59d7a1ec5e0f9d72c3edbb90e13620 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
import binascii
import logging
import struct
from gdbstubs.gdbstub import GdbStub
logger = logging.getLogger("gdbstub")
class RegNum():
R0 = 0
R1 = 1
R2 = 2
R3 = 3
R4 = 4
R5 = 5
R6 = 6
R7 = 7
R8 = 8
R9 = 9
R10 = 10
R11 = 11
R12 = 12
SP = 13
LR = 14
PC = 15
XPSR = 16
class GdbStub_ARM_CortexM(GdbStub):
ARCH_DATA_BLK_STRUCT = "<IIIIIIIII"
ARCH_DATA_BLK_STRUCT_V2 = "<IIIIIIIIIIIIIIIII"
GDB_SIGNAL_DEFAULT = 7
GDB_G_PKT_NUM_REGS = 17
def __init__(self, logfile, elffile):
super().__init__(logfile=logfile, elffile=elffile)
self.registers = None
self.gdb_signal = self.GDB_SIGNAL_DEFAULT
self.parse_arch_data_block()
def parse_arch_data_block(self):
arch_data_blk = self.logfile.get_arch_data()['data']
arch_data_ver = self.logfile.get_arch_data()['hdr_ver']
if arch_data_ver == 1:
tu = struct.unpack(self.ARCH_DATA_BLK_STRUCT, arch_data_blk)
elif arch_data_ver == 2:
tu = struct.unpack(self.ARCH_DATA_BLK_STRUCT_V2, arch_data_blk)
self.registers = dict()
self.registers[RegNum.R0] = tu[0]
self.registers[RegNum.R1] = tu[1]
self.registers[RegNum.R2] = tu[2]
self.registers[RegNum.R3] = tu[3]
self.registers[RegNum.R12] = tu[4]
self.registers[RegNum.LR] = tu[5]
self.registers[RegNum.PC] = tu[6]
self.registers[RegNum.XPSR] = tu[7]
self.registers[RegNum.SP] = tu[8]
if arch_data_ver > 1:
self.registers[RegNum.R4] = tu[9]
self.registers[RegNum.R5] = tu[10]
self.registers[RegNum.R6] = tu[11]
self.registers[RegNum.R7] = tu[12]
self.registers[RegNum.R8] = tu[13]
self.registers[RegNum.R9] = tu[14]
self.registers[RegNum.R10] = tu[15]
self.registers[RegNum.R11] = tu[16]
def handle_register_group_read_packet(self):
reg_fmt = "<I"
idx = 0
pkt = b''
while idx < self.GDB_G_PKT_NUM_REGS:
if idx in self.registers:
bval = struct.pack(reg_fmt, self.registers[idx])
pkt += binascii.hexlify(bval)
else:
# Register not in coredump -> unknown value
# Send in "xxxxxxxx"
pkt += b'x' * 8
idx += 1
self.put_gdb_packet(pkt)
def handle_register_single_read_packet(self, pkt):
# Mark registers as "<unavailable>".
# 'p' packets are usually used for registers
# other than the general ones (e.g. eax, ebx)
# so we can safely reply "xxxxxxxx" here.
self.put_gdb_packet(b'x' * 8)