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