xref: /xnu-10002.81.5/tools/lldbmacros/core/cvalue.py (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
1"""
2Defines a class value which encapsulates the basic lldb Scripting Bridge APIs. This provides an easy
3wrapper to extract information from C based constructs.
4
5 |------- core.value------------|
6 | |--lldb Scripting Bridge--|  |
7 | |    |--lldb core--|      |  |
8 | |-------------------------|  |
9 |------------------------------|
10
11Use the member function GetSBValue() to access the base Scripting Bridge value.
12"""
13from __future__ import absolute_import, division, print_function
14
15# The value class is designed to be Python 2/3 compatible. Pulling in more
16# builtins classes may break it.
17from builtins import range
18import numbers
19
20# Override int with valueint so we get the desired behavior.
21from .compat import valueint as int
22
23from past.utils import old_div
24import lldb
25import re
26from .caching import (
27    cache_statically,
28)
29import six
30from .pointer import PointerPolicy
31
32_CSTRING_REX = re.compile(r"((?:\s*|const\s+)\s*char(?:\s+\*|\s+[A-Za-z_0-9]*\s*\[|)\s*)", re.MULTILINE | re.DOTALL)
33
34
35# pragma pylint: disable=hex-method, div-method, rdiv-method, idiv-method, oct-method, nonzero-method
36class value(object):
37    """A class designed to wrap lldb.SBValue() objects so the resulting object
38    can be used as a variable would be in code. So if you have a Point structure
39    variable in your code in the current frame named "pt", you can initialize an instance
40    of this class with it:
41
42    pt = lldb.value(lldb.frame.FindVariable("pt"))
43    print pt
44    print pt.x
45    print pt.y
46
47    pt = lldb.value(lldb.frame.FindVariable("rectangle_array"))
48    print rectangle_array[12]
49    print rectangle_array[5].origin.x
50    """
51
52    __slots__ = ('__sbval', '__ptr')
53
54    def __init__(self, sbvalue, usePtrPolicy=True):
55        # Using a double `__` means this will be hidden from getattr()
56        # and can't conflict with C/C++ type field names.
57        self.__sbval = sbvalue
58        self.__ptr = PointerPolicy.match(sbvalue) if usePtrPolicy else None
59
60    @property
61    def sbvalue(self):
62        """backward compability for the old .sbvalue property"""
63        return self.GetSBValue()
64
65    @property
66    def ptrpolicy(self):
67        return self.__ptr
68
69    @ptrpolicy.setter
70    def ptrpolicy(self, policy):
71        self.__ptr = policy
72
73    def __bool__(self):
74        return self.__sbval.__bool__() and self._GetValueAsUnsigned() != 0
75
76    def __nonzero__(self):
77        return self.__sbval.__nonzero__() and self._GetValueAsUnsigned() != 0
78
79    def __repr__(self):
80        return self.__sbval.__str__()
81
82    #
83    # Compare operators
84    #
85
86    def __eq__(self, other):
87        self_val = self._GetValueAsUnsigned()
88        if isinstance(other, value):
89            other_val = other._GetValueAsUnsigned()
90            return self_val == other_val
91        if isinstance(other, numbers.Integral):
92            return int(self) == other
93        raise TypeError("EQ operator is not defined for this type.")
94
95    def __ne__(self, other):
96        return not self == other
97
98    def __lt__(self, other):
99        self_val = self._GetValueAsUnsigned()
100        if isinstance(other, value):
101            other_val = other._GetValueAsUnsigned()
102            return self_val < other_val
103        if isinstance(other, numbers.Integral):
104            return int(self) < int(other)
105        raise TypeError("LT operator is not defined for this type")
106
107    def __le__(self, other):
108        return self < other or self == other
109
110    def __gt__(self, other):
111        return not self <= other
112
113    def __ge__(self, other):
114        return not self < other
115
116    def __str__(self):
117        global _CSTRING_REX
118        sbv = self.__sbval
119        type_name = sbv.GetType().GetCanonicalType().GetName()
120        if len(_CSTRING_REX.findall(type_name)) > 0:
121            return self._GetValueAsString()
122        summary = sbv.GetSummary()
123        if summary:
124            return summary.strip('"')
125        return sbv.__str__()
126
127    def __getitem__(self, key):
128        # Allow array access if this value has children...
129        if type(key) is slice:
130            _start = int(key.start)
131            _end = int(key.stop)
132            _step = 1
133            if key.step is not None:
134                _step = int(key.step)
135            retval = []
136            while _start < _end:
137                retval.append(self[_start])
138                _start += _step
139            return retval
140        if type(key) is value:
141            key = int(key)
142        if isinstance(key, numbers.Integral):
143            sbv = self.__sbval
144            if self.__ptr:
145                sbv = self.__ptr.GetPointerSBValue(sbv)
146            child_sbvalue = sbv.GetValueForExpressionPath("[%i]" % key)
147            if child_sbvalue and child_sbvalue.IsValid():
148                return value(child_sbvalue)
149            raise IndexError("Index '%d' is out of range" % key)
150        raise TypeError("Cannot fetch array item for key of type {}".format(str(type(key))))
151
152    def __getattr__(self, name):
153        sbv = self.__sbval
154        if self.__ptr:
155            sbv = self.__ptr.GetPointerSBValue(sbv)
156        child_sbvalue = sbv.GetChildMemberWithName(name)
157        if child_sbvalue and child_sbvalue.IsValid():
158            return value(child_sbvalue)
159        raise AttributeError("No field by name: " + name)
160
161    def __add__(self, other):
162        return int(self) + int(other)
163
164    def __radd__(self, other):
165        return int(self) + int(other)
166
167    def __sub__(self, other):
168        return int(self) - int(other)
169
170    def __rsub__(self, other):
171        return int(other) - int(self)
172
173    def __mul__(self, other):
174        return int(self) * int(other)
175
176    def __rmul__(self, other):
177        return int(self) * int(other)
178
179    def __floordiv__(self, other):
180        return int(self) // int(other)
181
182    def __rfloordiv__(self, other):
183        return int(other) // int(self)
184
185    def __mod__(self, other):
186        return int(self) % int(other)
187
188    def __rmod__(self, other):
189        return int(other) % int(self)
190
191    def __divmod__(self, other):
192        return divmod(int(self), int(other))
193
194    def __rdivmod__(self, other):
195        return divmod(int(other), int(self))
196
197    def __pow__(self, other):
198        return int(self) ** int(other)
199
200    def __lshift__(self, other):
201        return int(self) << int(other)
202
203    def __rshift__(self, other):
204        return int(self) >> int(other)
205
206    def __and__(self, other):
207        return int(self) & int(other)
208
209    def __rand__(self, other):
210        return int(other) & int(self)
211
212    def __xor__(self, other):
213        return int(self) ^ int(other)
214
215    def __or__(self, other):
216        return int(self) | int(other)
217
218    def __div__(self, other):
219        return old_div(int(self), int(other))
220
221    def __rdiv__(self, other):
222        return old_div(int(other), int(self))
223
224    def __truediv__(self, other):
225        return int(self) / int(other)
226
227    def __rtruediv__(self, other):
228        return int(other) / int(self)
229
230    def __iadd__(self, other):
231        result = self.__add__(other)
232        self.__sbval.SetValueFromCString(str(result))
233        return result
234
235    def __isub__(self, other):
236        result = self.__sub__(other)
237        self.__sbval.SetValueFromCString(str(result))
238        return result
239
240    def __imul__(self, other):
241        result = self.__mul__(other)
242        self.__sbval.SetValueFromCString(str(result))
243        return result
244
245    def __idiv__(self, other):
246        result = self.__div__(other)
247        self.__sbval.SetValueFromCString(str(result))
248        return result
249
250    def __itruediv__(self, other):
251        result = self.__truediv__(other)
252        self.__sbval.SetValueFromCString(str(result))
253        return result
254
255    def __ifloordiv__(self, other):
256        result = self.__floordiv__(other)
257        self.__sbval.SetValueFromCString(str(result))
258        return result
259
260    def __imod__(self, other):
261        result = self.__mod__(other)
262        self.__sbval.SetValueFromCString(str(result))
263        return result
264
265    def __ipow__(self, other):
266        result = self.__pow__(other)
267        self.__sbval.SetValueFromCString(str(result))
268        return result
269
270    def __ilshift__(self, other):
271        result = self.__lshift__(other)
272        self.__sbval.SetValueFromCString(str(result))
273        return result
274
275    def __irshift__(self, other):
276        result = self.__rshift__(other)
277        self.__sbval.SetValueFromCString(str(result))
278        return result
279
280    def __iand__(self, other):
281        result = self.__and__(other)
282        self.__sbval.SetValueFromCString(str(result))
283        return result
284
285    def __ixor__(self, other):
286        result = self.__xor__(other)
287        self.__sbval.SetValueFromCString(str(result))
288        return result
289
290    def __ior__(self, other):
291        result = self.__or__(other)
292        self.__sbval.SetValueFromCString(str(result))
293        return result
294
295    def __neg__(self):
296        return -int(self)
297
298    def __pos__(self):
299        return +int(self)
300
301    def __abs__(self):
302        return abs(int(self))
303
304    def __invert__(self):
305        return ~int(self)
306
307    def __complex__(self):
308        return complex(int(self))
309
310    def __int__(self):
311        sbv = self.__sbval
312        if self.__ptr:
313            sbv = self.__ptr.GetPointerSBValue(sbv)
314
315        flags = sbv.GetType().GetTypeFlags()
316        if flags & lldb.eTypeIsPointer:
317            return sbv.GetValueAsAddress()
318        if not flags & lldb.eTypeIsSigned:
319            return self._GetValueAsUnsigned()
320
321        return sbv.GetValueAsSigned()
322
323    # Python 3 conversion to int calls this.
324    def __index__(self):
325        return self.__int__()
326
327    def __long__(self):
328        sbv = self.__sbval
329        if self.__ptr:
330            sbv = self.__ptr.GetPointerSBValue(sbv)
331
332        flags = sbv.GetType().GetTypeFlags()
333        if flags & lldb.eTypeIsPointer:
334            return sbv.GetValueAsAddress()
335        if not flags & lldb.eTypeIsSigned:
336            return self._GetValueAsUnsigned()
337
338        return sbv.GetValueAsSigned()
339
340    def __float__(self):
341        return float(self.__sbval.GetValueAsSigned())
342
343    # Python 2 must return native string.
344    def __oct__(self):
345        return '0%o' % self._GetValueAsUnsigned()
346
347    # Python 2 must return native string.
348    def __hex__(self):
349        return '0x%x' % self._GetValueAsUnsigned()
350
351    def __hash__(self):
352        return hash(self.__sbval)
353
354    def GetRawSBValue(self):
355        return self.__sbval
356
357    def GetSBValue(self):
358        sbv = self.__sbval
359        if self.__ptr:
360            sbv = self.__ptr.GetPointerSBValue(sbv)
361
362        return sbv
363
364    def __getstate__(self):
365        err = lldb.SBError()
366        sbv = self.__sbval
367        if self.__ptr:
368            sbv = self.__ptr.GetPointerSBValue(sbv)
369            addr = sbv.GetValueAsAddress()
370            size = sbv.GetType().GetPointeeType().GetByteSize()
371        else:
372            addr = sbv.GetLoadAddress()
373            size = sbv.GetType().GetByteSize()
374
375        content = sbv.GetProcess().ReadMemory(addr, size, err)
376        if err.fail:
377            content = ''
378        return content
379
380    def _GetValueAsSigned(self):
381        sbv = self.__sbval
382        if self.__ptr:
383            print("ERROR: You cannot get 'int' from pointer type %s, please use unsigned(obj) for such purposes." % sbv.GetType().GetDisplayTypeName())
384            raise ValueError("Cannot get signed int for pointer data.")
385        serr = lldb.SBError()
386        retval = sbv.GetValueAsSigned(serr)
387        if serr.success:
388            return retval
389        raise ValueError("Failed to read signed data. {} (type = {}) Error description: {}".format(
390            str(sbv), sbv.GetType().GetDisplayTypeName(), serr.GetCString()))
391
392    def _GetValueAsCast(self, dest_type):
393        if not isinstance(dest_type, lldb.SBType):
394            raise ValueError("Invalid type for dest_type: {}".format(type(dest_type)))
395        addr = self._GetValueAsUnsigned()
396        sbval = self.__sbval.target.CreateValueFromExpression("newname", "(void *)"+str(addr))
397        val = value(sbval.Cast(dest_type))
398        return val
399
400    def _GetValueAsUnsigned(self):
401        sbv = self.__sbval
402        if self.__ptr:
403            sbv = self.__ptr.GetPointerSBValue(sbv)
404            return sbv.GetValueAsAddress()
405        serr = lldb.SBError()
406        retval = sbv.GetValueAsUnsigned(serr)
407        if serr.success:
408            return retval
409        raise ValueError("Failed to read unsigned data. {} (type = {}) Error description: {}".format(
410            str(sbv), sbv.GetType().GetDisplayTypeName(), serr.GetCString()))
411
412    def _GetValueAsString(self, offset=0, maxlen=1024):
413        sbv = self.__sbval
414        serr = lldb.SBError()
415        sbdata = None
416        if self.__ptr:
417            sbv = self.__ptr.GetPointerSBValue(sbv)
418            sbdata = sbv.GetPointeeData(offset, maxlen)
419        else:
420            sbdata = sbv.GetData()
421
422        retval = ''
423        bytesize = sbdata.GetByteSize()
424        if bytesize == 0:
425            # raise ValueError('Unable to read value as string')
426            return ''
427        for i in range(0, bytesize):
428            serr.Clear()
429            ch = chr(sbdata.GetUnsignedInt8(serr, i))
430            if serr.fail:
431                raise ValueError("Unable to read string data: " + serr.GetCString())
432            if ch == '\0':
433                break
434            retval += ch
435        return retval
436
437    def __format__(self, format_spec):
438        # typechar is last char. see http://www.python.org/dev/peps/pep-3101/
439        typechar = format_spec[-1] if len(format_spec) else ''
440
441        if typechar in 'bcdoxX': # requires integral conversion
442            return format(int(self), format_spec)
443
444        if typechar in 'eEfFgG%': # requires float conversion
445            return format(float(self), format_spec)
446
447        if typechar in 's': # requires string conversion
448            return format(str(self), format_spec)
449
450        # 'n' or '' mean "whatever you got for me"
451        flags = self.__sbval.GetType().GetTypeFlags()
452        if flags & lldb.eTypeIsFloat:
453            return format(float(self), format_spec)
454        elif flags & lldb.eTypeIsScalar:
455            return format(int(self), format_spec)
456        else:
457            return format(str(self), format_spec)
458
459def unsigned(val):
460    """ Helper function to get unsigned value from core.value
461        params: val - value (see value class above) representation of an integer type
462        returns: int which is unsigned.
463        raises : ValueError if the type cannot be represented as unsigned int.
464    """
465    if type(val) is value:
466        return int(val._GetValueAsUnsigned())
467    return int(val)
468
469
470def signed(val):
471    """ Helper function to get signed value from core.value
472        params: val - value (see value class above) representation of an integer type
473        returns: int which is signed.
474        raises: ValueError if the type cannot be represented as signed int.
475    """
476    if type(val) is value:
477        return val.GetSBValue().GetValueAsSigned()
478    return int(val)
479
480
481def sizeof(t):
482    """ Find the byte size of a type.
483        params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C
484                t - value: ex a value object. returns size of the object
485        returns: int - byte size length
486    """
487    if type(t) is value:
488        return t.GetSBValue().GetByteSize()
489    if isinstance(t, six.string_types):
490        return gettype(t).GetByteSize()
491    raise ValueError("Cannot get sizeof. Invalid argument")
492
493
494def dereference(val):
495    """ Get a dereferenced obj for a pointer type obj
496        params: val - value object representing a pointer type C construct in lldb
497        returns: value - value
498        ex. val = dereference(ptr_obj) #python
499        is same as
500            obj_ptr = (int *)0x1234  #C
501            val = *obj_ptr           #C
502    """
503    if type(val) is value:
504        sbv = val.GetSBValue()
505        if val.ptrpolicy:
506            sbv = val.ptrpolicy.GetPointerSBValue(sbv)
507            return value(sbv.Dereference())
508    raise TypeError('Cannot dereference this type.')
509
510
511def wrapped(val):
512    """ Get original pointer value without aplying pointer policy.
513        param: val - value object representing a pointer
514        returns: value - value
515    """
516    if isinstance(val, value):
517        policy = val.ptrpolicy
518        val.ptrpolicy = None
519        newval = value(val.GetSBValue(), False)
520        val.ptrpolicy = policy
521        return newval
522    raise TypeError("Cannot do wrapped for non-value type objects")
523
524
525def addressof(val):
526    """ Get address of a core.value object.
527        params: val - value object representing a C construct in lldb
528        returns: value - value object referring to 'type(val) *' type
529        ex. addr = addressof(hello_obj)  #python
530        is same as
531           uintptr_t addr = (uintptr_t)&hello_obj  #C
532    """
533    if type(val) is value:
534        return value(val.GetSBValue().AddressOf())
535    raise TypeError("Cannot do addressof for non-value type objects")
536
537
538def cast(obj, target_type):
539    """ Type cast an object to another C type.
540        params:
541            obj - core.value  object representing some C construct in lldb
542            target_type - str : ex 'char *'
543                        - lldb.SBType :
544    """
545    dest_type = target_type
546    if isinstance(target_type, six.string_types):
547        dest_type = gettype(target_type)
548    elif type(target_type) is value:
549        dest_type = target_type.GetSBValue().GetType()
550
551    if type(obj) is value:
552        return obj._GetValueAsCast(dest_type)
553    elif type(obj) is int:
554        print("ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type))
555    raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj)), str(target_type)))
556
557
558def containerof(obj, target_type, field_name):
559    """ Type cast an object to another C type from a pointer to a field.
560        params:
561            obj - core.value  object representing some C construct in lldb
562            target_type - str : ex 'struct thread'
563                        - lldb.SBType :
564            field_name - the field name within the target_type obj is a pointer to
565    """
566    addr = int(obj) - getfieldoffset(target_type, field_name)
567    sbv  = obj.GetSBValue()
568    sbv  = sbv.chkCreateValueFromAddress(None, addr, gettype(target_type))
569    return value(sbv.AddressOf())
570
571
572@cache_statically
573def gettype(target_type, target=None):
574    """ Returns lldb.SBType of the given target_type
575        params:
576            target_type - str, ex. 'char', 'uint32_t' etc
577        returns:
578            lldb.SBType - SBType corresponding to the given target_type
579        raises:
580            NameError  - Incase the type is not identified
581    """
582
583    #
584    # If the type was qualified with a `struct` or `class`, ...
585    # make sure we pick up the proper definition in case of clashes.
586    #
587    want = 0
588    name = str(target_type).strip()
589
590    if name.startswith("struct"):
591        want = lldb.eTypeClassStruct
592    elif name.startswith("union"):
593        want = lldb.eTypeClassUnion
594    elif name.startswith("class"):
595        want = lldb.eTypeClassClass
596    elif name.startswith("enum"):
597        want = lldb.eTypeClassEnumeration
598    elif name.startswith("typedef"):
599        want = lldb.eTypeClassTypedef
600
601    #
602    # Now remove constness and speficiers, and pointers
603    #
604    tmpname  = re.sub(r'\bconst\b', '', name).strip(" ")
605    tmpname  = re.sub(r'^(struct|class|union|enum|typedef) ', '', tmpname)
606    basename = tmpname.rstrip(" *")
607    ptrlevel = tmpname.count('*', len(basename))
608
609    # After the sort, the struct type with more fields will be at index [0].
610    # This heuristic helps selecting struct type with more fields
611    # compared to ones with "opaque" members
612    type_lst = target.chkFindTypes(basename)
613    type_arr = [type_lst.GetTypeAtIndex(i) for i in range(len(type_lst))]
614    type_arr.sort(reverse=True, key=lambda x: x.GetNumberOfFields())
615
616    for tyobj in type_arr:
617        if want and tyobj.GetTypeClass() != want:
618            continue
619
620        for i in range(ptrlevel):
621            tyobj = tyobj.GetPointerType()
622
623        return tyobj
624
625    raise NameError('Unable to find type {}'.format(target_type))
626
627
628@cache_statically
629def getfieldoffset(struct_type, field_name_or_path, target=None):
630    """ Returns the byte offset of a field inside a given struct
631        Understands anonymous unions and field names in sub-structs
632        params:
633            field_name_or_path  - str, name or path to the field inside the struct ex. 'ip_messages'
634        returns:
635            int - byte offset of the field_name inside the struct_type
636    """
637
638    return gettype(struct_type).xGetFieldOffset(field_name_or_path)
639
640
641def islong(x):
642    """ Returns True if a string represents a long integer, False otherwise
643    """
644    try:
645        int(x, 16)
646    except ValueError:
647        try:
648            int(x)
649        except ValueError:
650            return False
651    return True
652
653
654def readmemory(val):
655    """ Returns a string of hex data that is referenced by the value.
656        params: val - a value object.
657        return: str - string of hex bytes.
658        raises: TypeError if val is not a valid type
659    """
660    if not type(val) is value:
661        raise TypeError('%s is not of type value' % str(type(val)))
662    return val.__getstate__()
663
664
665def getOSPtr(cpp_obj):
666    """ Returns a core.value created from an intrusive_shared_ptr or itself, cpp_obj
667        params: cpp_obj - core.value object representing a C construct in lldb
668        return: core.value - newly created core.value or cpp_obj
669    """
670    child = cpp_obj.GetSBValue().GetChildAtIndex(0)
671    if 'intrusive_shared_ptr' in str(child):
672        return value(child.GetChildMemberWithName('ptr_'))
673    return cpp_obj
674