xref: /openbsd-src/gnu/llvm/lldb/examples/python/operating_system.py (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1*be691f3bSpatrick#!/usr/bin/env python
2061da546Spatrick
3061da546Spatrickimport lldb
4061da546Spatrickimport struct
5061da546Spatrick
6061da546Spatrick
7061da546Spatrickclass OperatingSystemPlugIn(object):
8061da546Spatrick    """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
9061da546Spatrick
10061da546Spatrick    def __init__(self, process):
11061da546Spatrick        '''Initialization needs a valid.SBProcess object.
12061da546Spatrick
13061da546Spatrick        This plug-in will get created after a live process is valid and has stopped for the
14061da546Spatrick        first time.'''
15061da546Spatrick        self.process = None
16061da546Spatrick        self.registers = None
17061da546Spatrick        self.threads = None
18061da546Spatrick        if isinstance(process, lldb.SBProcess) and process.IsValid():
19061da546Spatrick            self.process = process
20061da546Spatrick            self.threads = None  # Will be an dictionary containing info for each thread
21061da546Spatrick
22061da546Spatrick    def get_target(self):
23061da546Spatrick        # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
24061da546Spatrick        # tracks the current target in the LLDB command interpreter which isn't the
25061da546Spatrick        # correct thing to use for this plug-in.
26061da546Spatrick        return self.process.target
27061da546Spatrick
28061da546Spatrick    def create_thread(self, tid, context):
29061da546Spatrick        if tid == 0x444444444:
30061da546Spatrick            thread_info = {
31061da546Spatrick                'tid': tid,
32061da546Spatrick                'name': 'four',
33061da546Spatrick                'queue': 'queue4',
34061da546Spatrick                'state': 'stopped',
35061da546Spatrick                'stop_reason': 'none'}
36061da546Spatrick            self.threads.append(thread_info)
37061da546Spatrick            return thread_info
38061da546Spatrick        return None
39061da546Spatrick
40061da546Spatrick    def get_thread_info(self):
41061da546Spatrick        if not self.threads:
42061da546Spatrick            # The sample dictionary below shows the values that can be returned for a thread
43061da546Spatrick            # tid => thread ID (mandatory)
44061da546Spatrick            # name => thread name (optional key/value pair)
45061da546Spatrick            # queue => thread dispatch queue name (optional key/value pair)
46061da546Spatrick            # state => thred state (mandatory, set to 'stopped' for now)
47061da546Spatrick            # stop_reason => thread stop reason. (mandatory, usually set to 'none')
48061da546Spatrick            #  Possible values include:
49061da546Spatrick            #   'breakpoint' if the thread is stopped at a breakpoint
50061da546Spatrick            #   'none' thread is just stopped because the process is stopped
51061da546Spatrick            #   'trace' the thread just single stepped
52061da546Spatrick            #   The usual value for this while threads are in memory is 'none'
53061da546Spatrick            # register_data_addr => the address of the register data in memory (optional key/value pair)
54061da546Spatrick            #   Specifying this key/value pair for a thread will avoid a call to get_register_data()
55061da546Spatrick            #   and can be used when your registers are in a thread context structure that is contiguous
56061da546Spatrick            #   in memory. Don't specify this if your register layout in memory doesn't match the layout
57061da546Spatrick            # described by the dictionary returned from a call to the
58061da546Spatrick            # get_register_info() method.
59061da546Spatrick            self.threads = [{'tid': 0x111111111,
60061da546Spatrick                             'name': 'one',
61061da546Spatrick                             'queue': 'queue1',
62061da546Spatrick                             'state': 'stopped',
63061da546Spatrick                             'stop_reason': 'breakpoint'},
64061da546Spatrick                            {'tid': 0x222222222,
65061da546Spatrick                             'name': 'two',
66061da546Spatrick                             'queue': 'queue2',
67061da546Spatrick                             'state': 'stopped',
68061da546Spatrick                             'stop_reason': 'none'},
69061da546Spatrick                            {'tid': 0x333333333,
70061da546Spatrick                             'name': 'three',
71061da546Spatrick                             'queue': 'queue3',
72061da546Spatrick                             'state': 'stopped',
73061da546Spatrick                             'stop_reason': 'trace',
74061da546Spatrick                             'register_data_addr': 0x100000000}]
75061da546Spatrick        return self.threads
76061da546Spatrick
77061da546Spatrick    def get_register_info(self):
78061da546Spatrick        if self.registers is None:
79061da546Spatrick            self.registers = dict()
80061da546Spatrick            triple = self.process.target.triple
81061da546Spatrick            if triple:
82061da546Spatrick                arch = triple.split('-')[0]
83061da546Spatrick                if arch == 'x86_64':
84061da546Spatrick                    self.registers['sets'] = ['GPR', 'FPU', 'EXC']
85061da546Spatrick                    self.registers['registers'] = [
86061da546Spatrick                        {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0},
87061da546Spatrick                        {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3},
88061da546Spatrick                        {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', },
89061da546Spatrick                        {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', },
90061da546Spatrick                        {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', },
91061da546Spatrick                        {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', },
92061da546Spatrick                        {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', },
93061da546Spatrick                        {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', },
94061da546Spatrick                        {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', },
95061da546Spatrick                        {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', },
96061da546Spatrick                        {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10},
97061da546Spatrick                        {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11},
98061da546Spatrick                        {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12},
99061da546Spatrick                        {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13},
100061da546Spatrick                        {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14},
101061da546Spatrick                        {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15},
102061da546Spatrick                        {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'},
103061da546Spatrick                        {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'},
104061da546Spatrick                        {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0},
105061da546Spatrick                        {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0},
106061da546Spatrick                        {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0},
107061da546Spatrick                    ]
108061da546Spatrick        return self.registers
109061da546Spatrick
110061da546Spatrick    def get_register_data(self, tid):
111061da546Spatrick        if tid == 0x111111111:
112061da546Spatrick            return struct.pack(
113061da546Spatrick                '21Q',
114061da546Spatrick                1,
115061da546Spatrick                2,
116061da546Spatrick                3,
117061da546Spatrick                4,
118061da546Spatrick                5,
119061da546Spatrick                6,
120061da546Spatrick                7,
121061da546Spatrick                8,
122061da546Spatrick                9,
123061da546Spatrick                10,
124061da546Spatrick                11,
125061da546Spatrick                12,
126061da546Spatrick                13,
127061da546Spatrick                14,
128061da546Spatrick                15,
129061da546Spatrick                16,
130061da546Spatrick                17,
131061da546Spatrick                18,
132061da546Spatrick                19,
133061da546Spatrick                20,
134061da546Spatrick                21)
135061da546Spatrick        elif tid == 0x222222222:
136061da546Spatrick            return struct.pack(
137061da546Spatrick                '21Q',
138061da546Spatrick                11,
139061da546Spatrick                12,
140061da546Spatrick                13,
141061da546Spatrick                14,
142061da546Spatrick                15,
143061da546Spatrick                16,
144061da546Spatrick                17,
145061da546Spatrick                18,
146061da546Spatrick                19,
147061da546Spatrick                110,
148061da546Spatrick                111,
149061da546Spatrick                112,
150061da546Spatrick                113,
151061da546Spatrick                114,
152061da546Spatrick                115,
153061da546Spatrick                116,
154061da546Spatrick                117,
155061da546Spatrick                118,
156061da546Spatrick                119,
157061da546Spatrick                120,
158061da546Spatrick                121)
159061da546Spatrick        elif tid == 0x333333333:
160061da546Spatrick            return struct.pack(
161061da546Spatrick                '21Q',
162061da546Spatrick                21,
163061da546Spatrick                22,
164061da546Spatrick                23,
165061da546Spatrick                24,
166061da546Spatrick                25,
167061da546Spatrick                26,
168061da546Spatrick                27,
169061da546Spatrick                28,
170061da546Spatrick                29,
171061da546Spatrick                210,
172061da546Spatrick                211,
173061da546Spatrick                212,
174061da546Spatrick                213,
175061da546Spatrick                214,
176061da546Spatrick                215,
177061da546Spatrick                216,
178061da546Spatrick                217,
179061da546Spatrick                218,
180061da546Spatrick                219,
181061da546Spatrick                220,
182061da546Spatrick                221)
183061da546Spatrick        elif tid == 0x444444444:
184061da546Spatrick            return struct.pack(
185061da546Spatrick                '21Q',
186061da546Spatrick                31,
187061da546Spatrick                32,
188061da546Spatrick                33,
189061da546Spatrick                34,
190061da546Spatrick                35,
191061da546Spatrick                36,
192061da546Spatrick                37,
193061da546Spatrick                38,
194061da546Spatrick                39,
195061da546Spatrick                310,
196061da546Spatrick                311,
197061da546Spatrick                312,
198061da546Spatrick                313,
199061da546Spatrick                314,
200061da546Spatrick                315,
201061da546Spatrick                316,
202061da546Spatrick                317,
203061da546Spatrick                318,
204061da546Spatrick                319,
205061da546Spatrick                320,
206061da546Spatrick                321)
207061da546Spatrick        else:
208061da546Spatrick            return struct.pack(
209061da546Spatrick                '21Q',
210061da546Spatrick                41,
211061da546Spatrick                42,
212061da546Spatrick                43,
213061da546Spatrick                44,
214061da546Spatrick                45,
215061da546Spatrick                46,
216061da546Spatrick                47,
217061da546Spatrick                48,
218061da546Spatrick                49,
219061da546Spatrick                410,
220061da546Spatrick                411,
221061da546Spatrick                412,
222061da546Spatrick                413,
223061da546Spatrick                414,
224061da546Spatrick                415,
225061da546Spatrick                416,
226061da546Spatrick                417,
227061da546Spatrick                418,
228061da546Spatrick                419,
229061da546Spatrick                420,
230061da546Spatrick                421)
231061da546Spatrick        return None
232