xref: /xnu-10063.141.1/tools/lldbmacros/core/lldbwrap.py (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
1*d8b80295SApple OSS Distributionsimport functools
2*d8b80295SApple OSS Distributionsimport inspect
3*d8b80295SApple OSS Distributionsimport numbers
4*d8b80295SApple OSS Distributionsimport struct
5*d8b80295SApple OSS Distributionsimport sys
6*d8b80295SApple OSS Distributions
7*d8b80295SApple OSS Distributionsimport lldb
8*d8b80295SApple OSS Distributions
9*d8b80295SApple OSS Distributions__all__ = []
10*d8b80295SApple OSS Distributions
11*d8b80295SApple OSS DistributionsUPCASTS = {}
12*d8b80295SApple OSS Distributions
13*d8b80295SApple OSS Distributions#
14*d8b80295SApple OSS Distributions# List of Quirks, once fixed, replace the booleans with an evaluation
15*d8b80295SApple OSS Distributions# of whether the lldb being used has the fix or not.
16*d8b80295SApple OSS Distributions#
17*d8b80295SApple OSS Distributions
18*d8b80295SApple OSS Distributions#
19*d8b80295SApple OSS Distributions# rdar://99785324 (GetValueAsUnsigned performs sign extension
20*d8b80295SApple OSS Distributions#                  when it REALLY shouldn't on bitfields)
21*d8b80295SApple OSS Distributions#
22*d8b80295SApple OSS DistributionsQUIRK_99785324 = True
23*d8b80295SApple OSS Distributions
24*d8b80295SApple OSS Distributions#
25*d8b80295SApple OSS Distributions# rdar://99806493 (SBValue.Cast() is not doing the right thing with PAC)
26*d8b80295SApple OSS Distributions#
27*d8b80295SApple OSS DistributionsQUIRK_99806493 = True
28*d8b80295SApple OSS Distributions
29*d8b80295SApple OSS Distributions#
30*d8b80295SApple OSS Distributions# rdar://100103405 (Default value for target.prefer-dynamic-value makes
31*d8b80295SApple OSS Distributions#                  macros 40x as slow when connected to Astris)
32*d8b80295SApple OSS Distributions#
33*d8b80295SApple OSS DistributionsQUIRK_100103405 = True
34*d8b80295SApple OSS Distributions
35*d8b80295SApple OSS Distributions#
36*d8b80295SApple OSS Distributions# rdar://100162262 ([correctness] Multiple dereferences do not result
37*d8b80295SApple OSS Distributions#                  in the same load address in some cases depending
38*d8b80295SApple OSS Distributions#                  on whether the original value is a pointer created
39*d8b80295SApple OSS Distributions#                  with AddressOf() or not.)
40*d8b80295SApple OSS Distributions#
41*d8b80295SApple OSS DistributionsQUIRK_100162262 = True
42*d8b80295SApple OSS Distributions
43*d8b80295SApple OSS Distributions#
44*d8b80295SApple OSS Distributions# rdar://102642763 (LLDB macros are unable to access member of anon struct
45*d8b80295SApple OSS Distributions#                  or union in C++ class)
46*d8b80295SApple OSS Distributions#
47*d8b80295SApple OSS DistributionsQUIRK_102642763 = True
48*d8b80295SApple OSS Distributions
49*d8b80295SApple OSS Distributions#
50*d8b80295SApple OSS Distributions# rdar://104494282 (Lldb computes correct "Value As Address" but Dereference()s
51*d8b80295SApple OSS Distributions#                   wrong)
52*d8b80295SApple OSS Distributions#
53*d8b80295SApple OSS DistributionsQUIRK_104494282 = True
54*d8b80295SApple OSS Distributions
55*d8b80295SApple OSS Distributions
56*d8b80295SApple OSS DistributionsI8_STRUCT  = struct.Struct('b')
57*d8b80295SApple OSS DistributionsI16_STRUCT = struct.Struct('h')
58*d8b80295SApple OSS DistributionsI32_STRUCT = struct.Struct('i')
59*d8b80295SApple OSS DistributionsI64_STRUCT = struct.Struct('q')
60*d8b80295SApple OSS Distributions
61*d8b80295SApple OSS DistributionsU8_STRUCT  = struct.Struct('B')
62*d8b80295SApple OSS DistributionsU16_STRUCT = struct.Struct('H')
63*d8b80295SApple OSS DistributionsU32_STRUCT = struct.Struct('I')
64*d8b80295SApple OSS DistributionsU64_STRUCT = struct.Struct('Q')
65*d8b80295SApple OSS Distributions
66*d8b80295SApple OSS DistributionsFLT_STRUCT = struct.Struct('f')
67*d8b80295SApple OSS DistributionsDBL_STRUCT = struct.Struct('d')
68*d8b80295SApple OSS Distributions
69*d8b80295SApple OSS Distributions
70*d8b80295SApple OSS Distributionsdef lldbwrap_raise(exn, fn, reason, *args, **kwargs):
71*d8b80295SApple OSS Distributions    """
72*d8b80295SApple OSS Distributions    Helper to form a helpful exception string for the generic lldb.SB*
73*d8b80295SApple OSS Distributions    checked wrappers
74*d8b80295SApple OSS Distributions
75*d8b80295SApple OSS Distributions    @param exn (Exception type)
76*d8b80295SApple OSS Distributions        The type of exception to raise
77*d8b80295SApple OSS Distributions
78*d8b80295SApple OSS Distributions    @param fn (Function)
79*d8b80295SApple OSS Distributions        The function that failed (approximately)
80*d8b80295SApple OSS Distributions
81*d8b80295SApple OSS Distributions    @param reason (string)
82*d8b80295SApple OSS Distributions        A reason string to append
83*d8b80295SApple OSS Distributions
84*d8b80295SApple OSS Distributions    @params *args, **kwargs
85*d8b80295SApple OSS Distributions        The arguments that have been passed to @c fn
86*d8b80295SApple OSS Distributions        in order to pretty pring them in something useful
87*d8b80295SApple OSS Distributions    """
88*d8b80295SApple OSS Distributions    args_str = []
89*d8b80295SApple OSS Distributions
90*d8b80295SApple OSS Distributions    for arg in args:
91*d8b80295SApple OSS Distributions        if isinstance(arg, lldb.SBValue):
92*d8b80295SApple OSS Distributions            args_str.append("<lldb.SBValue ({} &){:#x}>".format(
93*d8b80295SApple OSS Distributions                lldb.SBValue(arg).GetType().GetDisplayTypeName(),
94*d8b80295SApple OSS Distributions                lldb.SBValue(arg).GetLoadAddress())
95*d8b80295SApple OSS Distributions            )
96*d8b80295SApple OSS Distributions        elif isinstance(arg, lldb.SBType):
97*d8b80295SApple OSS Distributions            args_str.append("<lldb.SBType {}>".format(lldb.SBType(arg).GetDisplayTypeName()))
98*d8b80295SApple OSS Distributions        elif isinstance(arg, numbers.Integral):
99*d8b80295SApple OSS Distributions            args_str.append("{:#x}".format(arg))
100*d8b80295SApple OSS Distributions        else:
101*d8b80295SApple OSS Distributions            args_str.append(repr(arg))
102*d8b80295SApple OSS Distributions
103*d8b80295SApple OSS Distributions    if len(kwargs) > 0:
104*d8b80295SApple OSS Distributions        args_str.append("...")
105*d8b80295SApple OSS Distributions
106*d8b80295SApple OSS Distributions    if reason:
107*d8b80295SApple OSS Distributions        raise exn("{}({}) failed: {}".format(
108*d8b80295SApple OSS Distributions            fn.__name__, ", ".join(args_str), reason))
109*d8b80295SApple OSS Distributions    raise exn("{}({}) failed".format(fn.__name__, ", ".join(args_str)))
110*d8b80295SApple OSS Distributions
111*d8b80295SApple OSS Distributions
112*d8b80295SApple OSS Distributionsdef lldbwrap_update_class_dict(basename, basecls, attr):
113*d8b80295SApple OSS Distributions    """
114*d8b80295SApple OSS Distributions    Make the extension dictionary for our synthesized classes
115*d8b80295SApple OSS Distributions
116*d8b80295SApple OSS Distributions    This function will add wrappers around certain functions
117*d8b80295SApple OSS Distributions    that will inspect their return type, and when it is
118*d8b80295SApple OSS Distributions    of one of the @c UPCASTS ones, will monkey patch
119*d8b80295SApple OSS Distributions    the return value __class__.
120*d8b80295SApple OSS Distributions
121*d8b80295SApple OSS Distributions    It would be cleaner to invoke a "copy constructor", however
122*d8b80295SApple OSS Distributions    it has a very high cost, so this brittle monkey patching
123*d8b80295SApple OSS Distributions    is used instead.
124*d8b80295SApple OSS Distributions    """
125*d8b80295SApple OSS Distributions
126*d8b80295SApple OSS Distributions    def _make_upcast_wrapper(fn):
127*d8b80295SApple OSS Distributions        @functools.wraps(fn)
128*d8b80295SApple OSS Distributions        def wrapper(*args, **kwargs):
129*d8b80295SApple OSS Distributions            result = fn(*args, **kwargs)
130*d8b80295SApple OSS Distributions            upcast = UPCASTS.get(result.__class__)
131*d8b80295SApple OSS Distributions            if upcast: upcast(result)
132*d8b80295SApple OSS Distributions            return result
133*d8b80295SApple OSS Distributions
134*d8b80295SApple OSS Distributions        return wrapper
135*d8b80295SApple OSS Distributions
136*d8b80295SApple OSS Distributions    def _make_checked_upcast_wrapper(fn):
137*d8b80295SApple OSS Distributions        @functools.wraps(fn)
138*d8b80295SApple OSS Distributions        def wrapper(*args, **kwargs):
139*d8b80295SApple OSS Distributions            result = fn(*args, **kwargs)
140*d8b80295SApple OSS Distributions            upcast = UPCASTS.get(result.__class__)
141*d8b80295SApple OSS Distributions            if not upcast:
142*d8b80295SApple OSS Distributions                return result
143*d8b80295SApple OSS Distributions            if result.IsValid():
144*d8b80295SApple OSS Distributions                upcast(result)
145*d8b80295SApple OSS Distributions                return result
146*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, fn, None, *args, **kwargs)
147*d8b80295SApple OSS Distributions
148*d8b80295SApple OSS Distributions        return wrapper
149*d8b80295SApple OSS Distributions
150*d8b80295SApple OSS Distributions    @classmethod
151*d8b80295SApple OSS Distributions    def xUpcast(cls, value):
152*d8b80295SApple OSS Distributions        value.__class__ = cls
153*d8b80295SApple OSS Distributions
154*d8b80295SApple OSS Distributions    #
155*d8b80295SApple OSS Distributions    # Those methods return scalars, and are very popular
156*d8b80295SApple OSS Distributions    # wrapping only makes them slow with no benefit.
157*d8b80295SApple OSS Distributions    #
158*d8b80295SApple OSS Distributions    DO_NOT_WRAP = set([
159*d8b80295SApple OSS Distributions        'GetByteSize',
160*d8b80295SApple OSS Distributions        'GetAddressByteSize',
161*d8b80295SApple OSS Distributions        'GetLoadAddress',
162*d8b80295SApple OSS Distributions        'GetName',
163*d8b80295SApple OSS Distributions        'GetOffsetInBits',
164*d8b80295SApple OSS Distributions        'GetOffsetInBytes',
165*d8b80295SApple OSS Distributions        'GetStopID',
166*d8b80295SApple OSS Distributions        'GetTypeFlags',
167*d8b80295SApple OSS Distributions        'GetUniqueID',
168*d8b80295SApple OSS Distributions        'GetValueAsAddress',
169*d8b80295SApple OSS Distributions        'GetValueAsSigned',
170*d8b80295SApple OSS Distributions        'GetValueAsUnsigned',
171*d8b80295SApple OSS Distributions        'TypeIsPointerType',
172*d8b80295SApple OSS Distributions        'IsValid',
173*d8b80295SApple OSS Distributions    ])
174*d8b80295SApple OSS Distributions
175*d8b80295SApple OSS Distributions    DO_NOT_WRAP_PREFIX = [
176*d8b80295SApple OSS Distributions        '__',           # do not wrap magic python functions
177*d8b80295SApple OSS Distributions        'Is',           # LLDB's "Is*" APIs return booleans
178*d8b80295SApple OSS Distributions        'GetNum',       # LLDB's "GetNum*" APIs return integers
179*d8b80295SApple OSS Distributions        'GetIndex',     # LLDB's "GetIndex*" APIs return integers
180*d8b80295SApple OSS Distributions    ]
181*d8b80295SApple OSS Distributions
182*d8b80295SApple OSS Distributions    for fname, value in inspect.getmembers(basecls):
183*d8b80295SApple OSS Distributions        if fname in DO_NOT_WRAP:
184*d8b80295SApple OSS Distributions            continue
185*d8b80295SApple OSS Distributions
186*d8b80295SApple OSS Distributions        elif any(fname.startswith(pfx) for pfx in DO_NOT_WRAP_PREFIX):
187*d8b80295SApple OSS Distributions            continue
188*d8b80295SApple OSS Distributions
189*d8b80295SApple OSS Distributions        elif inspect.isfunction(value) or inspect.ismethod(value):
190*d8b80295SApple OSS Distributions            attr.setdefault(fname, _make_upcast_wrapper(value))
191*d8b80295SApple OSS Distributions            attr.setdefault('chk' + fname, _make_checked_upcast_wrapper(value))
192*d8b80295SApple OSS Distributions            attr.setdefault('raw' + fname, value)
193*d8b80295SApple OSS Distributions
194*d8b80295SApple OSS Distributions        elif isinstance(value, property):
195*d8b80295SApple OSS Distributions            attr[fname] = property(_make_upcast_wrapper(value.fget), value.fset, doc=value.__doc__)
196*d8b80295SApple OSS Distributions
197*d8b80295SApple OSS Distributions    attr.setdefault('xUpcast', xUpcast)
198*d8b80295SApple OSS Distributions
199*d8b80295SApple OSS Distributions
200*d8b80295SApple OSS Distributionsclass LLDBWrapMetaclass(type):
201*d8b80295SApple OSS Distributions    """ Metaclass used for manual definitions of lldb.SB* subclasses """
202*d8b80295SApple OSS Distributions
203*d8b80295SApple OSS Distributions    def __new__(cls, name, bases, attr):
204*d8b80295SApple OSS Distributions        lldbwrap_update_class_dict(name, bases[0], attr)
205*d8b80295SApple OSS Distributions        return type.__new__(cls, name, bases, attr)
206*d8b80295SApple OSS Distributions
207*d8b80295SApple OSS Distributions
208*d8b80295SApple OSS Distributionsclass SBProcess(lldb.SBProcess, metaclass=LLDBWrapMetaclass):
209*d8b80295SApple OSS Distributions
210*d8b80295SApple OSS Distributions    #
211*d8b80295SApple OSS Distributions    # Manually written checked wrappers
212*d8b80295SApple OSS Distributions    #
213*d8b80295SApple OSS Distributions
214*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBProcess.ReadMemory)
215*d8b80295SApple OSS Distributions    def chkReadMemory(self, addr, size):
216*d8b80295SApple OSS Distributions        err = lldb.SBError()
217*d8b80295SApple OSS Distributions        res = self.ReadMemory(addr, size, err)
218*d8b80295SApple OSS Distributions        if err.Success():
219*d8b80295SApple OSS Distributions            return res
220*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.ReadMemory, err.GetCString(),
221*d8b80295SApple OSS Distributions            self, addr, size)
222*d8b80295SApple OSS Distributions
223*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBProcess.WriteMemory)
224*d8b80295SApple OSS Distributions    def chkWriteMemory(self, addr, buf):
225*d8b80295SApple OSS Distributions        err = lldb.SBError()
226*d8b80295SApple OSS Distributions        res = self.WriteMemory(addr, buf, err)
227*d8b80295SApple OSS Distributions        if err.Success():
228*d8b80295SApple OSS Distributions            return res
229*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.WriteMemory, err.GetCString(),
230*d8b80295SApple OSS Distributions            self, addr, buf)
231*d8b80295SApple OSS Distributions
232*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBProcess.ReadCStringFromMemory)
233*d8b80295SApple OSS Distributions    def chkReadCStringFromMemory(self, addr, max_size):
234*d8b80295SApple OSS Distributions        err = lldb.SBError()
235*d8b80295SApple OSS Distributions        res = self.ReadCStringFromMemory(addr, max_size, err)
236*d8b80295SApple OSS Distributions        if err.Success():
237*d8b80295SApple OSS Distributions            return res
238*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.ReadCStringFromMemory, err.GetCString(),
239*d8b80295SApple OSS Distributions            self, addr, max_size)
240*d8b80295SApple OSS Distributions
241*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBProcess.ReadUnsignedFromMemory)
242*d8b80295SApple OSS Distributions    def chkReadUnsignedFromMemory(self, addr, byte_size):
243*d8b80295SApple OSS Distributions        err = lldb.SBError()
244*d8b80295SApple OSS Distributions        res = self.ReadUnsignedFromMemory(addr, byte_size, err)
245*d8b80295SApple OSS Distributions        if err.Success():
246*d8b80295SApple OSS Distributions            return res
247*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.ReadUnsignedFromMemory, err.GetCString(),
248*d8b80295SApple OSS Distributions            self, addr, byte_size)
249*d8b80295SApple OSS Distributions
250*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBProcess.ReadPointerFromMemory)
251*d8b80295SApple OSS Distributions    def chkReadPointerFromMemory(self, addr):
252*d8b80295SApple OSS Distributions        err = lldb.SBError()
253*d8b80295SApple OSS Distributions        res = self.ReadPointerFromMemory(addr, err)
254*d8b80295SApple OSS Distributions        if err.Success():
255*d8b80295SApple OSS Distributions            return res
256*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.ReadPointerFromMemory, err.GetCString(),
257*d8b80295SApple OSS Distributions            self, addr)
258*d8b80295SApple OSS Distributions
259*d8b80295SApple OSS Distributions
260*d8b80295SApple OSS Distributionsclass SBTarget(lldb.SBTarget, metaclass=LLDBWrapMetaclass):
261*d8b80295SApple OSS Distributions
262*d8b80295SApple OSS Distributions    #
263*d8b80295SApple OSS Distributions    # Manually written checked wrappers
264*d8b80295SApple OSS Distributions    #
265*d8b80295SApple OSS Distributions
266*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBTarget.ReadMemory)
267*d8b80295SApple OSS Distributions    def chkReadMemory(self, addr, buf):
268*d8b80295SApple OSS Distributions        err = lldb.SBError()
269*d8b80295SApple OSS Distributions        res = self.ReadMemory(addr, buf, err)
270*d8b80295SApple OSS Distributions        if err.Success():
271*d8b80295SApple OSS Distributions            return res
272*d8b80295SApple OSS Distributions        lldbwrap_raise(IOError, self.ReadMemory, err.GetCString(),
273*d8b80295SApple OSS Distributions            self, addr, buf)
274*d8b80295SApple OSS Distributions
275*d8b80295SApple OSS Distributions
276*d8b80295SApple OSS Distributions    #
277*d8b80295SApple OSS Distributions    # Extensions
278*d8b80295SApple OSS Distributions    #
279*d8b80295SApple OSS Distributions
280*d8b80295SApple OSS Distributions    def xReadBytes(self, addr, size):
281*d8b80295SApple OSS Distributions        """
282*d8b80295SApple OSS Distributions        Reads memory from the current process's address space and removes any
283*d8b80295SApple OSS Distributions        traps that may have been inserted into the memory.
284*d8b80295SApple OSS Distributions
285*d8b80295SApple OSS Distributions        @param addr (int)
286*d8b80295SApple OSS Distributions            The address to start reading at
287*d8b80295SApple OSS Distributions
288*d8b80295SApple OSS Distributions        @param size (int)
289*d8b80295SApple OSS Distributions            The size of the read to perform
290*d8b80295SApple OSS Distributions
291*d8b80295SApple OSS Distributions        @returns (bytes)
292*d8b80295SApple OSS Distributions        """
293*d8b80295SApple OSS Distributions        return bytes(self.GetProcess().chkReadMemory(addr, size))
294*d8b80295SApple OSS Distributions
295*d8b80295SApple OSS Distributions    def xReadCString(self, addr, max_size):
296*d8b80295SApple OSS Distributions        """
297*d8b80295SApple OSS Distributions        Reads a NULL terminated C string from the current process's address space.
298*d8b80295SApple OSS Distributions        It returns a python string of the exact length, or truncates the string if
299*d8b80295SApple OSS Distributions        the maximum character limit is reached. Example: ::
300*d8b80295SApple OSS Distributions
301*d8b80295SApple OSS Distributions        @param addr (int)
302*d8b80295SApple OSS Distributions            The address to start reading at
303*d8b80295SApple OSS Distributions
304*d8b80295SApple OSS Distributions        @param max_size (int)
305*d8b80295SApple OSS Distributions            The maximum size of the string
306*d8b80295SApple OSS Distributions
307*d8b80295SApple OSS Distributions        @returns (str)
308*d8b80295SApple OSS Distributions        """
309*d8b80295SApple OSS Distributions
310*d8b80295SApple OSS Distributions        return self.GetProcess().chkReadCStringFromMemory(addr, max_size)
311*d8b80295SApple OSS Distributions
312*d8b80295SApple OSS Distributions    def xReadInt8(self, addr):
313*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an int8_t at the specified address """
314*d8b80295SApple OSS Distributions        return int(I8_STRUCT.unpack(self.xReadBytes(addr, 1))[0])
315*d8b80295SApple OSS Distributions
316*d8b80295SApple OSS Distributions    def xReadInt16(self, addr):
317*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an int16_t at the specified address """
318*d8b80295SApple OSS Distributions        return int(I16_STRUCT.unpack(self.xReadBytes(addr, 2))[0])
319*d8b80295SApple OSS Distributions
320*d8b80295SApple OSS Distributions    def xReadInt32(self, addr):
321*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an int32_t at the specified address """
322*d8b80295SApple OSS Distributions        return int(I32_STRUCT.unpack(self.xReadBytes(addr, 4))[0])
323*d8b80295SApple OSS Distributions
324*d8b80295SApple OSS Distributions    def xReadInt64(self, addr):
325*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an int64_t at the specified address """
326*d8b80295SApple OSS Distributions        return int(I64_STRUCT.unpack(self.xReadBytes(addr, 8))[0])
327*d8b80295SApple OSS Distributions
328*d8b80295SApple OSS Distributions    def xReadUInt8(self, addr):
329*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an uint8_t at the specified address """
330*d8b80295SApple OSS Distributions        return int(U8_STRUCT.unpack(self.xReadBytes(addr, 1))[0])
331*d8b80295SApple OSS Distributions
332*d8b80295SApple OSS Distributions    def xReadUInt16(self, addr):
333*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an uint16_t at the specified address """
334*d8b80295SApple OSS Distributions        return int(U16_STRUCT.unpack(self.xReadBytes(addr, 2))[0])
335*d8b80295SApple OSS Distributions
336*d8b80295SApple OSS Distributions    def xReadUInt32(self, addr):
337*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an uint32_t at the specified address """
338*d8b80295SApple OSS Distributions        return int(U32_STRUCT.unpack(self.xReadBytes(addr, 4))[0])
339*d8b80295SApple OSS Distributions
340*d8b80295SApple OSS Distributions    def xReadUInt64(self, addr):
341*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read an uint64_t at the specified address """
342*d8b80295SApple OSS Distributions        return int(U64_STRUCT.unpack(self.xReadBytes(addr, 8))[0])
343*d8b80295SApple OSS Distributions
344*d8b80295SApple OSS Distributions    def xReadLong(self, addr):
345*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read a long at the specified address """
346*d8b80295SApple OSS Distributions        if self.GetProcess().GetAddressByteSize() == 8:
347*d8b80295SApple OSS Distributions            return int(I64_STRUCT.unpack(self.xReadBytes(addr, 8))[0])
348*d8b80295SApple OSS Distributions        return int(I32_STRUCT.unpack(self.xReadBytes(addr, 4))[0])
349*d8b80295SApple OSS Distributions
350*d8b80295SApple OSS Distributions    def xReadULong(self, addr):
351*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read a long at the specified address """
352*d8b80295SApple OSS Distributions        if self.GetProcess().GetAddressByteSize() == 8:
353*d8b80295SApple OSS Distributions            return int(U64_STRUCT.unpack(self.xReadBytes(addr, 8))[0])
354*d8b80295SApple OSS Distributions        return int(U32_STRUCT.unpack(self.xReadBytes(addr, 4))[0])
355*d8b80295SApple OSS Distributions
356*d8b80295SApple OSS Distributions    def xReadFloat(self, addr):
357*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read a float at the specified address """
358*d8b80295SApple OSS Distributions        return FLT_STRUCT.unpack(self.xReadBytes(addr, 4))[0]
359*d8b80295SApple OSS Distributions
360*d8b80295SApple OSS Distributions    def xReadDouble(self, addr):
361*d8b80295SApple OSS Distributions        """ Conveniency wrapper to read a double at the specified address """
362*d8b80295SApple OSS Distributions        return DBL_STRUCT.unpack(self.xReadBytes(addr, 8))[0]
363*d8b80295SApple OSS Distributions
364*d8b80295SApple OSS Distributions
365*d8b80295SApple OSS Distributions    def xIterAsStruct(self, spec, addr, count):
366*d8b80295SApple OSS Distributions        """
367*d8b80295SApple OSS Distributions        Iterate the memory as defined by the specified struct spec
368*d8b80295SApple OSS Distributions
369*d8b80295SApple OSS Distributions        @param spec (struct.Struct)
370*d8b80295SApple OSS Distributions            A struct unpack spec
371*d8b80295SApple OSS Distributions
372*d8b80295SApple OSS Distributions        @param addr (int)
373*d8b80295SApple OSS Distributions            The address to start ieterating from
374*d8b80295SApple OSS Distributions
375*d8b80295SApple OSS Distributions        @param count (int)
376*d8b80295SApple OSS Distributions            The number of structs to read
377*d8b80295SApple OSS Distributions        """
378*d8b80295SApple OSS Distributions
379*d8b80295SApple OSS Distributions        if not count:
380*d8b80295SApple OSS Distributions            return ()
381*d8b80295SApple OSS Distributions
382*d8b80295SApple OSS Distributions        size = spec.size
383*d8b80295SApple OSS Distributions        data = self.xReadBytes(addr, count * size)
384*d8b80295SApple OSS Distributions        if hasattr(spec, 'iter_unpack'):
385*d8b80295SApple OSS Distributions            return spec.iter_unpack(data)
386*d8b80295SApple OSS Distributions
387*d8b80295SApple OSS Distributions        # Python 2
388*d8b80295SApple OSS Distributions        return (
389*d8b80295SApple OSS Distributions            spec.unpack(data[i : i + size])
390*d8b80295SApple OSS Distributions            for i in range(0, count * size, size)
391*d8b80295SApple OSS Distributions        )
392*d8b80295SApple OSS Distributions
393*d8b80295SApple OSS Distributions
394*d8b80295SApple OSS Distributions    def xIterAsScalar(self, spec, addr, count):
395*d8b80295SApple OSS Distributions        """
396*d8b80295SApple OSS Distributions        Iterate the memory as defined by the specified scalar spec
397*d8b80295SApple OSS Distributions
398*d8b80295SApple OSS Distributions        Unlike xIterAsStruct() this will return the first element
399*d8b80295SApple OSS Distributions        of the struct.Strict.iter_unpack() tuple.
400*d8b80295SApple OSS Distributions
401*d8b80295SApple OSS Distributions        @param spec (struct.Struct)
402*d8b80295SApple OSS Distributions            A struct unpack spec
403*d8b80295SApple OSS Distributions
404*d8b80295SApple OSS Distributions        @param addr (int)
405*d8b80295SApple OSS Distributions            The address to start ieterating from
406*d8b80295SApple OSS Distributions
407*d8b80295SApple OSS Distributions        @param count (int)
408*d8b80295SApple OSS Distributions            The number of scalars to read
409*d8b80295SApple OSS Distributions        """
410*d8b80295SApple OSS Distributions
411*d8b80295SApple OSS Distributions        if not count:
412*d8b80295SApple OSS Distributions            return ()
413*d8b80295SApple OSS Distributions
414*d8b80295SApple OSS Distributions        size = spec.size
415*d8b80295SApple OSS Distributions        data = self.xReadBytes(addr, count * size)
416*d8b80295SApple OSS Distributions        if hasattr(spec, 'iter_unpack'):
417*d8b80295SApple OSS Distributions            return (e[0] for e in spec.iter_unpack(data))
418*d8b80295SApple OSS Distributions
419*d8b80295SApple OSS Distributions        # Python 2
420*d8b80295SApple OSS Distributions        return (
421*d8b80295SApple OSS Distributions            int(spec.unpack(data[i : i + size])[0])
422*d8b80295SApple OSS Distributions            for i in range(0, count * size, size)
423*d8b80295SApple OSS Distributions        )
424*d8b80295SApple OSS Distributions
425*d8b80295SApple OSS Distributions    def xIterAsInt8(self, addr, count):
426*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on int8_t """
427*d8b80295SApple OSS Distributions        return self.xIterAsScalar(I8_STRUCT, addr, count)
428*d8b80295SApple OSS Distributions
429*d8b80295SApple OSS Distributions    def xIterAsInt16(self, addr, count):
430*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on int16_t """
431*d8b80295SApple OSS Distributions        return self.xIterAsScalar(I16_STRUCT, addr, count)
432*d8b80295SApple OSS Distributions
433*d8b80295SApple OSS Distributions    def xIterAsInt32(self, addr, count):
434*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on int32_t """
435*d8b80295SApple OSS Distributions        return self.xIterAsScalar(I32_STRUCT, addr, count)
436*d8b80295SApple OSS Distributions
437*d8b80295SApple OSS Distributions    def xIterAsInt64(self, addr, count):
438*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on int64_t """
439*d8b80295SApple OSS Distributions        return self.xIterAsScalar(I64_STRUCT, addr, count)
440*d8b80295SApple OSS Distributions
441*d8b80295SApple OSS Distributions    def xIterAsUInt8(self, addr, count):
442*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on uint8_t """
443*d8b80295SApple OSS Distributions        return self.xIterAsScalar(U8_STRUCT, addr, count)
444*d8b80295SApple OSS Distributions
445*d8b80295SApple OSS Distributions    def xIterAsUInt16(self, addr, count):
446*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on uint16_t """
447*d8b80295SApple OSS Distributions        return self.xIterAsScalar(U16_STRUCT, addr, count)
448*d8b80295SApple OSS Distributions
449*d8b80295SApple OSS Distributions    def xIterAsUInt32(self, addr, count):
450*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on uint32_t """
451*d8b80295SApple OSS Distributions        return self.xIterAsScalar(U32_STRUCT, addr, count)
452*d8b80295SApple OSS Distributions
453*d8b80295SApple OSS Distributions    def xIterAsUInt64(self, addr, count):
454*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on uint64_t """
455*d8b80295SApple OSS Distributions        return self.xIterAsScalar(U64_STRUCT, addr, count)
456*d8b80295SApple OSS Distributions
457*d8b80295SApple OSS Distributions    def xIterAsLong(self, addr, count):
458*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on long """
459*d8b80295SApple OSS Distributions        if self.GetProcess().GetAddressByteSize() == 8:
460*d8b80295SApple OSS Distributions            return self.xIterAsScalar(I64_STRUCT, addr, count)
461*d8b80295SApple OSS Distributions        return self.xIterAsScalar(I32_STRUCT, addr, count)
462*d8b80295SApple OSS Distributions
463*d8b80295SApple OSS Distributions    def xIterAsULong(self, addr, count):
464*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on unsigned long """
465*d8b80295SApple OSS Distributions        if self.GetProcess().GetAddressByteSize() == 8:
466*d8b80295SApple OSS Distributions            return self.xIterAsScalar(U64_STRUCT, addr, count)
467*d8b80295SApple OSS Distributions        return self.xIterAsScalar(U32_STRUCT, addr, count)
468*d8b80295SApple OSS Distributions
469*d8b80295SApple OSS Distributions    def xIterAsFloat(self, addr, count):
470*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on float """
471*d8b80295SApple OSS Distributions        return self.xIterAsScalar(FLT_STRUCT, addr, count)
472*d8b80295SApple OSS Distributions
473*d8b80295SApple OSS Distributions    def xIterAsDouble(self, addr, count):
474*d8b80295SApple OSS Distributions        """ Conveniency wrapper to xIterAsScalar() on double """
475*d8b80295SApple OSS Distributions        return self.xIterAsScalar(DBL_STRUCT, addr, count)
476*d8b80295SApple OSS Distributions
477*d8b80295SApple OSS Distributions
478*d8b80295SApple OSS Distributions    def xCreateValueFromAddress(self, name, addr, ty):
479*d8b80295SApple OSS Distributions        """
480*d8b80295SApple OSS Distributions        Create an SBValue with the given name by treating the memory starting
481*d8b80295SApple OSS Distributions        at addr as an entity of type.
482*d8b80295SApple OSS Distributions
483*d8b80295SApple OSS Distributions        More tolerant wrapper around CreateValueFromAddress() that accepts
484*d8b80295SApple OSS Distributions        for @c name to be None and @c addr to be an int.
485*d8b80295SApple OSS Distributions
486*d8b80295SApple OSS Distributions        @param name (str or None)
487*d8b80295SApple OSS Distributions            The name of the resultant SBValue
488*d8b80295SApple OSS Distributions
489*d8b80295SApple OSS Distributions        @param addr (int or lldb.SBAddress)
490*d8b80295SApple OSS Distributions            The address of the start of the memory region to be used.
491*d8b80295SApple OSS Distributions
492*d8b80295SApple OSS Distributions        @param ty (lldb.SBType)
493*d8b80295SApple OSS Distributions            The type to use to interpret the memory starting at addr.
494*d8b80295SApple OSS Distributions
495*d8b80295SApple OSS Distributions        @return (lldb.SBValue)
496*d8b80295SApple OSS Distributions            An SBValue of the given type.
497*d8b80295SApple OSS Distributions
498*d8b80295SApple OSS Distributions        @raises ValueError
499*d8b80295SApple OSS Distributions            For various error conditions.
500*d8b80295SApple OSS Distributions        """
501*d8b80295SApple OSS Distributions
502*d8b80295SApple OSS Distributions        if not isinstance(addr, lldb.SBAddress):
503*d8b80295SApple OSS Distributions            addr = self.rawResolveLoadAddress(addr)
504*d8b80295SApple OSS Distributions
505*d8b80295SApple OSS Distributions        if name is None:
506*d8b80295SApple OSS Distributions            # unlike SBValue's variant, SBTargets's will fail to produce
507*d8b80295SApple OSS Distributions            # a value if the name is None, don't ask.
508*d8b80295SApple OSS Distributions            name = 'newvalue'
509*d8b80295SApple OSS Distributions
510*d8b80295SApple OSS Distributions        v = self.rawCreateValueFromAddress(name, addr, ty)
511*d8b80295SApple OSS Distributions        if v.IsValid():
512*d8b80295SApple OSS Distributions            if QUIRK_100103405 and not addr:
513*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
514*d8b80295SApple OSS Distributions            v.__class__ = SBValue
515*d8b80295SApple OSS Distributions            return v
516*d8b80295SApple OSS Distributions
517*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.CreateValueFromAddress, None, name)
518*d8b80295SApple OSS Distributions
519*d8b80295SApple OSS Distributions
520*d8b80295SApple OSS Distributionsclass SBType(lldb.SBType, metaclass=LLDBWrapMetaclass):
521*d8b80295SApple OSS Distributions
522*d8b80295SApple OSS Distributions    #
523*d8b80295SApple OSS Distributions    # Extensions
524*d8b80295SApple OSS Distributions    #
525*d8b80295SApple OSS Distributions
526*d8b80295SApple OSS Distributions    def _findFieldOffsetByName(self, name):
527*d8b80295SApple OSS Distributions        """ internal helper """
528*d8b80295SApple OSS Distributions
529*d8b80295SApple OSS Distributions        for idx in range(self.GetNumberOfFields()):
530*d8b80295SApple OSS Distributions            field = self.GetFieldAtIndex(idx)
531*d8b80295SApple OSS Distributions            fname = field.GetName()
532*d8b80295SApple OSS Distributions
533*d8b80295SApple OSS Distributions            if fname == name:
534*d8b80295SApple OSS Distributions                return field.GetOffsetInBytes(), field.GetType()
535*d8b80295SApple OSS Distributions
536*d8b80295SApple OSS Distributions            if fname is None:
537*d8b80295SApple OSS Distributions                offs, ty = field.GetType()._findFieldOffsetByName(name)
538*d8b80295SApple OSS Distributions                if offs is not None:
539*d8b80295SApple OSS Distributions                    return offs + field.GetOffsetInBytes(), ty
540*d8b80295SApple OSS Distributions
541*d8b80295SApple OSS Distributions        return None, None
542*d8b80295SApple OSS Distributions
543*d8b80295SApple OSS Distributions    def _findFieldOffsetByPath(self, path):
544*d8b80295SApple OSS Distributions        """ internal helper """
545*d8b80295SApple OSS Distributions
546*d8b80295SApple OSS Distributions        offs = 0
547*d8b80295SApple OSS Distributions        ty   = self
548*d8b80295SApple OSS Distributions
549*d8b80295SApple OSS Distributions        key = path[1:] if path[0] == '.' else path
550*d8b80295SApple OSS Distributions
551*d8b80295SApple OSS Distributions        while key != '':
552*d8b80295SApple OSS Distributions            name, _, key = key.partition('.')
553*d8b80295SApple OSS Distributions            index = None
554*d8b80295SApple OSS Distributions
555*d8b80295SApple OSS Distributions            if name[-1] == ']':
556*d8b80295SApple OSS Distributions                name, _, index = name[:-1].partition('[')
557*d8b80295SApple OSS Distributions                if not index.isdigit():
558*d8b80295SApple OSS Distributions                    raise KeyError("Invalid path '{}'".format(path))
559*d8b80295SApple OSS Distributions                index = int(index)
560*d8b80295SApple OSS Distributions
561*d8b80295SApple OSS Distributions            f_offs, ty = ty._findFieldOffsetByName(name)
562*d8b80295SApple OSS Distributions            if f_offs is None:
563*d8b80295SApple OSS Distributions                return None, None, None
564*d8b80295SApple OSS Distributions
565*d8b80295SApple OSS Distributions            offs += f_offs
566*d8b80295SApple OSS Distributions            if index is not None:
567*d8b80295SApple OSS Distributions                if ty.GetTypeFlags() & lldb.eTypeIsArray:
568*d8b80295SApple OSS Distributions                    ty = ty.GetArrayElementType()
569*d8b80295SApple OSS Distributions                else:
570*d8b80295SApple OSS Distributions                    ty = ty.GetPointeeType()
571*d8b80295SApple OSS Distributions                offs += ty.GetByteSize() * index
572*d8b80295SApple OSS Distributions
573*d8b80295SApple OSS Distributions        return offs, ty, name
574*d8b80295SApple OSS Distributions
575*d8b80295SApple OSS Distributions    def xGetFieldOffset(self, path_or_name):
576*d8b80295SApple OSS Distributions        """
577*d8b80295SApple OSS Distributions        Returns offsetof(type, path_or_name) in bytes.
578*d8b80295SApple OSS Distributions
579*d8b80295SApple OSS Distributions        @param path_or_name (str)
580*d8b80295SApple OSS Distributions            The field path or name to compute the offset of
581*d8b80295SApple OSS Distributions
582*d8b80295SApple OSS Distributions        @return (int or None)
583*d8b80295SApple OSS Distributions            The requested offset of the field within the type,
584*d8b80295SApple OSS Distributions            or None if the field wasn't found
585*d8b80295SApple OSS Distributions        """
586*d8b80295SApple OSS Distributions        return self._findFieldOffsetByPath(path_or_name)[0]
587*d8b80295SApple OSS Distributions
588*d8b80295SApple OSS Distributions    def xContainerOfTransform(self, path):
589*d8b80295SApple OSS Distributions        """
590*d8b80295SApple OSS Distributions        Returns a function that can be used to apply a "__container_of"
591*d8b80295SApple OSS Distributions        transformation repeatedly (by field path).
592*d8b80295SApple OSS Distributions
593*d8b80295SApple OSS Distributions        @param path_or_name (str)
594*d8b80295SApple OSS Distributions            The field path or name to compute the offset of
595*d8b80295SApple OSS Distributions
596*d8b80295SApple OSS Distributions        @returns (function)
597*d8b80295SApple OSS Distributions            A function that returns the value resulting of
598*d8b80295SApple OSS Distributions            __container_of(value, type_t, path) for this type.
599*d8b80295SApple OSS Distributions        """
600*d8b80295SApple OSS Distributions
601*d8b80295SApple OSS Distributions        offs = self.xGetFieldOffset(path)
602*d8b80295SApple OSS Distributions
603*d8b80295SApple OSS Distributions        return lambda x: x.xCreateValueFromAddress(None, x.GetLoadAddress() - offs, self)
604*d8b80295SApple OSS Distributions
605*d8b80295SApple OSS Distributions    def xContainerOf(self, path_or_name, value):
606*d8b80295SApple OSS Distributions        """ same as self.xContainerOfTransform(path_or_name)(value) """
607*d8b80295SApple OSS Distributions
608*d8b80295SApple OSS Distributions        return self.xContainerOfTransform(path_or_name)(value)
609*d8b80295SApple OSS Distributions
610*d8b80295SApple OSS Distributions
611*d8b80295SApple OSS Distributionsclass SBValue(lldb.SBValue, metaclass=LLDBWrapMetaclass):
612*d8b80295SApple OSS Distributions
613*d8b80295SApple OSS Distributions    if QUIRK_100103405:
614*d8b80295SApple OSS Distributions        @classmethod
615*d8b80295SApple OSS Distributions        def xUpcast(cls, value):
616*d8b80295SApple OSS Distributions            #
617*d8b80295SApple OSS Distributions            # LLDB insists on trying to translate "NULL" for `void *`
618*d8b80295SApple OSS Distributions            # when dynamic values are enabled. It never caches the
619*d8b80295SApple OSS Distributions            # negative result which can yield really slow performance.
620*d8b80295SApple OSS Distributions            #
621*d8b80295SApple OSS Distributions            # Work it around by disabling dynamic values, looking at whether
622*d8b80295SApple OSS Distributions            # it's vaguely looking like a pointer and its value is a NULL
623*d8b80295SApple OSS Distributions            # pointer, and if not, turn dynamic values back on
624*d8b80295SApple OSS Distributions            #
625*d8b80295SApple OSS Distributions            # This check is extremely expensive and makes shorcuts,
626*d8b80295SApple OSS Distributions            # such as testing against "8" (sizeof(void *) on LP64)
627*d8b80295SApple OSS Distributions            # in order to delay realizing the type as much as possible
628*d8b80295SApple OSS Distributions            #
629*d8b80295SApple OSS Distributions            dyn = value.GetPreferDynamicValue()
630*d8b80295SApple OSS Distributions            if dyn:
631*d8b80295SApple OSS Distributions                value.SetPreferDynamicValue(0)
632*d8b80295SApple OSS Distributions                if (value.GetByteSize() != 8 or
633*d8b80295SApple OSS Distributions                        value.GetValueAsUnsigned() or
634*d8b80295SApple OSS Distributions                        not value.TypeIsPointerType()):
635*d8b80295SApple OSS Distributions                    value.SetPreferDynamicValue(dyn)
636*d8b80295SApple OSS Distributions
637*d8b80295SApple OSS Distributions            value.__class__ = cls
638*d8b80295SApple OSS Distributions
639*d8b80295SApple OSS Distributions    #
640*d8b80295SApple OSS Distributions    # Manually written checked wrappers
641*d8b80295SApple OSS Distributions    #
642*d8b80295SApple OSS Distributions
643*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBValue.GetValueAsSigned)
644*d8b80295SApple OSS Distributions    def chkGetValueAsSigned(self):
645*d8b80295SApple OSS Distributions        err = lldb.SBError()
646*d8b80295SApple OSS Distributions        res = self.GetValueAsSigned(err)
647*d8b80295SApple OSS Distributions        if res or err.Success():
648*d8b80295SApple OSS Distributions            return res
649*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.chkGetValueAsSigned, err.GetCString(),
650*d8b80295SApple OSS Distributions            self)
651*d8b80295SApple OSS Distributions
652*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBValue.GetValueAsUnsigned)
653*d8b80295SApple OSS Distributions    def chkGetValueAsUnsigned(self):
654*d8b80295SApple OSS Distributions        err = lldb.SBError()
655*d8b80295SApple OSS Distributions        res = self.GetValueAsUnsigned(err)
656*d8b80295SApple OSS Distributions        if res or err.Success():
657*d8b80295SApple OSS Distributions            return res
658*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.chkGetValueAsUnsigned, err.GetCString(),
659*d8b80295SApple OSS Distributions            self)
660*d8b80295SApple OSS Distributions
661*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBValue.SetValueFromCString)
662*d8b80295SApple OSS Distributions    def chkSetValueFromCString(self, value_str):
663*d8b80295SApple OSS Distributions        err = lldb.SBError()
664*d8b80295SApple OSS Distributions        if not self.SetValueFromCString(value_str, err):
665*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, self.chkSetValueFromCString, err.GetCString(),
666*d8b80295SApple OSS Distributions                self, value_str)
667*d8b80295SApple OSS Distributions
668*d8b80295SApple OSS Distributions    @functools.wraps(lldb.SBValue.SetData)
669*d8b80295SApple OSS Distributions    def chkSetData(self, data):
670*d8b80295SApple OSS Distributions        err = lldb.SBError()
671*d8b80295SApple OSS Distributions        if not self.SetData(data, err):
672*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, self.chkSetData, err.GetCString(),
673*d8b80295SApple OSS Distributions                self, data)
674*d8b80295SApple OSS Distributions
675*d8b80295SApple OSS Distributions    if QUIRK_99806493:
676*d8b80295SApple OSS Distributions        def Cast(self, ty):
677*d8b80295SApple OSS Distributions            v = super(SBValue, self).Cast(ty)
678*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
679*d8b80295SApple OSS Distributions
680*d8b80295SApple OSS Distributions            if not v.IsValid() or not v.TypeIsPointerType():
681*d8b80295SApple OSS Distributions                return v
682*d8b80295SApple OSS Distributions
683*d8b80295SApple OSS Distributions            #
684*d8b80295SApple OSS Distributions            # NULL is fine, needs no PAC stripping,
685*d8b80295SApple OSS Distributions            # and it makes CreateValueFromAddress behave funny.
686*d8b80295SApple OSS Distributions            #
687*d8b80295SApple OSS Distributions            addr = v.GetValueAsAddress()
688*d8b80295SApple OSS Distributions            if addr == 0:
689*d8b80295SApple OSS Distributions                return v
690*d8b80295SApple OSS Distributions
691*d8b80295SApple OSS Distributions            #
692*d8b80295SApple OSS Distributions            # Casting from a pointer type to another
693*d8b80295SApple OSS Distributions            # is not stripping __ptrauth, let's fix it
694*d8b80295SApple OSS Distributions            #
695*d8b80295SApple OSS Distributions            nv = v.rawCreateValueFromAddress(v.GetName(), addr, ty)
696*d8b80295SApple OSS Distributions            nv.SetPreferDynamicValue(v.GetPreferDynamicValue())
697*d8b80295SApple OSS Distributions            v = nv.AddressOf().Cast(ty)
698*d8b80295SApple OSS Distributions
699*d8b80295SApple OSS Distributions            if QUIRK_100162262:
700*d8b80295SApple OSS Distributions                nv = v.Persist()
701*d8b80295SApple OSS Distributions                nv.SetPreferDynamicValue(v.GetPreferDynamicValue())
702*d8b80295SApple OSS Distributions                v = nv
703*d8b80295SApple OSS Distributions
704*d8b80295SApple OSS Distributions            # no need for QUIRK_100103405, can't be NULL
705*d8b80295SApple OSS Distributions            v.__class__ = SBValue
706*d8b80295SApple OSS Distributions            return v
707*d8b80295SApple OSS Distributions
708*d8b80295SApple OSS Distributions        def chkCast(self, ty):
709*d8b80295SApple OSS Distributions            v = self.Cast(ty)
710*d8b80295SApple OSS Distributions            if v.IsValid():
711*d8b80295SApple OSS Distributions                return v
712*d8b80295SApple OSS Distributions
713*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, SBValue.Cast, None, self, ty)
714*d8b80295SApple OSS Distributions
715*d8b80295SApple OSS Distributions    if QUIRK_100162262:
716*d8b80295SApple OSS Distributions        def AddressOf(self):
717*d8b80295SApple OSS Distributions            v = super(SBValue, self).AddressOf().Persist()
718*d8b80295SApple OSS Distributions            # no need for QUIRK_100103405
719*d8b80295SApple OSS Distributions            v.__class__ = SBValue
720*d8b80295SApple OSS Distributions            return v
721*d8b80295SApple OSS Distributions
722*d8b80295SApple OSS Distributions        def chkAddressOf(self):
723*d8b80295SApple OSS Distributions            v = self.AddressOf()
724*d8b80295SApple OSS Distributions            if v.IsValid():
725*d8b80295SApple OSS Distributions                return v
726*d8b80295SApple OSS Distributions
727*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, SBValue.AddressOf, None, self)
728*d8b80295SApple OSS Distributions
729*d8b80295SApple OSS Distributions    if QUIRK_104494282:
730*d8b80295SApple OSS Distributions        def Dereference(self):
731*d8b80295SApple OSS Distributions            addr = self.GetValueAsAddress()
732*d8b80295SApple OSS Distributions            if addr == self.GetValueAsUnsigned():
733*d8b80295SApple OSS Distributions                v = super(SBValue, self).Dereference()
734*d8b80295SApple OSS Distributions                SBValue.xUpcast(v)
735*d8b80295SApple OSS Distributions                return v
736*d8b80295SApple OSS Distributions
737*d8b80295SApple OSS Distributions            return self.xCreateValueFromAddress(self.GetName(),
738*d8b80295SApple OSS Distributions                addr, self.GetType().GetPointeeType())
739*d8b80295SApple OSS Distributions
740*d8b80295SApple OSS Distributions    if QUIRK_102642763:
741*d8b80295SApple OSS Distributions        def GetChildMemberWithName(self, name):
742*d8b80295SApple OSS Distributions            v = super(SBValue, self).GetChildMemberWithName(name)
743*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
744*d8b80295SApple OSS Distributions            if v.IsValid():
745*d8b80295SApple OSS Distributions                return v
746*d8b80295SApple OSS Distributions
747*d8b80295SApple OSS Distributions            # Emulate compiler logic and visit all nested anon struct/unions.
748*d8b80295SApple OSS Distributions            if self.GetType().IsPointerType():
749*d8b80295SApple OSS Distributions                return self.xDereference().GetChildMemberWithName(name)
750*d8b80295SApple OSS Distributions
751*d8b80295SApple OSS Distributions            offs, mty = self.GetType()._findFieldOffsetByName(name)
752*d8b80295SApple OSS Distributions            if offs is None:
753*d8b80295SApple OSS Distributions                # LLDB returns instance of SBValue that is set as invalid.
754*d8b80295SApple OSS Distributions                # Re-use the invalid one from initial lookup.
755*d8b80295SApple OSS Distributions                return v
756*d8b80295SApple OSS Distributions
757*d8b80295SApple OSS Distributions            return self.xCreateValueFromAddress(name, self.GetLoadAddress() + offs, mty)
758*d8b80295SApple OSS Distributions
759*d8b80295SApple OSS Distributions        def GetValueForExpressionPath(self, path):
760*d8b80295SApple OSS Distributions            v = super(SBValue, self).GetValueForExpressionPath(path)
761*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
762*d8b80295SApple OSS Distributions            if v.IsValid():
763*d8b80295SApple OSS Distributions                return v
764*d8b80295SApple OSS Distributions
765*d8b80295SApple OSS Distributions            # Emulate compiler logic and visit all nested anon struct/unions.
766*d8b80295SApple OSS Distributions            if self.GetType().IsPointerType():
767*d8b80295SApple OSS Distributions                return self.xDereference().GetValueForExpressionPath(path)
768*d8b80295SApple OSS Distributions
769*d8b80295SApple OSS Distributions            # Emulate compiler logic and visit all nested anon struct/unions.
770*d8b80295SApple OSS Distributions            offs, mty, name = self.GetType()._findFieldOffsetByPath(path)
771*d8b80295SApple OSS Distributions            if offs is None:
772*d8b80295SApple OSS Distributions                # LLDB returns instance of SBValue that is set as invalid.
773*d8b80295SApple OSS Distributions                # Re-use the invalid one from initial lookup.
774*d8b80295SApple OSS Distributions                return v
775*d8b80295SApple OSS Distributions
776*d8b80295SApple OSS Distributions            return self.xCreateValueFromAddress(name, self.GetLoadAddress() + offs, mty)
777*d8b80295SApple OSS Distributions
778*d8b80295SApple OSS Distributions    #
779*d8b80295SApple OSS Distributions    # Extensions
780*d8b80295SApple OSS Distributions    #
781*d8b80295SApple OSS Distributions
782*d8b80295SApple OSS Distributions    def xCreateValueFromAddress(self, name, addr, ty):
783*d8b80295SApple OSS Distributions        """
784*d8b80295SApple OSS Distributions        Create an SBValue with the given name by treating the memory starting
785*d8b80295SApple OSS Distributions        at addr as an entity of type.
786*d8b80295SApple OSS Distributions
787*d8b80295SApple OSS Distributions        More tolerant wrapper around CreateValueFromAddress() that accepts
788*d8b80295SApple OSS Distributions        for @c name to be None and @c addr to be an lldb.SBAddress
789*d8b80295SApple OSS Distributions
790*d8b80295SApple OSS Distributions        @param name (str or None)
791*d8b80295SApple OSS Distributions            The name of the resultant SBValue
792*d8b80295SApple OSS Distributions
793*d8b80295SApple OSS Distributions        @param addr (int or lldb.SBAddress)
794*d8b80295SApple OSS Distributions            The address of the start of the memory region to be used.
795*d8b80295SApple OSS Distributions
796*d8b80295SApple OSS Distributions        @param ty (lldb.SBType)
797*d8b80295SApple OSS Distributions            The type to use to interpret the memory starting at addr.
798*d8b80295SApple OSS Distributions
799*d8b80295SApple OSS Distributions        @return (lldb.SBValue)
800*d8b80295SApple OSS Distributions            An SBValue of the given type.
801*d8b80295SApple OSS Distributions
802*d8b80295SApple OSS Distributions        @raises ValueError
803*d8b80295SApple OSS Distributions            For various error conditions.
804*d8b80295SApple OSS Distributions        """
805*d8b80295SApple OSS Distributions
806*d8b80295SApple OSS Distributions        if isinstance(addr, lldb.SBAddress):
807*d8b80295SApple OSS Distributions            addr = addr.GetLoadAddress()
808*d8b80295SApple OSS Distributions
809*d8b80295SApple OSS Distributions        if name is None:
810*d8b80295SApple OSS Distributions            # SBValue's version of CreateValueFromAddress() accepts None,
811*d8b80295SApple OSS Distributions            # but let's be consistent.
812*d8b80295SApple OSS Distributions            name = 'newvalue'
813*d8b80295SApple OSS Distributions
814*d8b80295SApple OSS Distributions        return self.chkCreateValueFromAddress(name, addr, ty)
815*d8b80295SApple OSS Distributions
816*d8b80295SApple OSS Distributions    def xGetSiblingValueAtIndex(self, index, stride=None):
817*d8b80295SApple OSS Distributions        """
818*d8b80295SApple OSS Distributions        Returns a sibling value to the current one in an array.
819*d8b80295SApple OSS Distributions
820*d8b80295SApple OSS Distributions        This basically performs pointer arithmetics on the SBValue.
821*d8b80295SApple OSS Distributions
822*d8b80295SApple OSS Distributions        @param index (int)
823*d8b80295SApple OSS Distributions            The index of the element to return relative to the current one.
824*d8b80295SApple OSS Distributions
825*d8b80295SApple OSS Distributions        @param stride (int or None):
826*d8b80295SApple OSS Distributions            If specified, use this stride instead of the natural value type size.
827*d8b80295SApple OSS Distributions
828*d8b80295SApple OSS Distributions        @returns (lldb.SBValue)
829*d8b80295SApple OSS Distributions            The resulting value.
830*d8b80295SApple OSS Distributions        """
831*d8b80295SApple OSS Distributions
832*d8b80295SApple OSS Distributions        if index:
833*d8b80295SApple OSS Distributions            addr = self.GetLoadAddress() + index * (stride or self.GetByteSize())
834*d8b80295SApple OSS Distributions            return self.chkCreateValueFromAddress(self.GetName(), addr, self.GetType())
835*d8b80295SApple OSS Distributions        return self
836*d8b80295SApple OSS Distributions
837*d8b80295SApple OSS Distributions    def xIterSiblings(self, start, stop, step=1):
838*d8b80295SApple OSS Distributions        """
839*d8b80295SApple OSS Distributions        Returns an iterator for sibling value to the current one in an array.
840*d8b80295SApple OSS Distributions
841*d8b80295SApple OSS Distributions        This basically performs pointer arithmetics on the SBValue.
842*d8b80295SApple OSS Distributions
843*d8b80295SApple OSS Distributions        @param start (int)
844*d8b80295SApple OSS Distributions            The first index (inclusive) to return
845*d8b80295SApple OSS Distributions
846*d8b80295SApple OSS Distributions        @param stop (int)
847*d8b80295SApple OSS Distributions            The last index (exclusive) to return
848*d8b80295SApple OSS Distributions
849*d8b80295SApple OSS Distributions        @param step (int or None):
850*d8b80295SApple OSS Distributions            The increment step if any
851*d8b80295SApple OSS Distributions
852*d8b80295SApple OSS Distributions        @returns (lldb.SBValue)
853*d8b80295SApple OSS Distributions            The resulting value.
854*d8b80295SApple OSS Distributions        """
855*d8b80295SApple OSS Distributions
856*d8b80295SApple OSS Distributions        size = self.GetByteSize()
857*d8b80295SApple OSS Distributions        ty   = self.GetType()
858*d8b80295SApple OSS Distributions        base = self.GetLoadAddress()
859*d8b80295SApple OSS Distributions
860*d8b80295SApple OSS Distributions        # aggressively cache the data
861*d8b80295SApple OSS Distributions        self.target.xReadBytes(base + start * size, (stop - start) * size)
862*d8b80295SApple OSS Distributions
863*d8b80295SApple OSS Distributions        return (
864*d8b80295SApple OSS Distributions            self.chkCreateValueFromAddress(None, base + i * size, ty)
865*d8b80295SApple OSS Distributions            for i in range(start, stop, step)
866*d8b80295SApple OSS Distributions        )
867*d8b80295SApple OSS Distributions
868*d8b80295SApple OSS Distributions    def xDereference(self):
869*d8b80295SApple OSS Distributions        """
870*d8b80295SApple OSS Distributions        Version of Dereference() that does the right thing for flexible arrays,
871*d8b80295SApple OSS Distributions        and returns None if NULL is being dereferenced.
872*d8b80295SApple OSS Distributions
873*d8b80295SApple OSS Distributions        @returns (lldb.SBValue):
874*d8b80295SApple OSS Distributions            - a reference to value[0] if value is a valid pointer/array
875*d8b80295SApple OSS Distributions            - None otherwise
876*d8b80295SApple OSS Distributions        """
877*d8b80295SApple OSS Distributions
878*d8b80295SApple OSS Distributions        rawty = self.rawGetType()
879*d8b80295SApple OSS Distributions        fl    = rawty.GetTypeFlags()
880*d8b80295SApple OSS Distributions
881*d8b80295SApple OSS Distributions        if fl & lldb.eTypeIsArray:
882*d8b80295SApple OSS Distributions            return self.xCreateValueFromAddress(self.GetName(),
883*d8b80295SApple OSS Distributions                self.GetLoadAddress(), rawty.GetArrayElementType())
884*d8b80295SApple OSS Distributions
885*d8b80295SApple OSS Distributions        if fl & lldb.eTypeIsPointer:
886*d8b80295SApple OSS Distributions            return self.chkDereference() if self.GetValueAsAddress() else None
887*d8b80295SApple OSS Distributions
888*d8b80295SApple OSS Distributions        lldbwrap_raise(TypeError, self.xDereference, "Type can't be dereferenced")
889*d8b80295SApple OSS Distributions
890*d8b80295SApple OSS Distributions
891*d8b80295SApple OSS Distributions    def xGetValueAsScalar(self, needed=0, rejected=0):
892*d8b80295SApple OSS Distributions        """
893*d8b80295SApple OSS Distributions        Get the scalar value of an SBValue
894*d8b80295SApple OSS Distributions
895*d8b80295SApple OSS Distributions        @param needed (lldb.eTypeIs* mask)
896*d8b80295SApple OSS Distributions            Sets of flags that should be set or the conversion should fail.
897*d8b80295SApple OSS Distributions
898*d8b80295SApple OSS Distributions        @param rejected (lldb.eTypeIs* mask)
899*d8b80295SApple OSS Distributions            Sets of flags that should fail the conversion if set on the value.
900*d8b80295SApple OSS Distributions        """
901*d8b80295SApple OSS Distributions
902*d8b80295SApple OSS Distributions        flags = self.rawGetType().GetTypeFlags()
903*d8b80295SApple OSS Distributions
904*d8b80295SApple OSS Distributions        if (flags & needed) != needed:
905*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, self.xGetValueAsScalar,
906*d8b80295SApple OSS Distributions                "value of type {} has missing flags {:#x}".format(
907*d8b80295SApple OSS Distributions                self.GetType().GetDisplayTypeName(), (flags & needed) ^ needed),
908*d8b80295SApple OSS Distributions                self, needed=needed, rejected=rejected)
909*d8b80295SApple OSS Distributions
910*d8b80295SApple OSS Distributions        if flags & rejected:
911*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, self.xGetValueAsScalar,
912*d8b80295SApple OSS Distributions                "value of type {} has rejected flags {:#x}".format(
913*d8b80295SApple OSS Distributions                self.GetType().GetDisplayTypeName(), flags & rejected),
914*d8b80295SApple OSS Distributions                self, needed=needed, rejected=rejected)
915*d8b80295SApple OSS Distributions
916*d8b80295SApple OSS Distributions        if flags & lldb.eTypeIsPointer:
917*d8b80295SApple OSS Distributions            return self.GetValueAsAddress()
918*d8b80295SApple OSS Distributions
919*d8b80295SApple OSS Distributions        err = lldb.SBError()
920*d8b80295SApple OSS Distributions        if flags & lldb.eTypeIsSigned:
921*d8b80295SApple OSS Distributions            res = self.GetValueAsSigned(err)
922*d8b80295SApple OSS Distributions        else:
923*d8b80295SApple OSS Distributions            res = self.GetValueAsUnsigned(err)
924*d8b80295SApple OSS Distributions            if QUIRK_99785324 and res and flags & lldb.eTypeIsEnumeration:
925*d8b80295SApple OSS Distributions                try:
926*d8b80295SApple OSS Distributions                    if (res >> (self.GetByteSize() * 8 - 1) and
927*d8b80295SApple OSS Distributions                            not self.rawAddressOf().IsValid()):
928*d8b80295SApple OSS Distributions                        #
929*d8b80295SApple OSS Distributions                        # This field is:
930*d8b80295SApple OSS Distributions                        # - likely a bitfield (we can't take its AddressOf())
931*d8b80295SApple OSS Distributions                        # - unsigned
932*d8b80295SApple OSS Distributions                        # - with its top bit set
933*d8b80295SApple OSS Distributions                        #
934*d8b80295SApple OSS Distributions                        # This might be hitting rdar://99785324 where lldb
935*d8b80295SApple OSS Distributions                        # incorrectly sign-extends unsigned bit-fields.
936*d8b80295SApple OSS Distributions                        #
937*d8b80295SApple OSS Distributions                        # Here comes a crime against good taste: the expression
938*d8b80295SApple OSS Distributions                        # evaluator of lldb _knows_ how to do the right thing,
939*d8b80295SApple OSS Distributions                        # and now that the only thing we have is this lousy
940*d8b80295SApple OSS Distributions                        # lldb.SBValue(), we can only get to it via __str__().
941*d8b80295SApple OSS Distributions                        #
942*d8b80295SApple OSS Distributions                        # We parse something like this here:
943*d8b80295SApple OSS Distributions                        #   '(type_t:12) path = 42'
944*d8b80295SApple OSS Distributions                        #
945*d8b80295SApple OSS Distributions                        str_value = str(self)
946*d8b80295SApple OSS Distributions                        res = int(str_value[str_value.rfind(' '):], 0)
947*d8b80295SApple OSS Distributions                except:
948*d8b80295SApple OSS Distributions                    pass
949*d8b80295SApple OSS Distributions
950*d8b80295SApple OSS Distributions        if res or err.Success():
951*d8b80295SApple OSS Distributions            return res
952*d8b80295SApple OSS Distributions
953*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.xGetValueAsScalar, err.GetCString(),
954*d8b80295SApple OSS Distributions            self, needed=needed, rejected=rejected)
955*d8b80295SApple OSS Distributions
956*d8b80295SApple OSS Distributions
957*d8b80295SApple OSS Distributions    def xGetValueAsInteger(self):
958*d8b80295SApple OSS Distributions        """
959*d8b80295SApple OSS Distributions        Get the integer value of an SBValue (fails for floats or complex)
960*d8b80295SApple OSS Distributions        """
961*d8b80295SApple OSS Distributions
962*d8b80295SApple OSS Distributions        mask = lldb.eTypeIsFloat | lldb.eTypeIsComplex
963*d8b80295SApple OSS Distributions        return self.xGetValueAsScalar(rejected=mask)
964*d8b80295SApple OSS Distributions
965*d8b80295SApple OSS Distributions
966*d8b80295SApple OSS Distributions    def xGetValueAsCString(self, max_len=1024):
967*d8b80295SApple OSS Distributions        """
968*d8b80295SApple OSS Distributions        Gets the cstring value of an SBValue.
969*d8b80295SApple OSS Distributions
970*d8b80295SApple OSS Distributions        @param max_len (int)
971*d8b80295SApple OSS Distributions            The maximum lenght expected for that string
972*d8b80295SApple OSS Distributions
973*d8b80295SApple OSS Distributions        @returns (str)
974*d8b80295SApple OSS Distributions            A string holding the contents of the value.
975*d8b80295SApple OSS Distributions
976*d8b80295SApple OSS Distributions        @raises TypeError
977*d8b80295SApple OSS Distributions            If the value can't be converted to a string
978*d8b80295SApple OSS Distributions        """
979*d8b80295SApple OSS Distributions
980*d8b80295SApple OSS Distributions        if not self.IsValid():
981*d8b80295SApple OSS Distributions            lldbwrap_raise(ValueError, self.xGetValueAsCString, "Value is invalid", self)
982*d8b80295SApple OSS Distributions
983*d8b80295SApple OSS Distributions        return self.target.GetProcess().chkReadCStringFromMemory(self.GetValueAsAddress(), max_len)
984*d8b80295SApple OSS Distributions
985*d8b80295SApple OSS Distributions
986*d8b80295SApple OSS Distributions    def xGetScalarByName(self, name):
987*d8b80295SApple OSS Distributions        """ same as chkGetChildMemberWithName(name).xGetValueAsScalar() """
988*d8b80295SApple OSS Distributions
989*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildMemberWithName(name)
990*d8b80295SApple OSS Distributions        if v.IsValid():
991*d8b80295SApple OSS Distributions            if QUIRK_100103405:
992*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
993*d8b80295SApple OSS Distributions            v.__class__ = SBValue
994*d8b80295SApple OSS Distributions            return v.xGetValueAsScalar()
995*d8b80295SApple OSS Distributions
996*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildMemberWithName, None, name)
997*d8b80295SApple OSS Distributions
998*d8b80295SApple OSS Distributions    def xGetScalarAtIndex(self, index):
999*d8b80295SApple OSS Distributions        """ same as chkGetChildAtIndex(index).xGetValueAsScalar() """
1000*d8b80295SApple OSS Distributions
1001*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildAtIndex(index)
1002*d8b80295SApple OSS Distributions        if v.IsValid():
1003*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1004*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1005*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1006*d8b80295SApple OSS Distributions            return v.xGetValueAsScalar()
1007*d8b80295SApple OSS Distributions
1008*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildAtIndex, None, index)
1009*d8b80295SApple OSS Distributions
1010*d8b80295SApple OSS Distributions    def xGetScalarByPath(self, path):
1011*d8b80295SApple OSS Distributions        """ same as chkGetValueForExpressionPath(path).xGetValueAsScalar() """
1012*d8b80295SApple OSS Distributions
1013*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetValueForExpressionPath(path)
1014*d8b80295SApple OSS Distributions        if v.IsValid():
1015*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1016*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1017*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1018*d8b80295SApple OSS Distributions            return v.xGetValueAsScalar()
1019*d8b80295SApple OSS Distributions
1020*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetValueForExpressionPath, None, path)
1021*d8b80295SApple OSS Distributions
1022*d8b80295SApple OSS Distributions
1023*d8b80295SApple OSS Distributions    def xGetIntegerByName(self, name):
1024*d8b80295SApple OSS Distributions        """ same as chkGetChildMemberWithName(name).xGetValueAsInteger() """
1025*d8b80295SApple OSS Distributions
1026*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildMemberWithName(name)
1027*d8b80295SApple OSS Distributions        if v.IsValid():
1028*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1029*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1030*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1031*d8b80295SApple OSS Distributions            return v.xGetValueAsInteger()
1032*d8b80295SApple OSS Distributions
1033*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildMemberWithName, None, name)
1034*d8b80295SApple OSS Distributions
1035*d8b80295SApple OSS Distributions    def xGetIntegerAtIndex(self, index):
1036*d8b80295SApple OSS Distributions        """ same as chkGetChildAtIndex(index).xGetValueAsInteger() """
1037*d8b80295SApple OSS Distributions
1038*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildAtIndex(index)
1039*d8b80295SApple OSS Distributions        if v.IsValid():
1040*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1041*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1042*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1043*d8b80295SApple OSS Distributions            return v.xGetValueAsInteger()
1044*d8b80295SApple OSS Distributions
1045*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildAtIndex, None, index)
1046*d8b80295SApple OSS Distributions
1047*d8b80295SApple OSS Distributions    def xGetIntegerByPath(self, path):
1048*d8b80295SApple OSS Distributions        """ same as chkGetValueForExpressionPath(path).xGetValueAsInteger() """
1049*d8b80295SApple OSS Distributions
1050*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetValueForExpressionPath(path)
1051*d8b80295SApple OSS Distributions        if v.IsValid():
1052*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1053*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1054*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1055*d8b80295SApple OSS Distributions            return v.xGetValueAsInteger()
1056*d8b80295SApple OSS Distributions
1057*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetValueForExpressionPath, None, path)
1058*d8b80295SApple OSS Distributions
1059*d8b80295SApple OSS Distributions
1060*d8b80295SApple OSS Distributions    def xGetPointeeByName(self, name):
1061*d8b80295SApple OSS Distributions        """ same as chkGetChildMemberWithName(name).xDereference() """
1062*d8b80295SApple OSS Distributions
1063*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildMemberWithName(name)
1064*d8b80295SApple OSS Distributions        if v.IsValid():
1065*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
1066*d8b80295SApple OSS Distributions            return v.xDereference()
1067*d8b80295SApple OSS Distributions
1068*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildMemberWithName, None, name)
1069*d8b80295SApple OSS Distributions
1070*d8b80295SApple OSS Distributions    def xGetPointeeAtIndex(self, index):
1071*d8b80295SApple OSS Distributions        """ same as chkGetChildAtIndex(index).xDereference() """
1072*d8b80295SApple OSS Distributions
1073*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildAtIndex(index)
1074*d8b80295SApple OSS Distributions        if v.IsValid():
1075*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
1076*d8b80295SApple OSS Distributions            return v.xDereference()
1077*d8b80295SApple OSS Distributions
1078*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildAtIndex, None, index)
1079*d8b80295SApple OSS Distributions
1080*d8b80295SApple OSS Distributions    def xGetPointeeByPath(self, path):
1081*d8b80295SApple OSS Distributions        """ same as chkGetValueForExpressionPath(path).xDereference() """
1082*d8b80295SApple OSS Distributions
1083*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetValueForExpressionPath(path)
1084*d8b80295SApple OSS Distributions        if v.IsValid():
1085*d8b80295SApple OSS Distributions            SBValue.xUpcast(v)
1086*d8b80295SApple OSS Distributions            return v.xDereference()
1087*d8b80295SApple OSS Distributions
1088*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetValueForExpressionPath, None, path)
1089*d8b80295SApple OSS Distributions
1090*d8b80295SApple OSS Distributions
1091*d8b80295SApple OSS Distributions    def xGetLoadAddressByName(self, name):
1092*d8b80295SApple OSS Distributions        """ same as chkGetChildMemberWithName(name).GetLoadAddress() """
1093*d8b80295SApple OSS Distributions
1094*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildMemberWithName(name)
1095*d8b80295SApple OSS Distributions        if v.IsValid():
1096*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1097*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1098*d8b80295SApple OSS Distributions            return v.GetLoadAddress()
1099*d8b80295SApple OSS Distributions
1100*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildMemberWithName, None, name)
1101*d8b80295SApple OSS Distributions
1102*d8b80295SApple OSS Distributions    def xGetLoadAddressAtIndex(self, index):
1103*d8b80295SApple OSS Distributions        """ same as chkGetChildAtIndex(index).GetLoadAddress() """
1104*d8b80295SApple OSS Distributions
1105*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildAtIndex(index)
1106*d8b80295SApple OSS Distributions        if v.IsValid():
1107*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1108*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1109*d8b80295SApple OSS Distributions            return v.GetLoadAddress()
1110*d8b80295SApple OSS Distributions
1111*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildAtIndex, None, index)
1112*d8b80295SApple OSS Distributions
1113*d8b80295SApple OSS Distributions    def xGetLoadAddressByPath(self, path):
1114*d8b80295SApple OSS Distributions        """ same as chkGetValueForExpressionPath(path).GetLoadAddress() """
1115*d8b80295SApple OSS Distributions
1116*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetValueForExpressionPath(path)
1117*d8b80295SApple OSS Distributions        if v.IsValid():
1118*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1119*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1120*d8b80295SApple OSS Distributions            return v.GetLoadAddress()
1121*d8b80295SApple OSS Distributions
1122*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetValueForExpressionPath, None, path)
1123*d8b80295SApple OSS Distributions
1124*d8b80295SApple OSS Distributions
1125*d8b80295SApple OSS Distributions    def xGetCStringByName(self, name, *args):
1126*d8b80295SApple OSS Distributions        """ same as chkGetChildMemberWithName(name).xGetValueAsCString() """
1127*d8b80295SApple OSS Distributions
1128*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildMemberWithName(name)
1129*d8b80295SApple OSS Distributions        if v.IsValid():
1130*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1131*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1132*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1133*d8b80295SApple OSS Distributions            return v.xGetValueAsCString(*args)
1134*d8b80295SApple OSS Distributions
1135*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildMemberWithName, None, name)
1136*d8b80295SApple OSS Distributions
1137*d8b80295SApple OSS Distributions    def xGetCStringAtIndex(self, index, *args):
1138*d8b80295SApple OSS Distributions        """ same as chkGetChildAtIndex(index).xGetValueAsCString() """
1139*d8b80295SApple OSS Distributions
1140*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetChildAtIndex(index)
1141*d8b80295SApple OSS Distributions        if v.IsValid():
1142*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1143*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1144*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1145*d8b80295SApple OSS Distributions            return v.xGetValueAsCString(*args)
1146*d8b80295SApple OSS Distributions
1147*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetChildAtIndex, None, index)
1148*d8b80295SApple OSS Distributions
1149*d8b80295SApple OSS Distributions    def xGetCStringByPath(self, path, *args):
1150*d8b80295SApple OSS Distributions        """ same as chkGetValueForExpressionPath(path).xGetValueAsCString() """
1151*d8b80295SApple OSS Distributions
1152*d8b80295SApple OSS Distributions        v = super(SBValue, self).GetValueForExpressionPath(path)
1153*d8b80295SApple OSS Distributions        if v.IsValid():
1154*d8b80295SApple OSS Distributions            if QUIRK_100103405:
1155*d8b80295SApple OSS Distributions                v.SetPreferDynamicValue(0)
1156*d8b80295SApple OSS Distributions            v.__class__ = SBValue
1157*d8b80295SApple OSS Distributions            return v.xGetValueAsCString(*args)
1158*d8b80295SApple OSS Distributions
1159*d8b80295SApple OSS Distributions        lldbwrap_raise(ValueError, self.GetValueForExpressionPath, None, path)
1160*d8b80295SApple OSS Distributions
1161*d8b80295SApple OSS Distributions
1162*d8b80295SApple OSS Distributionsdef GetDebugger():
1163*d8b80295SApple OSS Distributions    """ Alternative to lldb.debugger since we can't hook globals """
1164*d8b80295SApple OSS Distributions    return SBDebugger(lldb.debugger)
1165*d8b80295SApple OSS Distributions
1166*d8b80295SApple OSS Distributionsdef GetTarget():
1167*d8b80295SApple OSS Distributions    """
1168*d8b80295SApple OSS Distributions    Alternative to lldb.target
1169*d8b80295SApple OSS Distributions
1170*d8b80295SApple OSS Distributions    Using lldb.target has several issues because it is set late by lldb,
1171*d8b80295SApple OSS Distributions    and might resolve to None even when there is a selected target already.
1172*d8b80295SApple OSS Distributions    """
1173*d8b80295SApple OSS Distributions
1174*d8b80295SApple OSS Distributions    return GetDebugger().GetSelectedTarget()
1175*d8b80295SApple OSS Distributions
1176*d8b80295SApple OSS Distributionsdef GetProcess():
1177*d8b80295SApple OSS Distributions    """
1178*d8b80295SApple OSS Distributions    Alternative to lldb.process
1179*d8b80295SApple OSS Distributions
1180*d8b80295SApple OSS Distributions    Using lldb.process has several issues because it is set late by lldb,
1181*d8b80295SApple OSS Distributions    and might resolve to None even when there is a selected target already.
1182*d8b80295SApple OSS Distributions    """
1183*d8b80295SApple OSS Distributions    return GetTarget().GetProcess()
1184*d8b80295SApple OSS Distributions
1185*d8b80295SApple OSS Distributions__all__.extend((
1186*d8b80295SApple OSS Distributions    GetDebugger.__name__,
1187*d8b80295SApple OSS Distributions    GetProcess.__name__,
1188*d8b80295SApple OSS Distributions    GetTarget.__name__,
1189*d8b80295SApple OSS Distributions))
1190*d8b80295SApple OSS Distributions
1191*d8b80295SApple OSS Distributions
1192*d8b80295SApple OSS Distributions################################################################################
1193*d8b80295SApple OSS Distributions#
1194*d8b80295SApple OSS Distributions# Code to generate the module content by replicating `lldb`
1195*d8b80295SApple OSS Distributions#
1196*d8b80295SApple OSS Distributions
1197*d8b80295SApple OSS Distributionsdef lldbwrap_generate(this_module):
1198*d8b80295SApple OSS Distributions    sb_classes = (
1199*d8b80295SApple OSS Distributions       m
1200*d8b80295SApple OSS Distributions       for m in inspect.getmembers(lldb, inspect.isclass)
1201*d8b80295SApple OSS Distributions       if m[0][:2] == "SB"
1202*d8b80295SApple OSS Distributions    )
1203*d8b80295SApple OSS Distributions
1204*d8b80295SApple OSS Distributions    for name, base in sb_classes:
1205*d8b80295SApple OSS Distributions        cls = getattr(this_module, name, None)
1206*d8b80295SApple OSS Distributions        if not hasattr(this_module, name):
1207*d8b80295SApple OSS Distributions            attr = {}
1208*d8b80295SApple OSS Distributions            lldbwrap_update_class_dict(name, base, attr)
1209*d8b80295SApple OSS Distributions            cls = type(name, (base,), attr)
1210*d8b80295SApple OSS Distributions            setattr(this_module, name, cls)
1211*d8b80295SApple OSS Distributions
1212*d8b80295SApple OSS Distributions        UPCASTS[base] = cls.xUpcast
1213*d8b80295SApple OSS Distributions        __all__.append(name)
1214*d8b80295SApple OSS Distributions
1215*d8b80295SApple OSS Distributions    #
1216*d8b80295SApple OSS Distributions    # Re-export globals
1217*d8b80295SApple OSS Distributions    #
1218*d8b80295SApple OSS Distributions
1219*d8b80295SApple OSS Distributions    for name, value in inspect.getmembers(lldb):
1220*d8b80295SApple OSS Distributions
1221*d8b80295SApple OSS Distributions        if name.startswith("LLDB_"):
1222*d8b80295SApple OSS Distributions            setattr(this_module, name, value)
1223*d8b80295SApple OSS Distributions            __all__.append(name)
1224*d8b80295SApple OSS Distributions            continue
1225*d8b80295SApple OSS Distributions
1226*d8b80295SApple OSS Distributions        if name[0] == 'e' and name[1].isupper():
1227*d8b80295SApple OSS Distributions            setattr(this_module, name, value)
1228*d8b80295SApple OSS Distributions            __all__.append(name)
1229*d8b80295SApple OSS Distributions            continue
1230*d8b80295SApple OSS Distributions
1231*d8b80295SApple OSS Distributionslldbwrap_generate(sys.modules[__name__])
1232