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