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