blob: 1a5eafa4d88749da259bc919370c2e88b3e4a13b [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 Granataeb4a4792012-02-23 23:10:27 +00008# summary provider for NSData
9import lldb
10import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000011import lldb.runtime.objc.objc_runtime
12import lldb.formatters.metrics
13import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000014
Enrico Granata28399ad2012-04-25 01:39:27 +000015statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000016statistics.add_metric('invalid_isa')
17statistics.add_metric('invalid_pointer')
18statistics.add_metric('unknown_class')
19statistics.add_metric('code_notrun')
20
21# despite the similary to synthetic children providers, these classes are not
22# trying to provide anything but the length for an NSData, so they need not
23# obey the interface specification for synthetic children providers
24class NSConcreteData_SummaryProvider:
25 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000026 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000027
Enrico Granatacfdafa32012-03-05 19:56:33 +000028 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000029 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000030 logger >> "NSConcreteData_SummaryProvider __init__"
Enrico Granataeb4a4792012-02-23 23:10:27 +000031 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000032 self.sys_params = params
33 if not(self.sys_params.types_cache.NSUInteger):
34 if self.sys_params.is_64_bit:
35 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
36 else:
37 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
Enrico Granataeb4a4792012-02-23 23:10:27 +000038 self.update();
39
40 def update(self):
41 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000042
43 # one pointer is the ISA
44 # then there are 32 bit worth of flags and other data
45 # however, on 64bit systems these are padded to be a full
46 # machine word long, which means we actually have two pointers
47 # worth of data to skip
48 def offset(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000049 return 2 * self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000050
51 def length(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000052 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000053 logger >> "NSConcreteData_SummaryProvider length"
Enrico Granataeb4a4792012-02-23 23:10:27 +000054 size = self.valobj.CreateChildAtOffset("count",
55 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000056 self.sys_params.types_cache.NSUInteger)
Enrico Granatad50f18b2012-03-29 19:29:45 +000057 logger >> str(size)
58 logger >> str(size.GetValueAsUnsigned(0))
Enrico Granataeb4a4792012-02-23 23:10:27 +000059 return size.GetValueAsUnsigned(0)
60
61
62class NSDataUnknown_SummaryProvider:
63 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000064 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000065
Enrico Granatacfdafa32012-03-05 19:56:33 +000066 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000067 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000068 logger >> "NSDataUnknown_SummaryProvider __init__"
Enrico Granataeb4a4792012-02-23 23:10:27 +000069 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000070 self.sys_params = params
71 self.update();
Enrico Granataeb4a4792012-02-23 23:10:27 +000072
73 def update(self):
74 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000075
76 def length(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000077 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000078 logger >> "NSDataUnknown_SummaryProvider length"
Enrico Granataeb4a4792012-02-23 23:10:27 +000079 stream = lldb.SBStream()
80 self.valobj.GetExpressionPath(stream)
Enrico Granatad50f18b2012-03-29 19:29:45 +000081 logger >> stream.GetData()
Enrico Granataeb4a4792012-02-23 23:10:27 +000082 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " length]");
Enrico Granatad50f18b2012-03-29 19:29:45 +000083 logger >> "still in after expression: " + str(num_children_vo)
Enrico Granata3f1052b2012-03-13 21:52:00 +000084 if num_children_vo.IsValid():
Enrico Granatad50f18b2012-03-29 19:29:45 +000085 logger >> "wow - expr output is valid: " + str(num_children_vo.GetValueAsUnsigned())
Enrico Granata3f1052b2012-03-13 21:52:00 +000086 return num_children_vo.GetValueAsUnsigned(0)
Enrico Granatad50f18b2012-03-29 19:29:45 +000087 logger >> "invalid expr output - too bad"
Enrico Granata3f1052b2012-03-13 21:52:00 +000088 return '<variable is not NSData>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000089
90
91def GetSummary_Impl(valobj):
92 global statistics
Enrico Granata28399ad2012-04-25 01:39:27 +000093 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +000094 logger >> "NSData GetSummary_Impl"
Enrico Granata3f1052b2012-03-13 21:52:00 +000095 class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
96 if wrapper:
Enrico Granatad50f18b2012-03-29 19:29:45 +000097 logger >> "got a wrapper summary - using it"
Enrico Granata3f1052b2012-03-13 21:52:00 +000098 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +000099
100 name_string = class_data.class_name()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000101 logger >> "class name: " + name_string
Enrico Granataeb4a4792012-02-23 23:10:27 +0000102 if name_string == 'NSConcreteData' or \
103 name_string == 'NSConcreteMutableData' or \
104 name_string == '__NSCFData':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000105 wrapper = NSConcreteData_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000106 statistics.metric_hit('code_notrun',valobj)
107 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000108 wrapper = NSDataUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000109 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000110 return wrapper;
111
112def NSData_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000113 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000114 logger >> "NSData_SummaryProvider"
Enrico Granataeb4a4792012-02-23 23:10:27 +0000115 provider = GetSummary_Impl(valobj);
Enrico Granatad50f18b2012-03-29 19:29:45 +0000116 logger >> "found a summary provider, it is: " + str(provider)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000117 if provider != None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000118 try:
119 summary = provider.length();
120 except:
121 summary = None
Enrico Granatad50f18b2012-03-29 19:29:45 +0000122 logger >> "got a summary: it is " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000123 if summary == None:
124 summary = '<variable is not NSData>'
125 elif isinstance(summary,basestring):
126 pass
127 else:
128 if summary == 1:
129 summary = '1 byte'
130 else:
131 summary = str(summary) + ' bytes'
132 return summary
133 return 'Summary Unavailable'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000134
Enrico Granata8c69c962012-03-13 00:25:59 +0000135def NSData_SummaryProvider2 (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000136 logger = lldb.formatters.Logger.Logger()
Enrico Granatad50f18b2012-03-29 19:29:45 +0000137 logger >> "NSData_SummaryProvider2"
Enrico Granata8c69c962012-03-13 00:25:59 +0000138 provider = GetSummary_Impl(valobj);
Enrico Granatad50f18b2012-03-29 19:29:45 +0000139 logger >> "found a summary provider, it is: " + str(provider)
Enrico Granata8c69c962012-03-13 00:25:59 +0000140 if provider != None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000141 if isinstance(provider,objc_runtime.SpecialSituation_Description):
142 return provider.message()
143 try:
144 summary = provider.length();
145 except:
146 summary = None
Enrico Granatad50f18b2012-03-29 19:29:45 +0000147 logger >> "got a summary: it is " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000148 if summary == None:
149 summary = '<variable is not CFData>'
150 elif isinstance(summary,basestring):
151 pass
152 else:
153 if summary == 1:
154 summary = '@"1 byte"'
155 else:
156 summary = '@"' + str(summary) + ' bytes"'
157 return summary
158 return 'Summary Unavailable'
Enrico Granata8c69c962012-03-13 00:25:59 +0000159
Enrico Granataeb4a4792012-02-23 23:10:27 +0000160def __lldb_init_module(debugger,dict):
Enrico Granata8c69c962012-03-13 00:25:59 +0000161 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider NSData")
162 debugger.HandleCommand("type summary add -F NSData.NSData_SummaryProvider2 CFDataRef CFMutableDataRef")