1 //===-- AppleObjCRuntime.h --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
10 #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
11 
12 
13 #include "AppleObjCTrampolineHandler.h"
14 #include "AppleThreadPlanStepThroughObjCTrampoline.h"
15 #include "lldb/Target/LanguageRuntime.h"
16 #include "lldb/lldb-private.h"
17 
18 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
19 #include <optional>
20 
21 namespace lldb_private {
22 
23 class AppleObjCRuntime : public lldb_private::ObjCLanguageRuntime {
24 public:
25   ~AppleObjCRuntime() override;
26 
27   // Static Functions
28   // Note there is no CreateInstance, Initialize & Terminate functions here,
29   // because
30   // you can't make an instance of this generic runtime.
31 
32   static char ID;
33 
34   static void Initialize();
35 
36   static void Terminate();
37 
isA(const void * ClassID)38   bool isA(const void *ClassID) const override {
39     return ClassID == &ID || ObjCLanguageRuntime::isA(ClassID);
40   }
41 
classof(const LanguageRuntime * runtime)42   static bool classof(const LanguageRuntime *runtime) {
43     return runtime->isA(&ID);
44   }
45 
46   // These are generic runtime functions:
47   llvm::Error GetObjectDescription(Stream &str, Value &value,
48                                    ExecutionContextScope *exe_scope) override;
49 
50   llvm::Error GetObjectDescription(Stream &str, ValueObject &object) override;
51 
52   bool CouldHaveDynamicValue(ValueObject &in_value) override;
53 
54   bool GetDynamicTypeAndAddress(ValueObject &in_value,
55                                 lldb::DynamicValueType use_dynamic,
56                                 TypeAndOrName &class_type_or_name,
57                                 Address &address,
58                                 Value::ValueType &value_type) override;
59 
60   TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
61                                  ValueObject &static_value) override;
62 
63   // These are the ObjC specific functions.
64 
65   bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp) override;
66 
67   bool ReadObjCLibrary(const lldb::ModuleSP &module_sp) override;
68 
HasReadObjCLibrary()69   bool HasReadObjCLibrary() override { return m_read_objc_library; }
70 
71   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
72                                                   bool stop_others) override;
73 
74   // Get the "libobjc.A.dylib" module from the current target if we can find
75   // it, also cache it once it is found to ensure quick lookups.
76   lldb::ModuleSP GetObjCModule();
77 
78   // Sync up with the target
79 
80   void ModulesDidLoad(const ModuleList &module_list) override;
81 
82   void SetExceptionBreakpoints() override;
83 
84   void ClearExceptionBreakpoints() override;
85 
86   bool ExceptionBreakpointsAreSet() override;
87 
88   bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
89 
90   lldb::SearchFilterSP CreateExceptionSearchFilter() override;
91 
92   static std::tuple<FileSpec, ConstString> GetExceptionThrowLocation();
93 
94   lldb::ValueObjectSP GetExceptionObjectForThread(
95       lldb::ThreadSP thread_sp) override;
96 
97   lldb::ThreadSP GetBacktraceThreadFromException(
98       lldb::ValueObjectSP thread_sp) override;
99 
100   uint32_t GetFoundationVersion();
101 
102   virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
103                                             lldb::addr_t &cf_false);
104 
IsTaggedPointer(lldb::addr_t addr)105   virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; }
106 
107 protected:
108   // Call CreateInstance instead.
109   AppleObjCRuntime(Process *process);
110 
111   bool CalculateHasNewLiteralsAndIndexing() override;
112 
113   static bool AppleIsModuleObjCLibrary(const lldb::ModuleSP &module_sp);
114 
115   static ObjCRuntimeVersions GetObjCVersion(Process *process,
116                                             lldb::ModuleSP &objc_module_sp);
117 
118   void ReadObjCLibraryIfNeeded(const ModuleList &module_list);
119 
120   Address *GetPrintForDebuggerAddr();
121 
122   std::unique_ptr<Address> m_PrintForDebugger_addr;
123   bool m_read_objc_library;
124   std::unique_ptr<lldb_private::AppleObjCTrampolineHandler>
125       m_objc_trampoline_handler_up;
126   lldb::BreakpointSP m_objc_exception_bp_sp;
127   lldb::ModuleWP m_objc_module_wp;
128   std::unique_ptr<FunctionCaller> m_print_object_caller_up;
129 
130   std::optional<uint32_t> m_Foundation_major;
131 };
132 
133 } // namespace lldb_private
134 
135 #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
136