1//===-- LanguageRuntime.h ---------------------------------------------------*- 2// C++ -*-===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef LLDB_TARGET_LANGUAGERUNTIME_H 11#define LLDB_TARGET_LANGUAGERUNTIME_H 12 13#include "lldb/Breakpoint/BreakpointResolver.h" 14#include "lldb/Breakpoint/BreakpointResolverName.h" 15#include "lldb/Core/PluginInterface.h" 16#include "lldb/Core/Value.h" 17#include "lldb/Core/ValueObject.h" 18#include "lldb/Expression/LLVMUserExpression.h" 19#include "lldb/Symbol/DeclVendor.h" 20#include "lldb/Target/ExecutionContextScope.h" 21#include "lldb/Target/Runtime.h" 22#include "lldb/lldb-private.h" 23#include "lldb/lldb-public.h" 24#include <optional> 25 26namespace lldb_private { 27 28class ExceptionSearchFilter : public SearchFilter { 29public: 30 ExceptionSearchFilter(const lldb::TargetSP &target_sp, 31 lldb::LanguageType language, 32 bool update_module_list = true); 33 34 ~ExceptionSearchFilter() override = default; 35 36 bool ModulePasses(const lldb::ModuleSP &module_sp) override; 37 38 bool ModulePasses(const FileSpec &spec) override; 39 40 void Search(Searcher &searcher) override; 41 42 void GetDescription(Stream *s) override; 43 44 static SearchFilter * 45 CreateFromStructuredData(Target &target, 46 const StructuredData::Dictionary &data_dict, 47 Status &error); 48 49 StructuredData::ObjectSP SerializeToStructuredData() override; 50 51protected: 52 lldb::LanguageType m_language; 53 LanguageRuntime *m_language_runtime; 54 lldb::SearchFilterSP m_filter_sp; 55 56 lldb::SearchFilterSP DoCreateCopy() override; 57 58 void UpdateModuleListIfNeeded(); 59}; 60 61class LanguageRuntime : public Runtime, public PluginInterface { 62public: 63 static LanguageRuntime *FindPlugin(Process *process, 64 lldb::LanguageType language); 65 66 static void InitializeCommands(CommandObject *parent); 67 68 virtual lldb::LanguageType GetLanguageType() const = 0; 69 70 /// Return the preferred language runtime instance, which in most cases will 71 /// be the current instance. 72 virtual LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) { 73 return nullptr; 74 } 75 76 virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0; 77 78 virtual bool GetObjectDescription(Stream &str, Value &value, 79 ExecutionContextScope *exe_scope) = 0; 80 81 82 struct VTableInfo { 83 Address addr; /// Address of the vtable's virtual function table 84 Symbol *symbol; /// The vtable symbol from the symbol table 85 }; 86 /// Get the vtable information for a given value. 87 /// 88 /// \param[in] in_value 89 /// The value object to try and extract the VTableInfo from. 90 /// 91 /// \param[in] check_type 92 /// If true, the compiler type of \a in_value will be checked to see if 93 /// it is an instance to, or pointer or reference to a class or struct 94 /// that has a vtable. If the type doesn't meet the requirements, an 95 /// error will be returned explaining why the type isn't suitable. 96 /// 97 /// \return 98 /// An error if anything goes wrong while trying to extract the vtable 99 /// or if \a check_type is true and the type doesn't have a vtable. 100 virtual llvm::Expected<VTableInfo> GetVTableInfo(ValueObject &in_value, 101 bool check_type) { 102 return llvm::createStringError( 103 std::errc::invalid_argument, 104 "language doesn't support getting vtable information"); 105 } 106 107 // this call should return true if it could set the name and/or the type 108 virtual bool GetDynamicTypeAndAddress(ValueObject &in_value, 109 lldb::DynamicValueType use_dynamic, 110 TypeAndOrName &class_type_or_name, 111 Address &address, 112 Value::ValueType &value_type) = 0; 113 114 // This call should return a CompilerType given a generic type name and an 115 // ExecutionContextScope in which one can actually fetch any specialization 116 // information required. 117 virtual CompilerType GetConcreteType(ExecutionContextScope *exe_scope, 118 ConstString abstract_type_name) { 119 return CompilerType(); 120 } 121 122 // This should be a fast test to determine whether it is likely that this 123 // value would have a dynamic type. 124 virtual bool CouldHaveDynamicValue(ValueObject &in_value) = 0; 125 126 // The contract for GetDynamicTypeAndAddress() is to return a "bare-bones" 127 // dynamic type For instance, given a Base* pointer, 128 // GetDynamicTypeAndAddress() will return the type of Derived, not Derived*. 129 // The job of this API is to correct this misalignment between the static 130 // type and the discovered dynamic type 131 virtual TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, 132 ValueObject &static_value) = 0; 133 134 virtual void SetExceptionBreakpoints() {} 135 136 virtual void ClearExceptionBreakpoints() {} 137 138 virtual bool ExceptionBreakpointsAreSet() { return false; } 139 140 virtual bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) { 141 return false; 142 } 143 144 static lldb::BreakpointSP 145 CreateExceptionBreakpoint(Target &target, lldb::LanguageType language, 146 bool catch_bp, bool throw_bp, 147 bool is_internal = false); 148 149 static lldb::BreakpointPreconditionSP 150 GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp); 151 152 virtual lldb::ValueObjectSP GetExceptionObjectForThread( 153 lldb::ThreadSP thread_sp) { 154 return lldb::ValueObjectSP(); 155 } 156 157 virtual lldb::ThreadSP GetBacktraceThreadFromException( 158 lldb::ValueObjectSP thread_sp) { 159 return lldb::ThreadSP(); 160 } 161 162 virtual DeclVendor *GetDeclVendor() { return nullptr; } 163 164 virtual lldb::BreakpointResolverSP 165 CreateExceptionResolver(const lldb::BreakpointSP &bkpt, 166 bool catch_bp, bool throw_bp) = 0; 167 168 virtual lldb::SearchFilterSP CreateExceptionSearchFilter() { 169 return m_process->GetTarget().GetSearchFilterForModule(nullptr); 170 } 171 172 virtual bool GetTypeBitSize(const CompilerType &compiler_type, 173 uint64_t &size) { 174 return false; 175 } 176 177 virtual void SymbolsDidLoad(const ModuleList &module_list) {} 178 179 virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, 180 bool stop_others) = 0; 181 182 /// Identify whether a name is a runtime value that should not be hidden by 183 /// from the user interface. 184 virtual bool IsAllowedRuntimeValue(ConstString name) { return false; } 185 186 virtual std::optional<CompilerType> GetRuntimeType(CompilerType base_type) { 187 return std::nullopt; 188 } 189 190 void ModulesDidLoad(const ModuleList &module_list) override {} 191 192 // Called by ClangExpressionParser::PrepareForExecution to query for any 193 // custom LLVM IR passes that need to be run before an expression is 194 // assembled and run. 195 virtual bool GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) { 196 return false; 197 } 198 199 // Given the name of a runtime symbol (e.g. in Objective-C, an ivar offset 200 // symbol), try to determine from the runtime what the value of that symbol 201 // would be. Useful when the underlying binary is stripped. 202 virtual lldb::addr_t LookupRuntimeSymbol(ConstString name) { 203 return LLDB_INVALID_ADDRESS; 204 } 205 206 virtual bool isA(const void *ClassID) const { return ClassID == &ID; } 207 static char ID; 208 209 /// A language runtime may be able to provide a special UnwindPlan for 210 /// the frame represented by the register contents \a regctx when that 211 /// frame is not following the normal ABI conventions. 212 /// Instead of using the normal UnwindPlan for the function, we will use 213 /// this special UnwindPlan for this one backtrace. 214 /// One example of this would be a language that has asynchronous functions, 215 /// functions that may not be currently-executing, while waiting on other 216 /// asynchronous calls they made, but are part of a logical backtrace that 217 /// we want to show the developer because that's how they think of the 218 /// program flow. 219 /// 220 /// \param[in] thread 221 /// The thread that the unwind is happening on. 222 /// 223 /// \param[in] regctx 224 /// The RegisterContext for the frame we need to create an UnwindPlan. 225 /// We don't yet have a StackFrame when we're selecting the UnwindPlan. 226 /// 227 /// \param[out] behaves_like_zeroth_frame 228 /// With normal ABI calls, all stack frames except the zeroth frame need 229 /// to have the return-pc value backed up by 1 for symbolication purposes. 230 /// For these LanguageRuntime unwind plans, they may not follow normal ABI 231 /// calling conventions and the return pc may need to be symbolicated 232 /// as-is. 233 /// 234 /// \return 235 /// Returns an UnwindPlan to find the caller frame if it should be used, 236 /// instead of the UnwindPlan that would normally be used for this 237 /// function. 238 static lldb::UnwindPlanSP 239 GetRuntimeUnwindPlan(lldb_private::Thread &thread, 240 lldb_private::RegisterContext *regctx, 241 bool &behaves_like_zeroth_frame); 242 243protected: 244 // The static GetRuntimeUnwindPlan method above is only implemented in the 245 // base class; subclasses may override this protected member if they can 246 // provide one of these UnwindPlans. 247 virtual lldb::UnwindPlanSP 248 GetRuntimeUnwindPlan(lldb::ProcessSP process_sp, 249 lldb_private::RegisterContext *regctx, 250 bool &behaves_like_zeroth_frame) { 251 return lldb::UnwindPlanSP(); 252 } 253 254 LanguageRuntime(Process *process); 255}; 256 257} // namespace lldb_private 258 259#endif // LLDB_TARGET_LANGUAGERUNTIME_H 260