1*515bc8c1Sserge-sans-paille#!/usr/bin/env python
22443cbd7SGreg Clayton
32443cbd7SGreg Claytonimport lldb
4435ce139SGreg Claytonimport struct
52443cbd7SGreg Clayton
6b9c1b51eSKate Stone
7c9d645d3SGreg Claytonclass OperatingSystemPlugIn(object):
82443cbd7SGreg Clayton    """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
92443cbd7SGreg Clayton
102443cbd7SGreg Clayton    def __init__(self, process):
11b28179bbSGreg Clayton        '''Initialization needs a valid.SBProcess object.
12b28179bbSGreg Clayton
13b28179bbSGreg Clayton        This plug-in will get created after a live process is valid and has stopped for the
14b28179bbSGreg Clayton        first time.'''
15a83b6cf2SGreg Clayton        self.process = None
16a83b6cf2SGreg Clayton        self.registers = None
17a83b6cf2SGreg Clayton        self.threads = None
18b9c1b51eSKate Stone        if isinstance(process, lldb.SBProcess) and process.IsValid():
192443cbd7SGreg Clayton            self.process = process
20b710b8dbSEnrico Granata            self.threads = None  # Will be an dictionary containing info for each thread
212443cbd7SGreg Clayton
22b28179bbSGreg Clayton    def get_target(self):
23b28179bbSGreg Clayton        # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
24b28179bbSGreg Clayton        # tracks the current target in the LLDB command interpreter which isn't the
25b28179bbSGreg Clayton        # correct thing to use for this plug-in.
26b28179bbSGreg Clayton        return self.process.target
27b28179bbSGreg Clayton
28a4d8747dSGreg Clayton    def create_thread(self, tid, context):
29a4d8747dSGreg Clayton        if tid == 0x444444444:
30b9c1b51eSKate Stone            thread_info = {
31b9c1b51eSKate Stone                'tid': tid,
32b9c1b51eSKate Stone                'name': 'four',
33b9c1b51eSKate Stone                'queue': 'queue4',
34b9c1b51eSKate Stone                'state': 'stopped',
35b9c1b51eSKate Stone                'stop_reason': 'none'}
36a4d8747dSGreg Clayton            self.threads.append(thread_info)
37a4d8747dSGreg Clayton            return thread_info
38a4d8747dSGreg Clayton        return None
39a4d8747dSGreg Clayton
402443cbd7SGreg Clayton    def get_thread_info(self):
412443cbd7SGreg Clayton        if not self.threads:
42b28179bbSGreg Clayton            # The sample dictionary below shows the values that can be returned for a thread
43b28179bbSGreg Clayton            # tid => thread ID (mandatory)
44b28179bbSGreg Clayton            # name => thread name (optional key/value pair)
45b28179bbSGreg Clayton            # queue => thread dispatch queue name (optional key/value pair)
46b28179bbSGreg Clayton            # state => thred state (mandatory, set to 'stopped' for now)
47b28179bbSGreg Clayton            # stop_reason => thread stop reason. (mandatory, usually set to 'none')
48b28179bbSGreg Clayton            #  Possible values include:
49b28179bbSGreg Clayton            #   'breakpoint' if the thread is stopped at a breakpoint
50b28179bbSGreg Clayton            #   'none' thread is just stopped because the process is stopped
51b28179bbSGreg Clayton            #   'trace' the thread just single stepped
52b28179bbSGreg Clayton            #   The usual value for this while threads are in memory is 'none'
5389f255e4SGreg Clayton            # register_data_addr => the address of the register data in memory (optional key/value pair)
5489f255e4SGreg Clayton            #   Specifying this key/value pair for a thread will avoid a call to get_register_data()
5589f255e4SGreg Clayton            #   and can be used when your registers are in a thread context structure that is contiguous
5689f255e4SGreg Clayton            #   in memory. Don't specify this if your register layout in memory doesn't match the layout
57b9c1b51eSKate Stone            # described by the dictionary returned from a call to the
58b9c1b51eSKate Stone            # get_register_info() method.
59b9c1b51eSKate Stone            self.threads = [{'tid': 0x111111111,
60b9c1b51eSKate Stone                             'name': 'one',
61b9c1b51eSKate Stone                             'queue': 'queue1',
62b9c1b51eSKate Stone                             'state': 'stopped',
63b9c1b51eSKate Stone                             'stop_reason': 'breakpoint'},
64b9c1b51eSKate Stone                            {'tid': 0x222222222,
65b9c1b51eSKate Stone                             'name': 'two',
66b9c1b51eSKate Stone                             'queue': 'queue2',
67b9c1b51eSKate Stone                             'state': 'stopped',
68b9c1b51eSKate Stone                             'stop_reason': 'none'},
69b9c1b51eSKate Stone                            {'tid': 0x333333333,
70b9c1b51eSKate Stone                             'name': 'three',
71b9c1b51eSKate Stone                             'queue': 'queue3',
72b9c1b51eSKate Stone                             'state': 'stopped',
73b9c1b51eSKate Stone                             'stop_reason': 'trace',
74b9c1b51eSKate Stone                             'register_data_addr': 0x100000000}]
752443cbd7SGreg Clayton        return self.threads
762443cbd7SGreg Clayton
772443cbd7SGreg Clayton    def get_register_info(self):
78b9c1b51eSKate Stone        if self.registers is None:
79a83b6cf2SGreg Clayton            self.registers = dict()
802443cbd7SGreg Clayton            triple = self.process.target.triple
812443cbd7SGreg Clayton            if triple:
822443cbd7SGreg Clayton                arch = triple.split('-')[0]
832443cbd7SGreg Clayton                if arch == 'x86_64':
84a83b6cf2SGreg Clayton                    self.registers['sets'] = ['GPR', 'FPU', 'EXC']
85a83b6cf2SGreg Clayton                    self.registers['registers'] = [
862443cbd7SGreg Clayton                        {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0},
872443cbd7SGreg Clayton                        {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3},
882443cbd7SGreg Clayton                        {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', },
892443cbd7SGreg Clayton                        {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', },
902443cbd7SGreg Clayton                        {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', },
912443cbd7SGreg Clayton                        {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', },
922443cbd7SGreg Clayton                        {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', },
932443cbd7SGreg Clayton                        {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', },
942443cbd7SGreg Clayton                        {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', },
952443cbd7SGreg Clayton                        {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', },
962443cbd7SGreg Clayton                        {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10},
972443cbd7SGreg Clayton                        {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11},
982443cbd7SGreg Clayton                        {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12},
992443cbd7SGreg Clayton                        {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13},
1002443cbd7SGreg Clayton                        {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14},
1012443cbd7SGreg Clayton                        {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15},
1022443cbd7SGreg Clayton                        {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'},
1032443cbd7SGreg Clayton                        {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'},
1042443cbd7SGreg Clayton                        {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0},
1052443cbd7SGreg Clayton                        {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0},
1062443cbd7SGreg Clayton                        {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0},
1072443cbd7SGreg Clayton                    ]
108a83b6cf2SGreg Clayton        return self.registers
1092443cbd7SGreg Clayton
1102443cbd7SGreg Clayton    def get_register_data(self, tid):
1112443cbd7SGreg Clayton        if tid == 0x111111111:
112b9c1b51eSKate Stone            return struct.pack(
113b9c1b51eSKate Stone                '21Q',
114b9c1b51eSKate Stone                1,
115b9c1b51eSKate Stone                2,
116b9c1b51eSKate Stone                3,
117b9c1b51eSKate Stone                4,
118b9c1b51eSKate Stone                5,
119b9c1b51eSKate Stone                6,
120b9c1b51eSKate Stone                7,
121b9c1b51eSKate Stone                8,
122b9c1b51eSKate Stone                9,
123b9c1b51eSKate Stone                10,
124b9c1b51eSKate Stone                11,
125b9c1b51eSKate Stone                12,
126b9c1b51eSKate Stone                13,
127b9c1b51eSKate Stone                14,
128b9c1b51eSKate Stone                15,
129b9c1b51eSKate Stone                16,
130b9c1b51eSKate Stone                17,
131b9c1b51eSKate Stone                18,
132b9c1b51eSKate Stone                19,
133b9c1b51eSKate Stone                20,
134b9c1b51eSKate Stone                21)
1352443cbd7SGreg Clayton        elif tid == 0x222222222:
136b9c1b51eSKate Stone            return struct.pack(
137b9c1b51eSKate Stone                '21Q',
138b9c1b51eSKate Stone                11,
139b9c1b51eSKate Stone                12,
140b9c1b51eSKate Stone                13,
141b9c1b51eSKate Stone                14,
142b9c1b51eSKate Stone                15,
143b9c1b51eSKate Stone                16,
144b9c1b51eSKate Stone                17,
145b9c1b51eSKate Stone                18,
146b9c1b51eSKate Stone                19,
147b9c1b51eSKate Stone                110,
148b9c1b51eSKate Stone                111,
149b9c1b51eSKate Stone                112,
150b9c1b51eSKate Stone                113,
151b9c1b51eSKate Stone                114,
152b9c1b51eSKate Stone                115,
153b9c1b51eSKate Stone                116,
154b9c1b51eSKate Stone                117,
155b9c1b51eSKate Stone                118,
156b9c1b51eSKate Stone                119,
157b9c1b51eSKate Stone                120,
158b9c1b51eSKate Stone                121)
1592443cbd7SGreg Clayton        elif tid == 0x333333333:
160b9c1b51eSKate Stone            return struct.pack(
161b9c1b51eSKate Stone                '21Q',
162b9c1b51eSKate Stone                21,
163b9c1b51eSKate Stone                22,
164b9c1b51eSKate Stone                23,
165b9c1b51eSKate Stone                24,
166b9c1b51eSKate Stone                25,
167b9c1b51eSKate Stone                26,
168b9c1b51eSKate Stone                27,
169b9c1b51eSKate Stone                28,
170b9c1b51eSKate Stone                29,
171b9c1b51eSKate Stone                210,
172b9c1b51eSKate Stone                211,
173b9c1b51eSKate Stone                212,
174b9c1b51eSKate Stone                213,
175b9c1b51eSKate Stone                214,
176b9c1b51eSKate Stone                215,
177b9c1b51eSKate Stone                216,
178b9c1b51eSKate Stone                217,
179b9c1b51eSKate Stone                218,
180b9c1b51eSKate Stone                219,
181b9c1b51eSKate Stone                220,
182b9c1b51eSKate Stone                221)
183a4d8747dSGreg Clayton        elif tid == 0x444444444:
184b9c1b51eSKate Stone            return struct.pack(
185b9c1b51eSKate Stone                '21Q',
186b9c1b51eSKate Stone                31,
187b9c1b51eSKate Stone                32,
188b9c1b51eSKate Stone                33,
189b9c1b51eSKate Stone                34,
190b9c1b51eSKate Stone                35,
191b9c1b51eSKate Stone                36,
192b9c1b51eSKate Stone                37,
193b9c1b51eSKate Stone                38,
194b9c1b51eSKate Stone                39,
195b9c1b51eSKate Stone                310,
196b9c1b51eSKate Stone                311,
197b9c1b51eSKate Stone                312,
198b9c1b51eSKate Stone                313,
199b9c1b51eSKate Stone                314,
200b9c1b51eSKate Stone                315,
201b9c1b51eSKate Stone                316,
202b9c1b51eSKate Stone                317,
203b9c1b51eSKate Stone                318,
204b9c1b51eSKate Stone                319,
205b9c1b51eSKate Stone                320,
206b9c1b51eSKate Stone                321)
207a4d8747dSGreg Clayton        else:
208b9c1b51eSKate Stone            return struct.pack(
209b9c1b51eSKate Stone                '21Q',
210b9c1b51eSKate Stone                41,
211b9c1b51eSKate Stone                42,
212b9c1b51eSKate Stone                43,
213b9c1b51eSKate Stone                44,
214b9c1b51eSKate Stone                45,
215b9c1b51eSKate Stone                46,
216b9c1b51eSKate Stone                47,
217b9c1b51eSKate Stone                48,
218b9c1b51eSKate Stone                49,
219b9c1b51eSKate Stone                410,
220b9c1b51eSKate Stone                411,
221b9c1b51eSKate Stone                412,
222b9c1b51eSKate Stone                413,
223b9c1b51eSKate Stone                414,
224b9c1b51eSKate Stone                415,
225b9c1b51eSKate Stone                416,
226b9c1b51eSKate Stone                417,
227b9c1b51eSKate Stone                418,
228b9c1b51eSKate Stone                419,
229b9c1b51eSKate Stone                420,
230b9c1b51eSKate Stone                421)
231a4d8747dSGreg Clayton        return None
232