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"""
8ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata# example summary provider for NSData
9ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata# the real summary is now C++ code built into LLDB
10b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb
11b370df27c76fd875f3312be487868528121a4838Enrico Granataimport ctypes
120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.runtime.objc.objc_runtime
130d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.metrics
140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger
15b370df27c76fd875f3312be487868528121a4838Enrico Granata
160d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics()
17b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa')
18b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer')
19b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class')
20b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun')
21b370df27c76fd875f3312be487868528121a4838Enrico Granata
22b370df27c76fd875f3312be487868528121a4838Enrico Granata# despite the similary to synthetic children providers, these classes are not
23b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but the length for an NSData, so they need not
24b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers
25b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSConcreteData_SummaryProvider:
26b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
28b370df27c76fd875f3312be487868528121a4838Enrico Granata
29f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
300d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
317e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "NSConcreteData_SummaryProvider __init__"
32b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		if not(self.sys_params.types_cache.NSUInteger):
35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			if self.sys_params.is_64_bit:
36f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
37f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			else:
38f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
39b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.update();
40b370df27c76fd875f3312be487868528121a4838Enrico Granata
41b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
42b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
43b370df27c76fd875f3312be487868528121a4838Enrico Granata
44b370df27c76fd875f3312be487868528121a4838Enrico Granata	# one pointer is the ISA
45b370df27c76fd875f3312be487868528121a4838Enrico Granata	# then there are 32 bit worth of flags and other data
46b370df27c76fd875f3312be487868528121a4838Enrico Granata	# however, on 64bit systems these are padded to be a full
47b370df27c76fd875f3312be487868528121a4838Enrico Granata	# machine word long, which means we actually have two pointers
48b370df27c76fd875f3312be487868528121a4838Enrico Granata	# worth of data to skip
49b370df27c76fd875f3312be487868528121a4838Enrico Granata	def offset(self):
50f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		return 2 * self.sys_params.pointer_size
51b370df27c76fd875f3312be487868528121a4838Enrico Granata
52b370df27c76fd875f3312be487868528121a4838Enrico Granata	def length(self):
530d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
547e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "NSConcreteData_SummaryProvider length"
55b370df27c76fd875f3312be487868528121a4838Enrico Granata		size = self.valobj.CreateChildAtOffset("count",
56b370df27c76fd875f3312be487868528121a4838Enrico Granata							self.offset(),
57f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.sys_params.types_cache.NSUInteger)
587e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> str(size)
597e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> str(size.GetValueAsUnsigned(0))
60b370df27c76fd875f3312be487868528121a4838Enrico Granata		return size.GetValueAsUnsigned(0)
61b370df27c76fd875f3312be487868528121a4838Enrico Granata
62b370df27c76fd875f3312be487868528121a4838Enrico Granata
63b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSDataUnknown_SummaryProvider:
64b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
65f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
66b370df27c76fd875f3312be487868528121a4838Enrico Granata
67f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
680d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
697e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "NSDataUnknown_SummaryProvider __init__"
70b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
71f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
72f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.update();
73b370df27c76fd875f3312be487868528121a4838Enrico Granata
74b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
75b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
76b370df27c76fd875f3312be487868528121a4838Enrico Granata
77b370df27c76fd875f3312be487868528121a4838Enrico Granata	def length(self):
780d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
797e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "NSDataUnknown_SummaryProvider length"
80b370df27c76fd875f3312be487868528121a4838Enrico Granata		stream = lldb.SBStream()
81b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj.GetExpressionPath(stream)
827e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> stream.GetData()
83b370df27c76fd875f3312be487868528121a4838Enrico Granata		num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
847e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "still in after expression: " + str(num_children_vo)
85579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if num_children_vo.IsValid():
867e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata			logger >> "wow - expr output is valid: " + str(num_children_vo.GetValueAsUnsigned())
87579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return num_children_vo.GetValueAsUnsigned(0)
887e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "invalid expr output - too bad"
89579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return '<variable is not NSData>'
90b370df27c76fd875f3312be487868528121a4838Enrico Granata
91b370df27c76fd875f3312be487868528121a4838Enrico Granata
92b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj):
93b370df27c76fd875f3312be487868528121a4838Enrico Granata	global statistics
940d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata	logger = lldb.formatters.Logger.Logger()
957e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "NSData GetSummary_Impl"
96a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata	class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
97579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	if wrapper:
987e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "got a wrapper summary - using it"
99579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return wrapper
100b370df27c76fd875f3312be487868528121a4838Enrico Granata
101b370df27c76fd875f3312be487868528121a4838Enrico Granata	name_string = class_data.class_name()
1027e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "class name: " + name_string
103b370df27c76fd875f3312be487868528121a4838Enrico Granata	if name_string == 'NSConcreteData' or \
104b370df27c76fd875f3312be487868528121a4838Enrico Granata	   name_string == 'NSConcreteMutableData' or \
105b370df27c76fd875f3312be487868528121a4838Enrico Granata	   name_string == '__NSCFData':
106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
107b370df27c76fd875f3312be487868528121a4838Enrico Granata		statistics.metric_hit('code_notrun',valobj)
108b370df27c76fd875f3312be487868528121a4838Enrico Granata	else:
109f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
110805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata		statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
111b370df27c76fd875f3312be487868528121a4838Enrico Granata	return wrapper;
112b370df27c76fd875f3312be487868528121a4838Enrico Granata
113b370df27c76fd875f3312be487868528121a4838Enrico Granatadef NSData_SummaryProvider (valobj,dict):
1140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata	logger = lldb.formatters.Logger.Logger()
1157e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "NSData_SummaryProvider"
116b370df27c76fd875f3312be487868528121a4838Enrico Granata	provider = GetSummary_Impl(valobj);
1177e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "found a summary provider, it is: " + str(provider)
118b370df27c76fd875f3312be487868528121a4838Enrico Granata	if provider != None:
119579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		try:
120579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = provider.length();
121579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		except:
122579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = None
1237e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "got a summary: it is " + str(summary)
124579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if summary == None:
125579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = '<variable is not NSData>'
126579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		elif isinstance(summary,basestring):
127579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			pass
128579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		else:
129579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			if summary == 1:
130579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata				summary = '1 byte'
131579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			else:
132579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata				summary = str(summary) + ' bytes'
133579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return summary
134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	return 'Summary Unavailable'
135b370df27c76fd875f3312be487868528121a4838Enrico Granata
1367b9aacf4a454465af905e505f74245173714b23bEnrico Granatadef NSData_SummaryProvider2 (valobj,dict):
1370d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata	logger = lldb.formatters.Logger.Logger()
1387e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "NSData_SummaryProvider2"
1397b9aacf4a454465af905e505f74245173714b23bEnrico Granata	provider = GetSummary_Impl(valobj);
1407e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata	logger >> "found a summary provider, it is: " + str(provider)
1417b9aacf4a454465af905e505f74245173714b23bEnrico Granata	if provider != None:
142a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata		if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
143579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return provider.message()
144579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		try:
145579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = provider.length();
146579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		except:
147579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = None
1487e202269d09cebf2f5047bf92fff8c8ecf732448Enrico Granata		logger >> "got a summary: it is " + str(summary)
149579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if summary == None:
150579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = '<variable is not CFData>'
151579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		elif isinstance(summary,basestring):
152579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			pass
153579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		else:
154579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			if summary == 1:
155579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata				summary = '@"1 byte"'
156579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			else:
157579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata				summary = '@"' + str(summary) + ' bytes"'
158579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return summary
159579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	return 'Summary Unavailable'
1607b9aacf4a454465af905e505f74245173714b23bEnrico Granata
161b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict):
1627b9aacf4a454465af905e505f74245173714b23bEnrico Granata	debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")
1637b9aacf4a454465af905e505f74245173714b23bEnrico Granata	debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")
164