import argparse
import os
def parse_args():
parser = argparse.ArgumentParser(
"""
parsecallstack.py -c CPUTYPE -f FILENAME\n\
This file can get the call stack when you get the log with the
register values from R0 to R15, together with the stack dump.\n
Then you will get a file with name callstack.cmm, run this file
in Trace32, load the symbol according to the indication, the call
stack will pop up.\n
Trace32 software is available at: https://www.lauterbach.com
"""
)
parser.add_argument(
"-f",
"--filename",
action="store",
help="log file with registers and stack information",
)
parser.add_argument(
"-c",
"--cputype",
action="store",
help='''It supports ARM family CPU such as:
"CortexM0" "CortexM1" "CortexM3" "CortexM4"
"CortexM7" "CortexM23" "CortexM33" "CortexM35P"
"CortexR5" "CortexR7" "CortexA5" "CortexA7"''',
)
return parser.parse_args()
def get_regs(filename):
reglist = []
with open(filename, mode="r") as fl:
for line in fl:
lst = line.strip("\n").split(" ")
if "R0:" in lst:
reglist = lst[-8:]
if "R8:" in lst:
reglist += lst[-8:]
return reglist
def get_stackvalue(filename):
stackvalue = []
first = 1
with open(filename, mode="r") as fl:
for line in fl:
lst = line.strip("\n").split(" ")
if "up_stackdump:" in lst:
if first == 1:
first += 1
sp = lst[-9].strip(":")
stackvalue.append(sp)
stackvalue += lst[-8:]
return stackvalue
def generate_cmm(cpu, regs, stackvalue):
filename = os.path.join(os.getcwd(), "callstack.cmm")
with open(filename, mode="w") as fl:
fl.write("SYStem.CPU %d\n" % cpu)
fl.write("SYS.M UP\n")
fl.write("Data.LOAD *\n")
fl.write("\n")
for num in range(len(regs)):
fl.write("Register.Set R%d 0x%s\n" % num, regs[num])
fl.write("\n")
sp = int(stackvalue[0], 16)
for num in range(len(stackvalue) - 1):
address = hex(sp + num * 4)
value = stackvalue[num + 1]
fl.write("Data.Set ZSD:%d %%LE %%Long 0x%d\n" % address, value)
fl.write("\n")
fl.write("data.view %%sYmbol.long %x\n" % sp)
fl.write("frame.view /Locals /Caller\n")
if __name__ == "__main__":
args = parse_args()
regs = get_regs(args.filename)
stackvalue = get_stackvalue(args.filename)
generate_cmm(args.cpu, regs, stackvalue)