1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters 3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure 5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source 6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details. 7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 8de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata# summary provider for CF(Mutable)BitVector 9de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granataimport lldb 10de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granataimport ctypes 110d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.runtime.objc.objc_runtime 120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.metrics 130d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger 14de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 15de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata# first define some utility functions 16de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef byte_index(abs_pos): 170d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 18de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return abs_pos/8 19de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 20de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef bit_index(abs_pos): 210d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 22de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return abs_pos & 7 23de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 24de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef get_bit(byte,index): 250d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 26de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if index < 0 or index > 7: 27de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return None 28de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return (byte >> (7-index)) & 1 29de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 30de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef grab_array_item_data(pointer,index): 310d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 32de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return pointer.GetPointeeData(index,1) 33de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 340d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics() 35de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatastatistics.add_metric('invalid_isa') 36de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatastatistics.add_metric('invalid_pointer') 37de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatastatistics.add_metric('unknown_class') 38de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatastatistics.add_metric('code_notrun') 39de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 40de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata# despite the similary to synthetic children providers, these classes are not 41de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata# trying to provide anything but a summary for a CF*BitVector, so they need not 42de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata# obey the interface specification for synthetic children providers 43de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granataclass CFBitVectorKnown_SummaryProvider: 44de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def adjust_for_architecture(self): 450d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 46f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize() 47f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 48de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 49de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def __init__(self, valobj, params): 500d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 51de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.valobj = valobj; 52de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.sys_params = params 53f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSUInteger): 54f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 55f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 56f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 57f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 58f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.charptr): 59f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType() 60de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.update(); 61de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 62de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def update(self): 630d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 64de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.adjust_for_architecture(); 65de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 66de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # we skip the CFRuntimeBase 67de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # then the next CFIndex is the count 68de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # then we skip another CFIndex and then we get at a byte array 69de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # that wraps the individual bits 70de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 71de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def contents(self): 720d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 73f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size, 74f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 75de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata count = count_vo.GetValueAsUnsigned(0) 76de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if count == 0: 77de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return '(empty)' 78de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 79de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata array_vo = self.valobj.CreateChildAtOffset("data", 80f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.cfruntime_size+2*self.uiint_size, 81f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.charptr) 82de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 83de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata data_list = [] 84de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte_pos = None 85de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata for i in range(0,count): 86de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if cur_byte_pos == None: 87de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte_pos = byte_index(i) 88de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte = grab_array_item_data(array_vo,cur_byte_pos) 89de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte_val = cur_byte.uint8[0] 90de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata else: 91de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata byte_pos = byte_index(i) 92de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # do not fetch the pointee data every single time through 93de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if byte_pos != cur_byte_pos: 94de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte_pos = byte_pos 95de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte = grab_array_item_data(array_vo,cur_byte_pos) 96de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata cur_byte_val = cur_byte.uint8[0] 97de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata bit = get_bit(cur_byte_val,bit_index(i)) 98de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if (i % 4) == 0: 99de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata data_list.append(' ') 100de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if bit == 1: 101de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata data_list.append('1') 102de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata else: 103de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata data_list.append('0') 104de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return ''.join(data_list) 105de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 106de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 107de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granataclass CFBitVectorUnknown_SummaryProvider: 108de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def adjust_for_architecture(self): 109f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 110de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 111f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 1120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 113de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.valobj = valobj; 114f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 115f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update(); 116de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 117de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def update(self): 1180d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 119de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.adjust_for_architecture(); 120de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 121de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata def contents(self): 1220d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 123579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<unable to summarize this CFBitVector>' 124de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 125de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 126de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef GetSummary_Impl(valobj): 1270d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 128de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata global statistics 129a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 130579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 131579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 132de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 133de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata name_string = class_data.class_name() 134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata actual_name = name_string 1358f18240a09893310c43673901d863892ae7b0611Enrico Granata 1368f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name) 1378f18240a09893310c43673901d863892ae7b0611Enrico Granata 138579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if class_data.is_cftype(): 139de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is 140de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata # an NSCFType and then check we are a pointer-to CFBitVectorRef 141de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata valobj_type = valobj.GetType() 142de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if valobj_type.IsValid() and valobj_type.IsPointerType(): 143579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata valobj_type = valobj_type.GetPointeeType() 144579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if valobj_type.IsValid(): 145579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata actual_name = valobj_type.GetName() 146579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector': 147579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params) 148579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('code_notrun',valobj) 149579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 150579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params) 151579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata print actual_name 152de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata else: 153f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params) 154de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata print name_string 155805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 156de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata return wrapper; 157de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 158de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef CFBitVector_SummaryProvider (valobj,dict): 1590d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 160de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata provider = GetSummary_Impl(valobj); 161de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata if provider != None: 162a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 163579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.message() 164579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 165579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = provider.contents(); 166579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 167579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1688f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "summary got from provider: " + str(summary) 169579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None or summary == '': 170579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not CFBitVector>' 171579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 172579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 173de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata 174de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granatadef __lldb_init_module(debugger,dict): 175de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef") 176