mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 11:26:12 +08:00
gdbserver.py: add arm64 support
Use struct.unpack_from to eliminate the need to specify data size. Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
+59
-22
@@ -117,6 +117,41 @@ reg_table = {
|
|||||||
"PC": 15,
|
"PC": 15,
|
||||||
"CPSR": 41,
|
"CPSR": 41,
|
||||||
},
|
},
|
||||||
|
"arm64": {
|
||||||
|
"X0": 0,
|
||||||
|
"X1": 1,
|
||||||
|
"X2": 2,
|
||||||
|
"X3": 3,
|
||||||
|
"X4": 4,
|
||||||
|
"X5": 5,
|
||||||
|
"X6": 6,
|
||||||
|
"X7": 7,
|
||||||
|
"X8": 8,
|
||||||
|
"X9": 9,
|
||||||
|
"X10": 10,
|
||||||
|
"X11": 11,
|
||||||
|
"X12": 12,
|
||||||
|
"X13": 13,
|
||||||
|
"X14": 14,
|
||||||
|
"X15": 15,
|
||||||
|
"X16": 16,
|
||||||
|
"X17": 17,
|
||||||
|
"X18": 18,
|
||||||
|
"X19": 19,
|
||||||
|
"X20": 20,
|
||||||
|
"X21": 21,
|
||||||
|
"X22": 22,
|
||||||
|
"X23": 23,
|
||||||
|
"X24": 24,
|
||||||
|
"X25": 25,
|
||||||
|
"X26": 26,
|
||||||
|
"X27": 27,
|
||||||
|
"X28": 28,
|
||||||
|
"X29": 29,
|
||||||
|
"X30": 30,
|
||||||
|
"SP_ELX": 31,
|
||||||
|
"ELR": 32,
|
||||||
|
},
|
||||||
# rv64 works with gdb-multiarch on Ubuntu
|
# rv64 works with gdb-multiarch on Ubuntu
|
||||||
"riscv": {
|
"riscv": {
|
||||||
"ZERO": 0,
|
"ZERO": 0,
|
||||||
@@ -375,9 +410,10 @@ class DumpLogFile:
|
|||||||
|
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
# find register value
|
# find register value
|
||||||
find_res = re.findall(r"(?P<REG>\w+): (?P<REGV>[0-9a-fA-F]+)", line)
|
find_res = re.findall(r"(?P<REG>\w+):\s*(?P<REGV>[0-9a-fxA-FX]+)", line)
|
||||||
|
|
||||||
for reg_name, reg_val in find_res:
|
for reg_name, reg_val in find_res:
|
||||||
|
reg_name = reg_name.upper()
|
||||||
if reg_name in self.reg_table:
|
if reg_name in self.reg_table:
|
||||||
reg_index = self.reg_table[reg_name]
|
reg_index = self.reg_table[reg_name]
|
||||||
self.registers[reg_index] = int(reg_val, 16)
|
self.registers[reg_index] = int(reg_val, 16)
|
||||||
@@ -526,6 +562,7 @@ class GDBStub:
|
|||||||
self.gdb_signal = GDB_SIGNAL_DEFAULT
|
self.gdb_signal = GDB_SIGNAL_DEFAULT
|
||||||
self.arch = arch
|
self.arch = arch
|
||||||
self.reg_fmt = "<I" if elffile.xlen() <= 32 else "<Q"
|
self.reg_fmt = "<I" if elffile.xlen() <= 32 else "<Q"
|
||||||
|
self.int_size = elffile.xlen() // 8
|
||||||
self.reg_digits = elffile.xlen() // 4
|
self.reg_digits = elffile.xlen() // 4
|
||||||
|
|
||||||
# new list oreder is coredump, rawfile, logfile, elffile
|
# new list oreder is coredump, rawfile, logfile, elffile
|
||||||
@@ -556,11 +593,11 @@ class GDBStub:
|
|||||||
self.regfix = True
|
self.regfix = True
|
||||||
logger.info(f"Current arch is {arch}, need reg index fix.")
|
logger.info(f"Current arch is {arch}, need reg index fix.")
|
||||||
|
|
||||||
except TypeError:
|
except TypeError as e:
|
||||||
if not self.registers:
|
if not self.registers:
|
||||||
logger.critical(
|
logger.critical(
|
||||||
"Logfile, coredump, or rawfile do not contain register,"
|
"Logfile, coredump, or rawfile do not contain register,"
|
||||||
"Please check if the files are correct."
|
f"Please check if the files are correct. {e}"
|
||||||
)
|
)
|
||||||
|
|
||||||
stack_trace = traceback.format_exc()
|
stack_trace = traceback.format_exc()
|
||||||
@@ -784,11 +821,11 @@ class GDBStub:
|
|||||||
self.put_gdb_packet(b"OK")
|
self.put_gdb_packet(b"OK")
|
||||||
|
|
||||||
def parse_thread(self):
|
def parse_thread(self):
|
||||||
def unpack_data(addr, size, fmt):
|
def unpack_data(addr, fmt):
|
||||||
r = self.get_mem_region(addr)
|
r = self.get_mem_region(addr)
|
||||||
offset = addr - r["start"]
|
offset = addr - r["start"]
|
||||||
data = r["data"][offset : offset + size]
|
data = r["data"]
|
||||||
return struct.unpack(fmt, data)
|
return struct.unpack_from(fmt, data, offset)
|
||||||
|
|
||||||
TCBINFO_FMT = "<8HQ"
|
TCBINFO_FMT = "<8HQ"
|
||||||
|
|
||||||
@@ -808,7 +845,6 @@ class GDBStub:
|
|||||||
|
|
||||||
unpacked_data = unpack_data(
|
unpacked_data = unpack_data(
|
||||||
self.elffile.symbol["g_tcbinfo"]["st_value"],
|
self.elffile.symbol["g_tcbinfo"]["st_value"],
|
||||||
self.elffile.symbol["g_tcbinfo"]["st_size"],
|
|
||||||
TCBINFO_FMT,
|
TCBINFO_FMT,
|
||||||
)
|
)
|
||||||
tcbinfo = {
|
tcbinfo = {
|
||||||
@@ -825,7 +861,6 @@ class GDBStub:
|
|||||||
|
|
||||||
unpacked_data = unpack_data(
|
unpacked_data = unpack_data(
|
||||||
self.elffile.symbol["g_npidhash"]["st_value"],
|
self.elffile.symbol["g_npidhash"]["st_value"],
|
||||||
self.elffile.symbol["g_npidhash"]["st_size"],
|
|
||||||
"<I",
|
"<I",
|
||||||
)
|
)
|
||||||
npidhash = int(unpacked_data[0])
|
npidhash = int(unpacked_data[0])
|
||||||
@@ -833,32 +868,35 @@ class GDBStub:
|
|||||||
|
|
||||||
unpacked_data = unpack_data(
|
unpacked_data = unpack_data(
|
||||||
self.elffile.symbol["g_pidhash"]["st_value"],
|
self.elffile.symbol["g_pidhash"]["st_value"],
|
||||||
self.elffile.symbol["g_pidhash"]["st_size"],
|
self.reg_fmt,
|
||||||
"<I",
|
|
||||||
)
|
)
|
||||||
pidhash = int(unpacked_data[0])
|
pidhash = int(unpacked_data[0])
|
||||||
logger.debug(f"g_pidhash is {hex(pidhash)}")
|
logger.debug(f"g_pidhash is {hex(pidhash)}")
|
||||||
|
|
||||||
tcbptr_list = []
|
tcbptr_list = []
|
||||||
for i in range(0, npidhash):
|
for i in range(0, npidhash):
|
||||||
unpacked_data = unpack_data(pidhash + i * 4, 4, "<I")
|
unpacked_data = unpack_data(pidhash + i * self.int_size, self.reg_fmt)
|
||||||
tcbptr_list.append(int(unpacked_data[0]))
|
tcbptr_list.append(int(unpacked_data[0]))
|
||||||
|
|
||||||
def parse_tcb(tcbptr):
|
def parse_tcb(tcbptr):
|
||||||
tcb = {}
|
tcb = {}
|
||||||
tcb["pid"] = int(unpack_data(tcbptr + tcbinfo["pid_off"], 4, "<I")[0])
|
tcb["pid"] = int(unpack_data(tcbptr + tcbinfo["pid_off"], "<I")[0])
|
||||||
tcb["state"] = int(unpack_data(tcbptr + tcbinfo["state_off"], 1, "<B")[0])
|
tcb["state"] = int(unpack_data(tcbptr + tcbinfo["state_off"], "<B")[0])
|
||||||
tcb["pri"] = int(unpack_data(tcbptr + tcbinfo["pri_off"], 1, "<B")[0])
|
tcb["pri"] = int(unpack_data(tcbptr + tcbinfo["pri_off"], "<B")[0])
|
||||||
tcb["stack"] = int(unpack_data(tcbptr + tcbinfo["stack_off"], 4, "<I")[0])
|
tcb["stack"] = int(
|
||||||
tcb["stack_size"] = int(
|
unpack_data(tcbptr + tcbinfo["stack_off"], self.reg_fmt)[0]
|
||||||
unpack_data(tcbptr + tcbinfo["stack_size_off"], 4, "<I")[0]
|
)
|
||||||
|
tcb["stack_size"] = int(
|
||||||
|
unpack_data(tcbptr + tcbinfo["stack_size_off"], self.reg_fmt)[0]
|
||||||
|
)
|
||||||
|
tcb["regs"] = int(
|
||||||
|
unpack_data(tcbptr + tcbinfo["regs_off"], self.reg_fmt)[0]
|
||||||
)
|
)
|
||||||
tcb["regs"] = int(unpack_data(tcbptr + tcbinfo["regs_off"], 4, "<I")[0])
|
|
||||||
tcb["tcbptr"] = tcbptr
|
tcb["tcbptr"] = tcbptr
|
||||||
i = 0
|
i = 0
|
||||||
tcb["name"] = ""
|
tcb["name"] = ""
|
||||||
while True:
|
while True:
|
||||||
c = int(unpack_data(tcbptr + tcbinfo["name_off"] + i, 1, "<B")[0])
|
c = int(unpack_data(tcbptr + tcbinfo["name_off"] + i, "<B")[0])
|
||||||
if c == 0:
|
if c == 0:
|
||||||
break
|
break
|
||||||
i += 1
|
i += 1
|
||||||
@@ -869,18 +907,17 @@ class GDBStub:
|
|||||||
def parse_regs_to_gdb(regs):
|
def parse_regs_to_gdb(regs):
|
||||||
gdb_regs = []
|
gdb_regs = []
|
||||||
for i in range(0, tcbinfo["regs_num"]):
|
for i in range(0, tcbinfo["regs_num"]):
|
||||||
reg_off = int(unpack_data(tcbinfo["reg_off"] + i * 2, 2, "<H")[0])
|
reg_off = int(unpack_data(tcbinfo["reg_off"] + i * 2, "<H")[0])
|
||||||
if reg_off == UINT16_MAX:
|
if reg_off == UINT16_MAX:
|
||||||
gdb_regs.append(b"x")
|
gdb_regs.append(b"x")
|
||||||
else:
|
else:
|
||||||
gdb_regs.append(int(unpack_data(regs + reg_off, 4, "<I")[0]))
|
gdb_regs.append(int(unpack_data(regs + reg_off, self.reg_fmt)[0]))
|
||||||
return gdb_regs
|
return gdb_regs
|
||||||
|
|
||||||
self.cpunum = self.elffile.symbol["g_running_tasks"]["st_size"] // 4
|
self.cpunum = self.elffile.symbol["g_running_tasks"]["st_size"] // 4
|
||||||
logger.debug(f"Have {self.cpunum} cpu")
|
logger.debug(f"Have {self.cpunum} cpu")
|
||||||
unpacked_data = unpack_data(
|
unpacked_data = unpack_data(
|
||||||
self.elffile.symbol["g_running_tasks"]["st_value"],
|
self.elffile.symbol["g_running_tasks"]["st_value"],
|
||||||
self.elffile.symbol["g_running_tasks"]["st_size"],
|
|
||||||
f"<{self.cpunum}I",
|
f"<{self.cpunum}I",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user