blob: 9acb2fefb3215aecd4d43577a39f2ef8f812c60d [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 Granata7bc0ec32012-02-29 03:28:49 +000018 self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
Enrico Granataeb4a4792012-02-23 23:10:27 +000019 self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
20 self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
21
22 def __init__(self, valobj):
23 self.valobj = valobj;
24 self.update();
25
26 def update(self):
27 self.adjust_for_architecture();
28 self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
Enrico Granata7bc0ec32012-02-29 03:28:49 +000029 if self.is_64_bit:
Enrico Granataeb4a4792012-02-23 23:10:27 +000030 self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
31 else:
32 self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
33
34 # one pointer is the ISA
35 # then there are 32 bit worth of flags and other data
36 # however, on 64bit systems these are padded to be a full
37 # machine word long, which means we actually have two pointers
38 # worth of data to skip
39 def offset(self):
Enrico Granata7bc0ec32012-02-29 03:28:49 +000040 if self.is_64_bit:
Enrico Granataeb4a4792012-02-23 23:10:27 +000041 return 16
42 else:
43 return 8
44
45 def length(self):
46 size = self.valobj.CreateChildAtOffset("count",
47 self.offset(),
48 self.NSUInteger)
49 return size.GetValueAsUnsigned(0)
50
51
52class NSDataUnknown_SummaryProvider:
53 def adjust_for_architecture(self):
Enrico Granata7bc0ec32012-02-29 03:28:49 +000054 self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
Enrico Granataeb4a4792012-02-23 23:10:27 +000055 self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
56 self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
57
58 def __init__(self, valobj):
59 self.valobj = valobj;
60 self.update()
61
62 def update(self):
63 self.adjust_for_architecture();
64 self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
65
66 def length(self):
67 stream = lldb.SBStream()
68 self.valobj.GetExpressionPath(stream)
69 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
70 return num_children_vo.GetValueAsUnsigned(0)
71
72
73def GetSummary_Impl(valobj):
74 global statistics
75 class_data = objc_runtime.ObjCRuntime(valobj)
76 if class_data.is_valid() == False:
77 statistics.metric_hit('invalid_pointer',valobj)
78 wrapper = None
79 return
80 class_data = class_data.read_class_data()
81 if class_data.is_valid() == False:
82 statistics.metric_hit('invalid_isa',valobj)
83 wrapper = None
84 return
85 if class_data.is_kvo():
86 class_data = class_data.get_superclass()
87 if class_data.is_valid() == False:
88 statistics.metric_hit('invalid_isa',valobj)
89 wrapper = None
90 return
91
92 name_string = class_data.class_name()
93 if name_string == 'NSConcreteData' or \
94 name_string == 'NSConcreteMutableData' or \
95 name_string == '__NSCFData':
96 wrapper = NSConcreteData_SummaryProvider(valobj)
97 statistics.metric_hit('code_notrun',valobj)
98 else:
99 wrapper = NSDataUnknown_SummaryProvider(valobj)
100 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
101 return wrapper;
102
103def NSData_SummaryProvider (valobj,dict):
104 provider = GetSummary_Impl(valobj);
105 if provider != None:
106 try:
107 summary = provider.length();
108 except:
109 summary = None
110 if summary == None:
111 summary = 'no valid data here'
112 if summary == 1:
113 return '1 byte'
114 return str(summary) + " bytes"
115 return ''
116
117def __lldb_init_module(debugger,dict):
118 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData CFDataRef CFMutableDataRef")