blob: 6eea6ca66816e5c8948dfef60ac6725db045c5a6 [file] [log] [blame]
Enrico Granata3f1052b2012-03-13 21:52:00 +00001"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
Enrico Granata50b5ee52013-03-16 00:50:25 +00008# example summary provider for NSMachPort
9# the real summary is now C++ code built into LLDB
Enrico Granataeb4a4792012-02-23 23:10:27 +000010import lldb
11import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000012import lldb.runtime.objc.objc_runtime
13import lldb.formatters.metrics
14import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000015
Enrico Granata28399ad2012-04-25 01:39:27 +000016statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000017statistics.add_metric('invalid_isa')
18statistics.add_metric('invalid_pointer')
19statistics.add_metric('unknown_class')
20statistics.add_metric('code_notrun')
21
22# despite the similary to synthetic children providers, these classes are not
23# trying to provide anything but the port number of an NSMachPort, so they need not
24# obey the interface specification for synthetic children providers
Kate Stoneb9c1b512016-09-06 20:57:50 +000025
26
Enrico Granataeb4a4792012-02-23 23:10:27 +000027class NSMachPortKnown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000028
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 def adjust_for_architecture(self):
30 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 def __init__(self, valobj, params):
33 logger = lldb.formatters.Logger.Logger()
34 self.valobj = valobj
35 self.sys_params = params
36 if not(self.sys_params.types_cache.NSUInteger):
37 if self.sys_params.is_64_bit:
38 self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
39 ).GetBasicType(lldb.eBasicTypeUnsignedLong)
40 else:
41 self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
42 ).GetBasicType(lldb.eBasicTypeUnsignedInt)
43 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000044
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 def update(self):
46 logger = lldb.formatters.Logger.Logger()
47 self.adjust_for_architecture()
Enrico Granataeb4a4792012-02-23 23:10:27 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 # one pointer is the ISA
50 # then we have one other internal pointer, plus
51 # 4 bytes worth of flags. hence, these values
52 def offset(self):
53 logger = lldb.formatters.Logger.Logger()
54 if self.sys_params.is_64_bit:
55 return 20
56 else:
57 return 12
58
59 def port(self):
60 logger = lldb.formatters.Logger.Logger()
61 vport = self.valobj.CreateChildAtOffset(
62 "port", self.offset(), self.sys_params.types_cache.NSUInteger)
63 return vport.GetValueAsUnsigned(0)
Enrico Granataeb4a4792012-02-23 23:10:27 +000064
65
66class NSMachPortUnknown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000067
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 def adjust_for_architecture(self):
69 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 def __init__(self, valobj, params):
72 logger = lldb.formatters.Logger.Logger()
73 self.valobj = valobj
74 self.sys_params = params
75 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 def update(self):
78 logger = lldb.formatters.Logger.Logger()
79 self.adjust_for_architecture()
80
81 def port(self):
82 logger = lldb.formatters.Logger.Logger()
83 stream = lldb.SBStream()
84 self.valobj.GetExpressionPath(stream)
85 num_children_vo = self.valobj.CreateValueFromExpression(
86 "port", "(int)[" + stream.GetData() + " machPort]")
87 if num_children_vo.IsValid():
88 return num_children_vo.GetValueAsUnsigned(0)
89 return '<variable is not NSMachPort>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000090
91
92def GetSummary_Impl(valobj):
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 logger = lldb.formatters.Logger.Logger()
94 global statistics
95 class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
96 valobj, statistics)
97 if wrapper:
98 return wrapper
Enrico Granata247bd412012-04-02 16:39:29 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 name_string = class_data.class_name()
101 logger >> "class name is: " + str(name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 if name_string == 'NSMachPort':
104 wrapper = NSMachPortKnown_SummaryProvider(
105 valobj, class_data.sys_params)
106 statistics.metric_hit('code_notrun', valobj)
107 else:
108 wrapper = NSMachPortUnknown_SummaryProvider(
109 valobj, class_data.sys_params)
110 statistics.metric_hit(
111 'unknown_class',
112 valobj.GetName() +
113 " seen as " +
114 name_string)
115 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117
118def NSMachPort_SummaryProvider(valobj, dict):
119 logger = lldb.formatters.Logger.Logger()
120 provider = GetSummary_Impl(valobj)
121 if provider is not None:
122 if isinstance(
123 provider,
124 lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
125 return provider.message()
126 try:
127 summary = provider.port()
128 except:
129 summary = None
130 logger >> "got summary " + str(summary)
131 if summary is None:
132 summary = '<variable is not NSMachPort>'
133 if isinstance(summary, basestring):
134 return summay
135 return 'mach port: ' + str(summary)
136 return 'Summary Unavailable'
137
138
139def __lldb_init_module(debugger, dict):
140 debugger.HandleCommand(
141 "type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort")