NSMachPort.py revision f2a84671ff78bee1f82b60698f3ee9791585f8ac
1# 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 port number of an NSMachPort, so they need not
15# obey the interface specification for synthetic children providers
16class NSMachPortKnown_SummaryProvider:
17	def adjust_for_architecture(self):
18		pass
19
20	def __init__(self, valobj, params):
21		self.valobj = valobj;
22		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)
28		self.update();
29
30	def update(self):
31		self.adjust_for_architecture();
32
33	# one pointer is the ISA
34	# then we have one other internal pointer, plus
35	# 4 bytes worth of flags. hence, these values
36	def offset(self):
37		if self.sys_params.is_64_bit:
38			return 20
39		else:
40			return 12
41
42	def port(self):
43		vport = self.valobj.CreateChildAtOffset("port",
44							self.offset(),
45							self.sys_params.types_cache.NSUInteger)
46		return vport.GetValueAsUnsigned(0)
47
48
49class NSMachPortUnknown_SummaryProvider:
50	def adjust_for_architecture(self):
51		pass
52
53	def __init__(self, valobj, params):
54		self.valobj = valobj;
55		self.sys_params = params
56		self.update();
57
58	def update(self):
59		self.adjust_for_architecture();
60
61	def port(self):
62		stream = lldb.SBStream()
63		self.valobj.GetExpressionPath(stream)
64		num_children_vo = self.valobj.CreateValueFromExpression("port","(int)[" + stream.GetData() + " machPort]");
65		return num_children_vo.GetValueAsUnsigned(0)
66
67
68def GetSummary_Impl(valobj):
69	global statistics
70	class_data = objc_runtime.ObjCRuntime(valobj)
71	if class_data.is_valid() == False:
72		statistics.metric_hit('invalid_pointer',valobj)
73		wrapper = None
74		return
75	class_data = class_data.read_class_data()
76	if class_data.is_valid() == False:
77		statistics.metric_hit('invalid_isa',valobj)
78		wrapper = None
79		return
80	if class_data.is_kvo():
81		class_data = class_data.get_superclass()
82	if class_data.is_valid() == False:
83		statistics.metric_hit('invalid_isa',valobj)
84		wrapper = None
85		return
86
87	name_string = class_data.class_name()
88	if name_string == 'NSMachPort':
89		wrapper = NSMachPortKnown_SummaryProvider(valobj, class_data.sys_params)
90		statistics.metric_hit('code_notrun',valobj)
91	else:
92		wrapper = NSMachPortUnknown_SummaryProvider(valobj, class_data.sys_params)
93		statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
94	return wrapper;
95
96def NSMachPort_SummaryProvider (valobj,dict):
97	provider = GetSummary_Impl(valobj);
98	if provider != None:
99	    try:
100	        summary = provider.port();
101	    except:
102	        summary = None
103	    if summary == None:
104	        summary = 'no valid mach port here'
105	    return 'mach port: ' + str(summary)
106	return ''
107
108def __lldb_init_module(debugger,dict):
109	debugger.HandleCommand("type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort")
110