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