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