X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/5ba3f43ea354af8ad55bea84372a2bc834d8757c..HEAD:/tools/lldbmacros/core/cvalue.py?ds=inline diff --git a/tools/lldbmacros/core/cvalue.py b/tools/lldbmacros/core/cvalue.py index 0941f7530..84641c9b9 100755 --- a/tools/lldbmacros/core/cvalue.py +++ b/tools/lldbmacros/core/cvalue.py @@ -1,9 +1,9 @@ """ Defines a class value which encapsulates the basic lldb Scripting Bridge APIs. This provides an easy -wrapper to extract information from C based constructs. +wrapper to extract information from C based constructs. |------- core.value------------| | |--lldb Scripting Bridge--| | - | | |--lldb core--| | | + | | |--lldb core--| | | | |-------------------------| | |------------------------------| Use the member function GetSBValue() to access the base Scripting Bridge value. @@ -19,7 +19,7 @@ class value(object): can be used as a variable would be in code. So if you have a Point structure variable in your code in the current frame named "pt", you can initialize an instance of this class with it: - + pt = lldb.value(lldb.frame.FindVariable("pt")) print pt print pt.x @@ -29,7 +29,7 @@ class value(object): print rectangle_array[12] print rectangle_array[5].origin.x''' def __init__(self, sbvalue): - #_sbval19k84obscure747 is specifically chosen to be obscure. + #_sbval19k84obscure747 is specifically chosen to be obscure. #This avoids conflicts when attributes could mean any field value in code self._sbval19k84obscure747 = sbvalue self._sbval19k84obscure747_type = sbvalue.GetType() @@ -41,7 +41,7 @@ class value(object): def __repr__(self): return self._sbval19k84obscure747.__str__() - + def __cmp__(self, other): if type(other) is int or type(other) is long: me = int(self) @@ -49,9 +49,12 @@ class value(object): other = long(other) return me.__cmp__(other) if type(other) is value: - return int(self).__cmp__(int(other)) + try: + return int(self).__cmp__(int(other)) + except TypeError: # Try promoting to long + return long(self).__cmp__(long(other)) raise TypeError("Cannot compare value with type {}".format(type(other))) - + def __str__(self): global _cstring_rex type_name = self._sbval19k84obscure747_type.GetName() @@ -89,152 +92,152 @@ class value(object): def __add__(self, other): return int(self) + int(other) - + def __radd__(self, other): return int(self) + int(other) - + def __sub__(self, other): return int(self) - int(other) - + def __rsub__(self, other): return int(other) - int(self) - + def __mul__(self, other): return int(self) * int(other) - + def __rmul__(self, other): return int(self) * int(other) - + def __floordiv__(self, other): return int(self) // int(other) - + def __mod__(self, other): return int(self) % int(other) - + def __rmod__(self, other): return int(other) % int(self) - + def __divmod__(self, other): return int(self) % int(other) - + def __rdivmod__(self, other): return int(other) % int(self) - + def __pow__(self, other): return int(self) ** int(other) - + def __lshift__(self, other): return int(self) << int(other) - + def __rshift__(self, other): return int(self) >> int(other) - + def __and__(self, other): return int(self) & int(other) - + def __rand(self, other): return int(self) & int(other) - + def __xor__(self, other): return int(self) ^ int(other) - + def __or__(self, other): return int(self) | int(other) - + def __div__(self, other): return int(self) / int(other) - + def __rdiv__(self, other): return int(other)/int(self) - + def __truediv__(self, other): return int(self) / int(other) - + def __iadd__(self, other): result = self.__add__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __isub__(self, other): result = self.__sub__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __imul__(self, other): result = self.__mul__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __idiv__(self, other): result = self.__div__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __itruediv__(self, other): result = self.__truediv__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ifloordiv__(self, other): result = self.__floordiv__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __imod__(self, other): result = self.__and__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ipow__(self, other): result = self.__pow__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ipow__(self, other, modulo): result = self.__pow__(self, other, modulo) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ilshift__(self, other): result = self.__lshift__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __irshift__(self, other): result = self.__rshift__(other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __iand__(self, other): result = self.__and__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ixor__(self, other): result = self.__xor__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __ior__(self, other): result = self.__ior__(self, other) self._sbval19k84obscure747.SetValueFromCString (str(result)) return result - + def __neg__(self): return -int(self) - + def __pos__(self): return +int(self) - + def __abs__(self): return abs(int(self)) - + def __invert__(self): return ~int(self) - + def __complex__(self): return complex (int(self)) - + def __int__(self): if self._sbval19k84obscure747_is_ptr: return self._GetValueAsUnsigned() @@ -246,76 +249,84 @@ class value(object): if (retval & 0x80000000): retval = retval - 0x100000000 return retval - + def __long__(self): return self._sbval19k84obscure747.GetValueAsSigned() - + def __float__(self): return float (self._sbval19k84obscure747.GetValueAsSigned()) - + def __oct__(self): return '0%o' % self._GetValueAsUnsigned() - + def __hex__(self): return '0x%x' % self._GetValueAsUnsigned() def __eq__(self, other): - self_err = lldb.SBError() - other_err = lldb.SBError() - self_val = self._sbval19k84obscure747.GetValueAsUnsigned(self_err) - if self_err.fail: - raise ValueError("unable to extract value of self") + self_val = self._GetValueAsUnsigned() if type(other) is value: - other_val = other._sbval19k84obscure747.GetValueAsUnsigned(other_err) - if other_err.fail: - raise ValueError("unable to extract value of other") + other_val = other._GetValueAsUnsigned() return self_val == other_val if type(other) is int: return int(self) == other raise TypeError("Equality operation is not defined for this type.") - + def __neq__(self, other): return not self.__eq__(other) - + def GetSBValue(self): return self._sbval19k84obscure747 - + def __getstate__(self): err = lldb.SBError() if self._sbval19k84obscure747_is_ptr: - addr = self._sbval19k84obscure747.GetValueAsUnsigned() + addr = self._sbval19k84obscure747.GetValueAsAddress() size = self._sbval19k84obscure747_type.GetPointeeType().GetByteSize() else: - addr = self._sbval19k84obscure747.AddressOf().GetValueAsUnsigned() + addr = self._sbval19k84obscure747.AddressOf().GetValueAsAddress() size = self._sbval19k84obscure747_type.GetByteSize() - + content = LazyTarget.GetProcess().ReadMemory(addr, size, err) if err.fail: content = '' return content def _GetValueAsSigned(self): + if self._sbval19k84obscure747_is_ptr: + print "ERROR: You cannot get 'int' from pointer type %s, please use unsigned(obj) for such purposes." % str(self._sbval19k84obscure747_type) + raise ValueError("Cannot get signed int for pointer data.") serr = lldb.SBError() retval = self._sbval19k84obscure747.GetValueAsSigned(serr) if serr.success: return retval raise ValueError("Failed to read signed data. "+ str(self._sbval19k84obscure747) +"(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) - + + def _GetValueAsCast(self, dest_type): + if type(dest_type) is not lldb.SBType: + raise ValueError("Invalid type for dest_type: {}".format(type(dest_type))) + addr = self._GetValueAsUnsigned() + sbval = self._sbval19k84obscure747.target.CreateValueFromExpression("newname", "(void *)"+str(addr)) + val = value(sbval.Cast(dest_type)) + return val + def _GetValueAsUnsigned(self): serr = lldb.SBError() - retval = self._sbval19k84obscure747.GetValueAsUnsigned(serr) + if self._sbval19k84obscure747_is_ptr: + retval = self._sbval19k84obscure747.GetValueAsAddress() + else: + retval = self._sbval19k84obscure747.GetValueAsUnsigned(serr) if serr.success: return retval raise ValueError("Failed to read unsigned data. "+ str(self._sbval19k84obscure747) +"(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString()) - + def _GetValueAsString(self, offset = 0, maxlen = 1024): serr = lldb.SBError() sbdata = None - if self._sbval19k84obscure747.TypeIsPointerType(): + if self._sbval19k84obscure747_is_ptr: sbdata = self._sbval19k84obscure747.GetPointeeData(offset, maxlen) else: sbdata = self._sbval19k84obscure747.GetData() - + retval = '' bytesize = sbdata.GetByteSize() if bytesize == 0 : @@ -329,8 +340,8 @@ class value(object): if ch == '\0': break retval += ch - return retval - + return retval + def __format__(self, format_spec): ret_format = "{0:"+format_spec+"}" # typechar is last char. see http://www.python.org/dev/peps/pep-3101/ @@ -345,14 +356,14 @@ class value(object): return ret_format.format(int(oct(self))) if type_spec == 'c': return ret_format.format(int(self)) - + return "unknown format " + format_spec + str(self) - - + + def unsigned(val): """ Helper function to get unsigned value from core.value params: val - value (see value class above) representation of an integer type - returns: int which is unsigned. + returns: int which is unsigned. raises : ValueError if the type cannot be represented as unsigned int. """ if type(val) is value: @@ -360,18 +371,18 @@ def unsigned(val): return int(val) def sizeof(t): - """ Find the byte size of a type. + """ Find the byte size of a type. params: t - str : ex 'time_spec' returns equivalent of sizeof(time_spec) in C t - value: ex a value object. returns size of the object - returns: int - byte size length + returns: int - byte size length """ if type(t) is value : return t.GetSBValue().GetByteSize() if type(t) is str: return gettype(t).GetByteSize() raise ValueError("Cannot get sizeof. Invalid argument") - - + + def dereference(val): """ Get a dereferenced obj for a pointer type obj params: val - value object representing a pointer type C construct in lldb @@ -381,15 +392,15 @@ def dereference(val): obj_ptr = (int *)0x1234 #C val = *obj_ptr #C """ - if type(val) is value and val.GetSBValue().TypeIsPointerType(): + if type(val) is value and val._sbval19k84obscure747_is_ptr: return value(val.GetSBValue().Dereference()) raise TypeError('Cannot dereference this type.') - + def addressof(val): - """ Get address of a core.value object. + """ Get address of a core.value object. params: val - value object representing a C construct in lldb returns: value - value object referring to 'type(val) *' type - ex. addr = addressof(hello_obj) #python + ex. addr = addressof(hello_obj) #python is same as uintptr_t addr = (uintptr_t)&hello_obj #C """ @@ -410,12 +421,24 @@ def cast(obj, target_type): elif type(target_type) is value: dest_type = target_type.GetSBValue().GetType() - if type(obj) is value : - return value(obj.GetSBValue().Cast(dest_type)) + if type(obj) is value: + return obj._GetValueAsCast(dest_type) elif type(obj) is int: - print "ERROR: You cannot cast an 'int' to %s, please use kern.GetValueFromAddress() for such purposes." % str(target_type) + 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))) +def containerof(obj, target_type, field_name): + """ Type cast an object to another C type from a pointer to a field. + params: + obj - core.value object representing some C construct in lldb + target_type - str : ex 'struct thread' + - lldb.SBType : + field_name - the field name within the target_type obj is a pointer to + """ + addr = int(obj) - getfieldoffset(target_type, field_name) + obj = value(obj.GetSBValue().CreateValueFromExpression(None,'(void *)'+str(addr))) + return cast(obj, target_type + " *") + _value_types_cache={} @@ -520,10 +543,20 @@ def islong(x): 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. + 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__() + +def getOSPtr(cpp_obj): + """ Returns a core.value created from an intrusive_shared_ptr or itself, cpp_obj + params: cpp_obj - core.value object representing a C construct in lldb + return: core.value - newly created core.value or cpp_obj + """ + child = cpp_obj._sbval19k84obscure747.GetChildAtIndex(0) + if 'intrusive_shared_ptr' in str(child): + return value(child.GetChildMemberWithName('ptr_')) + return cpp_obj