return self._sbval19k84obscure747.__str__()
def __cmp__(self, other):
- if type(other) is int:
+ if type(other) is int or type(other) is long:
me = int(self)
if type(me) is long:
other = long(other)
return me.__cmp__(other)
if type(other) is value:
return int(self).__cmp__(int(other))
- raise TypeError("Cannot compare value with this type")
+ raise TypeError("Cannot compare value with type {}".format(type(other)))
def __str__(self):
global _cstring_rex
def GetSBValue(self):
return self._sbval19k84obscure747
+ def __getstate__(self):
+ err = lldb.SBError()
+ if self._sbval19k84obscure747_is_ptr:
+ addr = self._sbval19k84obscure747.GetValueAsUnsigned()
+ size = self._sbval19k84obscure747_type.GetPointeeType().GetByteSize()
+ else:
+ addr = self._sbval19k84obscure747.AddressOf().GetValueAsUnsigned()
+ size = self._sbval19k84obscure747_type.GetByteSize()
+
+ content = LazyTarget.GetProcess().ReadMemory(addr, size, err)
+ if err.fail:
+ content = ''
+ return content
+
def _GetValueAsSigned(self):
serr = lldb.SBError()
retval = self._sbval19k84obscure747.GetValueAsSigned(serr)
print "ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type)
raise TypeError("object of type %s cannot be casted to %s" % (str(type(obj)), str(target_type)))
+
_value_types_cache={}
def gettype(target_type):
NameError - Incase the type is not identified
"""
global _value_types_cache
- # LLDB Somehow does not support finding types for 'struct pmap' while 'pmap' works fine
- # <rdar://problem/12473003>
- target_type = target_type.replace('struct', '')
target_type = str(target_type).strip()
- if target_type not in _value_types_cache:
- tmp_type = None
- if target_type.endswith('*') :
- tmp_type = LazyTarget.GetTarget().FindFirstType(target_type.rstrip('*').strip())
- if not tmp_type.IsValid():
- raise NameError('Unable to Cast to type '+target_type)
- tmp_type = tmp_type.GetPointerType()
- else :
- tmp_type = LazyTarget.GetTarget().FindFirstType(target_type)
- if not tmp_type.IsValid():
- raise NameError('Unable to Cast to type '+target_type)
- _value_types_cache[target_type] = tmp_type
+ if target_type in _value_types_cache:
+ return _value_types_cache[target_type]
+
+ target_type = target_type.strip()
+
+ requested_type_is_struct = False
+ m = re.match(r'\s*struct\s*(.*)$', target_type)
+ if m:
+ requested_type_is_struct = True
+ target_type = m.group(1)
+
+ tmp_type = None
+ requested_type_is_pointer = False
+ if target_type.endswith('*') :
+ requested_type_is_pointer = True
+
+ # tmp_type = LazyTarget.GetTarget().FindFirstType(target_type.rstrip('*').strip())
+ search_type = target_type.rstrip('*').strip()
+ type_arr = [t for t in LazyTarget.GetTarget().FindTypes(search_type)]
+
+ if requested_type_is_struct:
+ type_arr = [t for t in type_arr if t.type == lldb.eTypeClassStruct]
+
+ # After the sort, the struct type with more fields will be at index [0].
+ # This hueristic helps selecting struct type with more fields compared to ones with "opaque" members
+ type_arr.sort(reverse=True, key=lambda x: x.GetNumberOfFields())
+ if len(type_arr) > 0:
+ tmp_type = type_arr[0]
+ else:
+ raise NameError('Unable to find type '+target_type)
+
+ if not tmp_type.IsValid():
+ raise NameError('Unable to Cast to type '+target_type)
+
+ if requested_type_is_pointer:
+ tmp_type = tmp_type.GetPointerType()
+ _value_types_cache[target_type] = tmp_type
+
return _value_types_cache[target_type]
+
def getfieldoffset(struct_type, field_name):
""" Returns the byte offset of a field inside a given struct
+ Understands anonymous unions and field names in sub-structs
params:
struct_type - str or lldb.SBType, ex. 'struct ipc_port *' or port.gettype()
field_name - str, name of the field inside the struct ex. 'ip_messages'
raises:
TypeError - - In case the struct_type has no field with the name field_name
"""
+
if type(struct_type) == str:
struct_type = gettype(struct_type)
+
+ if '.' in field_name :
+ # Handle recursive fields in sub-structs
+ components = field_name.split('.', 1)
+ for field in struct_type.get_fields_array():
+ if str(field.GetName()) == components[0]:
+ return getfieldoffset(struct_type, components[0]) + getfieldoffset(field.GetType(), components[1])
+ raise TypeError('Field name "%s" not found in type "%s"' % (components[0], str(struct_type)))
+
offset = 0
for field in struct_type.get_fields_array():
if str(field.GetName()) == field_name:
return field.GetOffsetInBytes()
+
+ # Hack for anonymous unions - the compiler does this, so cvalue should too
+ if field.GetName() is None and field.GetType().GetTypeClass() == lldb.eTypeClassUnion :
+ for union_field in field.GetType().get_fields_array():
+ if str(union_field.GetName()) == field_name:
+ return union_field.GetOffsetInBytes() + field.GetOffsetInBytes()
raise TypeError('Field name "%s" not found in type "%s"' % (field_name, str(struct_type)))
def islong(x):
except ValueError:
return False
return True
+
+def readmemory(val):
+ """ Returns a string of hex data that is referenced by the value.
+ params: val - a value object.
+ return: str - string of hex bytes.
+ raises: TypeError if val is not a valid type
+ """
+ if not type(val) is value:
+ raise TypeError('%s is not of type value' % str(type(val)))
+ return val.__getstate__()