1*d8b80295SApple OSS Distributions""" Python I/O subsystem backed by LLDB. """ 2*d8b80295SApple OSS Distributions 3*d8b80295SApple OSS Distributionsimport io 4*d8b80295SApple OSS Distributionsimport lldb 5*d8b80295SApple OSS Distributions 6*d8b80295SApple OSS Distributions 7*d8b80295SApple OSS Distributionsclass SBProcessRawIO(io.RawIOBase): 8*d8b80295SApple OSS Distributions """ RAW I/O implementation backed by a process memory. """ 9*d8b80295SApple OSS Distributions 10*d8b80295SApple OSS Distributions def __init__(self, sbprocess, address, size): 11*d8b80295SApple OSS Distributions """ Create new SBProcess I/O. 12*d8b80295SApple OSS Distributions 13*d8b80295SApple OSS Distributions sbproces: SBProcess instance to read data from. 14*d8b80295SApple OSS Distributions address: Starting memory address in process' VA. 15*d8b80295SApple OSS Distributions size: Size of the memory range. 16*d8b80295SApple OSS Distributions """ 17*d8b80295SApple OSS Distributions super(SBProcessRawIO, self).__init__() 18*d8b80295SApple OSS Distributions 19*d8b80295SApple OSS Distributions self._sbprocess = sbprocess 20*d8b80295SApple OSS Distributions self._start = address 21*d8b80295SApple OSS Distributions self._offset = 0 22*d8b80295SApple OSS Distributions self._end = address + size 23*d8b80295SApple OSS Distributions 24*d8b80295SApple OSS Distributions # Base I/O methods 25*d8b80295SApple OSS Distributions 26*d8b80295SApple OSS Distributions def readable(self): 27*d8b80295SApple OSS Distributions return True 28*d8b80295SApple OSS Distributions 29*d8b80295SApple OSS Distributions def writable(self): 30*d8b80295SApple OSS Distributions # This is a lie that allows using BufferedRandom on top of this I/O. 31*d8b80295SApple OSS Distributions return True 32*d8b80295SApple OSS Distributions 33*d8b80295SApple OSS Distributions def seekable(self): 34*d8b80295SApple OSS Distributions return True 35*d8b80295SApple OSS Distributions 36*d8b80295SApple OSS Distributions # Raw I/O methods 37*d8b80295SApple OSS Distributions 38*d8b80295SApple OSS Distributions def tell(self): 39*d8b80295SApple OSS Distributions return self._offset 40*d8b80295SApple OSS Distributions 41*d8b80295SApple OSS Distributions def seek(self, offset, whence=0): 42*d8b80295SApple OSS Distributions seekto = offset 43*d8b80295SApple OSS Distributions if whence == 0: 44*d8b80295SApple OSS Distributions seekto += 0 45*d8b80295SApple OSS Distributions elif whence == 1: 46*d8b80295SApple OSS Distributions seekto += self.tell() 47*d8b80295SApple OSS Distributions elif whence == 2: 48*d8b80295SApple OSS Distributions seekto += self._end - self._start 49*d8b80295SApple OSS Distributions else: 50*d8b80295SApple OSS Distributions raise IOError("Invalid whence argument to seek: %r" % (whence,)) 51*d8b80295SApple OSS Distributions 52*d8b80295SApple OSS Distributions self._offset = seekto 53*d8b80295SApple OSS Distributions return seekto 54*d8b80295SApple OSS Distributions 55*d8b80295SApple OSS Distributions def read(self, size=-1): 56*d8b80295SApple OSS Distributions if size < 0: 57*d8b80295SApple OSS Distributions return self.readall() 58*d8b80295SApple OSS Distributions 59*d8b80295SApple OSS Distributions # Do not read past the end of the data range. 60*d8b80295SApple OSS Distributions read_size = min(size, self._end - (self._start + self._offset)) 61*d8b80295SApple OSS Distributions 62*d8b80295SApple OSS Distributions err = lldb.SBError() 63*d8b80295SApple OSS Distributions data = self._sbprocess.ReadMemory(self._start + self._offset, read_size, err) 64*d8b80295SApple OSS Distributions 65*d8b80295SApple OSS Distributions # EOF on failure 66*d8b80295SApple OSS Distributions if not err.Success(): 67*d8b80295SApple OSS Distributions return bytes() 68*d8b80295SApple OSS Distributions 69*d8b80295SApple OSS Distributions self._offset += len(data) 70*d8b80295SApple OSS Distributions return bytes(data) 71*d8b80295SApple OSS Distributions 72*d8b80295SApple OSS Distributions def readall(self): 73*d8b80295SApple OSS Distributions err = lldb.SBError() 74*d8b80295SApple OSS Distributions data = self._sbprocess.ReadMemory(self._start, self._end - self._start, err) 75*d8b80295SApple OSS Distributions 76*d8b80295SApple OSS Distributions if not err.Success(): 77*d8b80295SApple OSS Distributions return bytes() 78*d8b80295SApple OSS Distributions 79*d8b80295SApple OSS Distributions return bytes(data) 80*d8b80295SApple OSS Distributions 81*d8b80295SApple OSS Distributions def readinto(self, bytes): 82*d8b80295SApple OSS Distributions """ Reads data into existing object. """ 83*d8b80295SApple OSS Distributions data = self.read(len(bytes)) 84*d8b80295SApple OSS Distributions if data: 85*d8b80295SApple OSS Distributions bytes[:len(data)] = data 86*d8b80295SApple OSS Distributions return len(data) 87*d8b80295SApple OSS Distributions 88*d8b80295SApple OSS Distributions def readlines(self, hint=-1): 89*d8b80295SApple OSS Distributions raise NotImplementedError("Can't read lines yet.") 90*d8b80295SApple OSS Distributions 91*d8b80295SApple OSS Distributions def write(self, bytes): 92*d8b80295SApple OSS Distributions raise NotImplementedError("Can't write through LLDB yet.") 93