1*a325d9c4SApple OSS Distributionsimport logging 2*a325d9c4SApple OSS Distributionsimport struct 3*a325d9c4SApple OSS Distributions 4*a325d9c4SApple OSS Distributions 5*a325d9c4SApple OSS Distributionsclass Process(object): 6*a325d9c4SApple OSS Distributions """Base interface for process being debugged. Provides basic functions for gdbserver to interact. 7*a325d9c4SApple OSS Distributions Create a class object for your backing system to provide functionality 8*a325d9c4SApple OSS Distributions 9*a325d9c4SApple OSS Distributions Here is the list of must implement functions: 10*a325d9c4SApple OSS Distributions + please update hinfo['ostype'] and hinfo['vendor'] if its not in (macosx, ios) 11*a325d9c4SApple OSS Distributions + please populate threads_ids_list with ids of threads. 12*a325d9c4SApple OSS Distributions - getThreadStopInfo 13*a325d9c4SApple OSS Distributions - getProcessInfo 14*a325d9c4SApple OSS Distributions - getRegisterDataForThread 15*a325d9c4SApple OSS Distributions - getRegisterInfo 16*a325d9c4SApple OSS Distributions - readMemory 17*a325d9c4SApple OSS Distributions """ 18*a325d9c4SApple OSS Distributions def __init__(self, cputype, cpusubtype, ptrsize): 19*a325d9c4SApple OSS Distributions super(Process, self).__init__() 20*a325d9c4SApple OSS Distributions self.hinfo = { 21*a325d9c4SApple OSS Distributions 'cputype': cputype, 'cpusubtype': cpusubtype, 22*a325d9c4SApple OSS Distributions 'triple': None, 'vendor': 'apple', 'ostype': 'macosx', 23*a325d9c4SApple OSS Distributions 'endian': 'little', 'ptrsize': ptrsize, 'hostname': None, 'os_build': None, 24*a325d9c4SApple OSS Distributions 'os_kernel': None, 'os_version': None, 'watchpoint_exceptions_received': None, 25*a325d9c4SApple OSS Distributions 'default_packet_timeout': '10', 'distribution_id': None 26*a325d9c4SApple OSS Distributions } 27*a325d9c4SApple OSS Distributions 28*a325d9c4SApple OSS Distributions ## if cputype is arm assume its ios 29*a325d9c4SApple OSS Distributions if (cputype & 0xc) != 0xc: 30*a325d9c4SApple OSS Distributions self.hinfo['ostype'] = 'ios' 31*a325d9c4SApple OSS Distributions self.ptrsize = ptrsize 32*a325d9c4SApple OSS Distributions self.threads = {} 33*a325d9c4SApple OSS Distributions self.threads_ids_list = [] 34*a325d9c4SApple OSS Distributions 35*a325d9c4SApple OSS Distributions def getHostInfo(self): 36*a325d9c4SApple OSS Distributions retval = '' 37*a325d9c4SApple OSS Distributions for i in self.hinfo.keys(): 38*a325d9c4SApple OSS Distributions if self.hinfo[i] is None: 39*a325d9c4SApple OSS Distributions continue 40*a325d9c4SApple OSS Distributions retval += '%s:%s;' % (str(i), str(self.hinfo[i])) 41*a325d9c4SApple OSS Distributions return retval 42*a325d9c4SApple OSS Distributions 43*a325d9c4SApple OSS Distributions def getRegisterDataForThread(self, th_id, reg_num): 44*a325d9c4SApple OSS Distributions logging.critical("Not Implemented: getRegisterDataForThread") 45*a325d9c4SApple OSS Distributions return '' 46*a325d9c4SApple OSS Distributions 47*a325d9c4SApple OSS Distributions def readMemory(self, address, size): 48*a325d9c4SApple OSS Distributions logging.critical("readMemory: Not Implemented: readMemory") 49*a325d9c4SApple OSS Distributions #E08 means read failed 50*a325d9c4SApple OSS Distributions return 'E08' 51*a325d9c4SApple OSS Distributions 52*a325d9c4SApple OSS Distributions def writeMemory(self, address, data, size): 53*a325d9c4SApple OSS Distributions """ Unimplemented. address in ptr to save data to. data is native endian stream of bytes, 54*a325d9c4SApple OSS Distributions """ 55*a325d9c4SApple OSS Distributions return 'E09' 56*a325d9c4SApple OSS Distributions 57*a325d9c4SApple OSS Distributions def getRegisterInfo(regnum): 58*a325d9c4SApple OSS Distributions #something similar to 59*a325d9c4SApple OSS Distributions #"name:x1;bitsize:64;offset:8;encoding:uint;format:hex;gcc:1;dwarf:1;set:General Purpose Registers;" 60*a325d9c4SApple OSS Distributions logging.critical("getRegisterInfo: Not Implemented: getRegisterInfo") 61*a325d9c4SApple OSS Distributions return 'E45' 62*a325d9c4SApple OSS Distributions 63*a325d9c4SApple OSS Distributions def getProcessInfo(self): 64*a325d9c4SApple OSS Distributions logging.critical("Not Implemented: qProcessInfo") 65*a325d9c4SApple OSS Distributions return '' 66*a325d9c4SApple OSS Distributions 67*a325d9c4SApple OSS Distributions def getFirstThreadInfo(self): 68*a325d9c4SApple OSS Distributions """ describe all thread ids in the process. 69*a325d9c4SApple OSS Distributions """ 70*a325d9c4SApple OSS Distributions thinfo_str = self.getThreadsInfo() 71*a325d9c4SApple OSS Distributions if not thinfo_str: 72*a325d9c4SApple OSS Distributions logging.warning('getFirstThreadInfo: Process has no threads') 73*a325d9c4SApple OSS Distributions return '' 74*a325d9c4SApple OSS Distributions return 'm' + thinfo_str 75*a325d9c4SApple OSS Distributions 76*a325d9c4SApple OSS Distributions def getSubsequestThreadInfo(self): 77*a325d9c4SApple OSS Distributions """ return 'l' for last because all threads are listed in getFirstThreadInfo call. 78*a325d9c4SApple OSS Distributions """ 79*a325d9c4SApple OSS Distributions return 'l' 80*a325d9c4SApple OSS Distributions 81*a325d9c4SApple OSS Distributions def getSharedLibInfoAddress(self): 82*a325d9c4SApple OSS Distributions """ return int data of a hint where shared library is loaded. 83*a325d9c4SApple OSS Distributions """ 84*a325d9c4SApple OSS Distributions logging.critical("Not Implemented: qShlibInfoAddr") 85*a325d9c4SApple OSS Distributions raise NotImplementedError('getSharedLibInfoAddress is not Implemented') 86*a325d9c4SApple OSS Distributions 87*a325d9c4SApple OSS Distributions def getSignalInfo(self): 88*a325d9c4SApple OSS Distributions # return the signal info in required format. 89*a325d9c4SApple OSS Distributions return "T02" + "threads:" + self.getThreadsInfo() + ';' 90*a325d9c4SApple OSS Distributions 91*a325d9c4SApple OSS Distributions def getThreadsInfo(self): 92*a325d9c4SApple OSS Distributions """ returns ',' separeted values of thread ids """ 93*a325d9c4SApple OSS Distributions retval = '' 94*a325d9c4SApple OSS Distributions first = True 95*a325d9c4SApple OSS Distributions for tid in self.threads_ids_list: 96*a325d9c4SApple OSS Distributions if first is True: 97*a325d9c4SApple OSS Distributions first = False 98*a325d9c4SApple OSS Distributions retval += self.encodeThreadID(tid) 99*a325d9c4SApple OSS Distributions else: 100*a325d9c4SApple OSS Distributions retval += ',%s' % self.encodeThreadID(tid) 101*a325d9c4SApple OSS Distributions return retval 102*a325d9c4SApple OSS Distributions 103*a325d9c4SApple OSS Distributions def getCurrentThreadID(self): 104*a325d9c4SApple OSS Distributions """ returns int thread id of the first stopped thread 105*a325d9c4SApple OSS Distributions if subclass supports thread switching etc then 106*a325d9c4SApple OSS Distributions make sure to re-implement this funciton 107*a325d9c4SApple OSS Distributions """ 108*a325d9c4SApple OSS Distributions if self.threads_ids_list: 109*a325d9c4SApple OSS Distributions return self.threads_ids_list[0] 110*a325d9c4SApple OSS Distributions return 0 111*a325d9c4SApple OSS Distributions 112*a325d9c4SApple OSS Distributions def getThreadStopInfo(self, th_id): 113*a325d9c4SApple OSS Distributions """ returns stop signal and some thread register info. 114*a325d9c4SApple OSS Distributions """ 115*a325d9c4SApple OSS Distributions logging.critical("getThreadStopInfo: Not Implemented. returning basic info.") 116*a325d9c4SApple OSS Distributions 117*a325d9c4SApple OSS Distributions return 'T02thread:%s' % self.encodeThreadID(th_id) 118*a325d9c4SApple OSS Distributions 119*a325d9c4SApple OSS Distributions def encodeRegisterData(self, intdata, bytesize=None): 120*a325d9c4SApple OSS Distributions """ return an encoded string for unsigned int intdata 121*a325d9c4SApple OSS Distributions based on the bytesize and endianness value 122*a325d9c4SApple OSS Distributions """ 123*a325d9c4SApple OSS Distributions if not bytesize: 124*a325d9c4SApple OSS Distributions bytesize = self.ptrsize 125*a325d9c4SApple OSS Distributions 126*a325d9c4SApple OSS Distributions format = '<I' 127*a325d9c4SApple OSS Distributions if bytesize > 4: 128*a325d9c4SApple OSS Distributions format = '<Q' 129*a325d9c4SApple OSS Distributions packed_data = struct.pack(format, intdata) 130*a325d9c4SApple OSS Distributions return packed_data.encode('hex') 131*a325d9c4SApple OSS Distributions 132*a325d9c4SApple OSS Distributions def encodePointerRegisterData(self, ptrdata): 133*a325d9c4SApple OSS Distributions """ encodes pointer data based on ptrsize defined for the target """ 134*a325d9c4SApple OSS Distributions return self.encodeRegisterData(ptrdata, bytesize=self.ptrsize) 135*a325d9c4SApple OSS Distributions 136*a325d9c4SApple OSS Distributions def encodeThreadID(self, intdata): 137*a325d9c4SApple OSS Distributions format = '>Q' 138*a325d9c4SApple OSS Distributions return struct.pack(format, intdata).encode('hex') 139*a325d9c4SApple OSS Distributions 140*a325d9c4SApple OSS Distributions def encodeByteString(self, bytestr): 141*a325d9c4SApple OSS Distributions return bytestr.encode('hex') 142