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