xref: /llvm-project/lldb/examples/python/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                    "register_data_addr": 0x100000000,
82                },
83            ]
84        return self.threads
85
86    def get_register_info(self):
87        if self.registers is None:
88            self.registers = dict()
89            triple = self.process.target.triple
90            if triple:
91                arch = triple.split("-")[0]
92                if arch == "x86_64":
93                    self.registers["sets"] = ["GPR", "FPU", "EXC"]
94                    self.registers["registers"] = [
95                        {
96                            "name": "rax",
97                            "bitsize": 64,
98                            "offset": 0,
99                            "encoding": "uint",
100                            "format": "hex",
101                            "set": 0,
102                            "gcc": 0,
103                            "dwarf": 0,
104                        },
105                        {
106                            "name": "rbx",
107                            "bitsize": 64,
108                            "offset": 8,
109                            "encoding": "uint",
110                            "format": "hex",
111                            "set": 0,
112                            "gcc": 3,
113                            "dwarf": 3,
114                        },
115                        {
116                            "name": "rcx",
117                            "bitsize": 64,
118                            "offset": 16,
119                            "encoding": "uint",
120                            "format": "hex",
121                            "set": 0,
122                            "gcc": 2,
123                            "dwarf": 2,
124                            "generic": "arg4",
125                            "alt-name": "arg4",
126                        },
127                        {
128                            "name": "rdx",
129                            "bitsize": 64,
130                            "offset": 24,
131                            "encoding": "uint",
132                            "format": "hex",
133                            "set": 0,
134                            "gcc": 1,
135                            "dwarf": 1,
136                            "generic": "arg3",
137                            "alt-name": "arg3",
138                        },
139                        {
140                            "name": "rdi",
141                            "bitsize": 64,
142                            "offset": 32,
143                            "encoding": "uint",
144                            "format": "hex",
145                            "set": 0,
146                            "gcc": 5,
147                            "dwarf": 5,
148                            "generic": "arg1",
149                            "alt-name": "arg1",
150                        },
151                        {
152                            "name": "rsi",
153                            "bitsize": 64,
154                            "offset": 40,
155                            "encoding": "uint",
156                            "format": "hex",
157                            "set": 0,
158                            "gcc": 4,
159                            "dwarf": 4,
160                            "generic": "arg2",
161                            "alt-name": "arg2",
162                        },
163                        {
164                            "name": "rbp",
165                            "bitsize": 64,
166                            "offset": 48,
167                            "encoding": "uint",
168                            "format": "hex",
169                            "set": 0,
170                            "gcc": 6,
171                            "dwarf": 6,
172                            "generic": "fp",
173                            "alt-name": "fp",
174                        },
175                        {
176                            "name": "rsp",
177                            "bitsize": 64,
178                            "offset": 56,
179                            "encoding": "uint",
180                            "format": "hex",
181                            "set": 0,
182                            "gcc": 7,
183                            "dwarf": 7,
184                            "generic": "sp",
185                            "alt-name": "sp",
186                        },
187                        {
188                            "name": "r8",
189                            "bitsize": 64,
190                            "offset": 64,
191                            "encoding": "uint",
192                            "format": "hex",
193                            "set": 0,
194                            "gcc": 8,
195                            "dwarf": 8,
196                            "generic": "arg5",
197                            "alt-name": "arg5",
198                        },
199                        {
200                            "name": "r9",
201                            "bitsize": 64,
202                            "offset": 72,
203                            "encoding": "uint",
204                            "format": "hex",
205                            "set": 0,
206                            "gcc": 9,
207                            "dwarf": 9,
208                            "generic": "arg6",
209                            "alt-name": "arg6",
210                        },
211                        {
212                            "name": "r10",
213                            "bitsize": 64,
214                            "offset": 80,
215                            "encoding": "uint",
216                            "format": "hex",
217                            "set": 0,
218                            "gcc": 10,
219                            "dwarf": 10,
220                        },
221                        {
222                            "name": "r11",
223                            "bitsize": 64,
224                            "offset": 88,
225                            "encoding": "uint",
226                            "format": "hex",
227                            "set": 0,
228                            "gcc": 11,
229                            "dwarf": 11,
230                        },
231                        {
232                            "name": "r12",
233                            "bitsize": 64,
234                            "offset": 96,
235                            "encoding": "uint",
236                            "format": "hex",
237                            "set": 0,
238                            "gcc": 12,
239                            "dwarf": 12,
240                        },
241                        {
242                            "name": "r13",
243                            "bitsize": 64,
244                            "offset": 104,
245                            "encoding": "uint",
246                            "format": "hex",
247                            "set": 0,
248                            "gcc": 13,
249                            "dwarf": 13,
250                        },
251                        {
252                            "name": "r14",
253                            "bitsize": 64,
254                            "offset": 112,
255                            "encoding": "uint",
256                            "format": "hex",
257                            "set": 0,
258                            "gcc": 14,
259                            "dwarf": 14,
260                        },
261                        {
262                            "name": "r15",
263                            "bitsize": 64,
264                            "offset": 120,
265                            "encoding": "uint",
266                            "format": "hex",
267                            "set": 0,
268                            "gcc": 15,
269                            "dwarf": 15,
270                        },
271                        {
272                            "name": "rip",
273                            "bitsize": 64,
274                            "offset": 128,
275                            "encoding": "uint",
276                            "format": "hex",
277                            "set": 0,
278                            "gcc": 16,
279                            "dwarf": 16,
280                            "generic": "pc",
281                            "alt-name": "pc",
282                        },
283                        {
284                            "name": "rflags",
285                            "bitsize": 64,
286                            "offset": 136,
287                            "encoding": "uint",
288                            "format": "hex",
289                            "set": 0,
290                            "generic": "flags",
291                            "alt-name": "flags",
292                        },
293                        {
294                            "name": "cs",
295                            "bitsize": 64,
296                            "offset": 144,
297                            "encoding": "uint",
298                            "format": "hex",
299                            "set": 0,
300                        },
301                        {
302                            "name": "fs",
303                            "bitsize": 64,
304                            "offset": 152,
305                            "encoding": "uint",
306                            "format": "hex",
307                            "set": 0,
308                        },
309                        {
310                            "name": "gs",
311                            "bitsize": 64,
312                            "offset": 160,
313                            "encoding": "uint",
314                            "format": "hex",
315                            "set": 0,
316                        },
317                    ]
318        return self.registers
319
320    def get_register_data(self, tid):
321        if tid == 0x111111111:
322            return struct.pack(
323                "21Q",
324                1,
325                2,
326                3,
327                4,
328                5,
329                6,
330                7,
331                8,
332                9,
333                10,
334                11,
335                12,
336                13,
337                14,
338                15,
339                16,
340                17,
341                18,
342                19,
343                20,
344                21,
345            )
346        elif tid == 0x222222222:
347            return struct.pack(
348                "21Q",
349                11,
350                12,
351                13,
352                14,
353                15,
354                16,
355                17,
356                18,
357                19,
358                110,
359                111,
360                112,
361                113,
362                114,
363                115,
364                116,
365                117,
366                118,
367                119,
368                120,
369                121,
370            )
371        elif tid == 0x333333333:
372            return struct.pack(
373                "21Q",
374                21,
375                22,
376                23,
377                24,
378                25,
379                26,
380                27,
381                28,
382                29,
383                210,
384                211,
385                212,
386                213,
387                214,
388                215,
389                216,
390                217,
391                218,
392                219,
393                220,
394                221,
395            )
396        elif tid == 0x444444444:
397            return struct.pack(
398                "21Q",
399                31,
400                32,
401                33,
402                34,
403                35,
404                36,
405                37,
406                38,
407                39,
408                310,
409                311,
410                312,
411                313,
412                314,
413                315,
414                316,
415                317,
416                318,
417                319,
418                320,
419                321,
420            )
421        else:
422            return struct.pack(
423                "21Q",
424                41,
425                42,
426                43,
427                44,
428                45,
429                46,
430                47,
431                48,
432                49,
433                410,
434                411,
435                412,
436                413,
437                414,
438                415,
439                416,
440                417,
441                418,
442                419,
443                420,
444                421,
445            )
446        return None
447