blob: b0c9e79121066d02ae950d006ab9c7a4843c9e9f [file] [log] [blame]
Enrico Granata3f1052b2012-03-13 21:52:00 +00001"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
Enrico Granata385ad4e2012-03-03 00:45:57 +00008# summary provider for CF(Mutable)BitVector
9import lldb
10import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000011import lldb.runtime.objc.objc_runtime
12import lldb.formatters.metrics
13import lldb.formatters.Logger
Enrico Granata385ad4e2012-03-03 00:45:57 +000014
15# first define some utility functions
16def byte_index(abs_pos):
Enrico Granata28399ad2012-04-25 01:39:27 +000017 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000018 return abs_pos/8
19
20def bit_index(abs_pos):
Enrico Granata28399ad2012-04-25 01:39:27 +000021 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000022 return abs_pos & 7
23
24def get_bit(byte,index):
Enrico Granata28399ad2012-04-25 01:39:27 +000025 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000026 if index < 0 or index > 7:
27 return None
28 return (byte >> (7-index)) & 1
29
30def grab_array_item_data(pointer,index):
Enrico Granata28399ad2012-04-25 01:39:27 +000031 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000032 return pointer.GetPointeeData(index,1)
33
Enrico Granata28399ad2012-04-25 01:39:27 +000034statistics = lldb.formatters.metrics.Metrics()
Enrico Granata385ad4e2012-03-03 00:45:57 +000035statistics.add_metric('invalid_isa')
36statistics.add_metric('invalid_pointer')
37statistics.add_metric('unknown_class')
38statistics.add_metric('code_notrun')
39
40# despite the similary to synthetic children providers, these classes are not
41# trying to provide anything but a summary for a CF*BitVector, so they need not
42# obey the interface specification for synthetic children providers
43class CFBitVectorKnown_SummaryProvider:
44 def adjust_for_architecture(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000045 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +000046 self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
47 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +000048
49 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000050 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000051 self.valobj = valobj;
52 self.sys_params = params
Enrico Granatacfdafa32012-03-05 19:56:33 +000053 if not(self.sys_params.types_cache.NSUInteger):
54 if self.sys_params.is_64_bit:
55 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
56 else:
57 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
58 if not(self.sys_params.types_cache.charptr):
59 self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
Enrico Granata385ad4e2012-03-03 00:45:57 +000060 self.update();
61
62 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000063 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +000064 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +000065
66 # we skip the CFRuntimeBase
67 # then the next CFIndex is the count
68 # then we skip another CFIndex and then we get at a byte array
69 # that wraps the individual bits
70
71 def contents(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000072 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +000073 count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size,
74 self.sys_params.types_cache.NSUInteger)
Enrico Granata385ad4e2012-03-03 00:45:57 +000075 count = count_vo.GetValueAsUnsigned(0)
76 if count == 0:
77 return '(empty)'
78
79 array_vo = self.valobj.CreateChildAtOffset("data",
Enrico Granatacfdafa32012-03-05 19:56:33 +000080 self.sys_params.cfruntime_size+2*self.uiint_size,
81 self.sys_params.types_cache.charptr)
Enrico Granata385ad4e2012-03-03 00:45:57 +000082
83 data_list = []
84 cur_byte_pos = None
85 for i in range(0,count):
86 if cur_byte_pos == None:
87 cur_byte_pos = byte_index(i)
88 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
89 cur_byte_val = cur_byte.uint8[0]
90 else:
91 byte_pos = byte_index(i)
92 # do not fetch the pointee data every single time through
93 if byte_pos != cur_byte_pos:
94 cur_byte_pos = byte_pos
95 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
96 cur_byte_val = cur_byte.uint8[0]
97 bit = get_bit(cur_byte_val,bit_index(i))
98 if (i % 4) == 0:
99 data_list.append(' ')
100 if bit == 1:
101 data_list.append('1')
102 else:
103 data_list.append('0')
104 return ''.join(data_list)
105
106
107class CFBitVectorUnknown_SummaryProvider:
108 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000109 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +0000110
Enrico Granatacfdafa32012-03-05 19:56:33 +0000111 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +0000112 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +0000113 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000114 self.sys_params = params
115 self.update();
Enrico Granata385ad4e2012-03-03 00:45:57 +0000116
117 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000118 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +0000119 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +0000120
121 def contents(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000122 logger = lldb.formatters.Logger.Logger()
Enrico Granata3f1052b2012-03-13 21:52:00 +0000123 return '<unable to summarize this CFBitVector>'
Enrico Granata385ad4e2012-03-03 00:45:57 +0000124
125
126def GetSummary_Impl(valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000127 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +0000128 global statistics
Enrico Granata7d222212012-04-25 17:53:41 +0000129 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000130 if wrapper:
131 return wrapper
Enrico Granata385ad4e2012-03-03 00:45:57 +0000132
133 name_string = class_data.class_name()
Enrico Granata3f1052b2012-03-13 21:52:00 +0000134 actual_name = name_string
Enrico Granata247bd412012-04-02 16:39:29 +0000135
136 logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
137
Enrico Granata3f1052b2012-03-13 21:52:00 +0000138 if class_data.is_cftype():
Enrico Granata385ad4e2012-03-03 00:45:57 +0000139 # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
140 # an NSCFType and then check we are a pointer-to CFBitVectorRef
141 valobj_type = valobj.GetType()
142 if valobj_type.IsValid() and valobj_type.IsPointerType():
Enrico Granata3f1052b2012-03-13 21:52:00 +0000143 valobj_type = valobj_type.GetPointeeType()
144 if valobj_type.IsValid():
145 actual_name = valobj_type.GetName()
146 if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector':
147 wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
148 statistics.metric_hit('code_notrun',valobj)
149 else:
150 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
151 print actual_name
Enrico Granata385ad4e2012-03-03 00:45:57 +0000152 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000153 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata385ad4e2012-03-03 00:45:57 +0000154 print name_string
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000155 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granata385ad4e2012-03-03 00:45:57 +0000156 return wrapper;
157
158def CFBitVector_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000159 logger = lldb.formatters.Logger.Logger()
Enrico Granata385ad4e2012-03-03 00:45:57 +0000160 provider = GetSummary_Impl(valobj);
161 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000162 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000163 return provider.message()
164 try:
165 summary = provider.contents();
166 except:
167 summary = None
Enrico Granata247bd412012-04-02 16:39:29 +0000168 logger >> "summary got from provider: " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000169 if summary == None or summary == '':
170 summary = '<variable is not CFBitVector>'
171 return summary
172 return 'Summary Unavailable'
Enrico Granata385ad4e2012-03-03 00:45:57 +0000173
174def __lldb_init_module(debugger,dict):
175 debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")