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