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