blob: 7cd83fe6cb41915a9a648a2a9eedf6b5619ea0ff [file] [log] [blame]
Enrico Granata385ad4e2012-03-03 00:45:57 +00001# summary provider for CF(Mutable)BitVector
2import lldb
3import ctypes
4import objc_runtime
5import metrics
6
7# first define some utility functions
8def byte_index(abs_pos):
9 return abs_pos/8
10
11def bit_index(abs_pos):
12 return abs_pos & 7
13
14def get_bit(byte,index):
15 if index < 0 or index > 7:
16 return None
17 return (byte >> (7-index)) & 1
18
19def grab_array_item_data(pointer,index):
20 return pointer.GetPointeeData(index,1)
21
22statistics = metrics.Metrics()
23statistics.add_metric('invalid_isa')
24statistics.add_metric('invalid_pointer')
25statistics.add_metric('unknown_class')
26statistics.add_metric('code_notrun')
27
28# despite the similary to synthetic children providers, these classes are not
29# trying to provide anything but a summary for a CF*BitVector, so they need not
30# obey the interface specification for synthetic children providers
31class CFBitVectorKnown_SummaryProvider:
32 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000033 self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
34 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +000035
36 def __init__(self, valobj, params):
37 self.valobj = valobj;
38 self.sys_params = params
Enrico Granatacfdafa32012-03-05 19:56:33 +000039 if not(self.sys_params.types_cache.NSUInteger):
40 if self.sys_params.is_64_bit:
41 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
42 else:
43 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
44 if not(self.sys_params.types_cache.charptr):
45 self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
Enrico Granata385ad4e2012-03-03 00:45:57 +000046 self.update();
47
48 def update(self):
49 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +000050
51 # we skip the CFRuntimeBase
52 # then the next CFIndex is the count
53 # then we skip another CFIndex and then we get at a byte array
54 # that wraps the individual bits
55
56 def contents(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000057 count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size,
58 self.sys_params.types_cache.NSUInteger)
Enrico Granata385ad4e2012-03-03 00:45:57 +000059 count = count_vo.GetValueAsUnsigned(0)
60 if count == 0:
61 return '(empty)'
62
63 array_vo = self.valobj.CreateChildAtOffset("data",
Enrico Granatacfdafa32012-03-05 19:56:33 +000064 self.sys_params.cfruntime_size+2*self.uiint_size,
65 self.sys_params.types_cache.charptr)
Enrico Granata385ad4e2012-03-03 00:45:57 +000066
67 data_list = []
68 cur_byte_pos = None
69 for i in range(0,count):
70 if cur_byte_pos == None:
71 cur_byte_pos = byte_index(i)
72 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
73 cur_byte_val = cur_byte.uint8[0]
74 else:
75 byte_pos = byte_index(i)
76 # do not fetch the pointee data every single time through
77 if byte_pos != cur_byte_pos:
78 cur_byte_pos = byte_pos
79 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
80 cur_byte_val = cur_byte.uint8[0]
81 bit = get_bit(cur_byte_val,bit_index(i))
82 if (i % 4) == 0:
83 data_list.append(' ')
84 if bit == 1:
85 data_list.append('1')
86 else:
87 data_list.append('0')
88 return ''.join(data_list)
89
90
91class CFBitVectorUnknown_SummaryProvider:
92 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000093 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +000094
Enrico Granatacfdafa32012-03-05 19:56:33 +000095 def __init__(self, valobj, params):
Enrico Granata385ad4e2012-03-03 00:45:57 +000096 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000097 self.sys_params = params
98 self.update();
Enrico Granata385ad4e2012-03-03 00:45:57 +000099
100 def update(self):
101 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +0000102
103 def contents(self):
104 return '*** unknown class *** very bad thing *** find out my name ***'
105
106
107def GetSummary_Impl(valobj):
108 global statistics
109 class_data = objc_runtime.ObjCRuntime(valobj)
110 if class_data.is_valid() == False:
111 statistics.metric_hit('invalid_pointer',valobj)
112 wrapper = None
113 return
114 class_data = class_data.read_class_data()
115 if class_data.is_valid() == False:
116 statistics.metric_hit('invalid_isa',valobj)
117 wrapper = None
118 return
119 if class_data.is_kvo():
120 class_data = class_data.get_superclass()
121 if class_data.is_valid() == False:
122 statistics.metric_hit('invalid_isa',valobj)
123 wrapper = None
124 return
125
126 name_string = class_data.class_name()
127 if name_string == '__NSCFType':
128 # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
129 # an NSCFType and then check we are a pointer-to CFBitVectorRef
130 valobj_type = valobj.GetType()
131 if valobj_type.IsValid() and valobj_type.IsPointerType():
132 pointee_type = valobj_type.GetPointeeType()
133 if pointee_type.GetName() == '__CFBitVector' or pointee_type.GetName() == '__CFMutableBitVector':
134 wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
135 statistics.metric_hit('code_notrun',valobj)
136 else:
137 wrapper = CFBitVectorUnknown_SummaryProvider(valobj)
138 print pointee_type.GetName()
139 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000140 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata385ad4e2012-03-03 00:45:57 +0000141 print name_string
142 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
143 return wrapper;
144
145def CFBitVector_SummaryProvider (valobj,dict):
146 provider = GetSummary_Impl(valobj);
147 if provider != None:
148 #try:
149 summary = provider.contents();
150 #except:
151 # summary = None
152 if summary == None or summary == '':
153 summary = 'no valid bitvector here'
154 return summary
155 return ''
156
157def __lldb_init_module(debugger,dict):
158 debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")