1""" 2Defines a class value which encapsulates the basic lldb Scripting Bridge APIs. This provides an easy 3wrapper to extract information from C based constructs. 4 |------- core.value------------| 5 | |--lldb Scripting Bridge--| | 6 | | |--lldb core--| | | 7 | |-------------------------| | 8 |------------------------------| 9Use the member function GetSBValue() to access the base Scripting Bridge value. 10""" 11import lldb 12import re 13from lazytarget import * 14 15_cstring_rex = re.compile("((?:\s*|const\s+)\s*char(?:\s+\*|\s+[A-Za-z_0-9]*\s*\[|)\s*)",re.MULTILINE|re.DOTALL) 16 17class value(object): 18 '''A class designed to wrap lldb.SBValue() objects so the resulting object 19 can be used as a variable would be in code. So if you have a Point structure 20 variable in your code in the current frame named "pt", you can initialize an instance 21 of this class with it: 22 23 pt = lldb.value(lldb.frame.FindVariable("pt")) 24 print pt 25 print pt.x 26 print pt.y 27 28 pt = lldb.value(lldb.frame.FindVariable("rectangle_array")) 29 print rectangle_array[12] 30 print rectangle_array[5].origin.x''' 31 def __init__(self, sbvalue): 32 #_sbval19k84obscure747 is specifically chosen to be obscure. 33 #This avoids conflicts when attributes could mean any field value in code 34 self._sbval19k84obscure747 = sbvalue 35 self._sbval19k84obscure747_type = sbvalue.GetType() 36 self._sbval19k84obscure747_is_ptr = sbvalue.GetType().IsPointerType() 37 self.sbvalue = sbvalue 38 39 def __nonzero__(self): 40 return ( self._sbval19k84obscure747.__nonzero__() and self._GetValueAsUnsigned() != 0 ) 41 42 def __repr__(self): 43 return self._sbval19k84obscure747.__str__() 44 45 def __cmp__(self, other): 46 if type(other) is int: 47 me = int(self) 48 if type(me) is long: 49 other = long(other) 50 return me.__cmp__(other) 51 if type(other) is value: 52 return int(self).__cmp__(int(other)) 53 raise TypeError("Cannot compare value with this type") 54 55 def __str__(self): 56 global _cstring_rex 57 type_name = self._sbval19k84obscure747_type.GetName() 58 if len(_cstring_rex.findall(type_name)) > 0 : 59 return self._GetValueAsString() 60 summary = self._sbval19k84obscure747.GetSummary() 61 if summary: 62 return summary.strip('"') 63 return self._sbval19k84obscure747.__str__() 64 65 def __getitem__(self, key): 66 # Allow array access if this value has children... 67 if type(key) is slice: 68 _start = int(key.start) 69 _end = int(key.stop) 70 _step = 1 71 if key.step != None: 72 _step = int(key.step) 73 retval = [] 74 while _start < _end: 75 retval.append(self[_start]) 76 _start += _step 77 return retval 78 if type(key) in (int, long): 79 return value(self._sbval19k84obscure747.GetValueForExpressionPath("[%i]" % key)) 80 if type(key) is value: 81 return value(self._sbval19k84obscure747.GetValueForExpressionPath("[%i]" % int(key))) 82 raise TypeError("Cannot fetch Array item for this type") 83 84 def __getattr__(self, name): 85 child_sbvalue = self._sbval19k84obscure747.GetChildMemberWithName (name) 86 if child_sbvalue: 87 return value(child_sbvalue) 88 raise AttributeError("No field by name: "+name ) 89 90 def __add__(self, other): 91 return int(self) + int(other) 92 93 def __radd__(self, other): 94 return int(self) + int(other) 95 96 def __sub__(self, other): 97 return int(self) - int(other) 98 99 def __rsub__(self, other): 100 return int(other) - int(self) 101 102 def __mul__(self, other): 103 return int(self) * int(other) 104 105 def __rmul__(self, other): 106 return int(self) * int(other) 107 108 def __floordiv__(self, other): 109 return int(self) // int(other) 110 111 def __mod__(self, other): 112 return int(self) % int(other) 113 114 def __rmod__(self, other): 115 return int(other) % int(self) 116 117 def __divmod__(self, other): 118 return int(self) % int(other) 119 120 def __rdivmod__(self, other): 121 return int(other) % int(self) 122 123 def __pow__(self, other): 124 return int(self) ** int(other) 125 126 def __lshift__(self, other): 127 return int(self) << int(other) 128 129 def __rshift__(self, other): 130 return int(self) >> int(other) 131 132 def __and__(self, other): 133 return int(self) & int(other) 134 135 def __rand(self, other): 136 return int(self) & int(other) 137 138 def __xor__(self, other): 139 return int(self) ^ int(other) 140 141 def __or__(self, other): 142 return int(self) | int(other) 143 144 def __div__(self, other): 145 return int(self) / int(other) 146 147 def __rdiv__(self, other): 148 return int(other)/int(self) 149 150 def __truediv__(self, other): 151 return int(self) / int(other) 152 153 def __iadd__(self, other): 154 result = self.__add__(other) 155 self._sbval19k84obscure747.SetValueFromCString (str(result)) 156 return result 157 158 def __isub__(self, other): 159 result = self.__sub__(other) 160 self._sbval19k84obscure747.SetValueFromCString (str(result)) 161 return result 162 163 def __imul__(self, other): 164 result = self.__mul__(other) 165 self._sbval19k84obscure747.SetValueFromCString (str(result)) 166 return result 167 168 def __idiv__(self, other): 169 result = self.__div__(other) 170 self._sbval19k84obscure747.SetValueFromCString (str(result)) 171 return result 172 173 def __itruediv__(self, other): 174 result = self.__truediv__(other) 175 self._sbval19k84obscure747.SetValueFromCString (str(result)) 176 return result 177 178 def __ifloordiv__(self, other): 179 result = self.__floordiv__(self, other) 180 self._sbval19k84obscure747.SetValueFromCString (str(result)) 181 return result 182 183 def __imod__(self, other): 184 result = self.__and__(self, other) 185 self._sbval19k84obscure747.SetValueFromCString (str(result)) 186 return result 187 188 def __ipow__(self, other): 189 result = self.__pow__(self, other) 190 self._sbval19k84obscure747.SetValueFromCString (str(result)) 191 return result 192 193 def __ipow__(self, other, modulo): 194 result = self.__pow__(self, other, modulo) 195 self._sbval19k84obscure747.SetValueFromCString (str(result)) 196 return result 197 198 def __ilshift__(self, other): 199 result = self.__lshift__(other) 200 self._sbval19k84obscure747.SetValueFromCString (str(result)) 201 return result 202 203 def __irshift__(self, other): 204 result = self.__rshift__(other) 205 self._sbval19k84obscure747.SetValueFromCString (str(result)) 206 return result 207 208 def __iand__(self, other): 209 result = self.__and__(self, other) 210 self._sbval19k84obscure747.SetValueFromCString (str(result)) 211 return result 212 213 def __ixor__(self, other): 214 result = self.__xor__(self, other) 215 self._sbval19k84obscure747.SetValueFromCString (str(result)) 216 return result 217 218 def __ior__(self, other): 219 result = self.__ior__(self, other) 220 self._sbval19k84obscure747.SetValueFromCString (str(result)) 221 return result 222 223 def __neg__(self): 224 return -int(self) 225 226 def __pos__(self): 227 return +int(self) 228 229 def __abs__(self): 230 return abs(int(self)) 231 232 def __invert__(self): 233 return ~int(self) 234 235 def __complex__(self): 236 return complex (int(self)) 237 238 def __int__(self): 239 if self._sbval19k84obscure747_is_ptr: 240 return self._GetValueAsUnsigned() 241 tname= self._sbval19k84obscure747_type.GetName() 242 if tname.find('uint') >= 0 or tname.find('unsigned') >= 0: 243 return self._GetValueAsUnsigned() 244 retval = self._sbval19k84obscure747.GetValueAsSigned() 245 # <rdar://problem/12481949> lldb python: GetValueAsSigned does not return the correct value 246 if (retval & 0x80000000): 247 retval = retval - 0x100000000 248 return retval 249 250 def __long__(self): 251 return self._sbval19k84obscure747.GetValueAsSigned() 252 253 def __float__(self): 254 return float (self._sbval19k84obscure747.GetValueAsSigned()) 255 256 def __oct__(self): 257 return '0%o' % self._GetValueAsUnsigned() 258 259 def __hex__(self): 260 return '0x%x' % self._GetValueAsUnsigned() 261 262 def __eq__(self, other): 263 self_err = lldb.SBError() 264 other_err = lldb.SBError() 265 self_val = self._sbval19k84obscure747.GetValueAsUnsigned(self_err) 266 if self_err.fail: 267 raise ValueError("unable to extract value of self") 268 if type(other) is value: 269 other_val = other._sbval19k84obscure747.GetValueAsUnsigned(other_err) 270 if other_err.fail: 271 raise ValueError("unable to extract value of other") 272 return self_val == other_val 273 if type(other) is int: 274 return int(self) == other 275 raise TypeError("Equality operation is not defined for this type.") 276 277 def __neq__(self, other): 278 return not self.__eq__(other) 279 280 def GetSBValue(self): 281 return self._sbval19k84obscure747 282 283 def _GetValueAsSigned(self): 284 serr = lldb.SBError() 285 retval = self._sbval19k84obscure747.GetValueAsSigned(serr) 286 if serr.success: 287 return retval 288 raise ValueError("Failed to read signed data. "+ str(self._sbval19k84obscure747) +"(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) 289 290 def _GetValueAsUnsigned(self): 291 serr = lldb.SBError() 292 retval = self._sbval19k84obscure747.GetValueAsUnsigned(serr) 293 if serr.success: 294 return retval 295 raise ValueError("Failed to read unsigned data. "+ str(self._sbval19k84obscure747) +"(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) 296 297 def _GetValueAsString(self, offset = 0, maxlen = 1024): 298 serr = lldb.SBError() 299 sbdata = None 300 if self._sbval19k84obscure747.TypeIsPointerType(): 301 sbdata = self._sbval19k84obscure747.GetPointeeData(offset, maxlen) 302 else: 303 sbdata = self._sbval19k84obscure747.GetData() 304 305 retval = '' 306 bytesize = sbdata.GetByteSize() 307 if bytesize == 0 : 308 #raise ValueError('Unable to read value as string') 309 return '' 310 for i in range(0, bytesize) : 311 serr.Clear() 312 ch = chr(sbdata.GetUnsignedInt8(serr, i)) 313 if serr.fail : 314 raise ValueError("Unable to read string data: " + serr.GetCString()) 315 if ch == '\0': 316 break 317 retval += ch 318 return retval 319 320 def __format__(self, format_spec): 321 ret_format = "{0:"+format_spec+"}" 322 # typechar is last char. see http://www.python.org/dev/peps/pep-3101/ 323 type_spec=format_spec.strip().lower()[-1] 324 if type_spec == 'x': 325 return ret_format.format(self._GetValueAsUnsigned()) 326 if type_spec == 'd': 327 return ret_format.format(int(self)) 328 if type_spec == 's': 329 return ret_format.format(str(self)) 330 if type_spec == 'o': 331 return ret_format.format(int(oct(self))) 332 if type_spec == 'c': 333 return ret_format.format(int(self)) 334 335 return "unknown format " + format_spec + str(self) 336 337 338def unsigned(val): 339 """ Helper function to get unsigned value from core.value 340 params: val - value (see value class above) representation of an integer type 341 returns: int which is unsigned. 342 raises : ValueError if the type cannot be represented as unsigned int. 343 """ 344 if type(val) is value: 345 return val._GetValueAsUnsigned() 346 return int(val) 347 348def sizeof(t): 349 """ Find the byte size of a type. 350 params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C 351 t - value: ex a value object. returns size of the object 352 returns: int - byte size length 353 """ 354 if type(t) is value : 355 return t.GetSBValue().GetByteSize() 356 if type(t) is str: 357 return gettype(t).GetByteSize() 358 raise ValueError("Cannot get sizeof. Invalid argument") 359 360 361def dereference(val): 362 """ Get a dereferenced obj for a pointer type obj 363 params: val - value object representing a pointer type C construct in lldb 364 returns: value - value 365 ex. val = dereference(ptr_obj) #python 366 is same as 367 obj_ptr = (int *)0x1234 #C 368 val = *obj_ptr #C 369 """ 370 if type(val) is value and val.GetSBValue().TypeIsPointerType(): 371 return value(val.GetSBValue().Dereference()) 372 raise TypeError('Cannot dereference this type.') 373 374def addressof(val): 375 """ Get address of a core.value object. 376 params: val - value object representing a C construct in lldb 377 returns: value - value object referring to 'type(val) *' type 378 ex. addr = addressof(hello_obj) #python 379 is same as 380 uintptr_t addr = (uintptr_t)&hello_obj #C 381 """ 382 if type(val) is value: 383 return value(val.GetSBValue().AddressOf()) 384 raise TypeError("Cannot do addressof for non-value type objects") 385 386def cast(obj, target_type): 387 """ Type cast an object to another C type. 388 params: 389 obj - core.value object representing some C construct in lldb 390 target_type - str : ex 'char *' 391 - lldb.SBType : 392 """ 393 dest_type = target_type 394 if type(target_type) is str: 395 dest_type = gettype(target_type) 396 elif type(target_type) is value: 397 dest_type = target_type.GetSBValue().GetType() 398 399 if type(obj) is value : 400 return value(obj.GetSBValue().Cast(dest_type)) 401 elif type(obj) is int: 402 print "ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type) 403 raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj)), str(target_type))) 404 405_value_types_cache={} 406 407def gettype(target_type): 408 """ Returns lldb.SBType of the given target_type 409 params: 410 target_type - str, ex. 'char', 'uint32_t' etc 411 returns: 412 lldb.SBType - SBType corresponding to the given target_type 413 raises: 414 NameError - Incase the type is not identified 415 """ 416 global _value_types_cache 417 # LLDB Somehow does not support finding types for 'struct pmap' while 'pmap' works fine 418 # <rdar://problem/12473003> 419 target_type = target_type.replace('struct', '') 420 target_type = str(target_type).strip() 421 if target_type not in _value_types_cache: 422 tmp_type = None 423 if target_type.endswith('*') : 424 tmp_type = LazyTarget.GetTarget().FindFirstType(target_type.rstrip('*').strip()) 425 if not tmp_type.IsValid(): 426 raise NameError('Unable to Cast to type '+target_type) 427 tmp_type = tmp_type.GetPointerType() 428 else : 429 tmp_type = LazyTarget.GetTarget().FindFirstType(target_type) 430 if not tmp_type.IsValid(): 431 raise NameError('Unable to Cast to type '+target_type) 432 _value_types_cache[target_type] = tmp_type 433 return _value_types_cache[target_type] 434 435def getfieldoffset(struct_type, field_name): 436 """ Returns the byte offset of a field inside a given struct 437 params: 438 struct_type - str or lldb.SBType, ex. 'struct ipc_port *' or port.gettype() 439 field_name - str, name of the field inside the struct ex. 'ip_messages' 440 returns: 441 int - byte offset of the field_name inside the struct_type 442 raises: 443 TypeError - - In case the struct_type has no field with the name field_name 444 """ 445 if type(struct_type) == str: 446 struct_type = gettype(struct_type) 447 offset = 0 448 for field in struct_type.get_fields_array(): 449 if str(field.GetName()) == field_name: 450 return field.GetOffsetInBytes() 451 raise TypeError('Field name "%s" not found in type "%s"' % (field_name, str(struct_type))) 452 453def islong(x): 454 """ Returns True if a string represents a long integer, False otherwise 455 """ 456 try: 457 long(x,16) 458 except ValueError: 459 try: 460 long(x) 461 except ValueError: 462 return False 463 return True 464