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