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