xref: /xnu-10063.141.1/tools/lldbmacros/xnutriage.py (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
1"""
2    XNU Triage commands
3"""
4from xnu import *
5import sys, shlex
6from utils import *
7import xnudefines
8import re
9import os.path
10
11# Macro: xi
12def OutputAddress(cmd_args=None):
13    """ Returns out address and symbol corresponding to it without newline
14        Parameters: <address whose symbol is needed>
15    """
16    if not cmd_args:
17        print("No arguments passed")
18        print(OutputAddress.__doc__)
19        return False
20    a = unsigned(cmd_args[0])
21    cmd_str = "image lookup -a {:#x}".format(a)
22    cmd_out = lldb_run_command(cmd_str)
23    if len(cmd_out) != 0 and cmd_out != "ERROR:":
24        cmd_out1 = cmd_out.split('\n')
25        if len(cmd_out1) != 0:
26            cmd_out2 = cmd_out1[1].split('`')
27            if cmd_out2 != 0:
28                cmd_out3 = cmd_out2[1].split(' at')
29                if len(cmd_out3) != 0:
30                    symbol_str = "{:#018x} <{:s}>".format(unsigned(a), cmd_out3[0])
31                    return symbol_str
32    return ""
33
34@lldb_command('xi')
35def SymbolicateWithInstruction(cmd_args=None):
36    """ Prints out address and symbol similar to x/i
37        Usage: xi <address whose symbol is needed>
38    """
39    if not cmd_args:
40        print("No arguments passed")
41        print(SymbolicateWithInstruction.__doc__)
42        return False
43    a = ArgumentStringToInt(cmd_args[0])
44    print(OutputAddress([a]))
45
46# Macro: xi
47
48# Macro: newbt
49@lldb_command('newbt')
50def NewBt(cmd_args=None):
51    """ Prints all the instructions by walking the given stack pointer
52    """
53    if not cmd_args:
54        print("No arguments passed")
55        print(NewBt.__doc__)
56        return False
57    a = ArgumentStringToInt(cmd_args[0])
58    while a != 0:
59        if kern.arch == "x86_64" or kern.arch.startswith("arm64"):
60            offset = 8
61        else:
62            offset = 4
63        link_register = dereference(kern.GetValueFromAddress(a + offset, 'uintptr_t *'))
64        cmd_str = "di -s {:#x} -c 1".format(link_register)
65        cmd_out = lldb_run_command(cmd_str)
66        if len(cmd_out) != 0:
67            cmd_out1 = list(filter(None, cmd_out.split('\n')))
68            if len(cmd_out1) != 0:
69                address = OutputAddress([unsigned(link_register)])
70                if not address:
71                    address = '{:#018x} <???>'.format(unsigned(link_register))
72                print(address + ": " + cmd_out1[-1].split(':', 1)[1])
73        a = dereference(kern.GetValueFromAddress(unsigned(a), 'uintptr_t *'))
74
75# EndMacro: newbt
76
77# Macro: parseLR
78@lldb_command('parseLR')
79def parseLR(cmd_args=None):
80    """ Decode the LR value from panic log into source code location
81    """
82    global paniclog_data
83    panic_found = 1
84
85    if not paniclog_data:
86        if kern.arch == "x86_64":
87            paniclog_data += returnfunc("\n(lldb) paniclog\n", "paniclog -v")
88        else:
89            paniclog_data += returnfunc("\n(lldb) paniclog\n", "paniclog")
90
91    if panic_found == 1:
92        srch_string = "lr:\s+0x[a-fA-F0-9]+\s"
93        lr_pc_srch = re.findall(srch_string, paniclog_data)
94        if lr_pc_srch:
95            print(paniclog_data, lr_pc_srch)
96            for match in lr_pc_srch:
97                sp=match.strip("lr: ")
98                print(sp)
99                print("(lldb) list *{:s}".format(sp))
100                print(lldb_run_command("list *{:s}".format(sp)))
101
102    else:
103        print("Currently unsupported on x86_64 architecture")
104#EndMacro: parseLR
105
106# Macro: parseLRfromfile
107@lldb_command('parseLRfromfile')
108def parseLRfromfile(cmd_args=None):
109    """ Decode the LR value from file into source code location
110    """
111    f = open('/tmp/lrparsefile', 'r')
112    parse_data= f.read()
113    srch_string = "lr:\s+0x[a-fA-F0-9]+\s"
114    lr_pc_srch = re.findall(srch_string, parse_data)
115    if lr_pc_srch:
116        print(paniclog_data, lr_pc_srch)
117        for match in lr_pc_srch:
118            sp=match.strip("lr: ")
119            print(sp)
120            print("(lldb) list *{:s}".format(sp))
121            print(lldb_run_command("list *{:s}".format(sp)))
122
123#EndMacro: parseLRfromfile
124
125