2 Defines a class value which encapsulates the basic lldb Scripting Bridge APIs. This provides an easy
3 wrapper to extract information from C based constructs.
4 |------- core.value------------|
5 | |--lldb Scripting Bridge--| |
6 | | |--lldb core--| | |
7 | |-------------------------| |
8 |------------------------------|
9 Use the member function GetSBValue() to access the base Scripting Bridge value.
13 from lazytarget
import *
15 _cstring_rex
= re
.compile("((?:\s*|const\s+)\s*char(?:\s+\*|\s+[A-Za-z_0-9]*\s*\[|)\s*)",re
.MULTILINE|re
.DOTALL
)
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:
23 pt = lldb.value(lldb.frame.FindVariable("pt"))
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
._sbval
19k
84obscure
747 = sbvalue
35 self
._sbval
19k
84obscure
747_type
= sbvalue
.GetType()
36 self
._sbval
19k
84obscure
747_is
_ptr
= sbvalue
.GetType().IsPointerType()
37 self
.sbvalue
= sbvalue
39 def __nonzero__(self
):
40 return ( self
._sbval
19k
84obscure
747.__nonzero
__() and self
._GetValueAsUnsigned
() != 0 )
43 return self
._sbval
19k
84obscure
747.__str
__()
45 def __cmp__(self
, other
):
46 if type(other
) is int or type(other
) is long:
50 return me
.__cmp
__(other
)
51 if type(other
) is value
:
53 return int(self
).__cmp
__(int(other
))
54 except TypeError: # Try promoting to long
55 return long(self
).__cmp
__(long(other
))
56 raise TypeError("Cannot compare value with type {}".format(type(other
)))
60 type_name
= self
._sbval
19k
84obscure
747_type
.GetName()
61 if len(_cstring_rex
.findall(type_name
)) > 0 :
62 return self
._GetValueAsString
()
63 summary
= self
._sbval
19k
84obscure
747.GetSummary()
65 return summary
.strip('"')
66 return self
._sbval
19k
84obscure
747.__str
__()
68 def __getitem__(self
, key
):
69 # Allow array access if this value has children...
70 if type(key
) is slice:
71 _start
= int(key
.start
)
78 retval
.append(self
[_start
])
81 if type(key
) in (int, long):
82 return value(self
._sbval
19k
84obscure
747.GetValueForExpressionPath("[%i]" % key
))
83 if type(key
) is value
:
84 return value(self
._sbval
19k
84obscure
747.GetValueForExpressionPath("[%i]" % int(key
)))
85 raise TypeError("Cannot fetch Array item for this type")
87 def __getattr__(self
, name
):
88 child_sbvalue
= self
._sbval
19k
84obscure
747.GetChildMemberWithName (name
)
90 return value(child_sbvalue
)
91 raise AttributeError("No field by name: "+name
)
93 def __add__(self
, other
):
94 return int(self
) + int(other
)
96 def __radd__(self
, other
):
97 return int(self
) + int(other
)
99 def __sub__(self
, other
):
100 return int(self
) - int(other
)
102 def __rsub__(self
, other
):
103 return int(other
) - int(self
)
105 def __mul__(self
, other
):
106 return int(self
) * int(other
)
108 def __rmul__(self
, other
):
109 return int(self
) * int(other
)
111 def __floordiv__(self
, other
):
112 return int(self
) // int(other
)
114 def __mod__(self
, other
):
115 return int(self
) % int(other
)
117 def __rmod__(self
, other
):
118 return int(other
) % int(self
)
120 def __divmod__(self
, other
):
121 return int(self
) % int(other
)
123 def __rdivmod__(self
, other
):
124 return int(other
) % int(self
)
126 def __pow__(self
, other
):
127 return int(self
) ** int(other
)
129 def __lshift__(self
, other
):
130 return int(self
) << int(other
)
132 def __rshift__(self
, other
):
133 return int(self
) >> int(other
)
135 def __and__(self
, other
):
136 return int(self
) & int(other
)
138 def __rand(self
, other
):
139 return int(self
) & int(other
)
141 def __xor__(self
, other
):
142 return int(self
) ^
int(other
)
144 def __or__(self
, other
):
145 return int(self
) |
int(other
)
147 def __div__(self
, other
):
148 return int(self
) / int(other
)
150 def __rdiv__(self
, other
):
151 return int(other
)/int(self
)
153 def __truediv__(self
, other
):
154 return int(self
) / int(other
)
156 def __iadd__(self
, other
):
157 result
= self
.__add
__(other
)
158 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
161 def __isub__(self
, other
):
162 result
= self
.__sub
__(other
)
163 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
166 def __imul__(self
, other
):
167 result
= self
.__mul
__(other
)
168 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
171 def __idiv__(self
, other
):
172 result
= self
.__div
__(other
)
173 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
176 def __itruediv__(self
, other
):
177 result
= self
.__truediv
__(other
)
178 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
181 def __ifloordiv__(self
, other
):
182 result
= self
.__floordiv
__(self
, other
)
183 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
186 def __imod__(self
, other
):
187 result
= self
.__and
__(self
, other
)
188 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
191 def __ipow__(self
, other
):
192 result
= self
.__pow
__(self
, other
)
193 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
196 def __ipow__(self
, other
, modulo
):
197 result
= self
.__pow
__(self
, other
, modulo
)
198 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
201 def __ilshift__(self
, other
):
202 result
= self
.__lshift
__(other
)
203 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
206 def __irshift__(self
, other
):
207 result
= self
.__rshift
__(other
)
208 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
211 def __iand__(self
, other
):
212 result
= self
.__and
__(self
, other
)
213 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
216 def __ixor__(self
, other
):
217 result
= self
.__xor
__(self
, other
)
218 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
221 def __ior__(self
, other
):
222 result
= self
.__ior
__(self
, other
)
223 self
._sbval
19k
84obscure
747.SetValueFromCString (str(result
))
233 return abs(int(self
))
235 def __invert__(self
):
238 def __complex__(self
):
239 return complex (int(self
))
242 if self
._sbval
19k
84obscure
747_is
_ptr
:
243 return self
._GetValueAsUnsigned
()
244 tname
= self
._sbval
19k
84obscure
747_type
.GetName()
245 if tname
.find('uint') >= 0 or tname
.find('unsigned') >= 0:
246 return self
._GetValueAsUnsigned
()
247 retval
= self
._sbval
19k
84obscure
747.GetValueAsSigned()
248 # <rdar://problem/12481949> lldb python: GetValueAsSigned does not return the correct value
249 if (retval
& 0x80000000):
250 retval
= retval
- 0x100000000
254 return self
._sbval
19k
84obscure
747.GetValueAsSigned()
257 return float (self
._sbval
19k
84obscure
747.GetValueAsSigned())
260 return '0%o' % self
._GetValueAsUnsigned
()
263 return '0x%x' % self
._GetValueAsUnsigned
()
265 def __eq__(self
, other
):
266 self_val
= self
._GetValueAsUnsigned
()
267 if type(other
) is value
:
268 other_val
= other
._GetValueAsUnsigned
()
269 return self_val
== other_val
270 if type(other
) is int:
271 return int(self
) == other
272 raise TypeError("Equality operation is not defined for this type.")
274 def __neq__(self
, other
):
275 return not self
.__eq
__(other
)
277 def GetSBValue(self
):
278 return self
._sbval
19k
84obscure
747
280 def __getstate__(self
):
282 if self
._sbval
19k
84obscure
747_is
_ptr
:
283 addr
= self
._sbval
19k
84obscure
747.GetValueAsAddress()
284 size
= self
._sbval
19k
84obscure
747_type
.GetPointeeType().GetByteSize()
286 addr
= self
._sbval
19k
84obscure
747.AddressOf().GetValueAsAddress()
287 size
= self
._sbval
19k
84obscure
747_type
.GetByteSize()
289 content
= LazyTarget
.GetProcess().ReadMemory(addr
, size
, err
)
294 def _GetValueAsSigned(self
):
295 if self
._sbval
19k
84obscure
747_is
_ptr
:
296 print "ERROR: You cannot get 'int' from pointer type %s, please use unsigned(obj) for such purposes." % str(self
._sbval
19k
84obscure
747_type
)
297 raise ValueError("Cannot get signed int for pointer data.")
298 serr
= lldb
.SBError()
299 retval
= self
._sbval
19k
84obscure
747.GetValueAsSigned(serr
)
302 raise ValueError("Failed to read signed data. "+ str(self
._sbval
19k
84obscure
747) +"(type =" + str(self
._sbval
19k
84obscure
747_type
) + ") Error description: " + serr
.GetCString())
304 def _GetValueAsCast(self
, dest_type
):
305 if type(dest_type
) is not lldb
.SBType
:
306 raise ValueError("Invalid type for dest_type: {}".format(type(dest_type
)))
307 addr
= self
._GetValueAsUnsigned
()
308 sbval
= self
._sbval
19k
84obscure
747.target
.CreateValueFromExpression("newname", "(void *)"+str(addr
))
309 val
= value(sbval
.Cast(dest_type
))
312 def _GetValueAsUnsigned(self
):
313 serr
= lldb
.SBError()
314 if self
._sbval
19k
84obscure
747_is
_ptr
:
315 retval
= self
._sbval
19k
84obscure
747.GetValueAsAddress()
317 retval
= self
._sbval
19k
84obscure
747.GetValueAsUnsigned(serr
)
320 raise ValueError("Failed to read unsigned data. "+ str(self
._sbval
19k
84obscure
747) +"(type =" + str(self
._sbval
19k
84obscure
747_type
) + ") Error description: " + serr
.GetCString())
322 def _GetValueAsString(self
, offset
= 0, maxlen
= 1024):
323 serr
= lldb
.SBError()
325 if self
._sbval
19k
84obscure
747_is
_ptr
:
326 sbdata
= self
._sbval
19k
84obscure
747.GetPointeeData(offset
, maxlen
)
328 sbdata
= self
._sbval
19k
84obscure
747.GetData()
331 bytesize
= sbdata
.GetByteSize()
333 #raise ValueError('Unable to read value as string')
335 for i
in range(0, bytesize
) :
337 ch
= chr(sbdata
.GetUnsignedInt8(serr
, i
))
339 raise ValueError("Unable to read string data: " + serr
.GetCString())
345 def __format__(self
, format_spec
):
346 ret_format
= "{0:"+format_spec+"}"
347 # typechar is last char. see http://www.python.org/dev/peps/pep-3101/
348 type_spec
=format_spec
.strip().lower()[-1]
350 return ret_format
.format(self
._GetValueAsUnsigned
())
352 return ret_format
.format(int(self
))
354 return ret_format
.format(str(self
))
356 return ret_format
.format(int(oct(self
)))
358 return ret_format
.format(int(self
))
360 return "unknown format " + format_spec
+ str(self
)
364 """ Helper function to get unsigned value from core.value
365 params: val - value (see value class above) representation of an integer type
366 returns: int which is unsigned.
367 raises : ValueError if the type cannot be represented as unsigned int.
369 if type(val
) is value
:
370 return val
._GetValueAsUnsigned
()
374 """ Find the byte size of a type.
375 params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C
376 t - value: ex a value object. returns size of the object
377 returns: int - byte size length
379 if type(t
) is value
:
380 return t
.GetSBValue().GetByteSize()
382 return gettype(t
).GetByteSize()
383 raise ValueError("Cannot get sizeof. Invalid argument")
386 def dereference(val
):
387 """ Get a dereferenced obj for a pointer type obj
388 params: val - value object representing a pointer type C construct in lldb
389 returns: value - value
390 ex. val = dereference(ptr_obj) #python
392 obj_ptr = (int *)0x1234 #C
395 if type(val
) is value
and val
._sbval
19k
84obscure
747_is
_ptr
:
396 return value(val
.GetSBValue().Dereference())
397 raise TypeError('Cannot dereference this type.')
400 """ Get address of a core.value object.
401 params: val - value object representing a C construct in lldb
402 returns: value - value object referring to 'type(val) *' type
403 ex. addr = addressof(hello_obj) #python
405 uintptr_t addr = (uintptr_t)&hello_obj #C
407 if type(val
) is value
:
408 return value(val
.GetSBValue().AddressOf())
409 raise TypeError("Cannot do addressof for non-value type objects")
411 def cast(obj
, target_type
):
412 """ Type cast an object to another C type.
414 obj - core.value object representing some C construct in lldb
415 target_type - str : ex 'char *'
418 dest_type
= target_type
419 if type(target_type
) is str:
420 dest_type
= gettype(target_type
)
421 elif type(target_type
) is value
:
422 dest_type
= target_type
.GetSBValue().GetType()
424 if type(obj
) is value
:
425 return obj
._GetValueAsCast
(dest_type
)
426 elif type(obj
) is int:
427 print "ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type
)
428 raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj
)), str(target_type
)))
430 def containerof(obj
, target_type
, field_name
):
431 """ Type cast an object to another C type from a pointer to a field.
433 obj - core.value object representing some C construct in lldb
434 target_type - str : ex 'struct thread'
436 field_name - the field name within the target_type obj is a pointer to
438 addr
= int(obj
) - getfieldoffset(target_type
, field_name
)
439 obj
= value(obj
.GetSBValue().CreateValueFromExpression(None,'(void *)'+str(addr
)))
440 return cast(obj
, target_type
+ " *")
443 _value_types_cache
={}
445 def gettype(target_type
):
446 """ Returns lldb.SBType of the given target_type
448 target_type - str, ex. 'char', 'uint32_t' etc
450 lldb.SBType - SBType corresponding to the given target_type
452 NameError - Incase the type is not identified
454 global _value_types_cache
455 target_type
= str(target_type
).strip()
456 if target_type
in _value_types_cache
:
457 return _value_types_cache
[target_type
]
459 target_type
= target_type
.strip()
461 requested_type_is_struct
= False
462 m
= re
.match(r
'\s*struct\s*(.*)$', target_type
)
464 requested_type_is_struct
= True
465 target_type
= m
.group(1)
468 requested_type_is_pointer
= False
469 if target_type
.endswith('*') :
470 requested_type_is_pointer
= True
472 # tmp_type = LazyTarget.GetTarget().FindFirstType(target_type.rstrip('*').strip())
473 search_type
= target_type
.rstrip('*').strip()
474 type_arr
= [t
for t
in LazyTarget
.GetTarget().FindTypes(search_type
)]
476 if requested_type_is_struct
:
477 type_arr
= [t
for t
in type_arr
if t
.type == lldb
.eTypeClassStruct
]
479 # After the sort, the struct type with more fields will be at index [0].
480 # This hueristic helps selecting struct type with more fields compared to ones with "opaque" members
481 type_arr
.sort(reverse
=True, key
=lambda x
: x
.GetNumberOfFields())
482 if len(type_arr
) > 0:
483 tmp_type
= type_arr
[0]
485 raise NameError('Unable to find type '+target_type
)
487 if not tmp_type
.IsValid():
488 raise NameError('Unable to Cast to type '+target_type
)
490 if requested_type_is_pointer
:
491 tmp_type
= tmp_type
.GetPointerType()
492 _value_types_cache
[target_type
] = tmp_type
494 return _value_types_cache
[target_type
]
497 def getfieldoffset(struct_type
, field_name
):
498 """ Returns the byte offset of a field inside a given struct
499 Understands anonymous unions and field names in sub-structs
501 struct_type - str or lldb.SBType, ex. 'struct ipc_port *' or port.gettype()
502 field_name - str, name of the field inside the struct ex. 'ip_messages'
504 int - byte offset of the field_name inside the struct_type
506 TypeError - - In case the struct_type has no field with the name field_name
509 if type(struct_type
) == str:
510 struct_type
= gettype(struct_type
)
512 if '.' in field_name
:
513 # Handle recursive fields in sub-structs
514 components
= field_name
.split('.', 1)
515 for field
in struct_type
.get_fields_array():
516 if str(field
.GetName()) == components
[0]:
517 return getfieldoffset(struct_type
, components
[0]) + getfieldoffset(field
.GetType(), components
[1])
518 raise TypeError('Field name "%s" not found in type "%s"' % (components
[0], str(struct_type
)))
521 for field
in struct_type
.get_fields_array():
522 if str(field
.GetName()) == field_name
:
523 return field
.GetOffsetInBytes()
525 # Hack for anonymous unions - the compiler does this, so cvalue should too
526 if field
.GetName() is None and field
.GetType().GetTypeClass() == lldb
.eTypeClassUnion
:
527 for union_field
in field
.GetType().get_fields_array():
528 if str(union_field
.GetName()) == field_name
:
529 return union_field
.GetOffsetInBytes() + field
.GetOffsetInBytes()
530 raise TypeError('Field name "%s" not found in type "%s"' % (field_name
, str(struct_type
)))
533 """ Returns True if a string represents a long integer, False otherwise
545 """ Returns a string of hex data that is referenced by the value.
546 params: val - a value object.
547 return: str - string of hex bytes.
548 raises: TypeError if val is not a valid type
550 if not type(val
) is value
:
551 raise TypeError('%s is not of type value' % str(type(val
)))
552 return val
.__getstate
__()
554 def getOSPtr(cpp_obj
):
555 """ Returns a core.value created from an intrusive_shared_ptr or itself, cpp_obj
556 params: cpp_obj - core.value object representing a C construct in lldb
557 return: core.value - newly created core.value or cpp_obj
559 child
= cpp_obj
._sbval
19k
84obscure
747.GetChildAtIndex(0)
560 if 'intrusive_shared_ptr' in str(child
):
561 return value(child
.GetChildMemberWithName('ptr_'))