xref: /openbsd-src/gnu/llvm/lldb/examples/python/operating_system.py (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick#!/usr/bin/python
2*061da546Spatrick
3*061da546Spatrickimport lldb
4*061da546Spatrickimport struct
5*061da546Spatrick
6*061da546Spatrick
7*061da546Spatrickclass OperatingSystemPlugIn(object):
8*061da546Spatrick    """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
9*061da546Spatrick
10*061da546Spatrick    def __init__(self, process):
11*061da546Spatrick        '''Initialization needs a valid.SBProcess object.
12*061da546Spatrick
13*061da546Spatrick        This plug-in will get created after a live process is valid and has stopped for the
14*061da546Spatrick        first time.'''
15*061da546Spatrick        self.process = None
16*061da546Spatrick        self.registers = None
17*061da546Spatrick        self.threads = None
18*061da546Spatrick        if isinstance(process, lldb.SBProcess) and process.IsValid():
19*061da546Spatrick            self.process = process
20*061da546Spatrick            self.threads = None  # Will be an dictionary containing info for each thread
21*061da546Spatrick
22*061da546Spatrick    def get_target(self):
23*061da546Spatrick        # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
24*061da546Spatrick        # tracks the current target in the LLDB command interpreter which isn't the
25*061da546Spatrick        # correct thing to use for this plug-in.
26*061da546Spatrick        return self.process.target
27*061da546Spatrick
28*061da546Spatrick    def create_thread(self, tid, context):
29*061da546Spatrick        if tid == 0x444444444:
30*061da546Spatrick            thread_info = {
31*061da546Spatrick                'tid': tid,
32*061da546Spatrick                'name': 'four',
33*061da546Spatrick                'queue': 'queue4',
34*061da546Spatrick                'state': 'stopped',
35*061da546Spatrick                'stop_reason': 'none'}
36*061da546Spatrick            self.threads.append(thread_info)
37*061da546Spatrick            return thread_info
38*061da546Spatrick        return None
39*061da546Spatrick
40*061da546Spatrick    def get_thread_info(self):
41*061da546Spatrick        if not self.threads:
42*061da546Spatrick            # The sample dictionary below shows the values that can be returned for a thread
43*061da546Spatrick            # tid => thread ID (mandatory)
44*061da546Spatrick            # name => thread name (optional key/value pair)
45*061da546Spatrick            # queue => thread dispatch queue name (optional key/value pair)
46*061da546Spatrick            # state => thred state (mandatory, set to 'stopped' for now)
47*061da546Spatrick            # stop_reason => thread stop reason. (mandatory, usually set to 'none')
48*061da546Spatrick            #  Possible values include:
49*061da546Spatrick            #   'breakpoint' if the thread is stopped at a breakpoint
50*061da546Spatrick            #   'none' thread is just stopped because the process is stopped
51*061da546Spatrick            #   'trace' the thread just single stepped
52*061da546Spatrick            #   The usual value for this while threads are in memory is 'none'
53*061da546Spatrick            # register_data_addr => the address of the register data in memory (optional key/value pair)
54*061da546Spatrick            #   Specifying this key/value pair for a thread will avoid a call to get_register_data()
55*061da546Spatrick            #   and can be used when your registers are in a thread context structure that is contiguous
56*061da546Spatrick            #   in memory. Don't specify this if your register layout in memory doesn't match the layout
57*061da546Spatrick            # described by the dictionary returned from a call to the
58*061da546Spatrick            # get_register_info() method.
59*061da546Spatrick            self.threads = [{'tid': 0x111111111,
60*061da546Spatrick                             'name': 'one',
61*061da546Spatrick                             'queue': 'queue1',
62*061da546Spatrick                             'state': 'stopped',
63*061da546Spatrick                             'stop_reason': 'breakpoint'},
64*061da546Spatrick                            {'tid': 0x222222222,
65*061da546Spatrick                             'name': 'two',
66*061da546Spatrick                             'queue': 'queue2',
67*061da546Spatrick                             'state': 'stopped',
68*061da546Spatrick                             'stop_reason': 'none'},
69*061da546Spatrick                            {'tid': 0x333333333,
70*061da546Spatrick                             'name': 'three',
71*061da546Spatrick                             'queue': 'queue3',
72*061da546Spatrick                             'state': 'stopped',
73*061da546Spatrick                             'stop_reason': 'trace',
74*061da546Spatrick                             'register_data_addr': 0x100000000}]
75*061da546Spatrick        return self.threads
76*061da546Spatrick
77*061da546Spatrick    def get_register_info(self):
78*061da546Spatrick        if self.registers is None:
79*061da546Spatrick            self.registers = dict()
80*061da546Spatrick            triple = self.process.target.triple
81*061da546Spatrick            if triple:
82*061da546Spatrick                arch = triple.split('-')[0]
83*061da546Spatrick                if arch == 'x86_64':
84*061da546Spatrick                    self.registers['sets'] = ['GPR', 'FPU', 'EXC']
85*061da546Spatrick                    self.registers['registers'] = [
86*061da546Spatrick                        {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0},
87*061da546Spatrick                        {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3},
88*061da546Spatrick                        {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', },
89*061da546Spatrick                        {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', },
90*061da546Spatrick                        {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', },
91*061da546Spatrick                        {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', },
92*061da546Spatrick                        {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', },
93*061da546Spatrick                        {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', },
94*061da546Spatrick                        {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', },
95*061da546Spatrick                        {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', },
96*061da546Spatrick                        {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10},
97*061da546Spatrick                        {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11},
98*061da546Spatrick                        {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12},
99*061da546Spatrick                        {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13},
100*061da546Spatrick                        {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14},
101*061da546Spatrick                        {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15},
102*061da546Spatrick                        {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'},
103*061da546Spatrick                        {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'},
104*061da546Spatrick                        {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0},
105*061da546Spatrick                        {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0},
106*061da546Spatrick                        {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0},
107*061da546Spatrick                    ]
108*061da546Spatrick        return self.registers
109*061da546Spatrick
110*061da546Spatrick    def get_register_data(self, tid):
111*061da546Spatrick        if tid == 0x111111111:
112*061da546Spatrick            return struct.pack(
113*061da546Spatrick                '21Q',
114*061da546Spatrick                1,
115*061da546Spatrick                2,
116*061da546Spatrick                3,
117*061da546Spatrick                4,
118*061da546Spatrick                5,
119*061da546Spatrick                6,
120*061da546Spatrick                7,
121*061da546Spatrick                8,
122*061da546Spatrick                9,
123*061da546Spatrick                10,
124*061da546Spatrick                11,
125*061da546Spatrick                12,
126*061da546Spatrick                13,
127*061da546Spatrick                14,
128*061da546Spatrick                15,
129*061da546Spatrick                16,
130*061da546Spatrick                17,
131*061da546Spatrick                18,
132*061da546Spatrick                19,
133*061da546Spatrick                20,
134*061da546Spatrick                21)
135*061da546Spatrick        elif tid == 0x222222222:
136*061da546Spatrick            return struct.pack(
137*061da546Spatrick                '21Q',
138*061da546Spatrick                11,
139*061da546Spatrick                12,
140*061da546Spatrick                13,
141*061da546Spatrick                14,
142*061da546Spatrick                15,
143*061da546Spatrick                16,
144*061da546Spatrick                17,
145*061da546Spatrick                18,
146*061da546Spatrick                19,
147*061da546Spatrick                110,
148*061da546Spatrick                111,
149*061da546Spatrick                112,
150*061da546Spatrick                113,
151*061da546Spatrick                114,
152*061da546Spatrick                115,
153*061da546Spatrick                116,
154*061da546Spatrick                117,
155*061da546Spatrick                118,
156*061da546Spatrick                119,
157*061da546Spatrick                120,
158*061da546Spatrick                121)
159*061da546Spatrick        elif tid == 0x333333333:
160*061da546Spatrick            return struct.pack(
161*061da546Spatrick                '21Q',
162*061da546Spatrick                21,
163*061da546Spatrick                22,
164*061da546Spatrick                23,
165*061da546Spatrick                24,
166*061da546Spatrick                25,
167*061da546Spatrick                26,
168*061da546Spatrick                27,
169*061da546Spatrick                28,
170*061da546Spatrick                29,
171*061da546Spatrick                210,
172*061da546Spatrick                211,
173*061da546Spatrick                212,
174*061da546Spatrick                213,
175*061da546Spatrick                214,
176*061da546Spatrick                215,
177*061da546Spatrick                216,
178*061da546Spatrick                217,
179*061da546Spatrick                218,
180*061da546Spatrick                219,
181*061da546Spatrick                220,
182*061da546Spatrick                221)
183*061da546Spatrick        elif tid == 0x444444444:
184*061da546Spatrick            return struct.pack(
185*061da546Spatrick                '21Q',
186*061da546Spatrick                31,
187*061da546Spatrick                32,
188*061da546Spatrick                33,
189*061da546Spatrick                34,
190*061da546Spatrick                35,
191*061da546Spatrick                36,
192*061da546Spatrick                37,
193*061da546Spatrick                38,
194*061da546Spatrick                39,
195*061da546Spatrick                310,
196*061da546Spatrick                311,
197*061da546Spatrick                312,
198*061da546Spatrick                313,
199*061da546Spatrick                314,
200*061da546Spatrick                315,
201*061da546Spatrick                316,
202*061da546Spatrick                317,
203*061da546Spatrick                318,
204*061da546Spatrick                319,
205*061da546Spatrick                320,
206*061da546Spatrick                321)
207*061da546Spatrick        else:
208*061da546Spatrick            return struct.pack(
209*061da546Spatrick                '21Q',
210*061da546Spatrick                41,
211*061da546Spatrick                42,
212*061da546Spatrick                43,
213*061da546Spatrick                44,
214*061da546Spatrick                45,
215*061da546Spatrick                46,
216*061da546Spatrick                47,
217*061da546Spatrick                48,
218*061da546Spatrick                49,
219*061da546Spatrick                410,
220*061da546Spatrick                411,
221*061da546Spatrick                412,
222*061da546Spatrick                413,
223*061da546Spatrick                414,
224*061da546Spatrick                415,
225*061da546Spatrick                416,
226*061da546Spatrick                417,
227*061da546Spatrick                418,
228*061da546Spatrick                419,
229*061da546Spatrick                420,
230*061da546Spatrick                421)
231*061da546Spatrick        return None
232