NSMachPort.py revision b370df27c76fd875f3312be487868528121a4838
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		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
19		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)
29		self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
30
31	# one pointer is the ISA
32	# then we have one other internal pointer, plus
33	# 4 bytes worth of flags. hence, these values
34	def offset(self):
35		if self.lp64:
36			return 20
37		else:
38			return 12
39
40	def port(self):
41		vport = self.valobj.CreateChildAtOffset("port",
42							self.offset(),
43							self.NSUInteger)
44		return vport.GetValueAsUnsigned(0)
45
46
47class NSMachPortUnknown_SummaryProvider:
48	def adjust_for_architecture(self):
49		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
50		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
51		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
52
53	def __init__(self, valobj):
54		self.valobj = valobj;
55		self.update()
56
57	def update(self):
58		self.adjust_for_architecture();
59		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
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)
90		statistics.metric_hit('code_notrun',valobj)
91	else:
92		wrapper = NSMachPortUnknown_SummaryProvider(valobj)
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