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