Skip to content
Snippets Groups Projects
Commit b3c06fa9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "linux-ramdump-parser-v2: Add support for v2 memory dump"

parents 4df11048 1722c90c
No related branches found
No related tags found
No related merge requests found
# Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import struct
from print_out import print_out_str
from qdss import QDSSDump
from watchdog_v2 import TZRegDump_v2
MEMDUMPV2_MAGIC = 0x42445953
class client(object):
MSM_DUMP_DATA_CPU_CTX = 0x00
MSM_DUMP_DATA_L1_INST_CACHE = 0x60
MSM_DUMP_DATA_L1_DATA_CACHE = 0x80
MSM_DUMP_DATA_ETM_REG = 0xA0
MSM_DUMP_DATA_L2_CACHE = 0xC0
MSM_DUMP_DATA_L3_CACHE = 0xD0
MSM_DUMP_DATA_OCMEM = 0xE0
MSM_DUMP_DATA_TMC_ETF = 0xF0
MSM_DUMP_DATA_TMC_REG = 0x100
MSM_DUMP_DATA_TMC_ETF_REG = 0x101
MSM_DUMP_DATA_MAX = 0x110
client_table = {
'MSM_DUMP_DATA_CPU_CTX': 'parse_cpu_ctx',
'MSM_DUMP_DATA_L1_INST_CACHE': 'parse_l1_inst_cache',
'MSM_DUMP_DATA_L1_DATA_CACHE': 'parse_l1_data_cache',
'MSM_DUMP_DATA_ETM_REG': 'parse_qdss_common',
'MSM_DUMP_DATA_L2_CACHE': 'parse_l2_cache',
'MSM_DUMP_DATA_L3_CACHE': 'parse_l3_cache',
'MSM_DUMP_DATA_OCMEM': 'parse_ocmem',
'MSM_DUMP_DATA_TMC_ETF': 'parse_qdss_common',
'MSM_DUMP_DATA_TMC_REG': 'parse_qdss_common',
}
qdss_tag_to_field_name = {
'MSM_DUMP_DATA_TMC_REG': 'tmc_etr_start',
'MSM_DUMP_DATA_TMC_ETF': 'etf_start',
'MSM_ETM0_REG': 'etm_regs0',
'MSM_ETM1_REG': 'etm_regs1',
'MSM_ETM2_REG': 'etm_regs2',
'MSM_ETM3_REG': 'etm_regs3',
}
class DebugImage_v2():
def __init__(self):
self.qdss = QDSSDump()
self.dump_type_lookup_table = []
self.dump_table_id_lookup_table = []
self.dump_data_id_lookup_table = []
def parse_cpu_ctx(self, start, end, client_id, ram_dump):
core = client_id - client.MSM_DUMP_DATA_CPU_CTX
print_out_str(
'Parsing CPU{2} context start {0:x} end {1:x}'.format(start, end, core))
regs = TZRegDump_v2()
if regs.init_regs(start, end, core, ram_dump) is False:
print_out_str('!!! Could not get registers from TZ dump')
return
regs.dump_core_pc(ram_dump)
regs.dump_all_regs(ram_dump)
def parse_qdss_common(self, start, end, client_id, ram_dump):
client_name = self.dump_data_id_lookup_table[client_id]
print_out_str(
'Parsing {0} context start {1:x} end {2:x}'.format(client_name, start, end))
if client_id == client.MSM_DUMP_DATA_TMC_ETF_REG:
setattr(self.qdss, 'tmc_etf_start', start)
else:
setattr(self.qdss, qdss_tag_to_field_name[client_name], start)
def parse_dump_v2(self, ram_dump):
self.dump_type_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
'msm_dump_type', 2)
self.dump_table_id_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
'msm_dump_table_ids', 0x110)
self.dump_data_id_lookup_table = ram_dump.gdbmi.get_enum_lookup_table(
'msm_dump_data_ids', 0x110)
cpu_present_bits = ram_dump.read_word('cpu_present_bits')
cpus = bin(cpu_present_bits).count('1')
# per cpu entries
for i in range(1, cpus):
self.dump_data_id_lookup_table[
client.MSM_DUMP_DATA_CPU_CTX + i] = 'MSM_DUMP_DATA_CPU_CTX'
self.dump_data_id_lookup_table[
client.MSM_DUMP_DATA_L1_INST_CACHE + i] = 'MSM_DUMP_DATA_L1_INST_CACHE'
self.dump_data_id_lookup_table[
client.MSM_DUMP_DATA_L1_DATA_CACHE + i] = 'MSM_DUMP_DATA_L1_DATA_CACHE'
self.dump_data_id_lookup_table[
client.MSM_DUMP_DATA_ETM_REG + i] = 'MSM_DUMP_DATA_ETM_REG'
# 0x100 - tmc-etr registers and 0x101 - for tmc-etf registers
self.dump_data_id_lookup_table[
client.MSM_DUMP_DATA_TMC_REG + 1] = 'MSM_DUMP_DATA_TMC_REG'
dump_table_ptr_offset = ram_dump.field_offset(
'struct msm_memory_dump', 'table')
dump_table_version_offset = ram_dump.field_offset(
'struct msm_dump_table', 'version')
dump_table_num_entry_offset = ram_dump.field_offset(
'struct msm_dump_table', 'num_entries')
dump_table_entry_offset = ram_dump.field_offset(
'struct msm_dump_table', 'entries')
dump_entry_id_offset = ram_dump.field_offset(
'struct msm_dump_entry', 'id')
dump_entry_name_offset = ram_dump.field_offset(
'struct msm_dump_entry', 'name')
dump_entry_type_offset = ram_dump.field_offset(
'struct msm_dump_entry', 'type')
dump_entry_addr_offset = ram_dump.field_offset(
'struct msm_dump_entry', 'addr')
dump_data_version_offset = ram_dump.field_offset(
'struct msm_dump_data', 'version')
dump_data_magic_offset = ram_dump.field_offset(
'struct msm_dump_data', 'magic')
dump_data_name_offset = ram_dump.field_offset(
'struct msm_dump_data', 'name')
dump_data_addr_offset = ram_dump.field_offset(
'struct msm_dump_data', 'addr')
dump_data_len_offset = ram_dump.field_offset(
'struct msm_dump_data', 'len')
dump_data_reserved_offset = ram_dump.field_offset(
'struct msm_dump_data', 'reserved')
dump_entry_size = ram_dump.sizeof('struct msm_dump_entry')
dump_data_size = ram_dump.sizeof('struct msm_dump_data')
mem_dump_data = ram_dump.addr_lookup('memdump')
mem_dump_table = ram_dump.read_word(
mem_dump_data + dump_table_ptr_offset)
mem_table_version = ram_dump.read_u32(
mem_dump_table + dump_table_version_offset)
if mem_table_version is None:
print_out_str('Version is bogus! Can\'t parse debug image')
return
mem_table_num_entry = ram_dump.read_u32(
mem_dump_table + dump_table_num_entry_offset)
if mem_table_num_entry is None or mem_table_num_entry > 100:
print_out_str('num_entries is bogus! Can\'t parse debug image')
return
print_out_str('\nDebug image version: {0}.{1} Number of table entries {2}'.format(
mem_table_version >> 20, mem_table_version & 0xFFFFF, mem_table_num_entry))
print_out_str('--------')
for i in range(0, mem_table_num_entry):
this_entry = mem_dump_table + dump_table_entry_offset + \
i * dump_entry_size
entry_id = ram_dump.read_u32(this_entry + dump_entry_id_offset)
entry_type = ram_dump.read_u32(this_entry + dump_entry_type_offset)
entry_addr = ram_dump.read_word(this_entry + dump_entry_addr_offset)
if entry_id < 0 or entry_id > len(self.dump_table_id_lookup_table):
print_out_str(
'!!! Invalid dump table entry id found {0:x}'.format(entry_id))
continue
if entry_type > len(self.dump_type_lookup_table):
print_out_str(
'!!! Invalid dump table entry type found {0:x}'.format(entry_type))
continue
table_version = ram_dump.read_u32(
entry_addr + dump_table_version_offset, False)
if table_version is None:
print_out_str('Dump table entry version is bogus! Can\'t parse debug image')
return
table_num_entries = ram_dump.read_u32(
entry_addr + dump_table_num_entry_offset, False)
if table_num_entries is None or table_num_entries > 100:
print_out_str('Dump table entry num_entries is bogus! Can\'t parse debug image')
return
print_out_str(
'Debug image version: {0}.{1} Entry id: {2} Entry type: {3} Number of entries: {4}'.format(
table_version >> 20, table_version & 0xFFFFF, self.dump_table_id_lookup_table[entry_id],
self.dump_type_lookup_table[entry_type], table_num_entries))
for j in range(0, table_num_entries):
print_out_str('--------')
client_entry = entry_addr + dump_table_entry_offset + j * dump_entry_size
client_id = ram_dump.read_u32(client_entry + dump_entry_id_offset, False)
client_type = ram_dump.read_u32(client_entry + dump_entry_type_offset, False)
client_addr = ram_dump.read_word(client_entry + dump_entry_addr_offset, False)
if client_id < 0 or client_id > len(self.dump_data_id_lookup_table):
print_out_str(
'!!! Invalid dump client id found {0:x}'.format(client_id))
continue
if client_type > len(self.dump_type_lookup_table):
print_out_str(
'!!! Invalid dump client type found {0:x}'.format(client_type))
continue
dump_data_magic = ram_dump.read_u32(client_addr + dump_data_magic_offset, False)
dump_data_version = ram_dump.read_u32(client_addr + dump_data_version_offset, False)
dump_data_addr = ram_dump.read_dword(client_addr + dump_data_addr_offset, False)
dump_data_len = ram_dump.read_dword(client_addr + dump_data_len_offset, False)
client_name = self.dump_data_id_lookup_table[client_id]
if client_name not in client_table:
print_out_str(
'!!! {0} Does not have an associated function. The parser needs to be updated!'.format(client_name))
else:
print_out_str('Parsing debug information for {0}. Version: {1} Magic: {2:x}'.format(
client_name, dump_data_version, dump_data_magic))
if dump_data_magic is None:
print_out_str(
"!!! Address {0:x} is bogus! Can't parse!".format(start))
continue
if dump_data_magic != MEMDUMPV2_MAGIC:
print_out_str(
"!!! Magic {0:x} doesn't match! No context will be parsed".format(dump_data_magic))
continue
func = client_table[client_name]
getattr(DebugImage_v2, func)(self, dump_data_addr, dump_data_addr + dump_data_len,
client_id, ram_dump)
self.qdss.dump_all(ram_dump)
......@@ -16,6 +16,7 @@ from print_out import print_out_str
from qdss import QDSSDump
from cachedump import save_l1_dump, parse_cache_dump
from watchdog import TZRegDump
from debug_image_v2 import DebugImage_v2
QDSS_MAGIC = 0x5D1DB1Bf
......@@ -126,12 +127,7 @@ class DebugImage(RamParser):
setattr(self.qdss, tag_to_field_name[tag], start + 4096)
def parse(self):
if not self.ramdump.is_config_defined('CONFIG_MSM_MEMORY_DUMP'):
print_out_str(
'!!! Debug image was not enabled. No debug dump will be provided')
return
def parse_dump(self):
out_dir = self.ramdump.outdir
self.name_lookup_table = self.ramdump.gdbmi.get_enum_lookup_table(
'dump_client_type', 32)
......@@ -195,3 +191,18 @@ class DebugImage(RamParser):
print_out_str('--------')
self.qdss.dump_all(self.ramdump)
def parse(self):
# use the mem_dump_data variable to detect if debug image feature was compiled in,
# and memdump data variable for debug image v2 feature, rather than relying on
# configuration option.
if self.ramdump.addr_lookup('mem_dump_data'):
self.parse_dump()
elif self.ramdump.addr_lookup('memdump'):
regs = DebugImage_v2()
regs.parse_dump_v2(self.ramdump)
else:
print_out_str(
'!!! Debug image was not enabled. No debug dump will be provided')
return
......@@ -216,7 +216,7 @@ class QDSSDump():
for a, b in tmc_registers.iteritems():
offset, name = b
tmc_etf_out.write('{0} ({1}): {2:x}\n'.format(
a, name, ram_dump.read_word(self.tmc_etf_start + offset, False)))
a, name, ram_dump.read_u32(self.tmc_etf_start + offset, False)))
tmc_etf_out.close()
def print_tmc_etr(self, ram_dump):
......@@ -230,7 +230,7 @@ class QDSSDump():
for a, b in tmc_registers.iteritems():
offset, name = b
tmc_etf_out.write('{0} ({1}): {2:x}\n'.format(
a, name, ram_dump.read_word(self.tmc_etr_start + offset, False)))
a, name, ram_dump.read_u32(self.tmc_etr_start + offset, False)))
tmc_etf_out.close()
def print_etm_registers(self, ram_dump, base, fname):
......@@ -238,7 +238,7 @@ class QDSSDump():
for a, b in etm_registers.iteritems():
offset, name = b
etm_out.write('{0} ({1}): {2:x})\n'.format(
a, name, ram_dump.read_word(base + offset * 4, False)))
a, name, ram_dump.read_u32(base + offset * 4, False)))
etm_out.close()
def print_all_etm_register(self, ram_dump):
......@@ -275,13 +275,16 @@ class QDSSDump():
ctl_offset, ctl_desc = tmc_registers['CTL']
mode_offset, mode_desc = tmc_registers['MODE']
rsz_offset, rsz_desc = tmc_registers['RSZ']
ctl = ram_dump.read_word(self.tmc_etf_start + ctl_offset, False)
mode = ram_dump.read_word(self.tmc_etf_start + mode_offset, False)
ctl = ram_dump.read_u32(self.tmc_etf_start + ctl_offset, False)
mode = ram_dump.read_u32(self.tmc_etf_start + mode_offset, False)
rsz = ram_dump.read_u32(self.tmc_etf_start + rsz_offset, False)
# rsz is given in words so convert to bytes
rsz = 4 * rsz
if (ctl & 0x1) == 1 and (mode == 0):
# Save the 64kb of data
for i in range(0, 64 * 1024):
for i in range(0, rsz):
val = ram_dump.read_byte(self.etf_start + i, False)
tmc_etf.write(struct.pack('<B', val))
else:
......@@ -299,24 +302,24 @@ class QDSSDump():
ctl_offset, ctl_desc = tmc_registers['CTL']
mode_offset, mode_desc = tmc_registers['MODE']
ctl = ram_dump.read_word(self.tmc_etr_start + ctl_offset, False)
mode = ram_dump.read_word(self.tmc_etr_start + mode_offset, False)
ctl = ram_dump.read_u32(self.tmc_etr_start + ctl_offset, False)
mode = ram_dump.read_u32(self.tmc_etr_start + mode_offset, False)
if (ctl & 0x1) == 1 and (mode == 0):
sts_offset, sts_desc = tmc_registers['STS']
sts = ram_dump.read_word(self.tmc_etr_start + sts_offset, False)
sts = ram_dump.read_u32(self.tmc_etr_start + sts_offset, False)
dbalo_offset, dbalo_desc = tmc_registers['DBALO']
dbalo = ram_dump.read_word(
dbalo = ram_dump.read_u32(
self.tmc_etr_start + dbalo_offset, False)
rsz_offset, rsz_desc = tmc_registers['RSZ']
rsz = ram_dump.read_word(self.tmc_etr_start + rsz_offset, False)
rsz = ram_dump.read_u32(self.tmc_etr_start + rsz_offset, False)
# rsz is given in words so convert to bytes
rsz = 4 * rsz
rwp_offset, rwp_desc = tmc_registers['RWP']
rwp = ram_dump.read_word(self.tmc_etr_start + rwp_offset, False)
rwp = ram_dump.read_u32(self.tmc_etr_start + rwp_offset, False)
if (sts & 0x1) == 1:
for i in range(rwp, dbalo + rsz):
......
# Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import struct
from print_out import print_out_str
# (name from tz dump, corresponding T32 register, whether or not to print_out_str (the function name))
sysdbg_cpu64_register_names = [
('x0', 'x0', False),
('x1', 'x1', False),
('x2', 'x2', False),
('x3', 'x3', False),
('x4', 'x4', False),
('x5', 'x5', False),
('x6', 'x6', False),
('x7', 'x7', False),
('x8', 'x8', False),
('x9', 'x9', False),
('x10', 'x10', False),
('x11', 'x11', False),
('x12', 'x12', False),
('x13', 'x13', False),
('x14', 'x14', False),
('x15', 'x15', False),
('x16', 'x16', False),
('x17', 'x17', False),
('x18', 'x18', False),
('x19', 'x19', False),
('x20', 'x20', False),
('x21', 'x21', False),
('x22', 'x22', False),
('x23', 'x23', False),
('x24', 'x24', False),
('x25', 'x25', False),
('x26', 'x26', False),
('x27', 'x27', False),
('x28', 'x28', False),
('x29', 'x29', False),
('x30', 'x30', True),
('pc', 'pc', True),
('currentEL', None, False),
('sp_el3', 'sp_el3', False),
('elr_el3', 'elr_el3', True),
('spsr_el3', 'spsr_el3', False),
('sp_el2', 'sp_el2', False),
('elr_el2', 'elr_el2', True),
('spsr_el2', 'spsr_el2', False),
('sp_el1', 'sp_el1', False),
('elr_el1', 'elr_el1', True),
('spsr_el1', 'spsr_el1', False),
('sp_el0', 'sp_el0', False),
('__reserved1', '__reserved1', False),
('__reserved2', '__reserved2', False),
('__reserved3', '__reserved3', False),
('__reserved4', '__reserved4', False),
]
sysdbg_cpu64_ctxt_regs_type = ''.join([
'Q', # x0
'Q', # x1
'Q', # x2
'Q', # x3
'Q', # x4
'Q', # x5
'Q', # x6
'Q', # x7
'Q', # x8
'Q', # x9
'Q', # x10
'Q', # x11
'Q', # x12
'Q', # x13
'Q', # x14
'Q', # x15
'Q', # x16
'Q', # x17
'Q', # x18
'Q', # x19
'Q', # x20
'Q', # x21
'Q', # x22
'Q', # x23
'Q', # x24
'Q', # x25
'Q', # x26
'Q', # x27
'Q', # x28
'Q', # x29
'Q', # x30
'Q', # pc
'Q', # currentEL
'Q', # sp_el3
'Q', # elr_el3
'Q', # spsr_el3
'Q', # sp_el2
'Q', # elr_el2
'Q', # spsr_el2
'Q', # sp_el1
'Q', # elr_el1
'Q', # spsr_el1
'Q', # sp_el0
'Q', # __reserved1
'Q', # __reserved2
'Q', # __reserved3
'Q', # __reserved4
])
sysdbg_cpu32_register_names = [
('r0', 'r0', False),
('r1', 'r1', False),
('r2', 'r2', False),
('r3', 'r3', False),
('r4', 'r4', False),
('r5', 'r5', False),
('r6', 'r6', False),
('r7', 'r7', False),
('r8', 'r8', False),
('r9', 'r9', False),
('r10', 'r10', False),
('r11', 'r11', False),
('r12', 'r12', False),
('r13_usr', 'r13_usr', False),
('r14_usr', 'r14_usr', False),
('r13_hyp', 'r13_hyp', False),
('r14_irq', 'r14_irq', True),
('r13_irq', 'r13_irq', False),
('r14_svc', 'r14_svc', True),
('r13_svc', 'r13_svc', False),
('r14_abt', 'r14_abt', True),
('r13_abt', 'r13_abt', False),
('r14_und', 'r14_und', True),
('r13_und', 'r13_und', False),
('r8_fiq', 'r8_fiq', False),
('r9_fiq', 'r9_fiq', False),
('r10_fiq', 'r10_fiq', False),
('r11_fiq', 'r11_fiq', False),
('r12_fiq', 'r12_fiq', False),
('r13_fiq', 'r13_fiq', False),
('r14_fiq', 'r14_fiq', True),
('pc', 'pc', True),
('cpsr', 'cpsr', False),
('r13_mon', 'r13_mon', False),
('r14_mon', 'r14_mon', True),
('r14_hyp', 'r14_hyp', True),
('_reserved', '_reserved', False),
('__reserved1', '__reserved1', False),
('__reserved2', '__reserved2', False),
('__reserved3', '__reserved3', False),
('__reserved4', '__reserved4', False),
]
sysdbg_cpu32_ctxt_regs_type = ''.join([
'Q', # r0
'Q', # r1
'Q', # r2
'Q', # r3
'Q', # r4
'Q', # r5
'Q', # r6
'Q', # r7
'Q', # r8
'Q', # r9
'Q', # r10
'Q', # r11
'Q', # r12
'Q', # r13_usr
'Q', # r14_usr
'Q', # r13_hyp
'Q', # r14_irq
'Q', # r13_irq
'Q', # r14_svc
'Q', # r13_svc
'Q', # r14_abt
'Q', # r13_abt
'Q', # r14_und
'Q', # r13_und
'Q', # r8_fiq
'Q', # r9_fiq
'Q', # r10_fiq
'Q', # r11_fiq
'Q', # r12_fiq
'Q', # r13_fiq
'Q', # r14_fiq
'Q', # pc
'Q', # cpsr
'Q', # r13_mon
'Q', # r14_mon
'Q', # r14_hyp
'Q', # _reserved
'Q', # __reserved1
'Q', # __reserved2
'Q', # __reserved3
'Q', # __reserved4
])
cpu_name = (
'Invalid',
'A53',
'A57',
'Hydra',
)
class TZCpuCtx_v2():
def __init__(self, regs_t, ramdump):
i = 0
self.regs = {}
for r in regs_t:
if ramdump.arm64:
self.regs[sysdbg_cpu64_register_names[i][0]] = r
else:
self.regs[sysdbg_cpu32_register_names[i][0]] = r
i += 1
def print_regs(self, outfile, ramdump):
if ramdump.arm64:
register_names = sysdbg_cpu64_register_names
else:
register_names = sysdbg_cpu32_register_names
for reg_name, t32_name, print_pc in register_names:
if print_pc:
a = ramdump.unwind_lookup(self.regs[reg_name])
if a is not None:
symname, offset = ramdump.unwind_lookup(
self.regs[reg_name])
pc_string = '[{0}+0x{1:x}]'.format(symname, offset)
else:
pc_string = None
else:
pc_string = None
if pc_string is not None:
print_out_str(' {0:8} = 0x{1:016x} {2}'.format(
reg_name, self.regs[reg_name], pc_string))
else:
print_out_str(' {0:8} = 0x{1:016x}'.format(
reg_name, self.regs[reg_name]))
if t32_name is not None:
outfile.write(
'r.s {0} 0x{1:x}\n'.format(t32_name, self.regs[reg_name]))
class TZRegDump_v2():
def __init__(self):
self.core_regs = None
self.sec_regs = None
self.start_addr = 0
self.end_addr = 0
self.core = 0
self.status = []
def dump_all_regs(self, ram_dump):
coren_regs = ram_dump.open_file('core{0}_regs.cmm'.format(self.core))
print_out_str('core{0} regs:'.format(self.core))
self.core_regs.print_regs(coren_regs, ram_dump)
coren_regs.close()
secure_regs = ram_dump.open_file('secure_world_core{0}_regs.cmm'.format(self.core))
print_out_str('\n=============== secure contex ===========')
self.sec_regs.print_regs(secure_regs, ram_dump)
print_out_str('============ end secure context ===========')
secure_regs.close()
def dump_core_pc(self, ram_dump):
print ''
pc = self.core_regs.regs['pc']
if ram_dump.arm64:
lr = self.core_regs.regs['elr_el1']
bt = self.core_regs.regs['sp_el1']
else:
lr = self.core_regs.regs['r14_svc']
bt = self.core_regs.regs['r13_svc']
a = ram_dump.unwind_lookup(pc)
if a is not None:
symname, offset = a
else:
symname = 'UNKNOWN'
offset = 0
print_out_str(
'Core {3} PC: {0}+{1:x} <{2:x}>'.format(symname, offset, pc, self.core))
a = ram_dump.unwind_lookup(lr)
if a is not None:
symname, offset = a
else:
symname = 'UNKNOWN'
offset = 0
print_out_str(
'Core {3} LR: {0}+{1:x} <{2:x}>'.format(symname, offset, lr, self.core))
print_out_str('')
ram_dump.unwind.unwind_backtrace(bt, 0, pc, lr, '')
print_out_str('')
def init_regs(self, start_addr, end_addr, core, ram_dump):
self.start_addr = start_addr
self.end_addr = end_addr
self.core = core
# uint32 status[4]; -- status fields
# sdi_cpu_ctxt_regs_type cpu_regs; -- ctxt for all cpus
# sdi_cpu_ctxt_regs_type __reserved3; -- secure ctxt
for i in range(0, 4):
self.status.append(ram_dump.read_u32(self.start_addr, False))
self.start_addr += 4
if ram_dump.arm64:
sc_regs = ram_dump.read_string(
self.start_addr, sysdbg_cpu64_ctxt_regs_type, False)
self.start_addr += struct.calcsize(sysdbg_cpu64_ctxt_regs_type)
sc_secure = ram_dump.read_string(
self.start_addr, sysdbg_cpu64_ctxt_regs_type , False)
self.start_addr += struct.calcsize(sysdbg_cpu64_ctxt_regs_type)
else:
sc_regs = ram_dump.read_string(
self.start_addr, sysdbg_cpu32_ctxt_regs_type, False)
self.start_addr += struct.calcsize(sysdbg_cpu32_ctxt_regs_type)
sc_secure = ram_dump.read_string(
self.start_addr, sysdbg_cpu32_ctxt_regs_type , False)
self.start_addr += struct.calcsize(sysdbg_cpu32_ctxt_regs_type)
self.core_regs = TZCpuCtx_v2(sc_regs, ram_dump)
self.sec_regs = TZCpuCtx_v2(sc_secure, ram_dump)
return True
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment