xref: /llvm-project/lldb/test/API/functionalities/plugins/python_os_plugin/operating_system.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1#!/usr/bin/env python
2
3import lldb
4import struct
5
6
7class OperatingSystemPlugIn(object):
8    """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
9
10    def __init__(self, process):
11        """Initialization needs a valid.SBProcess object.
12
13        This plug-in will get created after a live process is valid and has stopped for the
14        first time."""
15        self.process = None
16        self.registers = None
17        self.threads = None
18        if isinstance(process, lldb.SBProcess) and process.IsValid():
19            self.process = process
20            self.threads = None  # Will be an dictionary containing info for each thread
21
22    def get_target(self):
23        # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
24        # tracks the current target in the LLDB command interpreter which isn't the
25        # correct thing to use for this plug-in.
26        return self.process.target
27
28    def create_thread(self, tid, context):
29        if tid == 0x444444444:
30            thread_info = {
31                "tid": tid,
32                "name": "four",
33                "queue": "queue4",
34                "state": "stopped",
35                "stop_reason": "none",
36            }
37            self.threads.append(thread_info)
38            return thread_info
39        return None
40
41    def get_thread_info(self):
42        if not self.threads:
43            # The sample dictionary below shows the values that can be returned for a thread
44            # tid => thread ID (mandatory)
45            # name => thread name (optional key/value pair)
46            # queue => thread dispatch queue name (optional key/value pair)
47            # state => thred state (mandatory, set to 'stopped' for now)
48            # stop_reason => thread stop reason. (mandatory, usually set to 'none')
49            #  Possible values include:
50            #   'breakpoint' if the thread is stopped at a breakpoint
51            #   'none' thread is just stopped because the process is stopped
52            #   'trace' the thread just single stepped
53            #   The usual value for this while threads are in memory is 'none'
54            # register_data_addr => the address of the register data in memory (optional key/value pair)
55            #   Specifying this key/value pair for a thread will avoid a call to get_register_data()
56            #   and can be used when your registers are in a thread context structure that is contiguous
57            #   in memory. Don't specify this if your register layout in memory doesn't match the layout
58            # described by the dictionary returned from a call to the
59            # get_register_info() method.
60            self.threads = [
61                {
62                    "tid": 0x111111111,
63                    "name": "one",
64                    "queue": "queue1",
65                    "state": "stopped",
66                    "stop_reason": "breakpoint",
67                },
68                {
69                    "tid": 0x222222222,
70                    "name": "two",
71                    "queue": "queue2",
72                    "state": "stopped",
73                    "stop_reason": "none",
74                },
75                {
76                    "tid": 0x333333333,
77                    "name": "three",
78                    "queue": "queue3",
79                    "state": "stopped",
80                    "stop_reason": "trace",
81                },
82            ]
83        return self.threads
84
85    def get_register_info(self):
86        if self.registers is None:
87            self.registers = dict()
88            self.registers["sets"] = ["GPR"]
89            self.registers["registers"] = [
90                {
91                    "name": "rax",
92                    "bitsize": 64,
93                    "offset": 0,
94                    "encoding": "uint",
95                    "format": "hex",
96                    "set": 0,
97                    "gcc": 0,
98                    "dwarf": 0,
99                },
100                {
101                    "name": "rbx",
102                    "bitsize": 64,
103                    "offset": 8,
104                    "encoding": "uint",
105                    "format": "hex",
106                    "set": 0,
107                    "gcc": 3,
108                    "dwarf": 3,
109                },
110                {
111                    "name": "rcx",
112                    "bitsize": 64,
113                    "offset": 16,
114                    "encoding": "uint",
115                    "format": "hex",
116                    "set": 0,
117                    "gcc": 2,
118                    "dwarf": 2,
119                    "generic": "arg4",
120                    "alt-name": "arg4",
121                },
122                {
123                    "name": "rdx",
124                    "bitsize": 64,
125                    "offset": 24,
126                    "encoding": "uint",
127                    "format": "hex",
128                    "set": 0,
129                    "gcc": 1,
130                    "dwarf": 1,
131                    "generic": "arg3",
132                    "alt-name": "arg3",
133                },
134                {
135                    "name": "rdi",
136                    "bitsize": 64,
137                    "offset": 32,
138                    "encoding": "uint",
139                    "format": "hex",
140                    "set": 0,
141                    "gcc": 5,
142                    "dwarf": 5,
143                    "generic": "arg1",
144                    "alt-name": "arg1",
145                },
146                {
147                    "name": "rsi",
148                    "bitsize": 64,
149                    "offset": 40,
150                    "encoding": "uint",
151                    "format": "hex",
152                    "set": 0,
153                    "gcc": 4,
154                    "dwarf": 4,
155                    "generic": "arg2",
156                    "alt-name": "arg2",
157                },
158                {
159                    "name": "rbp",
160                    "bitsize": 64,
161                    "offset": 48,
162                    "encoding": "uint",
163                    "format": "hex",
164                    "set": 0,
165                    "gcc": 6,
166                    "dwarf": 6,
167                    "generic": "fp",
168                    "alt-name": "fp",
169                },
170                {
171                    "name": "rsp",
172                    "bitsize": 64,
173                    "offset": 56,
174                    "encoding": "uint",
175                    "format": "hex",
176                    "set": 0,
177                    "gcc": 7,
178                    "dwarf": 7,
179                    "generic": "sp",
180                    "alt-name": "sp",
181                },
182                {
183                    "name": "r8",
184                    "bitsize": 64,
185                    "offset": 64,
186                    "encoding": "uint",
187                    "format": "hex",
188                    "set": 0,
189                    "gcc": 8,
190                    "dwarf": 8,
191                    "generic": "arg5",
192                    "alt-name": "arg5",
193                },
194                {
195                    "name": "r9",
196                    "bitsize": 64,
197                    "offset": 72,
198                    "encoding": "uint",
199                    "format": "hex",
200                    "set": 0,
201                    "gcc": 9,
202                    "dwarf": 9,
203                    "generic": "arg6",
204                    "alt-name": "arg6",
205                },
206                {
207                    "name": "r10",
208                    "bitsize": 64,
209                    "offset": 80,
210                    "encoding": "uint",
211                    "format": "hex",
212                    "set": 0,
213                    "gcc": 10,
214                    "dwarf": 10,
215                },
216                {
217                    "name": "r11",
218                    "bitsize": 64,
219                    "offset": 88,
220                    "encoding": "uint",
221                    "format": "hex",
222                    "set": 0,
223                    "gcc": 11,
224                    "dwarf": 11,
225                },
226                {
227                    "name": "r12",
228                    "bitsize": 64,
229                    "offset": 96,
230                    "encoding": "uint",
231                    "format": "hex",
232                    "set": 0,
233                    "gcc": 12,
234                    "dwarf": 12,
235                },
236                {
237                    "name": "r13",
238                    "bitsize": 64,
239                    "offset": 104,
240                    "encoding": "uint",
241                    "format": "hex",
242                    "set": 0,
243                    "gcc": 13,
244                    "dwarf": 13,
245                },
246                {
247                    "name": "r14",
248                    "bitsize": 64,
249                    "offset": 112,
250                    "encoding": "uint",
251                    "format": "hex",
252                    "set": 0,
253                    "gcc": 14,
254                    "dwarf": 14,
255                },
256                {
257                    "name": "r15",
258                    "bitsize": 64,
259                    "offset": 120,
260                    "encoding": "uint",
261                    "format": "hex",
262                    "set": 0,
263                    "gcc": 15,
264                    "dwarf": 15,
265                },
266                {
267                    "name": "rip",
268                    "bitsize": 64,
269                    "offset": 128,
270                    "encoding": "uint",
271                    "format": "hex",
272                    "set": 0,
273                    "gcc": 16,
274                    "dwarf": 16,
275                    "generic": "pc",
276                    "alt-name": "pc",
277                },
278                {
279                    "name": "rflags",
280                    "bitsize": 64,
281                    "offset": 136,
282                    "encoding": "uint",
283                    "format": "hex",
284                    "set": 0,
285                    "generic": "flags",
286                    "alt-name": "flags",
287                },
288                {
289                    "name": "cs",
290                    "bitsize": 64,
291                    "offset": 144,
292                    "encoding": "uint",
293                    "format": "hex",
294                    "set": 0,
295                },
296                {
297                    "name": "fs",
298                    "bitsize": 64,
299                    "offset": 152,
300                    "encoding": "uint",
301                    "format": "hex",
302                    "set": 0,
303                },
304                {
305                    "name": "gs",
306                    "bitsize": 64,
307                    "offset": 160,
308                    "encoding": "uint",
309                    "format": "hex",
310                    "set": 0,
311                },
312            ]
313        return self.registers
314
315    def get_register_data(self, tid):
316        return struct.pack(
317            "21Q",
318            tid + 1,
319            tid + 2,
320            tid + 3,
321            tid + 4,
322            tid + 5,
323            tid + 6,
324            tid + 7,
325            tid + 8,
326            tid + 9,
327            tid + 10,
328            tid + 11,
329            tid + 12,
330            tid + 13,
331            tid + 14,
332            tid + 15,
333            tid + 16,
334            tid + 17,
335            tid + 18,
336            tid + 19,
337            tid + 20,
338            tid + 21,
339        )
340