diff options
Diffstat (limited to 'lldb/examples/summaries')
19 files changed, 594 insertions, 750 deletions
diff --git a/lldb/examples/summaries/cocoa/CFArray.py b/lldb/examples/summaries/cocoa/CFArray.py index 4545a1b2370..0721e76b9f8 100644 --- a/lldb/examples/summaries/cocoa/CFArray.py +++ b/lldb/examples/summaries/cocoa/CFArray.py @@ -16,17 +16,14 @@ statistics.add_metric('code_notrun') class NSArrayKVC_SynthProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj, dict): + def __init__(self, valobj, dict, params): self.valobj = valobj; self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def num_children(self): stream = lldb.SBStream() @@ -34,199 +31,78 @@ class NSArrayKVC_SynthProvider: num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]"); return num_children_vo.GetValueAsUnsigned(0) - def get_child_index(self,name): - if name == "len": - return self.num_children(); - else: - return None - - def get_child_at_index(self, index): - return None - - - # much less functional than the other two cases below # just runs code to get to the count and then returns # no children class NSArrayCF_SynthProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() - self.cfruntime_size = self.size_of_cfruntime_base() - - # CFRuntimeBase is defined as having an additional - # 4 bytes (padding?) on LP64 architectures - # to get its size we add up sizeof(pointer)+4 - # and then add 4 more bytes if we are on a 64bit system - def size_of_cfruntime_base(self): - if self.is_64_bit == True: - return 8+4+4; - else: - return 4+4; + pass - def __init__(self, valobj, dict): + def __init__(self, valobj, dict, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.ulong): + self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def num_children(self): num_children_vo = self.valobj.CreateChildAtOffset("count", - self.cfruntime_size, - self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)) + self.sys_params.cfruntime_size, + self.sys_params.types_cache.ulong) return num_children_vo.GetValueAsUnsigned(0) - def get_child_index(self,name): - if name == "len": - return self.num_children(); - else: - return None - - def get_child_at_index(self, index): - return None - - class NSArrayI_SynthProvider: - def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj, dict): + def __init__(self, valobj, dict, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.long): + self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) # skip the isa pointer and get at the size def num_children(self): - offset = self.pointer_size; - datatype = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) count = self.valobj.CreateChildAtOffset("count", - offset, - datatype); - return int(count.GetValue(), 0) - - def get_child_index(self,name): - if name == "len": - return self.num_children(); - else: - return int(name.lstrip('[').rstrip(']'), 0) - - def get_child_at_index(self, index): - if index == self.num_children(): - return self.valobj.CreateValueFromExpression("len", - str(index)) - offset = 2 * self.pointer_size + self.id_type.GetByteSize()*index - return self.valobj.CreateChildAtOffset('[' + str(index) + ']', - offset, - self.id_type) - + self.sys_params.pointer_size, + self.sys_params.types_cache.long); + return count.GetValueAsUnsigned(0) class NSArrayM_SynthProvider: - def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj, dict): + def __init__(self, valobj, dict, params): self.valobj = valobj; - self.update(); + self.sys_params = params + if not(self.sys_params.types_cache.long): + self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) + self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) # skip the isa pointer and get at the size def num_children(self): - offset = self.pointer_size; - datatype = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) count = self.valobj.CreateChildAtOffset("count", - offset, - datatype); - return int(count.GetValue(), 0) - - def get_child_index(self,name): - if name == "len": - return self.num_children(); - else: - return int(name.lstrip('[').rstrip(']'), 0) - - def data_offset(self): - offset = self.pointer_size; # isa - offset += self.pointer_size; # _used - offset += self.pointer_size; # _doHardRetain, _doWeakAccess, _size - offset += self.pointer_size; # _hasObjects, _hasStrongReferences, _offset - offset += self.pointer_size; # _mutations - return offset; - - # the _offset field is used to calculate the actual offset - # when reading a value out of the array. we need to read it - # to do so we read a whole pointer_size of data from the - # right spot, and then zero out the two LSB - def read_offset_field(self): - disp = self.pointer_size; # isa - disp += self.pointer_size; # _used - disp += self.pointer_size; # _doHardRetain, _doWeakAccess, _size - offset = self.valobj.CreateChildAtOffset("offset", - disp, - self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)) - offset_value = int(offset.GetValue(), 0) - offset_value = ctypes.c_uint32((offset_value & 0xFFFFFFFC) >> 2).value - return offset_value - - # the _used field tells how many items are in the array - # but since this is a mutable array, it allocates more space - # for performance reasons. we need to get the real _size of - # the array to calculate the actual offset of each element - # in get_child_at_index() (see NSArray.m for details) - def read_size_field(self): - disp = self.pointer_size; # isa - disp += self.pointer_size; # _used - size = self.valobj.CreateChildAtOffset("size", - disp, - self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)) - size_value = int(size.GetValue(), 0) - size_value = ctypes.c_uint32((size_value & 0xFFFFFFFA) >> 2).value - return size_value - - def get_child_at_index(self, index): - if index == self.num_children(): - return self.valobj.CreateValueFromExpression("len", - str(index)) - size = self.read_size_field() - offset = self.read_offset_field() - phys_idx = offset + index - if size <= phys_idx: - phys_idx -=size; - # we still need to multiply by element size to do a correct pointer read - phys_idx *= self.id_type.GetByteSize() - list_ptr = self.valobj.CreateChildAtOffset("_list", - self.data_offset(), - self.id_type.GetBasicType(lldb.eBasicTypeUnsignedLongLong)) - list_addr = int(list_ptr.GetValue(), 0) - return self.valobj.CreateValueFromAddress('[' + str(index) + ']', - list_addr + phys_idx, - self.id_type) + self.sys_params.pointer_size, + self.sys_params.types_cache.long); + return count.GetValueAsUnsigned(0) # this is the actual synth provider, but is just a wrapper that checks # whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an # appropriate backend layer to do the computations class NSArray_SynthProvider: - def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) + pass def __init__(self, valobj, dict): self.valobj = valobj; @@ -234,16 +110,6 @@ class NSArray_SynthProvider: self.wrapper = self.make_wrapper(valobj,dict) self.invalid = (self.wrapper == None) - def get_child_at_index(self, index): - if self.wrapper == None: - return None; - return self.wrapper.get_child_at_index(index) - - def get_child_index(self,name): - if self.wrapper == None: - return None; - return self.wrapper.get_child_index(name) - def num_children(self): if self.wrapper == None: return 0; @@ -251,23 +117,8 @@ class NSArray_SynthProvider: def update(self): if self.wrapper == None: - return None; - return self.wrapper.update() - - def read_ascii(self, pointer): - process = self.valobj.GetTarget().GetProcess() - error = lldb.SBError() - pystr = '' - # cannot do the read at once because there is no length byte - while True: - content = process.ReadMemory(pointer, 1, error) - new_bytes = bytearray(content) - b0 = new_bytes[0] - pointer = pointer + 1 - if b0 == 0: - break - pystr = pystr + chr(b0) - return pystr + return + self.wrapper.update() # this code acts as our defense against NULL and unitialized # NSArray pointers, which makes it much longer than it would be otherwise @@ -292,16 +143,16 @@ class NSArray_SynthProvider: name_string = class_data.class_name() if name_string == '__NSArrayI': - wrapper = NSArrayI_SynthProvider(valobj, dict) + wrapper = NSArrayI_SynthProvider(valobj, dict, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSArrayM': - wrapper = NSArrayM_SynthProvider(valobj, dict) + wrapper = NSArrayM_SynthProvider(valobj, dict, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSCFArray': - wrapper = NSArrayCF_SynthProvider(valobj, dict) + wrapper = NSArrayCF_SynthProvider(valobj, dict, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSArrayKVC_SynthProvider(valobj, dict) + wrapper = NSArrayKVC_SynthProvider(valobj, dict, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/CFBag.py b/lldb/examples/summaries/cocoa/CFBag.py index 1403a122eb6..2db70ab603c 100644 --- a/lldb/examples/summaries/cocoa/CFBag.py +++ b/lldb/examples/summaries/cocoa/CFBag.py @@ -15,27 +15,26 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class CFBagRef_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # 12 bytes on i386 # 20 bytes on x64 # most probably 2 pointers and 4 bytes of data def offset(self): - if self.is_64_bit: + if self.sys_params.is_64_bit: return 20 else: return 12 @@ -43,23 +42,21 @@ class CFBagRef_SummaryProvider: def length(self): size = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return size.GetValueAsUnsigned(0) class CFBagUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def length(self): stream = lldb.SBStream() @@ -98,10 +95,10 @@ def GetSummary_Impl(valobj): actual_name = pointee_type.GetName() if actual_name == '__CFBag' or \ actual_name == 'const struct __CFBag': - wrapper = CFBagRef_SummaryProvider(valobj) + wrapper = CFBagRef_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) return wrapper - wrapper = CFBagUnknown_SummaryProvider(valobj) + wrapper = CFBagUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + actual_name) return wrapper; @@ -120,7 +117,7 @@ def CFBag_SummaryProvider (valobj,dict): if summary == None: summary = 'no valid set here' else: - if provider.is_64_bit: + if provider.sys_params.is_64_bit: summary = summary & ~0x1fff000000000000 if summary == 1: return '1 item' diff --git a/lldb/examples/summaries/cocoa/CFBinaryHeap.py b/lldb/examples/summaries/cocoa/CFBinaryHeap.py index 0a120745c3c..160389eae4e 100644 --- a/lldb/examples/summaries/cocoa/CFBinaryHeap.py +++ b/lldb/examples/summaries/cocoa/CFBinaryHeap.py @@ -15,51 +15,45 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class CFBinaryHeapRef_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # 8 bytes on i386 # 16 bytes on x64 # most probably 2 pointers def offset(self): - if self.is_64_bit: - return 16 - else: - return 8 + return 2 * self.sys_params.pointer_size def length(self): size = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return size.GetValueAsUnsigned(0) class CFBinaryHeapUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def length(self): stream = lldb.SBStream() @@ -95,10 +89,10 @@ def GetSummary_Impl(valobj): if valobj_type.IsValid() and valobj_type.IsPointerType(): pointee_type = valobj_type.GetPointeeType() if pointee_type.GetName() == '__CFBinaryHeap': - wrapper = CFBinaryHeapRef_SummaryProvider(valobj) + wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) return wrapper - wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj) + wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; @@ -117,7 +111,7 @@ def CFBinaryHeap_SummaryProvider (valobj,dict): if summary == None: summary = 'no valid set here' else: - if provider.is_64_bit: + if provider.sys_params.is_64_bit: summary = summary & ~0x1fff000000000000 if summary == 1: return '1 item' diff --git a/lldb/examples/summaries/cocoa/CFBitVector.py b/lldb/examples/summaries/cocoa/CFBitVector.py index a469ed407f7..7cd83fe6cb4 100644 --- a/lldb/examples/summaries/cocoa/CFBitVector.py +++ b/lldb/examples/summaries/cocoa/CFBitVector.py @@ -30,25 +30,23 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class CFBitVectorKnown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = self.sys_params.is_64_bit - self.is_little = self.sys_params.is_little - self.pointer_size = self.sys_params.pointer_size - self.cfruntime_size = 16 if self.is_64_bit else 8 + self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize() + pass def __init__(self, valobj, params): self.valobj = valobj; self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) + if not(self.sys_params.types_cache.charptr): + self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType() self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) - self.charptr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType() - self.uiint_size = self.NSUInteger.GetByteSize() # we skip the CFRuntimeBase # then the next CFIndex is the count @@ -56,15 +54,15 @@ class CFBitVectorKnown_SummaryProvider: # that wraps the individual bits def contents(self): - count_vo = self.valobj.CreateChildAtOffset("count",self.cfruntime_size, - self.NSUInteger) + count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size, + self.sys_params.types_cache.NSUInteger) count = count_vo.GetValueAsUnsigned(0) if count == 0: return '(empty)' array_vo = self.valobj.CreateChildAtOffset("data", - self.cfruntime_size+2*self.uiint_size, - self.charptr_type) + self.sys_params.cfruntime_size+2*self.uiint_size, + self.sys_params.types_cache.charptr) data_list = [] cur_byte_pos = None @@ -92,17 +90,15 @@ class CFBitVectorKnown_SummaryProvider: class CFBitVectorUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def contents(self): return '*** unknown class *** very bad thing *** find out my name ***' @@ -141,7 +137,7 @@ def GetSummary_Impl(valobj): wrapper = CFBitVectorUnknown_SummaryProvider(valobj) print pointee_type.GetName() else: - wrapper = CFBitVectorUnknown_SummaryProvider(valobj) + wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params) print name_string statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/CFDictionary.py b/lldb/examples/summaries/cocoa/CFDictionary.py index 5bd9e690b36..e2f6bdd51e6 100644 --- a/lldb/examples/summaries/cocoa/CFDictionary.py +++ b/lldb/examples/summaries/cocoa/CFDictionary.py @@ -15,28 +15,27 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSCFDictionary_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # empirically determined on both 32 and 64bit desktop Mac OS X # probably boils down to 2 pointers and 4 bytes of data, but # the description of __CFDictionary is not readily available so most # of this is guesswork, plain and simple def offset(self): - if self.is_64_bit: + if self.sys_params.is_64_bit: return 20 else: return 12 @@ -44,45 +43,41 @@ class NSCFDictionary_SummaryProvider: def num_children(self): num_children_vo = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return num_children_vo.GetValueAsUnsigned(0) class NSDictionaryI_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # we just need to skip the ISA and the count immediately follows def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def num_children(self): num_children_vo = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) value = num_children_vo.GetValueAsUnsigned(0) if value != None: # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity # not sure if it is a bug or some weird sort of feature, but masking that out # gets the count right - if self.is_64_bit: + if self.sys_params.is_64_bit: value = value & ~0xFC00000000000000 else: value = value & ~0xFC000000 @@ -90,58 +85,51 @@ class NSDictionaryI_SummaryProvider: class NSDictionaryM_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # we just need to skip the ISA and the count immediately follows def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def num_children(self): num_children_vo = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) value = num_children_vo.GetValueAsUnsigned(0) if value != None: - # the MS6bits on mutable dictionaries seem to be taken by flags for - # KVO and probably other features. however, masking it out does get - # the count right - if self.is_64_bit: + # the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity + # not sure if it is a bug or some weird sort of feature, but masking that out + # gets the count right + if self.sys_params.is_64_bit: value = value & ~0xFC00000000000000 else: value = value & ~0xFC000000 return value - class NSDictionaryUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def num_children(self): stream = lldb.SBStream() @@ -171,16 +159,16 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == '__NSCFDictionary': - wrapper = NSCFDictionary_SummaryProvider(valobj) + wrapper = NSCFDictionary_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSDictionaryI': - wrapper = NSDictionaryI_SummaryProvider(valobj) + wrapper = NSDictionaryI_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSDictionaryM': - wrapper = NSDictionaryM_SummaryProvider(valobj) + wrapper = NSDictionaryM_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSDictionaryUnknown_SummaryProvider(valobj) + wrapper = NSDictionaryUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; @@ -200,14 +188,14 @@ def CFDictionary_SummaryProvider2 (valobj,dict): provider = GetSummary_Impl(valobj); if provider != None: try: - summary = (provider.num_children()); + summary = provider.num_children(); except: summary = None if summary == None: summary = 'no valid dictionary here' # needed on OSX Mountain Lion - elif provider.is_64_bit: - summary = int(summary) & ~0x0f1f000000000000 + elif provider.sys_params.is_64_bit: + summary = summary & ~0x0f1f000000000000 return str(summary) + " key/value pairs" return '' diff --git a/lldb/examples/summaries/cocoa/CFString.py b/lldb/examples/summaries/cocoa/CFString.py index c954ae4d0de..ad2a1e4d6ba 100644 --- a/lldb/examples/summaries/cocoa/CFString.py +++ b/lldb/examples/summaries/cocoa/CFString.py @@ -102,10 +102,7 @@ class CFStringSynthProvider: return self.handle_unicode_string_safe(); else: # a full pointer is skipped here before getting to the live data - if self.is_64_bit == False: - pointer = pointer + 4 - else: - pointer = pointer + 8; + pointer = pointer + self.pointer_size else: pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base(); # read 8 bytes here and make an address out of them @@ -123,19 +120,13 @@ class CFStringSynthProvider: "(char*)\"" + pystr.encode('utf-8') + "\"") def handle_inline_explicit(self): - if self.is_64_bit: - offset = 24 - else: - offset = 12 + offset = 3*self.pointer_size offset = offset + self.valobj.GetValueAsUnsigned(0) return self.valobj.CreateValueFromExpression("content", "(char*)(" + str(offset) + ")") def handle_mutable_string(self): - if self.is_64_bit: - offset = 16 - else: - offset = 8 + offset = 2 * self.pointer_size data = self.valobj.CreateChildAtOffset("content", offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()); data_value = data.GetValueAsUnsigned(0) @@ -208,21 +199,12 @@ class CFStringSynthProvider: if name == "special": return 4; - def is_64bit(self): - return self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8 - - def is_little_endian(self): - return self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle - # CFRuntimeBase is defined as having an additional # 4 bytes (padding?) on LP64 architectures # to get its size we add up sizeof(pointer)+4 # and then add 4 more bytes if we are on a 64bit system def size_of_cfruntime_base(self): - if self.is_64_bit == True: - return 8+4+4; - else: - return 4+4; + return self.pointer_size+4+(4 if self.is_64_bit else 0) # the info bits are part of the CFRuntimeBase structure # to get at them we have to skip a uintptr_t and then get @@ -230,10 +212,7 @@ class CFStringSynthProvider: # on big-endian this means going to byte 3, if we are on # little endian (OSX & iOS), this means reading byte 0 def offset_of_info_bits(self): - if self.is_64_bit == True: - offset = 8; - else: - offset = 4; + offset = self.pointer_size if self.is_little == False: offset = offset + 3; return offset; @@ -278,8 +257,9 @@ class CFStringSynthProvider: # preparing ourselves to read into memory # by adjusting architecture-specific info def adjust_for_architecture(self): - self.is_64_bit = self.is_64bit(); - self.is_little = self.is_little_endian(); + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + self.is_64_bit = self.pointer_size == 8 + self.is_little = self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle # reading info bits out of the CFString and computing # useful values to get at the real data diff --git a/lldb/examples/summaries/cocoa/NSBundle.py b/lldb/examples/summaries/cocoa/NSBundle.py index cb748f5217f..b38b027a35a 100644 --- a/lldb/examples/summaries/cocoa/NSBundle.py +++ b/lldb/examples/summaries/cocoa/NSBundle.py @@ -16,41 +16,33 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSBundleKnown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSString): + self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType() self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.pointer_size = 8 - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) - self.pointer_size = 4 - self.NSString = self.valobj.GetTarget().FindFirstType('NSString') - self.NSURL = self.valobj.GetTarget().FindFirstType('NSURL') # we need to skip the ISA, plus four other values # that are luckily each a pointer in size # which makes our computation trivial :-) def offset(self): - return 5 * self.pointer_size + return 5 * self.sys_params.pointer_size def url_text(self): global statistics text = self.valobj.CreateChildAtOffset("text", self.offset(), - self.NSString.GetPointerType()) + self.sys_params.types_cache.NSString) my_string = text.GetSummary() if (my_string == None) or (my_string == ''): statistics.metric_hit('unknown_class',str(self.valobj) + " triggered unkown pointer location") - return NSBundleUnknown_SummaryProvider(self.valobj).url_text() + return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text() else: statistics.metric_hit('code_notrun',self.valobj) return my_string @@ -58,17 +50,15 @@ class NSBundleKnown_SummaryProvider: class NSBundleUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def url_text(self): stream = lldb.SBStream() @@ -99,13 +89,13 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSBundle': - wrapper = NSBundleKnown_SummaryProvider(valobj) + wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params) # [NSBundle mainBundle] does return an object that is # not correctly filled out for our purposes, so we still # end up having to run code in that case #statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSBundleUnknown_SummaryProvider(valobj) + wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSData.py b/lldb/examples/summaries/cocoa/NSData.py index 9acb2fefb32..8407a33f59e 100644 --- a/lldb/examples/summaries/cocoa/NSData.py +++ b/lldb/examples/summaries/cocoa/NSData.py @@ -15,21 +15,20 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSConcreteData_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # one pointer is the ISA # then there are 32 bit worth of flags and other data @@ -37,31 +36,26 @@ class NSConcreteData_SummaryProvider: # machine word long, which means we actually have two pointers # worth of data to skip def offset(self): - if self.is_64_bit: - return 16 - else: - return 8 + return 2 * self.sys_params.pointer_size def length(self): size = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return size.GetValueAsUnsigned(0) class NSDataUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def length(self): stream = lldb.SBStream() @@ -93,10 +87,10 @@ def GetSummary_Impl(valobj): if name_string == 'NSConcreteData' or \ name_string == 'NSConcreteMutableData' or \ name_string == '__NSCFData': - wrapper = NSConcreteData_SummaryProvider(valobj) + wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSDataUnknown_SummaryProvider(valobj) + wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSDate.py b/lldb/examples/summaries/cocoa/NSDate.py index 800cf3200e2..3f0273fe16e 100644 --- a/lldb/examples/summaries/cocoa/NSDate.py +++ b/lldb/examples/summaries/cocoa/NSDate.py @@ -37,12 +37,11 @@ def osx_to_python_time(osx): # obey the interface specification for synthetic children providers class NSTaggedDate_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj, info_bits, data): + def __init__(self, valobj, info_bits, data, params): self.valobj = valobj; + self.sys_params = params self.update(); # NSDate is not using its info_bits for info like NSNumber is # so we need to regroup info_bits and data @@ -50,18 +49,6 @@ class NSTaggedDate_SummaryProvider: def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - - self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar) - self.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort) - self.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort) - self.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt) - self.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) - self.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong) - self.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong) - self.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat) - self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) def value(self): # the value of the date-time object is wrapped into the pointer value @@ -74,96 +61,78 @@ class NSTaggedDate_SummaryProvider: class NSUntaggedDate_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.double): + self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 - + return self.sys_params.pointer_size def value(self): value = self.valobj.CreateChildAtOffset("value", self.offset(), - self.double) + self.sys_params.types_cache.double) value_double = struct.unpack('d', struct.pack('Q', value.GetValueAsUnsigned(0)))[0] return time.ctime(osx_to_python_time(value_double)) class NSCalendarDate_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.double): + self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) def offset(self): - if self.is_64_bit: - return 16 - else: - return 8 - + return 2*self.sys_params.pointer_size def value(self): value = self.valobj.CreateChildAtOffset("value", self.offset(), - self.double) + self.sys_params.types_cache.double) value_double = struct.unpack('d', struct.pack('Q', value.GetValueAsUnsigned(0)))[0] return time.ctime(osx_to_python_time(value_double)) class NSTimeZoneClass_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.voidptr): + self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType() self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.voidptr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType() def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def timezone(self): tz_string = self.valobj.CreateChildAtOffset("tz_name", self.offset(), - self.voidptr_type) + self.sys_params.types_cache.voidptr) return CFString.CFString_SummaryProvider(tz_string,None) class NSUnknownDate_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass def __init__(self, valobj): self.valobj = valobj; @@ -171,7 +140,6 @@ class NSUnknownDate_SummaryProvider: def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def value(self): stream = lldb.SBStream() @@ -202,19 +170,19 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate': if class_data.is_tagged(): - wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value()) + wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSUntaggedDate_SummaryProvider(valobj) + wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == 'NSCalendarDate': - wrapper = NSCalendarDate_SummaryProvider(valobj) + wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSTimeZone': - wrapper = NSTimeZoneClass_SummaryProvider(valobj) + wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSUnknownDate_SummaryProvider(valobj) + wrapper = NSUnknownDate_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSException.py b/lldb/examples/summaries/cocoa/NSException.py index ac85fe8c143..3a09198f84c 100644 --- a/lldb/examples/summaries/cocoa/NSException.py +++ b/lldb/examples/summaries/cocoa/NSException.py @@ -12,49 +12,43 @@ statistics.add_metric('code_notrun') class NSKnownException_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.id): + self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - # skip the ISA and go to the name pointer - def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + def offset_name(self): + return self.sys_params.pointer_size + def offset_reason(self): + return 2*self.sys_params.pointer_size def description(self): name_ptr = self.valobj.CreateChildAtOffset("name", - self.offset(), - self.id_type) + self.offset_name(), + self.sys_params.types_cache.id) reason_ptr = self.valobj.CreateChildAtOffset("reason", - 2*self.offset(), - self.id_type) + self.offset_reason(), + self.sys_params.types_cache.id) return CFString.CFString_SummaryProvider(name_ptr,None) + " " + CFString.CFString_SummaryProvider(reason_ptr,None) - class NSUnknownException_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def description(self): stream = lldb.SBStream() @@ -85,10 +79,10 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSException': - wrapper = NSKnownException_SummaryProvider(valobj) + wrapper = NSKnownException_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSUnknownException_SummaryProvider(valobj) + wrapper = NSUnknownException_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSIndexSet.py b/lldb/examples/summaries/cocoa/NSIndexSet.py index c030e16d388..043f8889858 100644 --- a/lldb/examples/summaries/cocoa/NSIndexSet.py +++ b/lldb/examples/summaries/cocoa/NSIndexSet.py @@ -15,18 +15,20 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSIndexSetClass_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) # NS(Mutable)IndexSet works in one of two modes: when having a compact block of data (e.g. a Range) # the count is stored in the set itself, 3 pointers into it @@ -37,10 +39,10 @@ class NSIndexSetClass_SummaryProvider: # location to go look for count in mode 2 def count(self): mode_chooser_vo = self.valobj.CreateChildAtOffset("mode_chooser", - 2*self.pointer_size, - self.NSUInteger) + 2*self.sys_params.pointer_size, + self.sys_params.types_cache.NSUInteger) mode_chooser = mode_chooser_vo.GetValueAsUnsigned(0) - if self.is_64_bit: + if self.sys_params.is_64_bit: mode_chooser = mode_chooser & 0xFFFFFFFFFFFFFF00 else: mode_chooser = mode_chooser & 0xFFFFFF00 @@ -50,29 +52,27 @@ class NSIndexSetClass_SummaryProvider: mode = 2 if mode == 1: count_vo = self.valobj.CreateChildAtOffset("count", - 3*self.pointer_size, - self.NSUInteger) + 3*self.sys_params.pointer_size, + self.sys_params.types_cache.NSUInteger) else: count_ptr = mode_chooser_vo.GetValueAsUnsigned(0) count_vo = self.valobj.CreateValueFromAddress("count", - count_ptr+2*self.pointer_size, - self.NSUInteger) + count_ptr+2*self.sys_params.pointer_size, + self.sys_params.types_cache.NSUInteger) return count_vo.GetValueAsUnsigned(0) class NSIndexSetUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def count(self): stream = lldb.SBStream() @@ -103,10 +103,10 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSIndexSet' or name_string == 'NSMutableIndexSet': - wrapper = NSIndexSetClass_SummaryProvider(valobj) + wrapper = NSIndexSetClass_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSIndexSetUnknown_SummaryProvider(valobj) + wrapper = NSIndexSetUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSMachPort.py b/lldb/examples/summaries/cocoa/NSMachPort.py index eceb2d9ccfe..c7ffcc0c59b 100644 --- a/lldb/examples/summaries/cocoa/NSMachPort.py +++ b/lldb/examples/summaries/cocoa/NSMachPort.py @@ -15,24 +15,26 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSMachPortKnown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) # one pointer is the ISA # then we have one other internal pointer, plus # 4 bytes worth of flags. hence, these values def offset(self): - if self.is_64_bit: + if self.sys_params.is_64_bit: return 20 else: return 12 @@ -40,23 +42,21 @@ class NSMachPortKnown_SummaryProvider: def port(self): vport = self.valobj.CreateChildAtOffset("port", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return vport.GetValueAsUnsigned(0) class NSMachPortUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def port(self): stream = lldb.SBStream() @@ -86,10 +86,10 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSMachPort': - wrapper = NSMachPortKnown_SummaryProvider(valobj) + wrapper = NSMachPortKnown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSMachPortUnknown_SummaryProvider(valobj) + wrapper = NSMachPortUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSNotification.py b/lldb/examples/summaries/cocoa/NSNotification.py index 0f8cccd322c..48ad18a4331 100644 --- a/lldb/examples/summaries/cocoa/NSNotification.py +++ b/lldb/examples/summaries/cocoa/NSNotification.py @@ -12,46 +12,39 @@ statistics.add_metric('code_notrun') class NSConcreteNotification_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + if not (self.sys_params.types_cache.id): + self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) # skip the ISA and go to the name pointer def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 - + return self.sys_params.pointer_size +\ def name(self): string_ptr = self.valobj.CreateChildAtOffset("name", self.offset(), - self.id_type) + self.sys_params.types_cache.id) return CFString.CFString_SummaryProvider(string_ptr,None) class NSNotificationUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def name(self): stream = lldb.SBStream() diff --git a/lldb/examples/summaries/cocoa/NSNumber.py b/lldb/examples/summaries/cocoa/NSNumber.py index 7726dedb179..7eddcb44d31 100644 --- a/lldb/examples/summaries/cocoa/NSNumber.py +++ b/lldb/examples/summaries/cocoa/NSNumber.py @@ -16,30 +16,17 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSTaggedNumber_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj, info_bits, data): + def __init__(self, valobj, info_bits, data, params): self.valobj = valobj; - self.update(); + self.sys_params = params self.info_bits = info_bits self.data = data + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - - self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar) - self.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort) - self.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort) - self.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt) - self.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) - self.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong) - self.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong) - self.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat) - self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) def value(self): # in spite of the plenty of types made available by the public NSNumber API @@ -60,28 +47,35 @@ class NSTaggedNumber_SummaryProvider: class NSUntaggedNumber_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + if not(self.sys_params.types_cache.char): + self.sys_params.types_cache.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar) + if not(self.sys_params.types_cache.short): + self.sys_params.types_cache.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort) + if not(self.sys_params.types_cache.ushort): + self.sys_params.types_cache.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort) + if not(self.sys_params.types_cache.int): + self.sys_params.types_cache.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt) + if not(self.sys_params.types_cache.long): + self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) + if not(self.sys_params.types_cache.ulong): + self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + if not(self.sys_params.types_cache.longlong): + self.sys_params.types_cache.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong) + if not(self.sys_params.types_cache.ulonglong): + self.sys_params.types_cache.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong) + if not(self.sys_params.types_cache.float): + self.sys_params.types_cache.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat) + if not(self.sys_params.types_cache.double): + self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - - self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar) - self.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort) - self.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort) - self.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt) - self.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) - self.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong) - self.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong) - self.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat) - self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble) def value(self): global statistics @@ -89,20 +83,20 @@ class NSUntaggedNumber_SummaryProvider: # we then skip one other full pointer worth of data and then fetch the contents # if we are fetching an int64 value, one more pointer must be skipped to get at our data data_type_vo = self.valobj.CreateChildAtOffset("dt", - self.pointer_size, - self.char) + self.sys_params.pointer_size, + self.sys_params.types_cache.char) data_type = ((data_type_vo.GetValueAsUnsigned(0) % 256) & 0x1F) - data_offset = 2 * self.pointer_size + data_offset = 2 * self.sys_params.pointer_size if data_type == 0B00001: data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.char) + self.sys_params.types_cache.char) statistics.metric_hit('code_notrun',self.valobj) return '(char)' + str(data_vo.GetValueAsUnsigned(0)) elif data_type == 0B0010: data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.short) + self.sys_params.types_cache.short) statistics.metric_hit('code_notrun',self.valobj) return '(short)' + str(data_vo.GetValueAsUnsigned(0) % (256*256)) # IF tagged pointers are possible on 32bit+v2 runtime @@ -111,7 +105,7 @@ class NSUntaggedNumber_SummaryProvider: elif data_type == 0B0011: data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.int) + self.sys_params.types_cache.int) statistics.metric_hit('code_notrun',self.valobj) return '(int)' + str(data_vo.GetValueAsUnsigned(0) % (256*256*256*256)) # apparently, on is_64_bit architectures, these are the only values that will ever @@ -120,21 +114,21 @@ class NSUntaggedNumber_SummaryProvider: data_offset = data_offset + 8 # 8 is needed even if we are on 32bit data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.longlong) + self.sys_params.types_cache.longlong) statistics.metric_hit('code_notrun',self.valobj) return '(long)' + str(data_vo.GetValueAsUnsigned(0)) elif data_type == 0B0100: - if self.is_64_bit: - data_offset = data_offset + self.pointer_size + if self.sys_params.is_64_bit: + data_offset = data_offset + self.sys_params.pointer_size data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.longlong) + self.sys_params.types_cache.longlong) statistics.metric_hit('code_notrun',self.valobj) return '(long)' + str(data_vo.GetValueAsUnsigned(0)) elif data_type == 0B0101: data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.longlong) + self.sys_params.types_cache.longlong) data_plain = int(str(data_vo.GetValueAsUnsigned(0) & 0x00000000FFFFFFFF)) packed = struct.pack('I', data_plain) data_float = struct.unpack('f', packed)[0] @@ -143,7 +137,7 @@ class NSUntaggedNumber_SummaryProvider: elif data_type == 0B0110: data_vo = self.valobj.CreateChildAtOffset("data", data_offset, - self.longlong) + self.sys_params.types_cache.longlong) data_plain = data_vo.GetValueAsUnsigned(0) data_double = struct.unpack('d', struct.pack('Q', data_plain))[0] statistics.metric_hit('code_notrun',self.valobj) @@ -154,17 +148,15 @@ class NSUntaggedNumber_SummaryProvider: class NSUnknownNumber_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def value(self): stream = lldb.SBStream() @@ -195,14 +187,14 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSNumber' or name_string == '__NSCFNumber': if class_data.is_tagged(): - wrapper = NSTaggedNumber_SummaryProvider(valobj,class_data.info_bits(),class_data.value()) + wrapper = NSTaggedNumber_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: # the wrapper might be unable to decipher what is into the NSNumber # and then have to run code on it - wrapper = NSUntaggedNumber_SummaryProvider(valobj) + wrapper = NSUntaggedNumber_SummaryProvider(valobj, class_data.sys_params) else: - wrapper = NSUnknownNumber_SummaryProvider(valobj) + wrapper = NSUnknownNumber_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/NSSet.py b/lldb/examples/summaries/cocoa/NSSet.py index 17ca6d39d7c..068949c2ee0 100644 --- a/lldb/examples/summaries/cocoa/NSSet.py +++ b/lldb/examples/summaries/cocoa/NSSet.py @@ -16,24 +16,26 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSCFSet_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) # one pointer is the ISA # then we have one other internal pointer, plus # 4 bytes worth of flags. hence, these values def offset(self): - if self.is_64_bit: + if self.sys_params.is_64_bit: return 20 else: return 12 @@ -41,23 +43,21 @@ class NSCFSet_SummaryProvider: def count(self): vcount = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return vcount.GetValueAsUnsigned(0) class NSSetUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; - self.update() + self.sys_params = params + self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def count(self): stream = lldb.SBStream() @@ -68,40 +68,36 @@ class NSSetUnknown_SummaryProvider: class NSSetI_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # we just need to skip the ISA and the count immediately follows def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def count(self): num_children_vo = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) value = num_children_vo.GetValueAsUnsigned(0) if value != None: # the MSB on immutable sets seems to be taken by some other data # not sure if it is a bug or some weird sort of feature, but masking it out # gets the count right (unless, of course, someone's dictionaries grow # too large - but I have not tested this) - if self.is_64_bit: + if self.sys_params.is_64_bit: value = value & ~0xFF00000000000000 else: value = value & ~0xFF000000 @@ -109,63 +105,55 @@ class NSSetI_SummaryProvider: class NSSetM_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSUInteger): + if self.sys_params.is_64_bit: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + else: + self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) # we just need to skip the ISA and the count immediately follows def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def count(self): num_children_vo = self.valobj.CreateChildAtOffset("count", self.offset(), - self.NSUInteger) + self.sys_params.types_cache.NSUInteger) return num_children_vo.GetValueAsUnsigned(0) class NSCountedSet_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not (self.sys_params.types_cache.voidptr): + self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType() self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - self.voidptr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType() # an NSCountedSet is implemented using a CFBag whose pointer just follows the ISA def offset(self): - if self.is_64_bit: - return 8 - else: - return 4 + return self.sys_params.pointer_size def count(self): cfbag_vo = self.valobj.CreateChildAtOffset("bag_impl", self.offset(), - self.voidptr_type) - return CFBag.CFBagRef_SummaryProvider(cfbag_vo).length() + self.sys_params.types_cache.voidptr) + return CFBag.CFBagRef_SummaryProvider(cfbag_vo,self.sys_params).length() def GetSummary_Impl(valobj): @@ -189,16 +177,16 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == '__NSCFSet': - wrapper = NSCFSet_SummaryProvider(valobj) + wrapper = NSCFSet_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSSetI': - wrapper = NSSetI_SummaryProvider(valobj) + wrapper = NSSetI_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == '__NSSetM': - wrapper = NSSetM_SummaryProvider(valobj) + wrapper = NSSetM_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) elif name_string == 'NSCountedSet': - wrapper = NSCountedSet_SummaryProvider(valobj) + wrapper = NSCountedSet_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: wrapper = NSSetUnknown_SummaryProvider(valobj) @@ -233,7 +221,7 @@ def NSSet_SummaryProvider2 (valobj,dict): if summary == None: summary = 'no valid set here' else: - if provider.is_64_bit: + if provider.sys_params.is_64_bit: summary = int(summary) & ~0x1fff000000000000 return str(summary) + ' objects' return '' diff --git a/lldb/examples/summaries/cocoa/NSURL.py b/lldb/examples/summaries/cocoa/NSURL.py index b242323f4bf..4273b43abd1 100644 --- a/lldb/examples/summaries/cocoa/NSURL.py +++ b/lldb/examples/summaries/cocoa/NSURL.py @@ -16,43 +16,36 @@ statistics.add_metric('code_notrun') # obey the interface specification for synthetic children providers class NSURLKnown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params + if not(self.sys_params.types_cache.NSString): + self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType() + if not(self.sys_params.types_cache.NSURL): + self.sys_params.types_cache.NSURL = self.valobj.GetTarget().FindFirstType('NSURL').GetPointerType() self.update(); def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) - if self.is_64_bit: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.pointer_size = 8 - else: - self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) - self.pointer_size = 4 - self.NSString = self.valobj.GetTarget().FindFirstType('NSString') - self.NSURL = self.valobj.GetTarget().FindFirstType('NSURL') # one pointer is the ISA # then there is one more pointer and 8 bytes of plain data # (which are also present on a 32-bit system) # plus another pointer, and then the real data - def offset(self): - if self.is_64_bit: - return 24 - else: - return 16 + def offset_text(self): + return 24 if self.sys_params.is_64_bit else 16 + def offset_base(self): + return self.offset_text()+self.sys_params.pointer_size def url_text(self): text = self.valobj.CreateChildAtOffset("text", - self.offset(), - self.NSString.GetPointerType()) + self.offset_text(), + self.sys_params.types_cache.NSString) base = self.valobj.CreateChildAtOffset("base", - self.offset()+self.pointer_size, - self.NSURL.GetPointerType()) + self.offset_base(), + self.sys_params.types_cache.NSURL) my_string = CFString.CFString_SummaryProvider(text,None) if base.GetValueAsUnsigned(0) != 0: my_string = my_string + " (base path: " + NSURL_SummaryProvider(base,None) + ")" @@ -61,17 +54,15 @@ class NSURLKnown_SummaryProvider: class NSURLUnknown_SummaryProvider: def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + pass - def __init__(self, valobj): + def __init__(self, valobj, params): self.valobj = valobj; + self.sys_params = params self.update() def update(self): self.adjust_for_architecture(); - self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) def url_text(self): stream = lldb.SBStream() @@ -101,10 +92,10 @@ def GetSummary_Impl(valobj): name_string = class_data.class_name() if name_string == 'NSURL': - wrapper = NSURLKnown_SummaryProvider(valobj) + wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('code_notrun',valobj) else: - wrapper = NSURLUnknown_SummaryProvider(valobj) + wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; diff --git a/lldb/examples/summaries/cocoa/attrib_fromdict.py b/lldb/examples/summaries/cocoa/attrib_fromdict.py new file mode 100644 index 00000000000..8ecd9ed27be --- /dev/null +++ b/lldb/examples/summaries/cocoa/attrib_fromdict.py @@ -0,0 +1,31 @@ +class AttributesDictionary: + def __init__(self, allow_reset = True): + self.__dict__['_dictionary'] = {} # need to do it this way to prevent endless recursion + self.__dict__['_allow_reset'] = allow_reset + + def __getattr__(self,name): + if not self._check_exists(name): + return None + value = self._dictionary[name] + return value + + def _set_impl(self,name,value): + self._dictionary[name] = value + + def _check_exists(self,name): + return name in self._dictionary + + def __setattr__(self,name,value): + if self._allow_reset: + self._set_impl(name,value) + else: + self.set_if_necessary(name,value) + + def set_if_necessary(self,name,value): + if not self._check_exists(name): + self._set_impl(name,value) + return True + return False + + def __len__(self): + return len(self._dictionary)
\ No newline at end of file diff --git a/lldb/examples/summaries/cocoa/objc_lldb.py b/lldb/examples/summaries/cocoa/objc_lldb.py index 877674c24cd..a9f9322b9bb 100644 --- a/lldb/examples/summaries/cocoa/objc_lldb.py +++ b/lldb/examples/summaries/cocoa/objc_lldb.py @@ -1,6 +1,7 @@ """ -Objective-C runtime wrapper - Replicates the behavior of AppleObjCRuntimeV2.cpp in Python code -for the benefit of synthetic children providers and Python summaries +Objective-C runtime wrapper for use by LLDB Python formatters +This is an old and deprecated version of the wrapper +The new code, to which everyone should convert, is in objc_runtime.py part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source diff --git a/lldb/examples/summaries/cocoa/objc_runtime.py b/lldb/examples/summaries/cocoa/objc_runtime.py index 0af07f0a3be..ddad00a2230 100644 --- a/lldb/examples/summaries/cocoa/objc_runtime.py +++ b/lldb/examples/summaries/cocoa/objc_runtime.py @@ -1,6 +1,14 @@ -# a wrapper for the Objective-C runtime for use by LLDB +""" +Objective-C runtime wrapper for use by LLDB Python formatters + +part of The LLVM Compiler Infrastructure +This file is distributed under the University of Illinois Open Source +License. See LICENSE.TXT for details. +""" import lldb import cache +import attrib_fromdict +import functools class Utilities: @staticmethod @@ -72,11 +80,11 @@ class RoT_Data: self.sys_params = params self.valobj = rot_pointer #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t) - self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t) - self.instanceSize = Utilities.read_child_of(self.valobj,8,self.sys_params.uint32_t) + #self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t) + self.instanceSize = None # lazy fetching offset = 24 if self.sys_params.is_64_bit else 16 #self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type) - self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type) + self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.types_cache.addr_ptr_type) self.check_valid() else: self.valid = False @@ -85,7 +93,7 @@ class RoT_Data: if not(Utilities.is_valid_identifier(self.name)): self.valid = False - # perform sanity checks on the contents of this class_rw_t + # perform sanity checks on the contents of this class_ro_t def check_valid(self): self.valid = True # misaligned pointers seem to be possible for this field @@ -95,13 +103,25 @@ class RoT_Data: def __str__(self): return \ - "instanceStart = " + hex(self.instanceStart) + "\n" + \ - "instanceSize = " + hex(self.instanceSize) + "\n" + \ + "instanceSize = " + hex(self.instance_size()) + "\n" + \ "namePointer = " + hex(self.namePointer) + " --> " + self.name def is_valid(self): return self.valid + def instance_size(self,align=False): + if self.is_valid() == False: + return None + if self.instanceSize == None: + self.instanceSize = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.uint32_t) + if align: + unalign = self.instance_size(False) + if self.sys_params.is_64_bit: + return ((unalign + 7) & ~7) % 0x100000000 + else: + return ((unalign + 3) & ~3) % 0x100000000 + else: + return self.instanceSize class RwT_Data: def __init__(self,rwt_pointer,params): @@ -110,12 +130,12 @@ class RwT_Data: self.valobj = rwt_pointer #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t) #self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t) - self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.addr_ptr_type) + self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.addr_ptr_type) self.check_valid() else: self.valid = False if self.valid: - self.rot = self.valobj.CreateValueFromAddress("rot",self.roPointer,self.sys_params.addr_ptr_type).AddressOf() + self.rot = self.valobj.CreateValueFromAddress("rot",self.roPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf() self.data = RoT_Data(self.rot,self.sys_params) # perform sanity checks on the contents of this class_rw_t @@ -138,53 +158,56 @@ class Class_Data_V2: if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)): self.sys_params = params self.valobj = isa_pointer - self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.addr_ptr_type) - self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.cachePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.vtablePointer = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) self.check_valid() else: self.valid = False if self.valid: - self.rwt = self.valobj.CreateValueFromAddress("rwt",self.dataPointer,self.sys_params.addr_ptr_type).AddressOf() + self.rwt = self.valobj.CreateValueFromAddress("rwt",self.dataPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf() self.data = RwT_Data(self.rwt,self.sys_params) # perform sanity checks on the contents of this class_t + # this call tries to minimize the amount of data fetched- as soon as we have "proven" + # that we have an invalid object, we stop reading def check_valid(self): self.valid = True + + self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type) if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=False)): self.valid = False return - if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False)): - # NULL is a valid value for superclass (it means we have reached NSObject) - if self.superclassIsaPointer != 0: - self.valid = False - return + if not(Utilities.is_allowed_pointer(self.isaPointer)): + self.valid = False + return + + self.cachePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) if not(Utilities.is_valid_pointer(self.cachePointer,self.sys_params.pointer_size,allow_tagged=False)): self.valid = False return + if not(Utilities.is_allowed_pointer(self.cachePointer)): + self.valid = False + return + + self.vtablePointer = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) if not(Utilities.is_valid_pointer(self.vtablePointer,self.sys_params.pointer_size,allow_tagged=False)): self.valid = False return - if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=False)): + if not(Utilities.is_allowed_pointer(self.vtablePointer)): self.valid = False return - if not(Utilities.is_allowed_pointer(self.isaPointer)): + + self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) + if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=False)): self.valid = False return - if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)): - # NULL is a valid value for superclass (it means we have reached NSObject) - if self.superclassIsaPointer != 0: - self.valid = False - return - if not(Utilities.is_allowed_pointer(self.cachePointer)): + if not(Utilities.is_allowed_pointer(self.dataPointer)): self.valid = False return - if not(Utilities.is_allowed_pointer(self.vtablePointer)): + + self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) + if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False, allow_NULL=True)): self.valid = False return - if not(Utilities.is_allowed_pointer(self.dataPointer)): + if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)): self.valid = False return @@ -198,6 +221,14 @@ class Class_Data_V2: return True return False + # some CF classes have a valid ObjC isa in their CFRuntimeBase + # but instead of being class-specific this isa points to a match-'em-all class + # which is __NSCFType (the versions without __ also exists and we are matching to it + # just to be on the safe side) + def is_cftype(self): + if self.is_valid(): + return self.name == '__NSCFType' or self.name == 'NSCFType' + def get_superclass(self): if self.is_valid(): parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa", @@ -231,14 +262,7 @@ class Class_Data_V2: def instance_size(self,align=False): if self.is_valid() == False: return None - if align: - unalign = self.instance_size(False) - if self.sys_params.is_64_bit: - return ((unalign + 7) & ~7) % 0x100000000 - else: - return ((unalign + 3) & ~3) % 0x100000000 - else: - return self.rwt.rot.instanceSize + return self.rwt.rot.instance_size(align) # runtime v1 is much less intricate than v2 and stores relevant information directly in the class_t object class Class_Data_V1: @@ -247,12 +271,7 @@ class Class_Data_V1: self.valid = True self.sys_params = params self.valobj = isa_pointer - self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.addr_ptr_type) - self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.namePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.version = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.info = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) - self.instanceSize = Utilities.read_child_of(self.valobj,5*self.sys_params.pointer_size,self.sys_params.addr_ptr_type) + self.check_valid() else: self.valid = False if self.valid: @@ -263,18 +282,22 @@ class Class_Data_V1: # perform sanity checks on the contents of this class_t def check_valid(self): self.valid = True + + self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type) if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=False)): self.valid = False return - if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False)): - # NULL is a valid value for superclass (it means we have reached NSObject) - if self.superclassIsaPointer != 0: - self.valid = False - return - if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=False,allow_NULL=True)): + + self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) + if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False,allow_NULL=True)): self.valid = False return + self.namePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) + #if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=False,allow_NULL=False)): + # self.valid = False + # return + # in general, KVO is implemented by transparently subclassing # however, there could be exceptions where a class does something else # internally to implement the feature - this method will have no clue that a class @@ -285,6 +308,14 @@ class Class_Data_V1: return True return False + # some CF classes have a valid ObjC isa in their CFRuntimeBase + # but instead of being class-specific this isa points to a match-'em-all class + # which is __NSCFType (the versions without __ also exists and we are matching to it + # just to be on the safe side) + def is_cftype(self): + if self.is_valid(): + return self.name == '__NSCFType' or self.name == 'NSCFType' + def get_superclass(self): if self.is_valid(): parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa", @@ -307,9 +338,7 @@ class Class_Data_V1: return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \ "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \ "namePointer = " + hex(self.namePointer) + " --> " + self.name + \ - "version = " + hex(self.version) + "\n" + \ - "info = " + hex(self.info) + "\n" + \ - "instanceSize = " + hex(self.instanceSize) + "\n" + "instanceSize = " + hex(self.instanceSize()) + "\n" def is_tagged(self): return False @@ -317,6 +346,8 @@ class Class_Data_V1: def instance_size(self,align=False): if self.is_valid() == False: return None + if self.instanceSize == None: + self.instanceSize = Utilities.read_child_of(self.valobj,5*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) if align: unalign = self.instance_size(False) if self.sys_params.is_64_bit: @@ -381,6 +412,9 @@ class TaggedClass_Data: def is_kvo(self): return False + def is_cftype(self): + return False + # we would need to go around looking for the superclass or ask the runtime # for now, we seem not to require support for this operation so we will merrily # pretend to be at a root point in the hierarchy @@ -395,7 +429,7 @@ class TaggedClass_Data: def instance_size(self,align=False): if self.is_valid() == False: return None - return 8 if self.sys_params.is_64_bit else 4 + return self.sys_params.pointer_size class InvalidClass_Data: @@ -404,40 +438,106 @@ class InvalidClass_Data: def is_valid(self): return False +@functools.total_ordering +class Version: + def __init__(self, major, minor, release, build_string): + self._major = major + self._minor = minor + self._release = release + self._build_string = build_string + + def get_major(self): + return self._major + def get_minor(self): + return self._minor + def get_release(self): + return self._release + def get_build_string(self): + return self._build_string + + major = property(get_major,None) + minor = property(get_minor,None) + release = property(get_release,None) + build_string = property(get_build_string,None) + + def __lt__(self,other): + if (self.major < other.major): + return True + if (self.minor < other.minor): + return True + if (self.release < other.release): + return True + # build strings are not compared since they are heavily platform-dependent and might not always + # be available + return False + + def __eq__(self,other): + return (self.major == other.major) and \ + (self.minor == other.minor) and \ + (self.release == other.release) and \ + (self.build_string == other.build_string) + runtime_version = cache.Cache() os_version = cache.Cache() +types_caches = cache.Cache() +isa_caches = cache.Cache() -# TODO: make more extensive use of this class in the individual formatters -# instead of recalculating the same information - since we are building this object -# it makes sense to pass it around to the formatters class SystemParameters: def __init__(self,valobj): self.adjust_for_architecture(valobj) + self.adjust_for_process(valobj) - def adjust_for_architecture(self,valobj): - self.process = valobj.GetTarget().GetProcess() - self.is_64_bit = (self.process.GetAddressByteSize() == 8) - self.is_little = (self.process.GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.process.GetAddressByteSize() - self.addr_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.addr_ptr_type = self.addr_type.GetPointerType() - self.uint32_t = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) + def adjust_for_process(self, valobj): global runtime_version global os_version - pid = self.process.GetProcessID() - if runtime_version.look_for_key(pid): - self.runtime_version = runtime_version.get_value(pid) + global types_caches + global isa_caches + + process = valobj.GetTarget().GetProcess() + self.pid = process.GetProcessID() + + if runtime_version.look_for_key(self.pid): + self.runtime_version = runtime_version.get_value(self.pid) else: - self.runtime_version = ObjCRuntime.runtime_version(self.process) - runtime_version.add_item(pid,self.runtime_version) - if os_version.look_for_key(pid): - self.is_lion = os_version.get_value(pid) + self.runtime_version = ObjCRuntime.runtime_version(process) + runtime_version.add_item(self.pid,self.runtime_version) + + if os_version.look_for_key(self.pid): + self.is_lion = os_version.get_value(self.pid) else: self.is_lion = Utilities.check_is_osx_lion(valobj.GetTarget()) - os_version.add_item(pid,self.is_lion) + os_version.add_item(self.pid,self.is_lion) + + if types_caches.look_for_key(self.pid): + self.types_cache = types_caches.get_value(self.pid) + else: + self.types_cache = attrib_fromdict.AttributesDictionary(allow_reset=False) + self.types_cache.addr_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + self.types_cache.addr_ptr_type = self.types_cache.addr_type.GetPointerType() + self.types_cache.uint32_t = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) + types_caches.add_item(self.pid,self.types_cache) + + if isa_caches.look_for_key(self.pid): + self.isa_cache = isa_caches.get_value(self.pid) + else: + self.isa_cache = cache.Cache() + isa_caches.add_item(self.pid,self.isa_cache) + + def adjust_for_architecture(self,valobj): + process = valobj.GetTarget().GetProcess() + self.pointer_size = process.GetAddressByteSize() + self.is_64_bit = (self.pointer_size == 8) + self.is_little = (process.GetByteOrder() == lldb.eByteOrderLittle) self.cfruntime_size = 16 if self.is_64_bit else 8 -isa_cache = cache.Cache() + # a simple helper function that makes it more explicit that one is calculating + # an offset that is made up of X pointers and Y bytes of additional data + # taking into account pointer size - if you know there is going to be some padding + # you can pass that in and it will be taken into account (since padding may be different between + # 32 and 64 bit versions, you can pass padding value for both, the right one will be used) + def calculate_offset(self, num_pointers = 0, bytes_count = 0, padding32 = 0, padding64 = 0): + value = bytes_count + num_pointers*self.pointer_size + return value + padding64 if self.is_64_bit else value + padding32 class ObjCRuntime: @@ -477,32 +577,28 @@ class ObjCRuntime: self.isa_value = None def adjust_for_architecture(self): - self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) - self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) - self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() - self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) - self.addr_ptr_type = self.addr_type.GetPointerType() + pass # an ObjC pointer can either be tagged or must be aligned def is_tagged(self): if self.valobj is None: return False - return (Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=True) and \ - not(Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=False))) + return (Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=True) and \ + not(Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=False))) def is_valid(self): if self.valobj is None: return False if self.valobj.IsInScope() == False: return False - return Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=True) + return Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=True) def read_isa(self): if self.isa_value != None: return self.isa_value isa_pointer = self.valobj.CreateChildAtOffset("cfisa", 0, - self.addr_ptr_type) + self.sys_params.types_cache.addr_ptr_type) if isa_pointer == None or isa_pointer.IsValid() == False: return None; if isa_pointer.GetValueAsUnsigned(1) == 1: @@ -530,7 +626,7 @@ class ObjCRuntime: isa_value = isa.GetValueAsUnsigned(1) if isa_value == 1: return InvalidClass_Data() - data = isa_cache.get_value(isa_value,default=None) + data = self.sys_params.isa_cache.get_value(isa_value,default=None) if data != None: return data if self.sys_params.runtime_version == 2: @@ -540,6 +636,6 @@ class ObjCRuntime: if data == None: return InvalidClass_Data() if data.is_valid(): - isa_cache.add_item(isa_value,data,ok_to_replace=True) + self.sys_params.isa_cache.add_item(isa_value,data,ok_to_replace=True) return data |