LLDB mainline
GNUstepObjCRuntime.cpp
Go to the documentation of this file.
1//===-- GNUstepObjCRuntime.cpp --------------------------------------------===//
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
10
12
13#include "lldb/Core/Module.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
27
29
32 GetPluginNameStatic(), "GNUstep Objective-C Language Runtime - libobjc2",
34}
35
38}
39
40static bool CanModuleBeGNUstepObjCLibrary(const ModuleSP &module_sp,
41 const llvm::Triple &TT) {
42 if (!module_sp)
43 return false;
44 const FileSpec &module_file_spec = module_sp->GetFileSpec();
45 if (!module_file_spec)
46 return false;
47 llvm::StringRef filename = module_file_spec.GetFilename().GetStringRef();
48 if (TT.isOSBinFormatELF())
49 return filename.starts_with("libobjc.so");
50 if (TT.isOSWindows())
51 return filename == "objc.dll";
52 return false;
53}
54
56 const llvm::Triple &TT) {
57 std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
58 size_t num_modules = modules.GetSize();
59 for (size_t i = 0; i < num_modules; i++) {
60 auto mod = modules.GetModuleAtIndex(i);
62 return true;
63 }
64 return false;
65}
66
68 LanguageType language) {
69 if (language != eLanguageTypeObjC)
70 return nullptr;
71 if (!process)
72 return nullptr;
73
74 Target &target = process->GetTarget();
75 const llvm::Triple &TT = target.GetArchitecture().GetTriple();
76 if (TT.getVendor() == llvm::Triple::VendorType::Apple)
77 return nullptr;
78
79 const ModuleList &images = target.GetImages();
81 return nullptr;
82
83 if (TT.isOSBinFormatELF()) {
84 SymbolContextList eh_pers;
85 RegularExpression regex("__gnustep_objc[x]*_personality_v[0-9]+");
87 if (eh_pers.GetSize() == 0)
88 return nullptr;
89 } else if (TT.isOSWindows()) {
90 SymbolContextList objc_mandatory;
91 images.FindSymbolsWithNameAndType(ConstString("__objc_load"),
92 eSymbolTypeCode, objc_mandatory);
93 if (objc_mandatory.GetSize() == 0)
94 return nullptr;
95 }
96
97 return new GNUstepObjCRuntime(process);
98}
99
101
103 : ObjCLanguageRuntime(process), m_objc_module_sp(nullptr) {
105}
106
108 ValueObject &valobj) {
109 return llvm::createStringError(
110 "LLDB's GNUStep runtime does not support object description");
111}
112
113llvm::Error
115 ExecutionContextScope *exe_scope) {
116 return llvm::createStringError(
117 "LLDB's GNUStep runtime does not support object description");
118}
119
121 static constexpr bool check_cxx = false;
122 static constexpr bool check_objc = true;
123 return in_value.GetCompilerType().IsPossibleDynamicType(nullptr, check_cxx,
124 check_objc);
125}
126
128 ValueObject &in_value, DynamicValueType use_dynamic,
129 TypeAndOrName &class_type_or_name, Address &address,
130 Value::ValueType &value_type) {
131 return false;
132}
133
136 ValueObject &static_value) {
137 CompilerType static_type(static_value.GetCompilerType());
138 Flags static_type_flags(static_type.GetTypeInfo());
139
140 TypeAndOrName ret(type_and_or_name);
141 if (type_and_or_name.HasType()) {
142 // The type will always be the type of the dynamic object. If our parent's
143 // type was a pointer, then our type should be a pointer to the type of the
144 // dynamic object. If a reference, then the original type should be
145 // okay...
146 CompilerType orig_type = type_and_or_name.GetCompilerType();
147 CompilerType corrected_type = orig_type;
148 if (static_type_flags.AllSet(eTypeIsPointer))
149 corrected_type = orig_type.GetPointerType();
150 ret.SetCompilerType(corrected_type);
151 } else {
152 // If we are here we need to adjust our dynamic type name to include the
153 // correct & or * symbol
154 std::string corrected_name(type_and_or_name.GetName().GetCString());
155 if (static_type_flags.AllSet(eTypeIsPointer))
156 corrected_name.append(" *");
157 // the parent type should be a correctly pointer'ed or referenc'ed type
158 ret.SetCompilerType(static_type);
159 ret.SetName(corrected_name.c_str());
160 }
161 return ret;
162}
163
166 bool catch_bp, bool throw_bp) {
167 BreakpointResolverSP resolver_sp;
168
169 if (throw_bp)
170 resolver_sp = std::make_shared<BreakpointResolverName>(
171 bkpt, "objc_exception_throw", eFunctionNameTypeBase,
173
174 return resolver_sp;
175}
176
177llvm::Expected<std::unique_ptr<UtilityFunction>>
179 ExecutionContext &exe_ctx) {
180 // TODO: This function is supposed to check whether an ObjC selector is
181 // present for an object. Might be implemented similar as in the Apple V2
182 // runtime.
183 const char *function_template = R"(
184 extern "C" void
185 %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {}
186 )";
187
188 char empty_function_code[2048];
189 int len = ::snprintf(empty_function_code, sizeof(empty_function_code),
190 function_template, name.c_str());
191
192 assert(len < (int)sizeof(empty_function_code));
194
195 return GetTargetRef().CreateUtilityFunction(empty_function_code, name,
196 eLanguageTypeC, exe_ctx);
197}
198
201 bool stop_others) {
202 // TODO: Implement this properly to avoid stepping into things like PLT stubs
203 return nullptr;
204}
205
207 // TODO: Support lazily named and dynamically loaded Objective-C classes
208}
209
211 const llvm::Triple &TT = GetTargetRef().GetArchitecture().GetTriple();
212 return CanModuleBeGNUstepObjCLibrary(module_sp, TT);
213}
214
216 assert(m_objc_module_sp == nullptr && "Check HasReadObjCLibrary() first");
217 m_objc_module_sp = module_sp;
218
219 // Right now we don't use this, but we might want to check for debugger
220 // runtime support symbols like 'gdb_object_getClass' in the future.
221 return true;
222}
223
225 ReadObjCLibraryIfNeeded(module_list);
226}
static bool ScanForGNUstepObjCLibraryCandidate(const ModuleList &modules, const llvm::Triple &TT)
static bool CanModuleBeGNUstepObjCLibrary(const ModuleSP &module_sp, const llvm::Triple &TT)
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:32
A section + offset based address class.
Definition: Address.h:62
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, bool check_objc) const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
A uniqued constant string class.
Definition: ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition: FileSpec.h:56
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:240
A class to manage flags.
Definition: Flags.h:22
bool AllSet(ValueType mask) const
Test if all bits in mask are 1 in the current flags.
Definition: Flags.h:83
bool CouldHaveDynamicValue(ValueObject &in_value) override
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) override
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override
TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
bool ReadObjCLibrary(const lldb::ModuleSP &module_sp) override
bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp) override
static llvm::StringRef GetPluginNameStatic()
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override
llvm::Error GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override
lldb::BreakpointResolverSP CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) override
void ModulesDidLoad(const ModuleList &module_list) override
Called when modules have been loaded in the process.
A collection class for Module objects.
Definition: ModuleList.h:103
std::recursive_mutex & GetMutex() const
Definition: ModuleList.h:230
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:527
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
Definition: ModuleList.cpp:429
void FindSymbolsMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:535
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:638
void ReadObjCLibraryIfNeeded(const ModuleList &module_list)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
Definition: Process.h:341
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1279
Target & GetTargetRef()
Definition: Runtime.h:23
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateUtilityFunction(std::string expression, std::string name, lldb::LanguageType language, ExecutionContext &exe_ctx)
Creates and installs a UtilityFunction for the given language.
Definition: Target.cpp:2567
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:981
const ArchSpec & GetArchitecture() const
Definition: Target.h:1023
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
Definition: Type.h:743
void SetName(ConstString type_name)
Definition: Type.cpp:878
CompilerType GetCompilerType() const
Definition: Type.h:757
ConstString GetName() const
Definition: Type.cpp:870
void SetCompilerType(CompilerType compiler_type)
Definition: Type.cpp:898
bool HasType() const
Definition: Type.h:775
CompilerType GetCompilerType()
Definition: ValueObject.h:352
ValueType
Type that describes Value::m_value.
Definition: Value.h:41
#define UNUSED_IF_ASSERT_DISABLED(x)
Definition: lldb-defines.h:140
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
Definition: lldb-forward.h:448
std::shared_ptr< lldb_private::BreakpointResolver > BreakpointResolverSP
Definition: lldb-forward.h:325
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:318
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:370