1*be691f3bSpatrick#!/usr/bin/env python 2061da546Spatrick 3061da546Spatrickimport lldb 4061da546Spatrickimport struct 5061da546Spatrick 6061da546Spatrick 7061da546Spatrickclass OperatingSystemPlugIn(object): 8061da546Spatrick """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" 9061da546Spatrick 10061da546Spatrick def __init__(self, process): 11061da546Spatrick '''Initialization needs a valid.SBProcess object. 12061da546Spatrick 13061da546Spatrick This plug-in will get created after a live process is valid and has stopped for the 14061da546Spatrick first time.''' 15061da546Spatrick self.process = None 16061da546Spatrick self.registers = None 17061da546Spatrick self.threads = None 18061da546Spatrick if isinstance(process, lldb.SBProcess) and process.IsValid(): 19061da546Spatrick self.process = process 20061da546Spatrick self.threads = None # Will be an dictionary containing info for each thread 21061da546Spatrick 22061da546Spatrick def get_target(self): 23061da546Spatrick # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target" 24061da546Spatrick # tracks the current target in the LLDB command interpreter which isn't the 25061da546Spatrick # correct thing to use for this plug-in. 26061da546Spatrick return self.process.target 27061da546Spatrick 28061da546Spatrick def create_thread(self, tid, context): 29061da546Spatrick if tid == 0x444444444: 30061da546Spatrick thread_info = { 31061da546Spatrick 'tid': tid, 32061da546Spatrick 'name': 'four', 33061da546Spatrick 'queue': 'queue4', 34061da546Spatrick 'state': 'stopped', 35061da546Spatrick 'stop_reason': 'none'} 36061da546Spatrick self.threads.append(thread_info) 37061da546Spatrick return thread_info 38061da546Spatrick return None 39061da546Spatrick 40061da546Spatrick def get_thread_info(self): 41061da546Spatrick if not self.threads: 42061da546Spatrick # The sample dictionary below shows the values that can be returned for a thread 43061da546Spatrick # tid => thread ID (mandatory) 44061da546Spatrick # name => thread name (optional key/value pair) 45061da546Spatrick # queue => thread dispatch queue name (optional key/value pair) 46061da546Spatrick # state => thred state (mandatory, set to 'stopped' for now) 47061da546Spatrick # stop_reason => thread stop reason. (mandatory, usually set to 'none') 48061da546Spatrick # Possible values include: 49061da546Spatrick # 'breakpoint' if the thread is stopped at a breakpoint 50061da546Spatrick # 'none' thread is just stopped because the process is stopped 51061da546Spatrick # 'trace' the thread just single stepped 52061da546Spatrick # The usual value for this while threads are in memory is 'none' 53061da546Spatrick # register_data_addr => the address of the register data in memory (optional key/value pair) 54061da546Spatrick # Specifying this key/value pair for a thread will avoid a call to get_register_data() 55061da546Spatrick # and can be used when your registers are in a thread context structure that is contiguous 56061da546Spatrick # in memory. Don't specify this if your register layout in memory doesn't match the layout 57061da546Spatrick # described by the dictionary returned from a call to the 58061da546Spatrick # get_register_info() method. 59061da546Spatrick self.threads = [{'tid': 0x111111111, 60061da546Spatrick 'name': 'one', 61061da546Spatrick 'queue': 'queue1', 62061da546Spatrick 'state': 'stopped', 63061da546Spatrick 'stop_reason': 'breakpoint'}, 64061da546Spatrick {'tid': 0x222222222, 65061da546Spatrick 'name': 'two', 66061da546Spatrick 'queue': 'queue2', 67061da546Spatrick 'state': 'stopped', 68061da546Spatrick 'stop_reason': 'none'}, 69061da546Spatrick {'tid': 0x333333333, 70061da546Spatrick 'name': 'three', 71061da546Spatrick 'queue': 'queue3', 72061da546Spatrick 'state': 'stopped', 73061da546Spatrick 'stop_reason': 'trace', 74061da546Spatrick 'register_data_addr': 0x100000000}] 75061da546Spatrick return self.threads 76061da546Spatrick 77061da546Spatrick def get_register_info(self): 78061da546Spatrick if self.registers is None: 79061da546Spatrick self.registers = dict() 80061da546Spatrick triple = self.process.target.triple 81061da546Spatrick if triple: 82061da546Spatrick arch = triple.split('-')[0] 83061da546Spatrick if arch == 'x86_64': 84061da546Spatrick self.registers['sets'] = ['GPR', 'FPU', 'EXC'] 85061da546Spatrick self.registers['registers'] = [ 86061da546Spatrick {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0}, 87061da546Spatrick {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3}, 88061da546Spatrick {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', }, 89061da546Spatrick {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', }, 90061da546Spatrick {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', }, 91061da546Spatrick {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', }, 92061da546Spatrick {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', }, 93061da546Spatrick {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', }, 94061da546Spatrick {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', }, 95061da546Spatrick {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', }, 96061da546Spatrick {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10}, 97061da546Spatrick {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11}, 98061da546Spatrick {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12}, 99061da546Spatrick {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13}, 100061da546Spatrick {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14}, 101061da546Spatrick {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15}, 102061da546Spatrick {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'}, 103061da546Spatrick {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'}, 104061da546Spatrick {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0}, 105061da546Spatrick {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0}, 106061da546Spatrick {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0}, 107061da546Spatrick ] 108061da546Spatrick return self.registers 109061da546Spatrick 110061da546Spatrick def get_register_data(self, tid): 111061da546Spatrick if tid == 0x111111111: 112061da546Spatrick return struct.pack( 113061da546Spatrick '21Q', 114061da546Spatrick 1, 115061da546Spatrick 2, 116061da546Spatrick 3, 117061da546Spatrick 4, 118061da546Spatrick 5, 119061da546Spatrick 6, 120061da546Spatrick 7, 121061da546Spatrick 8, 122061da546Spatrick 9, 123061da546Spatrick 10, 124061da546Spatrick 11, 125061da546Spatrick 12, 126061da546Spatrick 13, 127061da546Spatrick 14, 128061da546Spatrick 15, 129061da546Spatrick 16, 130061da546Spatrick 17, 131061da546Spatrick 18, 132061da546Spatrick 19, 133061da546Spatrick 20, 134061da546Spatrick 21) 135061da546Spatrick elif tid == 0x222222222: 136061da546Spatrick return struct.pack( 137061da546Spatrick '21Q', 138061da546Spatrick 11, 139061da546Spatrick 12, 140061da546Spatrick 13, 141061da546Spatrick 14, 142061da546Spatrick 15, 143061da546Spatrick 16, 144061da546Spatrick 17, 145061da546Spatrick 18, 146061da546Spatrick 19, 147061da546Spatrick 110, 148061da546Spatrick 111, 149061da546Spatrick 112, 150061da546Spatrick 113, 151061da546Spatrick 114, 152061da546Spatrick 115, 153061da546Spatrick 116, 154061da546Spatrick 117, 155061da546Spatrick 118, 156061da546Spatrick 119, 157061da546Spatrick 120, 158061da546Spatrick 121) 159061da546Spatrick elif tid == 0x333333333: 160061da546Spatrick return struct.pack( 161061da546Spatrick '21Q', 162061da546Spatrick 21, 163061da546Spatrick 22, 164061da546Spatrick 23, 165061da546Spatrick 24, 166061da546Spatrick 25, 167061da546Spatrick 26, 168061da546Spatrick 27, 169061da546Spatrick 28, 170061da546Spatrick 29, 171061da546Spatrick 210, 172061da546Spatrick 211, 173061da546Spatrick 212, 174061da546Spatrick 213, 175061da546Spatrick 214, 176061da546Spatrick 215, 177061da546Spatrick 216, 178061da546Spatrick 217, 179061da546Spatrick 218, 180061da546Spatrick 219, 181061da546Spatrick 220, 182061da546Spatrick 221) 183061da546Spatrick elif tid == 0x444444444: 184061da546Spatrick return struct.pack( 185061da546Spatrick '21Q', 186061da546Spatrick 31, 187061da546Spatrick 32, 188061da546Spatrick 33, 189061da546Spatrick 34, 190061da546Spatrick 35, 191061da546Spatrick 36, 192061da546Spatrick 37, 193061da546Spatrick 38, 194061da546Spatrick 39, 195061da546Spatrick 310, 196061da546Spatrick 311, 197061da546Spatrick 312, 198061da546Spatrick 313, 199061da546Spatrick 314, 200061da546Spatrick 315, 201061da546Spatrick 316, 202061da546Spatrick 317, 203061da546Spatrick 318, 204061da546Spatrick 319, 205061da546Spatrick 320, 206061da546Spatrick 321) 207061da546Spatrick else: 208061da546Spatrick return struct.pack( 209061da546Spatrick '21Q', 210061da546Spatrick 41, 211061da546Spatrick 42, 212061da546Spatrick 43, 213061da546Spatrick 44, 214061da546Spatrick 45, 215061da546Spatrick 46, 216061da546Spatrick 47, 217061da546Spatrick 48, 218061da546Spatrick 49, 219061da546Spatrick 410, 220061da546Spatrick 411, 221061da546Spatrick 412, 222061da546Spatrick 413, 223061da546Spatrick 414, 224061da546Spatrick 415, 225061da546Spatrick 416, 226061da546Spatrick 417, 227061da546Spatrick 418, 228061da546Spatrick 419, 229061da546Spatrick 420, 230061da546Spatrick 421) 231061da546Spatrick return None 232