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