xref: /openbsd-src/gnu/llvm/lldb/examples/summaries/cocoa/NSMachPort.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1"""
2LLDB AppKit formatters
3
4Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5See https://llvm.org/LICENSE.txt for license information.
6SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7"""
8# example summary provider for NSMachPort
9# the real summary is now C++ code built into LLDB
10import lldb
11import ctypes
12import lldb.runtime.objc.objc_runtime
13import lldb.formatters.metrics
14import lldb.formatters.Logger
15
16statistics = lldb.formatters.metrics.Metrics()
17statistics.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
25
26
27class NSMachPortKnown_SummaryProvider:
28
29    def adjust_for_architecture(self):
30        pass
31
32    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()
44
45    def update(self):
46        logger = lldb.formatters.Logger.Logger()
47        self.adjust_for_architecture()
48
49    # 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)
64
65
66class NSMachPortUnknown_SummaryProvider:
67
68    def adjust_for_architecture(self):
69        pass
70
71    def __init__(self, valobj, params):
72        logger = lldb.formatters.Logger.Logger()
73        self.valobj = valobj
74        self.sys_params = params
75        self.update()
76
77    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>'
90
91
92def GetSummary_Impl(valobj):
93    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
99
100    name_string = class_data.class_name()
101    logger >> "class name is: " + str(name_string)
102
103    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
116
117
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, str):
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")
142