blob: d2d2515e48f92183e6a392a27a7542c010147a14 [file] [log] [blame]
Enrico Granataeb4a4792012-02-23 23:10:27 +00001# summary provider for NSData
2import lldb
3import ctypes
4import objc_runtime
5import metrics
6
7statistics = metrics.Metrics()
8statistics.add_metric('invalid_isa')
9statistics.add_metric('invalid_pointer')
10statistics.add_metric('unknown_class')
11statistics.add_metric('code_notrun')
12
13# despite the similary to synthetic children providers, these classes are not
14# trying to provide anything but the length for an NSData, so they need not
15# obey the interface specification for synthetic children providers
16class NSConcreteData_SummaryProvider:
17 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000018 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000019
Enrico Granatacfdafa32012-03-05 19:56:33 +000020 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000021 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000022 self.sys_params = params
23 if not(self.sys_params.types_cache.NSUInteger):
24 if self.sys_params.is_64_bit:
25 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
26 else:
27 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
Enrico Granataeb4a4792012-02-23 23:10:27 +000028 self.update();
29
30 def update(self):
31 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000032
33 # one pointer is the ISA
34 # then there are 32 bit worth of flags and other data
35 # however, on 64bit systems these are padded to be a full
36 # machine word long, which means we actually have two pointers
37 # worth of data to skip
38 def offset(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000039 return 2 * self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000040
41 def length(self):
42 size = self.valobj.CreateChildAtOffset("count",
43 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000044 self.sys_params.types_cache.NSUInteger)
Enrico Granataeb4a4792012-02-23 23:10:27 +000045 return size.GetValueAsUnsigned(0)
46
47
48class NSDataUnknown_SummaryProvider:
49 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000050 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000051
Enrico Granatacfdafa32012-03-05 19:56:33 +000052 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000053 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000054 self.sys_params = params
55 self.update();
Enrico Granataeb4a4792012-02-23 23:10:27 +000056
57 def update(self):
58 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000059
60 def length(self):
61 stream = lldb.SBStream()
62 self.valobj.GetExpressionPath(stream)
63 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
64 return num_children_vo.GetValueAsUnsigned(0)
65
66
67def GetSummary_Impl(valobj):
68 global statistics
69 class_data = objc_runtime.ObjCRuntime(valobj)
70 if class_data.is_valid() == False:
71 statistics.metric_hit('invalid_pointer',valobj)
72 wrapper = None
73 return
74 class_data = class_data.read_class_data()
75 if class_data.is_valid() == False:
76 statistics.metric_hit('invalid_isa',valobj)
77 wrapper = None
78 return
79 if class_data.is_kvo():
80 class_data = class_data.get_superclass()
81 if class_data.is_valid() == False:
82 statistics.metric_hit('invalid_isa',valobj)
83 wrapper = None
84 return
85
86 name_string = class_data.class_name()
87 if name_string == 'NSConcreteData' or \
88 name_string == 'NSConcreteMutableData' or \
89 name_string == '__NSCFData':
Enrico Granatacfdafa32012-03-05 19:56:33 +000090 wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +000091 statistics.metric_hit('code_notrun',valobj)
92 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +000093 wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +000094 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
95 return wrapper;
96
97def NSData_SummaryProvider (valobj,dict):
98 provider = GetSummary_Impl(valobj);
99 if provider != None:
100 try:
101 summary = provider.length();
102 except:
103 summary = None
104 if summary == None:
105 summary = 'no valid data here'
Enrico Granataeb06e252012-03-07 00:56:09 +0000106 else:
107 if summary == 1:
108 summary = '1 byte'
109 else:
110 summary = str(summary) + ' bytes'
111 return summary
Enrico Granataeb4a4792012-02-23 23:10:27 +0000112 return ''
113
Enrico Granata8c69c962012-03-13 00:25:59 +0000114def NSData_SummaryProvider2 (valobj,dict):
115 provider = GetSummary_Impl(valobj);
116 if provider != None:
117 try:
118 summary = provider.length();
119 except:
120 summary = None
121 if summary == None:
122 summary = 'no valid data here'
123 else:
124 if summary == 1:
125 summary = '@"1 byte"'
126 else:
127 summary = '@"' + str(summary) + ' bytes"'
128 return summary
129 return ''
130
Enrico Granataeb4a4792012-02-23 23:10:27 +0000131def __lldb_init_module(debugger,dict):
Enrico Granata8c69c962012-03-13 00:25:59 +0000132 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")
133 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")