diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Plugins/LanguageRuntime | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime')
30 files changed, 839 insertions, 399 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index d556aae1c458..8aa803a8553e 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- CPPLanguageRuntime.cpp +//===-- CPPLanguageRuntime.cpp---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,7 +20,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" @@ -44,7 +43,7 @@ CPPLanguageRuntime::~CPPLanguageRuntime() {} CPPLanguageRuntime::CPPLanguageRuntime(Process *process) : LanguageRuntime(process) {} -bool CPPLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) { +bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) { return name == g_this; } diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h index abdd79fcd7b9..5b00590e6301 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPPLanguageRuntime_h_ -#define liblldb_CPPLanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H #include <vector> @@ -69,7 +69,7 @@ public: /// Obtain a ThreadPlan to get us into C++ constructs such as std::function. /// /// \param[in] thread - /// Curent thrad of execution. + /// Current thrad of execution. /// /// \param[in] stop_others /// True if other threads should pause during execution. @@ -79,7 +79,7 @@ public: lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override; - bool IsWhitelistedRuntimeValue(ConstString name) override; + bool IsAllowedRuntimeValue(ConstString name) override; protected: // Classes that inherit from CPPLanguageRuntime can see and modify these CPPLanguageRuntime(Process *process); @@ -90,9 +90,10 @@ private: OperatorStringToCallableInfoMap CallableLookupCache; - DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime); + CPPLanguageRuntime(const CPPLanguageRuntime &) = delete; + const CPPLanguageRuntime &operator=(const CPPLanguageRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_CPPLanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 9efb021caa83..3ab32641d9c1 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -1,5 +1,4 @@ -//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- -//C++ -*-===// +//===-- ItaniumABILanguageRuntime.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,6 +8,7 @@ #include "ItaniumABILanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" @@ -21,7 +21,6 @@ #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeList.h" @@ -41,6 +40,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE_ADV(ItaniumABILanguageRuntime, CXXItaniumABI) + static const char *vtable_demangled_prefix = "vtable for "; char ItaniumABILanguageRuntime::ID = 0; @@ -73,9 +74,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( Symbol *symbol = sc.symbol; if (symbol != nullptr) { const char *name = - symbol->GetMangled() - .GetDemangledName(lldb::eLanguageTypeC_plus_plus) - .AsCString(); + symbol->GetMangled().GetDemangledName().AsCString(); if (name && strstr(name, vtable_demangled_prefix) == name) { Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); @@ -118,7 +117,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( if (class_types.GetSize() == 1) { type_sp = class_types.GetTypeAtIndex(0); if (type_sp) { - if (ClangASTContext::IsCXXClassType( + if (TypeSystemClang::IsCXXClassType( type_sp->GetForwardCompilerType())) { LLDB_LOGF( log, @@ -150,7 +149,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( for (i = 0; i < class_types.GetSize(); i++) { type_sp = class_types.GetTypeAtIndex(i); if (type_sp) { - if (ClangASTContext::IsCXXClassType( + if (TypeSystemClang::IsCXXClassType( type_sp->GetForwardCompilerType())) { LLDB_LOGF( log, @@ -238,7 +237,7 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress( if (!type) return true; - if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), type)) { + if (TypeSystemClang::AreTypesSame(in_value.GetCompilerType(), type)) { // The dynamic type we found was the same type, so we don't have a // dynamic type here... return false; @@ -358,8 +357,7 @@ protected: Mangled mangled(name); if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { - ConstString demangled( - mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); + ConstString demangled(mangled.GetDisplayDemangledName()); demangled_any = true; result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(), demangled.GetCString()); @@ -420,12 +418,13 @@ lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() { uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; } BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( - Breakpoint *bkpt, bool catch_bp, bool throw_bp) { + const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) { return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false); } BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( - Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) { + const BreakpointSP &bkpt, bool catch_bp, bool throw_bp, + bool for_expressions) { // One complication here is that most users DON'T want to stop at // __cxa_allocate_expression, but until we can do anything better with // predicting unwinding the expression parser does. So we have two forms of @@ -536,8 +535,8 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread( if (!thread_sp->SafeToCallFunctions()) return {}; - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(m_process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(m_process->GetTarget()); if (!clang_ast_context) return {}; diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index 97cc81b8681f..d591527d9257 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ItaniumABILanguageRuntime_h_ -#define liblldb_ItaniumABILanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H #include <map> #include <mutex> @@ -66,9 +66,9 @@ public: bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override; - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; @@ -81,10 +81,9 @@ public: uint32_t GetPluginVersion() override; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp, - bool for_expressions); + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp, bool for_expressions); lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp, bool for_expressions, @@ -114,4 +113,4 @@ private: } // namespace lldb_private -#endif // liblldb_ItaniumABILanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index 859b693477a9..bdd5c29db848 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++ -//-*-===// +//===-- AppleObjCClassDescriptorV2.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,7 +16,7 @@ using namespace lldb_private; bool ClassDescriptorV2::Read_objc_class( Process *process, std::unique_ptr<objc_class_t> &objc_class) const { - objc_class.reset(new objc_class_t); + objc_class = std::make_unique<objc_class_t>(); bool ret = objc_class->Read(process, m_objc_class_ptr); @@ -198,14 +197,14 @@ bool ClassDescriptorV2::Read_class_row( return false; if (class_row_t_flags & RW_REALIZED) { - class_rw.reset(new class_rw_t); + class_rw = std::make_unique<class_rw_t>(); if (!class_rw->Read(process, objc_class.m_data_ptr)) { class_rw.reset(); return false; } - class_ro.reset(new class_ro_t); + class_ro = std::make_unique<class_ro_t>(); if (!class_ro->Read(process, class_rw->m_ro_ptr)) { class_rw.reset(); @@ -213,7 +212,7 @@ bool ClassDescriptorV2::Read_class_row( return false; } } else { - class_ro.reset(new class_ro_t); + class_ro = std::make_unique<class_ro_t>(); if (!class_ro->Read(process, objc_class.m_data_ptr)) { class_ro.reset(); @@ -242,15 +241,20 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process, lldb::offset_t cursor = 0; - m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3; + uint32_t entsize = extractor.GetU32_unchecked(&cursor); + m_is_small = (entsize & 0x80000000) != 0; + m_has_direct_selector = (entsize & 0x40000000) != 0; + m_entsize = entsize & 0xfffc; m_count = extractor.GetU32_unchecked(&cursor); m_first_ptr = addr + cursor; return true; } -bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) { - size_t size = GetSize(process); +bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, + bool is_small, bool has_direct_sel) { + size_t ptr_size = process->GetAddressByteSize(); + size_t size = GetSize(process, is_small); DataBufferHeap buffer(size, '\0'); Status error; @@ -261,13 +265,30 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) { } DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), - process->GetAddressByteSize()); - + ptr_size); lldb::offset_t cursor = 0; - m_name_ptr = extractor.GetAddress_unchecked(&cursor); - m_types_ptr = extractor.GetAddress_unchecked(&cursor); - m_imp_ptr = extractor.GetAddress_unchecked(&cursor); + if (is_small) { + uint32_t nameref_offset = extractor.GetU32_unchecked(&cursor); + uint32_t types_offset = extractor.GetU32_unchecked(&cursor); + uint32_t imp_offset = extractor.GetU32_unchecked(&cursor); + + m_name_ptr = addr + nameref_offset; + + if (!has_direct_sel) { + // The SEL offset points to a SELRef. We need to dereference twice. + m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size, + 0, error); + if (!error.Success()) + return false; + } + m_types_ptr = addr + 4 + types_offset; + m_imp_ptr = addr + 8 + imp_offset; + } else { + m_name_ptr = extractor.GetAddress_unchecked(&cursor); + m_types_ptr = extractor.GetAddress_unchecked(&cursor); + m_imp_ptr = extractor.GetAddress_unchecked(&cursor); + } process->ReadCStringFromMemory(m_name_ptr, m_name, error); if (error.Fail()) { @@ -358,19 +379,24 @@ bool ClassDescriptorV2::Describe( if (instance_method_func) { std::unique_ptr<method_list_t> base_method_list; - base_method_list.reset(new method_list_t); + base_method_list = std::make_unique<method_list_t>(); if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr)) return false; - if (base_method_list->m_entsize != method_t::GetSize(process)) + bool is_small = base_method_list->m_is_small; + bool has_direct_selector = base_method_list->m_has_direct_selector; + + if (base_method_list->m_entsize != method_t::GetSize(process, is_small)) return false; std::unique_ptr<method_t> method; - method.reset(new method_t); + method = std::make_unique<method_t>(); for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) { - method->Read(process, base_method_list->m_first_ptr + - (i * base_method_list->m_entsize)); + method->Read(process, + base_method_list->m_first_ptr + + (i * base_method_list->m_entsize), + is_small, has_direct_selector); if (instance_method_func(method->m_name.c_str(), method->m_types.c_str())) break; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index b8ba9dbb65f4..9ef21c6e7208 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCClassDescriptorV2_h_ -#define liblldb_AppleObjCClassDescriptorV2_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H #include <mutex> @@ -133,7 +133,9 @@ private: }; struct method_list_t { - uint32_t m_entsize; + uint16_t m_entsize; + bool m_is_small; + bool m_has_direct_selector; uint32_t m_count; lldb::addr_t m_first_ptr; @@ -148,15 +150,19 @@ private: std::string m_name; std::string m_types; - static size_t GetSize(Process *process) { - size_t ptr_size = process->GetAddressByteSize(); + static size_t GetSize(Process *process, bool is_small) { + size_t field_size; + if (is_small) + field_size = 4; // uint32_t relative indirect fields + else + field_size = process->GetAddressByteSize(); - return ptr_size // SEL name; - + ptr_size // const char *types; - + ptr_size; // IMP imp; + return field_size // SEL name; + + field_size // const char *types; + + field_size; // IMP imp; } - bool Read(Process *process, lldb::addr_t addr); + bool Read(Process *process, lldb::addr_t addr, bool, bool); }; struct ivar_list_t { @@ -328,4 +334,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCClassDescriptorV2_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 73843063606c..7b331307c0f7 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCDeclVendor.cpp ---------------------------------*- C++ -*-===// +//===-- AppleObjCDeclVendor.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "AppleObjCDeclVendor.h" +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTMetadata.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" @@ -30,17 +30,14 @@ public: bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, - "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%" - "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p", - current_id, + "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName" + " on (ASTContext*)%p Looking for %s in (%sDecl*)%p", static_cast<void *>(&decl_ctx->getParentASTContext()), name.getAsString().c_str(), decl_ctx->getDeclKindName(), static_cast<const void *>(decl_ctx)); @@ -70,44 +67,37 @@ public: } void CompleteType(clang::TagDecl *tag_decl) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? LLDB_LOGF(log, - "AppleObjCExternalASTSource::CompleteType[%u] on " + "AppleObjCExternalASTSource::CompleteType on " "(ASTContext*)%p Completing (TagDecl*)%p named %s", - current_id, static_cast<void *>(&tag_decl->getASTContext()), + static_cast<void *>(&tag_decl->getASTContext()), static_cast<void *>(tag_decl), tag_decl->getName().str().c_str()); - LLDB_LOG(log, " AOEAS::CT[{0}] Before:\n{1}", current_id, - ClangUtil::DumpDecl(tag_decl)); + LLDB_LOG(log, " AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl)); - LLDB_LOG(log, " AOEAS::CT[{1}] After:{1}", current_id, - ClangUtil::DumpDecl(tag_decl)); + LLDB_LOG(log, " AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl)); return; } void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) { LLDB_LOGF(log, - "AppleObjCExternalASTSource::CompleteType[%u] on " + "AppleObjCExternalASTSource::CompleteType on " "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s", - current_id, static_cast<void *>(&interface_decl->getASTContext()), static_cast<void *>(interface_decl), interface_decl->getName().str().c_str()); - LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id); + LLDB_LOGF(log, " AOEAS::CT Before:"); LLDB_LOG(log, " [CT] {0}", ClangUtil::DumpDecl(interface_decl)); } @@ -143,10 +133,9 @@ private: AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime) : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime), - m_ast_ctx(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple()), + m_ast_ctx( + "AppleObjCDeclVendor AST", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()), m_type_realizer_sp(m_runtime.GetEncodingToType()) { m_external_source = new AppleObjCExternalASTSource(*this); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr( @@ -309,7 +298,7 @@ public: } clang::ObjCMethodDecl * - BuildMethod(ClangASTContext &clang_ast_ctxt, + BuildMethod(TypeSystemClang &clang_ast_ctxt, clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance, ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp) { @@ -538,15 +527,13 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector<CompilerDecl> &decls) { - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; Log *log(GetLogIfAllCategoriesSet( LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? - LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )", - current_id, (const char *)name.AsCString(), - append ? "true" : "false", max_matches); + LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )", + (const char *)name.AsCString(), append ? "true" : "false", + max_matches); if (!append) decls.clear(); @@ -579,24 +566,21 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, isa_value = metadata->GetISAPtr(); LLDB_LOG(log, - "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 - ") in the ASTContext", - current_id, result_iface_type.getAsString(), isa_value); + "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext", + result_iface_type.getAsString(), isa_value); } - decls.push_back(CompilerDecl(&m_ast_ctx, result_iface_decl)); + decls.push_back(m_ast_ctx.GetCompilerDecl(result_iface_decl)); ret++; break; } else { - LLDB_LOGF(log, - "AOCTV::FT [%u] There's something in the ASTContext, but " - "it's not something we know about", - current_id); + LLDB_LOGF(log, "AOCTV::FT There's something in the ASTContext, but " + "it's not something we know about"); break; } } else if (log) { - LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext", - current_id, name.AsCString()); + LLDB_LOGF(log, "AOCTV::FT Couldn't find %s in the ASTContext", + name.AsCString()); } // It's not. If it exists, we have to put it into our ASTContext. @@ -604,7 +588,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name); if (!isa) { - LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id); + LLDB_LOGF(log, "AOCTV::FT Couldn't find the isa"); break; } @@ -613,9 +597,9 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (!iface_decl) { LLDB_LOGF(log, - "AOCTV::FT [%u] Couldn't get the Objective-C interface for " + "AOCTV::FT Couldn't get the Objective-C interface for " "isa 0x%" PRIx64, - current_id, (uint64_t)isa); + (uint64_t)isa); break; } @@ -623,11 +607,11 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (log) { clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl); - LLDB_LOG(log, "AOCTV::FT [{0}] Created {1} (isa 0x{2:x})", current_id, + LLDB_LOG(log, "AOCTV::FT Created {1} (isa 0x{2:x})", new_iface_type.getAsString(), (uint64_t)isa); } - decls.push_back(CompilerDecl(&m_ast_ctx, iface_decl)); + decls.push_back(m_ast_ctx.GetCompilerDecl(iface_decl)); ret++; break; } while (false); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h index f49ca3540c2c..c1201b985814 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCDeclVendor_h_ -#define liblldb_AppleObjCDeclVendor_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/lldb-private.h" #include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" namespace lldb_private { @@ -37,7 +37,7 @@ private: bool FinishDecl(clang::ObjCInterfaceDecl *decl); ObjCLanguageRuntime &m_runtime; - ClangASTContext m_ast_ctx; + TypeSystemClang m_ast_ctx; ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp; AppleObjCExternalASTSource *m_external_source; @@ -50,4 +50,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCDeclVendor_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 7076959bee97..22ea83a57beb 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCRuntime.cpp -------------------------------------*- C++ -//-*-===// +//===-- AppleObjCRuntime.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +7,12 @@ //===----------------------------------------------------------------------===// #include "AppleObjCRuntime.h" +#include "AppleObjCRuntimeV1.h" +#include "AppleObjCRuntimeV2.h" #include "AppleObjCTrampolineHandler.h" - -#include "clang/AST/Type.h" - +#include "Plugins/Language/ObjC/NSString.h" +#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/Process/Utility/HistoryThread.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" @@ -22,7 +23,6 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -35,16 +35,17 @@ #include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" +#include "clang/AST/Type.h" -#include "Plugins/Process/Utility/HistoryThread.h" -#include "Plugins/Language/ObjC/NSString.h" -#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include <vector> using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(AppleObjCRuntime) + char AppleObjCRuntime::ID = 0; AppleObjCRuntime::~AppleObjCRuntime() {} @@ -55,6 +56,16 @@ AppleObjCRuntime::AppleObjCRuntime(Process *process) ReadObjCLibraryIfNeeded(process->GetTarget().GetImages()); } +void AppleObjCRuntime::Initialize() { + AppleObjCRuntimeV2::Initialize(); + AppleObjCRuntimeV1::Initialize(); +} + +void AppleObjCRuntime::Terminate() { + AppleObjCRuntimeV2::Terminate(); + AppleObjCRuntimeV1::Terminate(); +} + bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) { CompilerType compiler_type(valobj.GetCompilerType()); bool is_signed; @@ -105,13 +116,13 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, Target *target = exe_ctx.GetTargetPtr(); CompilerType compiler_type = value.GetCompilerType(); if (compiler_type) { - if (!ClangASTContext::IsObjCObjectPointerType(compiler_type)) { + if (!TypeSystemClang::IsObjCObjectPointerType(compiler_type)) { strm.Printf("Value doesn't point to an ObjC object.\n"); return false; } } else { // If it is not a pointer, see if we can make it into a pointer. - ClangASTContext *ast_context = ClangASTContext::GetScratch(*target); + TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target); if (!ast_context) return false; @@ -126,7 +137,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, arg_value_list.PushValue(value); // This is the return value: - ClangASTContext *ast_context = ClangASTContext::GetScratch(*target); + TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target); if (!ast_context) return false; @@ -239,7 +250,8 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() { contexts.GetContextAtIndex(0, context); - m_PrintForDebugger_addr.reset(new Address(context.symbol->GetAddress())); + m_PrintForDebugger_addr = + std::make_unique<Address>(context.symbol->GetAddress()); } return m_PrintForDebugger_addr.get(); @@ -335,8 +347,8 @@ bool AppleObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) { // Maybe check here and if we have a handler already, and the UUID of this // module is the same as the one in the current module, then we don't have to // reread it? - m_objc_trampoline_handler_up.reset( - new AppleObjCTrampolineHandler(m_process->shared_from_this(), module_sp)); + m_objc_trampoline_handler_up = std::make_unique<AppleObjCTrampolineHandler>( + m_process->shared_from_this(), module_sp); if (m_objc_trampoline_handler_up != nullptr) { m_read_objc_library = true; return true; @@ -479,7 +491,7 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( auto descriptor = GetClassDescriptor(*cpp_exception); if (!descriptor || !descriptor->IsValid()) return ValueObjectSP(); - + while (descriptor) { ConstString class_name(descriptor->GetClassName()); if (class_name == "NSException") @@ -490,19 +502,32 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( return ValueObjectSP(); } +/// Utility method for error handling in GetBacktraceThreadFromException. +/// \param msg The message to add to the log. +/// \return An invalid ThreadSP to be returned from +/// GetBacktraceThreadFromException. +LLVM_NODISCARD +static ThreadSP FailExceptionParsing(llvm::StringRef msg) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); + LLDB_LOG(log, "Failed getting backtrace from exception: {0}", msg); + return ThreadSP(); +} + ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( lldb::ValueObjectSP exception_sp) { ValueObjectSP reserved_dict = exception_sp->GetChildMemberWithName(ConstString("reserved"), true); - if (!reserved_dict) return ThreadSP(); + if (!reserved_dict) + return FailExceptionParsing("Failed to get 'reserved' member."); reserved_dict = reserved_dict->GetSyntheticValue(); - if (!reserved_dict) return ThreadSP(); + if (!reserved_dict) + return FailExceptionParsing("Failed to get synthetic value."); - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(*exception_sp->GetTargetSP()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(*exception_sp->GetTargetSP()); if (!clang_ast_context) - return ThreadSP(); + return FailExceptionParsing("Failed to get scratch AST."); CompilerType objc_id = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID); ValueObjectSP return_addresses; @@ -527,8 +552,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( if (error.Fail()) return ThreadSP(); lldb::offset_t data_offset = 0; - auto dict_entry_key = data.GetPointer(&data_offset); - auto dict_entry_value = data.GetPointer(&data_offset); + auto dict_entry_key = data.GetAddress(&data_offset); + auto dict_entry_value = data.GetAddress(&data_offset); auto key_nsstring = objc_object_from_address(dict_entry_key, "key"); StreamString key_summary; @@ -543,15 +568,22 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( } } - if (!return_addresses) return ThreadSP(); + if (!return_addresses) + return FailExceptionParsing("Failed to get return addresses."); auto frames_value = return_addresses->GetChildMemberWithName(ConstString("_frames"), true); + if (!frames_value) + return FailExceptionParsing("Failed to get frames_value."); addr_t frames_addr = frames_value->GetValueAsUnsigned(0); auto count_value = return_addresses->GetChildMemberWithName(ConstString("_cnt"), true); + if (!count_value) + return FailExceptionParsing("Failed to get count_value."); size_t count = count_value->GetValueAsUnsigned(0); auto ignore_value = return_addresses->GetChildMemberWithName(ConstString("_ignore"), true); + if (!ignore_value) + return FailExceptionParsing("Failed to get ignore_value."); size_t ignore = ignore_value->GetValueAsUnsigned(0); size_t ptr_size = m_process->GetAddressByteSize(); @@ -563,7 +595,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( pcs.push_back(pc); } - if (pcs.empty()) return ThreadSP(); + if (pcs.empty()) + return FailExceptionParsing("Failed to get PC list."); ThreadSP new_thread_sp(new HistoryThread(*m_process, 0, pcs)); m_process->GetExtendedThreadList().AddThread(new_thread_sp); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 79ac53e1e440..e9790871e8c4 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntime_h_ -#define liblldb_AppleObjCRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H #include "llvm/ADT/Optional.h" @@ -31,6 +31,10 @@ public: static char ID; + static void Initialize(); + + static void Terminate(); + bool isA(const void *ClassID) const override { return ClassID == &ID || ObjCLanguageRuntime::isA(ClassID); } @@ -84,7 +88,7 @@ public: bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; - + static std::tuple<FileSpec, ConstString> GetExceptionThrowLocation(); lldb::ValueObjectSP GetExceptionObjectForThread( @@ -97,7 +101,7 @@ public: virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false); - + virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; } protected: @@ -128,4 +132,4 @@ protected: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 88bfe2ce0203..8202686597ae 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++ -//-*-===// +//===-- AppleObjCRuntimeV1.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,12 +12,12 @@ #include "clang/AST/Type.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -106,8 +105,8 @@ ConstString AppleObjCRuntimeV1::GetPluginName() { uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; } BreakpointResolverSP -AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, - bool throw_bp) { +AppleObjCRuntimeV1::CreateExceptionResolver(const BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; if (throw_bp) @@ -363,7 +362,7 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() { lldb::offset_t offset = addr_size; // Skip prototype const uint32_t count = data.GetU32(&offset); const uint32_t num_buckets = data.GetU32(&offset); - const addr_t buckets_ptr = data.GetPointer(&offset); + const addr_t buckets_ptr = data.GetAddress(&offset); if (m_hash_signature.NeedsUpdate(count, num_buckets, buckets_ptr)) { m_hash_signature.UpdateSignature(count, num_buckets, buckets_ptr); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 6fdae63d4126..d8725d0f57ce 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntimeV1_h_ -#define liblldb_AppleObjCRuntimeV1_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H #include "AppleObjCRuntime.h" #include "lldb/lldb-private.h" @@ -113,9 +113,9 @@ public: DeclVendor *GetDeclVendor() override; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; class HashTableSignature { public: @@ -153,4 +153,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntimeV1_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 4015f10c4966..ac9a09394021 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCRuntimeV2.cpp ----------------------------------*- C++ -*-===// +//===-- AppleObjCRuntimeV2.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,12 +15,11 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Host/OptionParser.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/lldb-enumerations.h" -#include "lldb/Core/ClangForward.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -35,7 +34,6 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValueBoolean.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/TypeList.h" @@ -64,6 +62,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/TargetInfo.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -582,8 +581,8 @@ protected: case 0: break; case 1: { - regex_up.reset(new RegularExpression( - llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)))); + regex_up = std::make_unique<RegularExpression>( + llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))); if (!regex_up->IsValid()) { result.AppendError( "invalid argument - please provide a valid regular expression"); @@ -826,8 +825,8 @@ lldb_private::ConstString AppleObjCRuntimeV2::GetPluginName() { uint32_t AppleObjCRuntimeV2::GetPluginVersion() { return 1; } BreakpointResolverSP -AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, - bool throw_bp) { +AppleObjCRuntimeV2::CreateExceptionResolver(const BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; if (throw_bp) @@ -897,12 +896,12 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type, const char *ivar_name) { uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET; - const char *class_name = parent_ast_type.GetConstTypeName().AsCString(); - if (class_name && class_name[0] && ivar_name && ivar_name[0]) { + ConstString class_name = parent_ast_type.GetTypeName(); + if (!class_name.IsEmpty() && ivar_name && ivar_name[0]) { // Make the objective C V2 mangled name for the ivar offset from the class // name and ivar name std::string buffer("OBJC_IVAR_$_"); - buffer.append(class_name); + buffer.append(class_name.AsCString()); buffer.push_back('.'); buffer.append(ivar_name); ConstString ivar_const_str(buffer.c_str()); @@ -1176,6 +1175,28 @@ AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) { return class_descriptor_sp; } +static std::pair<bool, ConstString> ObjCGetClassNameRaw( + AppleObjCRuntime::ObjCISA isa, + Process *process) { + StreamString expr_string; + std::string input = std::to_string(isa); + expr_string.Printf("(const char *)objc_debug_class_getNameRaw(%s)", + input.c_str()); + + ValueObjectSP result_sp; + EvaluateExpressionOptions eval_options; + eval_options.SetLanguage(lldb::eLanguageTypeObjC); + eval_options.SetResultIsInternal(true); + eval_options.SetGenerateDebugInfo(true); + eval_options.SetTimeout(process->GetUtilityExpressionTimeout()); + auto eval_result = process->GetTarget().EvaluateExpression( + expr_string.GetData(), + process->GetThreadList().GetSelectedThread()->GetSelectedFrame().get(), + result_sp, eval_options); + ConstString type_name(result_sp->GetSummaryAsCString()); + return std::make_pair(eval_result == eExpressionCompleted, type_name); +} + ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { ClassDescriptorSP objc_class_sp; @@ -1192,32 +1213,43 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) { // if we get an invalid VO (which might still happen when playing around with // pointers returned by the expression parser, don't consider this a valid // ObjC object) - if (valobj.GetCompilerType().IsValid()) { - addr_t isa_pointer = valobj.GetPointerValue(); + if (!valobj.GetCompilerType().IsValid()) + return objc_class_sp; + addr_t isa_pointer = valobj.GetPointerValue(); - // tagged pointer - if (IsTaggedPointer(isa_pointer)) { - return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer); - } else { - ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); + // tagged pointer + if (IsTaggedPointer(isa_pointer)) + return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer); + ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - if (process) { - Status error; - ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); - if (isa != LLDB_INVALID_ADDRESS) { - objc_class_sp = GetClassDescriptorFromISA(isa); - if (isa && !objc_class_sp) { - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - LLDB_LOGF(log, - "0x%" PRIx64 - ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " - "not in class descriptor cache 0x%" PRIx64, - isa_pointer, isa); - } - } - } - } + Process *process = exe_ctx.GetProcessPtr(); + if (!process) + return objc_class_sp; + + Status error; + ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); + if (isa == LLDB_INVALID_ADDRESS) + return objc_class_sp; + + objc_class_sp = GetClassDescriptorFromISA(isa); + + if (objc_class_sp) + return objc_class_sp; + else { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | + LIBLLDB_LOG_TYPES)); + LLDB_LOGF(log, + "0x%" PRIx64 + ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was " + "not in class descriptor cache 0x%" PRIx64, + isa_pointer, isa); + } + + ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, nullptr)); + auto resolved = ObjCGetClassNameRaw(isa, process); + if (resolved.first == true) { + AddClass(isa, descriptor_sp, resolved.second.AsCString()); + objc_class_sp = descriptor_sp; } return objc_class_sp; } @@ -1301,7 +1333,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( return DescriptorMapUpdateResult::Fail(); thread_sp->CalculateExecutionContext(exe_ctx); - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) return DescriptorMapUpdateResult::Fail(); @@ -1434,8 +1466,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( Value return_value; return_value.SetValueType(Value::eValueTypeScalar); - // return_value.SetContext (Value::eContextTypeClangType, - // clang_uint32_t_type); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1499,7 +1529,7 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data, // Iterate through all ClassInfo structures lldb::offset_t offset = 0; for (uint32_t i = 0; i < num_class_infos; ++i) { - ObjCISA isa = data.GetPointer(&offset); + ObjCISA isa = data.GetAddress(&offset); if (isa == 0) { if (should_log) @@ -1563,7 +1593,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { return DescriptorMapUpdateResult::Fail(); thread_sp->CalculateExecutionContext(exe_ctx); - ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget()); if (!ast) return DescriptorMapUpdateResult::Fail(); @@ -1660,13 +1690,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { // Next make the function caller for our implementation utility function. Value value; value.SetValueType(Value::eValueTypeScalar); - // value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type); value.SetCompilerType(clang_void_pointer_type); arguments.PushValue(value); arguments.PushValue(value); value.SetValueType(Value::eValueTypeScalar); - // value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type); value.SetCompilerType(clang_uint32_t_type); arguments.PushValue(value); arguments.PushValue(value); @@ -1732,8 +1760,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { Value return_value; return_value.SetValueType(Value::eValueTypeScalar); - // return_value.SetContext (Value::eContextTypeClangType, - // clang_uint32_t_type); return_value.SetCompilerType(clang_uint32_t_type); return_value.GetScalar() = 0; @@ -1980,7 +2006,7 @@ void AppleObjCRuntimeV2::WarnIfNoClassesCached( DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() { if (!m_decl_vendor_up) - m_decl_vendor_up.reset(new AppleObjCDeclVendor(*this)); + m_decl_vendor_up = std::make_unique<AppleObjCDeclVendor>(*this); return m_decl_vendor_up.get(); } @@ -2477,7 +2503,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( ObjCISA isa, ObjCISA &ret_isa) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); - LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa); + LLDB_LOGF(log, "AOCRT::NPI Evaluate(isa = 0x%" PRIx64 ")", (uint64_t)isa); if ((isa & ~m_objc_debug_isa_class_mask) == 0) return false; @@ -2550,7 +2576,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( lldb::offset_t offset = 0; for (unsigned i = 0; i != num_new_classes; ++i) - m_indexed_isa_cache.push_back(data.GetPointer(&offset)); + m_indexed_isa_cache.push_back(data.GetAddress(&offset)); } } @@ -2558,7 +2584,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( if (index > m_indexed_isa_cache.size()) return false; - LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")", + LLDB_LOGF(log, "AOCRT::NPI Evaluate(ret_isa = 0x%" PRIx64 ")", (uint64_t)m_indexed_isa_cache[index]); ret_isa = m_indexed_isa_cache[index]; @@ -2642,8 +2668,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { const lldb::ABISP &abi = process_sp->GetABI(); if (!abi) return; - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process_sp->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process_sp->GetTarget()); if (!clang_ast_context) return; CompilerType voidstar = @@ -2668,6 +2694,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { m_arguments = ValueObjectListSP(new ValueObjectList()); m_arguments->Append(exception); + + m_stop_desc = "hit Objective-C exception"; } ValueObjectSP exception; @@ -2689,8 +2717,10 @@ static void RegisterObjCExceptionRecognizer() { FileSpec module; ConstString function; std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation(); + std::vector<ConstString> symbols = {function}; StackFrameRecognizerManager::AddRecognizer( StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()), - module.GetFilename(), function, /*first_instruction_only*/ true); + module.GetFilename(), symbols, + /*first_instruction_only*/ true); }); } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index 785bb3938d2c..99264d556da5 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCRuntimeV2_h_ -#define liblldb_AppleObjCRuntimeV2_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H #include <map> #include <memory> @@ -103,9 +103,9 @@ public: static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6; protected: - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) override; private: class HashTableSignature { @@ -162,7 +162,8 @@ private: friend class AppleObjCRuntimeV2; - DISALLOW_COPY_AND_ASSIGN(NonPointerISACache); + NonPointerISACache(const NonPointerISACache &) = delete; + const NonPointerISACache &operator=(const NonPointerISACache &) = delete; }; class TaggedPointerVendorV2 @@ -181,7 +182,9 @@ private: : TaggedPointerVendor(), m_runtime(runtime) {} private: - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2); + TaggedPointerVendorV2(const TaggedPointerVendorV2 &) = delete; + const TaggedPointerVendorV2 & + operator=(const TaggedPointerVendorV2 &) = delete; }; class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 { @@ -212,7 +215,10 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted); + TaggedPointerVendorRuntimeAssisted( + const TaggedPointerVendorRuntimeAssisted &) = delete; + const TaggedPointerVendorRuntimeAssisted & + operator=(const TaggedPointerVendorRuntimeAssisted &) = delete; }; class TaggedPointerVendorExtended @@ -250,7 +256,9 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended); + TaggedPointerVendorExtended(const TaggedPointerVendorExtended &) = delete; + const TaggedPointerVendorExtended & + operator=(const TaggedPointerVendorExtended &) = delete; }; class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 { @@ -266,7 +274,9 @@ private: friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy); + TaggedPointerVendorLegacy(const TaggedPointerVendorLegacy &) = delete; + const TaggedPointerVendorLegacy & + operator=(const TaggedPointerVendorLegacy &) = delete; }; struct DescriptorMapUpdateResult { @@ -337,4 +347,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCRuntimeV2_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index 36f95c063b81..c96768c9f585 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -1,5 +1,4 @@ -//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++ -//-*-===// +//===-- AppleObjCTrampolineHandler.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,6 +9,7 @@ #include "AppleObjCTrampolineHandler.h" #include "AppleThreadPlanStepThroughObjCTrampoline.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -19,7 +19,6 @@ #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Expression/UtilityFunction.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" @@ -319,7 +318,7 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() { const uint16_t descriptor_size = data.GetU16(&offset); const size_t num_descriptors = data.GetU32(&offset); - m_next_region = data.GetPointer(&offset); + m_next_region = data.GetAddress(&offset); // If the header size is 0, that means we've come in too early before this // data is set up. @@ -521,8 +520,8 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( Process *process = exe_ctx.GetProcessPtr(); const ABI *abi = process->GetABI().get(); - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(process->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(process->GetTarget()); if (!clang_ast_context) return false; @@ -548,7 +547,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines( error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data, nullptr); lldb::offset_t offset = 0; - lldb::addr_t region_addr = data.GetPointer(&offset); + lldb::addr_t region_addr = data.GetAddress(&offset); if (region_addr != 0) vtable_handler->ReadRegions(region_addr); @@ -657,6 +656,27 @@ const AppleObjCTrampolineHandler::DispatchFunction DispatchFunction::eFixUpFixed}, }; +// This is the table of ObjC "accelerated dispatch" functions. They are a set +// of objc methods that are "seldom overridden" and so the compiler replaces the +// objc_msgSend with a call to one of the dispatch functions. That will check +// whether the method has been overridden, and directly call the Foundation +// implementation if not. +// This table is supposed to be complete. If ones get added in the future, we +// will have to add them to the table. +const char *AppleObjCTrampolineHandler::g_opt_dispatch_names[] = { + "objc_alloc", + "objc_autorelease", + "objc_release", + "objc_retain", + "objc_alloc_init", + "objc_allocWithZone", + "objc_opt_class", + "objc_opt_isKindOfClass", + "objc_opt_new", + "objc_opt_respondsToSelector", + "objc_opt_self", +}; + AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( const ProcessSP &process_sp, const ModuleSP &objc_module_sp) : m_process_wp(), m_objc_module_sp(objc_module_sp), @@ -751,9 +771,24 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i)); } } + + // Similarly, cache the addresses of the "optimized dispatch" function. + for (size_t i = 0; i != llvm::array_lengthof(g_opt_dispatch_names); i++) { + ConstString name_const_str(g_opt_dispatch_names[i]); + const Symbol *msgSend_symbol = + m_objc_module_sp->FindFirstSymbolWithNameAndType(name_const_str, + eSymbolTypeCode); + if (msgSend_symbol && msgSend_symbol->ValueIsAddress()) { + lldb::addr_t sym_addr = + msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target); + + m_opt_dispatch_map.emplace(sym_addr, i); + } + } // Build our vtable dispatch handler here: - m_vtables_up.reset(new AppleObjCVTables(process_sp, m_objc_module_sp)); + m_vtables_up = + std::make_unique<AppleObjCVTables>(process_sp, m_objc_module_sp); if (m_vtables_up) m_vtables_up->ReadRegions(); } @@ -804,8 +839,8 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, } // Next make the runner function for our implementation utility function. - ClangASTContext *clang_ast_context = - ClangASTContext::GetScratch(thread.GetProcess()->GetTarget()); + TypeSystemClang *clang_ast_context = + TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget()); if (!clang_ast_context) return LLDB_INVALID_ADDRESS; @@ -846,45 +881,53 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, return args_addr; } +const AppleObjCTrampolineHandler::DispatchFunction * +AppleObjCTrampolineHandler::FindDispatchFunction(lldb::addr_t addr) { + MsgsendMap::iterator pos; + pos = m_msgSend_map.find(addr); + if (pos != m_msgSend_map.end()) { + return &g_dispatch_functions[(*pos).second]; + } + return nullptr; +} + +void +AppleObjCTrampolineHandler::ForEachDispatchFunction( + std::function<void(lldb::addr_t, + const DispatchFunction &)> callback) { + for (auto elem : m_msgSend_map) { + callback(elem.first, g_dispatch_functions[elem.second]); + } +} + ThreadPlanSP AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, bool stop_others) { ThreadPlanSP ret_plan_sp; lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); - DispatchFunction this_dispatch; - bool found_it = false; + DispatchFunction vtable_dispatch + = {"vtable", 0, false, false, DispatchFunction::eFixUpFixed}; // First step is to look and see if we are in one of the known ObjC // dispatch functions. We've already compiled a table of same, so // consult it. - MsgsendMap::iterator pos; - pos = m_msgSend_map.find(curr_pc); - if (pos != m_msgSend_map.end()) { - this_dispatch = g_dispatch_functions[(*pos).second]; - found_it = true; - } - + const DispatchFunction *this_dispatch = FindDispatchFunction(curr_pc); + // Next check to see if we are in a vtable region: - if (!found_it) { + if (!this_dispatch && m_vtables_up) { uint32_t flags; - if (m_vtables_up) { - found_it = m_vtables_up->IsAddressInVTables(curr_pc, flags); - if (found_it) { - this_dispatch.name = "vtable"; - this_dispatch.stret_return = - (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == - AppleObjCVTables::eOBJC_TRAMPOLINE_STRET; - this_dispatch.is_super = false; - this_dispatch.is_super2 = false; - this_dispatch.fixedup = DispatchFunction::eFixUpFixed; - } + if (m_vtables_up->IsAddressInVTables(curr_pc, flags)) { + vtable_dispatch.stret_return = + (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) == + AppleObjCVTables::eOBJC_TRAMPOLINE_STRET; + this_dispatch = &vtable_dispatch; } } - if (found_it) { + if (this_dispatch) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); // We are decoding a method dispatch. First job is to pull the @@ -901,7 +944,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, TargetSP target_sp(thread.CalculateTarget()); - ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp); if (!clang_ast_context) return ret_plan_sp; @@ -921,7 +964,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // the return struct pointer, and the object is the second, and // the selector is the third. Otherwise the object is the first // and the selector the second. - if (this_dispatch.stret_return) { + if (this_dispatch->stret_return) { obj_index = 1; sel_index = 2; argument_values.PushValue(void_ptr_value); @@ -963,8 +1006,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // run-to-address plan directly. Otherwise we have to figure out // where the implementation lives. - if (this_dispatch.is_super) { - if (this_dispatch.is_super2) { + if (this_dispatch->is_super) { + if (this_dispatch->is_super2) { // In the objc_msgSendSuper2 case, we don't get the object // directly, we get a structure containing the object and the // class to which the super message is being sent. So we need @@ -1087,25 +1130,25 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); flag_value.SetCompilerType(clang_int_type); - if (this_dispatch.stret_return) + if (this_dispatch->stret_return) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - if (this_dispatch.is_super) + if (this_dispatch->is_super) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - if (this_dispatch.is_super2) + if (this_dispatch->is_super2) flag_value.GetScalar() = 1; else flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); - switch (this_dispatch.fixedup) { + switch (this_dispatch->fixedup) { case DispatchFunction::eFixUpNone: flag_value.GetScalar() = 0; dispatch_values.PushValue(flag_value); @@ -1135,7 +1178,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, // stop_others value passed in to us here: const bool trampoline_stop_others = false; ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>( - thread, this, dispatch_values, isa_addr, sel_addr, + thread, *this, dispatch_values, isa_addr, sel_addr, trampoline_stop_others); if (log) { StreamString s; @@ -1144,6 +1187,26 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread, } } } + + // Finally, check if we have hit an "optimized dispatch" function. This will + // either directly call the base implementation or dispatch an objc_msgSend + // if the method has been overridden. So we just do a "step in/step out", + // setting a breakpoint on objc_msgSend, and if we hit the msgSend, we + // will automatically step in again. That's the job of the + // AppleThreadPlanStepThroughDirectDispatch. + if (!this_dispatch && !ret_plan_sp) { + MsgsendMap::iterator pos; + pos = m_opt_dispatch_map.find(curr_pc); + if (pos != m_opt_dispatch_map.end()) { + + const char *opt_name = g_opt_dispatch_names[(*pos).second]; + + bool trampoline_stop_others = false; + LazyBool step_in_should_stop = eLazyBoolCalculate; + ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch> ( + thread, *this, opt_name, trampoline_stop_others, step_in_should_stop); + } + } return ret_plan_sp; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h index d120d671eeb3..27aebd8594df 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleObjCTrampolineHandler_h_ -#define lldb_AppleObjCTrampolineHandler_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H #include <map> #include <mutex> @@ -47,6 +47,9 @@ public: lldb::addr_t SetupDispatchFunction(Thread &thread, ValueList &dispatch_values); + const DispatchFunction *FindDispatchFunction(lldb::addr_t addr); + void ForEachDispatchFunction(std::function<void(lldb::addr_t, + const DispatchFunction &)>); private: static const char *g_lookup_implementation_function_name; @@ -96,7 +99,6 @@ private: void Dump(Stream &s); - public: bool m_valid; AppleObjCVTables *m_owner; lldb::addr_t m_header_addr; @@ -136,11 +138,13 @@ private: }; static const DispatchFunction g_dispatch_functions[]; + static const char *g_opt_dispatch_names[]; - typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch + using MsgsendMap = std::map<lldb::addr_t, int>; // This table maps an dispatch // fn address to the index in // g_dispatch_functions MsgsendMap m_msgSend_map; + MsgsendMap m_opt_dispatch_map; lldb::ProcessWP m_process_wp; lldb::ModuleSP m_objc_module_sp; const char *m_lookup_implementation_function_code; @@ -155,4 +159,4 @@ private: } // namespace lldb_private -#endif // lldb_AppleObjCTrampolineHandler_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 66f04bef6cbd..b19d3d90d4b7 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -1,4 +1,4 @@ -//===-- AppleObjCTypeEncodingParser.cpp -------------------------*- C++ -*-===// +//===-- AppleObjCTypeEncodingParser.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,13 +8,15 @@ #include "AppleObjCTypeEncodingParser.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/StringLexer.h" +#include "clang/Basic/TargetInfo.h" + #include <vector> using namespace lldb_private; @@ -23,17 +25,16 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser( ObjCLanguageRuntime &runtime) : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) { if (!m_scratch_ast_ctx_up) - m_scratch_ast_ctx_up.reset(new ClangASTContext(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple())); + m_scratch_ast_ctx_up = std::make_unique<TypeSystemClang>( + "AppleObjCTypeEncodingParser ASTContext", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()); } std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) { StreamString buffer; while (type.HasAtLeast(1) && type.Peek() != '=') buffer.Printf("%c", type.Next()); - return buffer.GetString(); + return std::string(buffer.GetString()); } std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) { @@ -43,7 +44,7 @@ std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) { StringLexer::Character next = type.Next(); UNUSED_IF_ASSERT_DISABLED(next); assert(next == '"'); - return buffer.GetString(); + return std::string(buffer.GetString()); } uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) { @@ -61,7 +62,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement() : name(""), type(clang::QualType()), bitfield(0) {} AppleObjCTypeEncodingParser::StructElement -AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx, +AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { StructElement retval; @@ -76,19 +77,19 @@ AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx, } clang::QualType AppleObjCTypeEncodingParser::BuildStruct( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '{', '}', clang::TTK_Struct); } clang::QualType AppleObjCTypeEncodingParser::BuildUnion( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { return BuildAggregate(ast_ctx, type, for_expression, '(', ')', clang::TTK_Union); } clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression, + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression, char opener, char closer, uint32_t kind) { if (!type.NextIf(opener)) return clang::QualType(); @@ -123,29 +124,30 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( return clang::QualType(); // This is where we bail out. Sorry! CompilerType union_type(ast_ctx.CreateRecordType( - nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC)); + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind, + lldb::eLanguageTypeC)); if (union_type) { - ClangASTContext::StartTagDeclarationDefinition(union_type); + TypeSystemClang::StartTagDeclarationDefinition(union_type); unsigned int count = 0; for (auto element : elements) { if (element.name.empty()) { StreamString elem_name; elem_name.Printf("__unnamed_%u", count); - element.name = elem_name.GetString(); + element.name = std::string(elem_name.GetString()); } - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( union_type, element.name.c_str(), ast_ctx.GetType(element.type), lldb::eAccessPublic, element.bitfield); ++count; } - ClangASTContext::CompleteTagDeclarationDefinition(union_type); + TypeSystemClang::CompleteTagDeclarationDefinition(union_type); } return ClangUtil::GetQualType(union_type); } clang::QualType AppleObjCTypeEncodingParser::BuildArray( - ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('[')) return clang::QualType(); uint32_t size = ReadNumber(type); @@ -163,7 +165,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray( // consume but ignore the type info and always return an 'id'; if anything, // dynamic typing will resolve things for us anyway clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( - ClangASTContext &clang_ast_ctx, StringLexer &type, bool for_expression) { + TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) { if (!type.NextIf('@')) return clang::QualType(); @@ -247,7 +249,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( } clang::QualType -AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx, +AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, uint32_t *bitfield_bit_size) { if (!type.HasAtLeast(1)) @@ -353,7 +355,7 @@ AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx, } } -CompilerType AppleObjCTypeEncodingParser::RealizeType(ClangASTContext &ast_ctx, +CompilerType AppleObjCTypeEncodingParser::RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) { if (name && name[0]) { diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index e43711bf4ee4..9a108967e1ab 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_AppleObjCTypeEncodingParser_h_ -#define liblldb_AppleObjCTypeEncodingParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H #include "clang/AST/ASTContext.h" @@ -22,7 +22,7 @@ public: AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime); ~AppleObjCTypeEncodingParser() override = default; - CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name, + CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) override; private: @@ -35,29 +35,29 @@ private: ~StructElement() = default; }; - clang::QualType BuildType(ClangASTContext &clang_ast_ctx, StringLexer &type, + clang::QualType BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, uint32_t *bitfield_bit_size = nullptr); - clang::QualType BuildStruct(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildStruct(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildAggregate(ClangASTContext &clang_ast_ctx, + clang::QualType BuildAggregate(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression, char opener, char closer, uint32_t kind); - clang::QualType BuildUnion(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildUnion(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildArray(ClangASTContext &ast_ctx, StringLexer &type, + clang::QualType BuildArray(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); std::string ReadStructName(StringLexer &type); - StructElement ReadStructElement(ClangASTContext &ast_ctx, StringLexer &type, + StructElement ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression); - clang::QualType BuildObjCObjectPointerType(ClangASTContext &clang_ast_ctx, + clang::QualType BuildObjCObjectPointerType(TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression); @@ -70,4 +70,4 @@ private: } // namespace lldb_private -#endif // liblldb_AppleObjCTypeEncodingParser_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index af630eee7265..653e007c7b5f 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -1,4 +1,4 @@ -//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp +//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp-----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,7 +29,7 @@ using namespace lldb_private; // ThreadPlanStepThroughObjCTrampoline constructor AppleThreadPlanStepThroughObjCTrampoline:: AppleThreadPlanStepThroughObjCTrampoline( - Thread &thread, AppleObjCTrampolineHandler *trampoline_handler, + Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, bool stop_others) : ThreadPlan(ThreadPlan::eKindGeneric, @@ -48,31 +48,30 @@ void AppleThreadPlanStepThroughObjCTrampoline::DidPush() { // Setting up the memory space for the called function text might require // allocations, i.e. a nested function call. This needs to be done as a // PreResumeAction. - m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller, - (void *)this); + m_process.AddPreResumeAction(PreResumeInitializeFunctionCaller, (void *)this); } bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() { if (!m_func_sp) { DiagnosticManager diagnostics; m_args_addr = - m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values); + m_trampoline_handler.SetupDispatchFunction(GetThread(), m_input_values); if (m_args_addr == LLDB_INVALID_ADDRESS) { return false; } m_impl_function = - m_trampoline_handler->GetLookupImplementationFunctionCaller(); + m_trampoline_handler.GetLookupImplementationFunctionCaller(); ExecutionContext exc_ctx; EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetStopOthers(m_stop_others); - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_func_sp = m_impl_function->GetThreadPlanToCallFunction( exc_ctx, m_args_addr, options, diagnostics); m_func_sp->SetOkayToDiscard(true); - m_thread.QueueThreadPlan(m_func_sp, false); + PushPlan(m_func_sp); } return true; } @@ -132,7 +131,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { if (!m_run_to_sp) { Value target_addr_value; ExecutionContext exc_ctx; - m_thread.CalculateExecutionContext(exc_ctx); + GetThread().CalculateExecutionContext(exc_ctx); m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr, target_addr_value); m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr); @@ -145,19 +144,19 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { SetPlanComplete(); return true; } - if (m_trampoline_handler->AddrIsMsgForward(target_addr)) { + if (m_trampoline_handler.AddrIsMsgForward(target_addr)) { LLDB_LOGF(log, "Implementation lookup returned msgForward function: 0x%" PRIx64 ", stopping.", target_addr); - SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext( + SymbolContext sc = GetThread().GetStackFrameAtIndex(0)->GetSymbolContext( eSymbolContextEverything); Status status; const bool abort_other_plans = false; const bool first_insn = true; const uint32_t frame_idx = 0; - m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( + m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop( abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx, status); if (m_run_to_sp && status.Success()) @@ -180,11 +179,10 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { // Extract the target address from the value: m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>( - m_thread, target_so_addr, m_stop_others); - m_thread.QueueThreadPlan(m_run_to_sp, false); - m_run_to_sp->SetPrivate(true); + GetThread(), target_so_addr, m_stop_others); + PushPlan(m_run_to_sp); return false; - } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) { + } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) { // Third stage, work the run to target plan. SetPlanComplete(); return true; @@ -199,3 +197,227 @@ bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() { } bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; } + +// Objective-C uses optimized dispatch functions for some common and seldom +// overridden methods. For instance +// [object respondsToSelector:]; +// will get compiled to: +// objc_opt_respondsToSelector(object); +// This checks whether the selector has been overridden, directly calling the +// implementation if it hasn't and calling objc_msgSend if it has. +// +// We need to get into the overridden implementation. We'll do that by +// setting a breakpoint on objc_msgSend, and doing a "step out". If we stop +// at objc_msgSend, we can step through to the target of the send, and see if +// that's a place we want to stop. +// +// A couple of complexities. The checking code might call some other method, +// so we might see objc_msgSend more than once. Also, these optimized dispatch +// functions might dispatch more than one message at a time (e.g. alloc followed +// by init.) So we can't give up at the first objc_msgSend. +// That means among other things that we have to handle the "ShouldStopHere" - +// since we can't just return control to the plan that's controlling us on the +// first step. + +AppleThreadPlanStepThroughDirectDispatch :: + AppleThreadPlanStepThroughDirectDispatch( + Thread &thread, AppleObjCTrampolineHandler &handler, + llvm::StringRef dispatch_func_name, bool stop_others, + LazyBool step_in_avoids_code_without_debug_info) + : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, + stop_others, eVoteNoOpinion, eVoteNoOpinion, + 0 /* Step out of zeroth frame */, + eLazyBoolNo /* Our parent plan will decide this + when we are done */ + , + true /* Run to branch for inline step out */, + false /* Don't gather the return value */), + m_trampoline_handler(handler), + m_dispatch_func_name(std::string(dispatch_func_name)), + m_at_msg_send(false), m_stop_others(stop_others) { + // Set breakpoints on the dispatch functions: + auto bkpt_callback = [&] (lldb::addr_t addr, + const AppleObjCTrampolineHandler + ::DispatchFunction &dispatch) { + m_msgSend_bkpts.push_back(GetTarget().CreateBreakpoint(addr, + true /* internal */, + false /* hard */)); + m_msgSend_bkpts.back()->SetThreadID(GetThread().GetID()); + }; + handler.ForEachDispatchFunction(bkpt_callback); + + // We'll set the step-out plan in the DidPush so it gets queued in the right + // order. + + bool avoid_nodebug = true; + + switch (step_in_avoids_code_without_debug_info) { + case eLazyBoolYes: + avoid_nodebug = true; + break; + case eLazyBoolNo: + avoid_nodebug = false; + break; + case eLazyBoolCalculate: + avoid_nodebug = GetThread().GetStepInAvoidsNoDebug(); + break; + } + if (avoid_nodebug) + GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); + else + GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug); + // We only care about step in. Our parent plan will figure out what to + // do when we've stepped out again. + GetFlags().Clear(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug); +} + +AppleThreadPlanStepThroughDirectDispatch:: + ~AppleThreadPlanStepThroughDirectDispatch() { + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + GetTarget().RemoveBreakpointByID(bkpt_sp->GetID()); + } +} + +void AppleThreadPlanStepThroughDirectDispatch::GetDescription( + Stream *s, lldb::DescriptionLevel level) { + switch (level) { + case lldb::eDescriptionLevelBrief: + s->PutCString("Step through ObjC direct dispatch function."); + break; + default: + s->Printf("Step through ObjC direct dispatch '%s' using breakpoints: ", + m_dispatch_func_name.c_str()); + bool first = true; + for (auto bkpt_sp : m_msgSend_bkpts) { + if (!first) { + s->PutCString(", "); + } + first = false; + s->Printf("%d", bkpt_sp->GetID()); + } + (*s) << "."; + break; + } +} + +bool +AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) { + if (ThreadPlanStepOut::DoPlanExplainsStop(event_ptr)) + return true; + + StopInfoSP stop_info_sp = GetPrivateStopInfo(); + + // Check if the breakpoint is one of ours msgSend dispatch breakpoints. + + StopReason stop_reason = eStopReasonNone; + if (stop_info_sp) + stop_reason = stop_info_sp->GetStopReason(); + + // See if this is one of our msgSend breakpoints: + if (stop_reason == eStopReasonBreakpoint) { + ProcessSP process_sp = GetThread().GetProcess(); + uint64_t break_site_id = stop_info_sp->GetValue(); + BreakpointSiteSP site_sp + = process_sp->GetBreakpointSiteList().FindByID(break_site_id); + // Some other plan might have deleted the site's last owner before this + // got to us. In which case, it wasn't our breakpoint... + if (!site_sp) + return false; + + for (BreakpointSP break_sp : m_msgSend_bkpts) { + if (site_sp->IsBreakpointAtThisSite(break_sp->GetID())) { + // If we aren't the only one with a breakpoint on this site, then we + // should just stop and return control to the user. + if (site_sp->GetNumberOfOwners() > 1) { + SetPlanComplete(true); + return false; + } + m_at_msg_send = true; + return true; + } + } + } + + // We're done here. If one of our sub-plans explained the stop, they + // would have already answered true to PlanExplainsStop, and if they were + // done, we'll get called to figure out what to do in ShouldStop... + return false; +} + +bool AppleThreadPlanStepThroughDirectDispatch + ::DoWillResume(lldb::StateType resume_state, bool current_plan) { + ThreadPlanStepOut::DoWillResume(resume_state, current_plan); + m_at_msg_send = false; + return true; +} + +bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) { + // If step out plan finished, that means we didn't find our way into a method + // implementation. Either we went directly to the default implementation, + // of the overridden implementation didn't have debug info. + // So we should mark ourselves as done. + const bool step_out_should_stop = ThreadPlanStepOut::ShouldStop(event_ptr); + if (step_out_should_stop) { + SetPlanComplete(true); + return true; + } + + // If we have a step through plan, then w're in the process of getting + // through an ObjC msgSend. If we arrived at the target function, then + // check whether we have debug info, and if we do, stop. + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + if (m_objc_step_through_sp && m_objc_step_through_sp->IsPlanComplete()) { + // If the plan failed for some reason, we should probably just let the + // step over plan get us out of here... We don't need to do anything about + // the step through plan, it is done and will get popped when we continue. + if (!m_objc_step_through_sp->PlanSucceeded()) { + LLDB_LOGF(log, "ObjC Step through plan failed. Stepping out."); + } + Status error; + if (InvokeShouldStopHereCallback(eFrameCompareYounger, error)) { + SetPlanComplete(true); + return true; + } + // If we didn't want to stop at this msgSend, there might be another so + // we should just continue on with the step out and see if our breakpoint + // triggers again. + m_objc_step_through_sp.reset(); + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + bkpt_sp->SetEnabled(true); + } + return false; + } + + // If we hit an msgSend breakpoint, then we should queue the step through + // plan: + + if (m_at_msg_send) { + LanguageRuntime *objc_runtime + = GetThread().GetProcess()->GetLanguageRuntime(eLanguageTypeObjC); + // There's no way we could have gotten here without an ObjC language + // runtime. + assert(objc_runtime); + m_objc_step_through_sp + = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others); + // If we failed to find the target for this dispatch, just keep going and + // let the step out complete. + if (!m_objc_step_through_sp) { + LLDB_LOG(log, "Couldn't find target for message dispatch, continuing."); + return false; + } + // Otherwise push the step through plan and continue. + GetThread().QueueThreadPlan(m_objc_step_through_sp, false); + for (BreakpointSP bkpt_sp : m_msgSend_bkpts) { + bkpt_sp->SetEnabled(false); + } + return false; + } + return true; +} + +bool AppleThreadPlanStepThroughDirectDispatch::MischiefManaged() { + if (IsPlanComplete()) + return true; + return ThreadPlanStepOut::MischiefManaged(); +} diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h index 96f37851a35f..89aed89f1ab1 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h @@ -6,12 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ -#define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H #include "AppleObjCTrampolineHandler.h" #include "lldb/Core/Value.h" #include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanStepInRange.h" +#include "lldb/Target/ThreadPlanStepOut.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" @@ -20,7 +23,7 @@ namespace lldb_private { class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { public: AppleThreadPlanStepThroughObjCTrampoline( - Thread &thread, AppleObjCTrampolineHandler *trampoline_handler, + Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, bool stop_others); @@ -52,25 +55,62 @@ protected: private: bool InitializeFunctionCaller(); - AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this - // doesn't go away on us? - // SP maybe? - lldb::addr_t m_args_addr; // Stores the address for our step through function - // result structure. - // lldb::addr_t m_object_addr; // This is only for Description. + AppleObjCTrampolineHandler &m_trampoline_handler; /// The handler itself. + lldb::addr_t m_args_addr; /// Stores the address for our step through function + /// result structure. ValueList m_input_values; - lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to - // cache the implementation. + lldb::addr_t m_isa_addr; /// isa_addr and sel_addr are the keys we will use to + /// cache the implementation. lldb::addr_t m_sel_addr; - lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it - // at start, then set it - // to NULL when this plan is done. That way we know to go to: - lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target. - FunctionCaller *m_impl_function; // This is a pointer to a impl function that - // is owned by the client that pushes this plan. - bool m_stop_others; + lldb::ThreadPlanSP m_func_sp; /// This is the function call plan. We fill it + /// at start, then set it to NULL when this plan + /// is done. That way we know to go on to: + lldb::ThreadPlanSP m_run_to_sp; /// The plan that runs to the target. + FunctionCaller *m_impl_function; /// This is a pointer to a impl function that + /// is owned by the client that pushes this + /// plan. + bool m_stop_others; /// Whether we should stop other threads. +}; + +class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { +public: + AppleThreadPlanStepThroughDirectDispatch( + Thread &thread, AppleObjCTrampolineHandler &handler, + llvm::StringRef dispatch_func_name, bool stop_others, + LazyBool step_in_avoids_code_without_debug_info); + + ~AppleThreadPlanStepThroughDirectDispatch() override; + + void GetDescription(Stream *s, lldb::DescriptionLevel level) override; + + bool ShouldStop(Event *event_ptr) override; + + bool StopOthers() override { return m_stop_others; } + + bool MischiefManaged() override; + + bool DoWillResume(lldb::StateType resume_state, bool current_plan) override; + + void SetFlagsToDefault() override { + GetFlags().Set(ThreadPlanStepInRange::GetDefaultFlagsValue()); + } + +protected: + bool DoPlanExplainsStop(Event *event_ptr) override; + + AppleObjCTrampolineHandler &m_trampoline_handler; + std::string m_dispatch_func_name; /// Which dispatch function we're stepping + /// through. + lldb::ThreadPlanSP m_objc_step_through_sp; /// When we hit an objc_msgSend, + /// we'll use this plan to get to + /// its target. + std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc + /// dispatch functions. + bool m_at_msg_send; /// Are we currently handling an msg_send + bool m_stop_others; /// Whether we should stop other threads. + }; } // namespace lldb_private -#endif // lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index 9eb493f83c84..2ccf9b33f9d8 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -1,4 +1,4 @@ -//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===// +//===-- ObjCLanguageRuntime.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +9,11 @@ #include "ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/MappedHash.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" @@ -41,7 +41,7 @@ ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process) m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(), m_negative_complete_class_cache() {} -bool ObjCLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) { +bool ObjCLanguageRuntime::IsAllowedRuntimeValue(ConstString name) { static ConstString g_self = ConstString("self"); static ConstString g_cmd = ConstString("_cmd"); return name == g_self || name == g_cmd; @@ -127,9 +127,9 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { for (uint32_t i = 0; i < types.GetSize(); ++i) { TypeSP type_sp(types.GetTypeAtIndex(i)); - if (ClangASTContext::IsObjCObjectOrInterfaceType( + if (TypeSystemClang::IsObjCObjectOrInterfaceType( type_sp->GetForwardCompilerType())) { - if (type_sp->IsCompleteObjCClass()) { + if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) { m_complete_class_cache[name] = type_sp; return type_sp; } @@ -387,9 +387,9 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) { CompilerType class_type; bool is_pointer_type = false; - if (ClangASTContext::IsObjCObjectPointerType(base_type, &class_type)) + if (TypeSystemClang::IsObjCObjectPointerType(base_type, &class_type)) is_pointer_type = true; - else if (ClangASTContext::IsObjCObjectOrInterfaceType(base_type)) + else if (TypeSystemClang::IsObjCObjectOrInterfaceType(base_type)) class_type = base_type; else return llvm::None; @@ -397,7 +397,7 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) { if (!class_type) return llvm::None; - ConstString class_name(class_type.GetConstTypeName()); + ConstString class_name(class_type.GetTypeName()); if (!class_name) return llvm::None; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h index b9a4d5dae08a..c43acf54bbcd 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCLanguageRuntime_h_ -#define liblldb_ObjCLanguageRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H #include <functional> #include <map> @@ -17,7 +17,6 @@ #include "llvm/Support/Casting.h" #include "lldb/Breakpoint/BreakpointPrecondition.h" -#include "lldb/Core/ClangForward.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Symbol/CompilerType.h" @@ -29,6 +28,7 @@ class CommandObjectObjC_ClassTable_Dump; namespace lldb_private { +class TypeSystemClang; class UtilityFunction; class ObjCLanguageRuntime : public LanguageRuntime { @@ -144,12 +144,12 @@ public: public: virtual ~EncodingToType(); - virtual CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name, + virtual CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name, bool for_expression) = 0; virtual CompilerType RealizeType(const char *name, bool for_expression); protected: - std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_up; + std::unique_ptr<TypeSystemClang> m_scratch_ast_ctx_up; }; class ObjCExceptionPrecondition : public BreakpointPrecondition { @@ -186,7 +186,8 @@ public: TaggedPointerVendor() = default; private: - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor); + TaggedPointerVendor(const TaggedPointerVendor &) = delete; + const TaggedPointerVendor &operator=(const TaggedPointerVendor &) = delete; }; ~ObjCLanguageRuntime() override; @@ -299,7 +300,7 @@ public: /// Check whether the name is "self" or "_cmd" and should show up in /// "frame variable". - bool IsWhitelistedRuntimeValue(ConstString name) override; + bool IsAllowedRuntimeValue(ConstString name) override; protected: // Classes that inherit from ObjCLanguageRuntime can see and modify these @@ -417,9 +418,10 @@ protected: void ReadObjCLibraryIfNeeded(const ModuleList &module_list); - DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime); + ObjCLanguageRuntime(const ObjCLanguageRuntime &) = delete; + const ObjCLanguageRuntime &operator=(const ObjCLanguageRuntime &) = delete; }; } // namespace lldb_private -#endif // liblldb_ObjCLanguageRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index b396781e6726..6858c7134d33 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptExpressionOpts.cpp --------------------------*- C++ -*-===// +//===-- RenderScriptExpressionOpts.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -86,7 +86,7 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { llvm::StringRef real_triple = m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple(); const llvm::Target *target_info = - llvm::TargetRegistry::lookupTarget(real_triple, err); + llvm::TargetRegistry::lookupTarget(std::string(real_triple), err); if (!target_info) { if (log) log->Warning("couldn't determine real target architecture: '%s'", diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h index 3ec4e37b6db0..52da677128e2 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_RENDERSCRIPT_EXPROPTS_H -#define LLDB_RENDERSCRIPT_EXPROPTS_H +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H #include "llvm/IR/Module.h" #include "llvm/Support/TargetRegistry.h" diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index 4edb8dec6082..dd9312234d8b 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===// +//===-- RenderScriptRuntime.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,6 +46,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_renderscript; +LLDB_PLUGIN_DEFINE(RenderScriptRuntime) + #define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")" char RenderScriptRuntime::ID = 0; @@ -791,6 +793,9 @@ RenderScriptRuntime::CreateInstance(Process *process, Searcher::CallbackReturn RSBreakpointResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *) { + BreakpointSP breakpoint_sp = GetBreakpoint(); + assert(breakpoint_sp); + ModuleSP module = context.module_sp; if (!module || !IsRenderScriptScriptModule(module)) @@ -811,7 +816,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter, if (kernel_sym) { Address bp_addr = kernel_sym->GetAddress(); if (filter.AddressPasses(bp_addr)) - m_breakpoint->AddLocation(bp_addr); + breakpoint_sp->AddLocation(bp_addr); } return Searcher::eCallbackReturnContinue; @@ -821,6 +826,9 @@ Searcher::CallbackReturn RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, lldb_private::SymbolContext &context, Address *) { + BreakpointSP breakpoint_sp = GetBreakpoint(); + assert(breakpoint_sp); + // We need to have access to the list of reductions currently parsed, as // reduce names don't actually exist as symbols in a module. They are only // identifiable by parsing the .rs.info packet, or finding the expand symbol. @@ -867,7 +875,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, if (!SkipPrologue(module, address)) { LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); } - m_breakpoint->AddLocation(address, &new_bp); + breakpoint_sp->AddLocation(address, &new_bp); LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s", __FUNCTION__, new_bp ? "new" : "existing", kernel_name.GetCString(), @@ -882,7 +890,8 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( SearchFilter &filter, SymbolContext &context, Address *addr) { - if (!m_breakpoint) + BreakpointSP breakpoint_sp = GetBreakpoint(); + if (!breakpoint_sp) return eCallbackReturnContinue; Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); @@ -892,7 +901,8 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( return Searcher::eCallbackReturnContinue; std::vector<std::string> names; - m_breakpoint->GetNames(names); + Breakpoint& breakpoint = *breakpoint_sp; + breakpoint.GetNames(names); if (names.empty()) return eCallbackReturnContinue; @@ -932,7 +942,7 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( } bool new_bp; - m_breakpoint->AddLocation(address, &new_bp); + breakpoint.AddLocation(address, &new_bp); LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__, new_bp ? "new " : "", k.m_name.AsCString()); @@ -1029,8 +1039,8 @@ bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) { } lldb::BreakpointResolverSP -RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bp, bool catch_bp, - bool throw_bp) { +RenderScriptRuntime::CreateExceptionResolver(const lldb::BreakpointSP &bp, + bool catch_bp, bool throw_bp) { BreakpointResolverSP resolver_sp; return resolver_sp; } @@ -1513,7 +1523,7 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, script->type = ScriptDetails::eScriptC; script->cache_dir = cache_dir; script->res_name = res_name; - script->shared_lib = strm.GetString(); + script->shared_lib = std::string(strm.GetString()); script->context = addr_t(args[eRsContext]); } @@ -3129,7 +3139,7 @@ void RenderScriptRuntime::DumpKernels(Stream &strm) const { strm.Printf("Resource '%s':", module->m_resname.c_str()); strm.EOL(); for (const auto &kernel : module->m_kernels) { - strm.Indent(kernel.m_name.AsCString()); + strm.Indent(kernel.m_name.GetStringRef()); strm.EOL(); } } @@ -3939,9 +3949,10 @@ void RSModuleDescriptor::Dump(Stream &strm) const { } void RSGlobalDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.AsCString()); + strm.Indent(m_name.GetStringRef()); VariableList var_list; - m_module->m_module->FindGlobalVariables(m_name, nullptr, 1U, var_list); + m_module->m_module->FindGlobalVariables(m_name, CompilerDeclContext(), 1U, + var_list); if (var_list.GetSize() == 1) { auto var = var_list.GetVariableAtIndex(0); auto type = var->GetType(); @@ -3964,12 +3975,12 @@ void RSGlobalDescriptor::Dump(Stream &strm) const { } void RSKernelDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.AsCString()); + strm.Indent(m_name.GetStringRef()); strm.EOL(); } void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const { - stream.Indent(m_reduce_name.AsCString()); + stream.Indent(m_reduce_name.GetStringRef()); stream.IndentMore(); stream.EOL(); stream.Indent(); diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index c3740ba55a11..5e3726548369 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RenderScriptRuntime_h_ -#define liblldb_RenderScriptRuntime_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H #include <array> #include <map> @@ -24,6 +24,10 @@ #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +namespace clang { +class TargetOptions; +} + namespace lldb_private { namespace lldb_renderscript { @@ -54,7 +58,7 @@ struct RSCoordinate { // for .expand kernels as a fallback. class RSBreakpointResolver : public BreakpointResolver { public: - RSBreakpointResolver(Breakpoint *bp, ConstString name) + RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name) : BreakpointResolver(bp, BreakpointResolver::NameResolver), m_kernel_name(name) {} @@ -73,9 +77,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp( - new RSBreakpointResolver(&breakpoint, m_kernel_name)); + new RSBreakpointResolver(breakpoint, m_kernel_name)); return ret_sp; } @@ -96,7 +100,7 @@ public: }; RSReduceBreakpointResolver( - Breakpoint *breakpoint, ConstString reduce_name, + const lldb::BreakpointSP &breakpoint, ConstString reduce_name, std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules, int kernel_types = eKernelTypeAll) : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver), @@ -123,9 +127,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver( - &breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); + breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); return ret_sp; } @@ -246,7 +250,8 @@ typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList; class RSScriptGroupBreakpointResolver : public BreakpointResolver { public: - RSScriptGroupBreakpointResolver(Breakpoint *bp, ConstString name, + RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp, + ConstString name, const RSScriptGroupList &groups, bool stop_on_all) : BreakpointResolver(bp, BreakpointResolver::NameResolver), @@ -268,9 +273,9 @@ public: lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP - CopyForBreakpoint(Breakpoint &breakpoint) override { + CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver( - &breakpoint, m_group_name, m_script_groups, m_stop_on_all)); + breakpoint, m_group_name, m_script_groups, m_stop_on_all)); return ret_sp; } @@ -343,9 +348,9 @@ public: bool CouldHaveDynamicValue(ValueObject &in_value) override; - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bp, - bool catch_bp, - bool throw_bp) override; + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bp, + bool catch_bp, bool throw_bp) override; bool LoadModule(const lldb::ModuleSP &module_sp); @@ -402,6 +407,8 @@ public: return false; } + bool GetOverrideExprOptions(clang::TargetOptions &prototype); + // PluginInterface protocol lldb_private::ConstString GetPluginName() override; @@ -421,7 +428,8 @@ protected: void InitSearchFilter(lldb::TargetSP target) { if (!m_filtersp) - m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); + m_filtersp = + std::make_shared<SearchFilterForUnconstrainedSearches>(target); } void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); @@ -577,11 +585,9 @@ private: // any previous stored allocation which has the same address. AllocationDetails *CreateAllocation(lldb::addr_t address); - bool GetOverrideExprOptions(clang::TargetOptions &prototype) override; - bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override; }; } // namespace lldb_private -#endif // liblldb_RenderScriptRuntime_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp index 45d0d028d047..b6f8b20c90c3 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptScriptGroup.cpp -----------------------------*- C++ -*-===// +//===-- RenderScriptScriptGroup.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h index c25e240f6d52..03d3a7823a98 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_RenderScriptScriptGroup_h_ -#define liblldb_RenderScriptScriptGroup_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H #include "lldb/Interpreter/CommandInterpreter.h" lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup( lldb_private::CommandInterpreter &interpreter); -#endif // liblldb_RenderScriptScriptGroup_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index 4ddff3ad9c4c..f51190e0c82c 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -1,4 +1,4 @@ -//===-- RenderScriptx86ABIFixups.cpp ----------------------------*- C++ -*-===// +//===-- RenderScriptx86ABIFixups.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" @@ -158,12 +157,11 @@ bool fixupX86StructRetCalls(llvm::Module &module) { assert(new_func_type && "failed to clone functionType for Renderscript ABI fixup"); - llvm::CallSite call_site(call_inst); llvm::Function *func = call_inst->getCalledFunction(); assert(func && "cannot resolve function in RenderScriptRuntime"); // Copy the original call arguments - std::vector<llvm::Value *> new_call_args(call_site.arg_begin(), - call_site.arg_end()); + std::vector<llvm::Value *> new_call_args(call_inst->arg_begin(), + call_inst->arg_end()); // Allocate enough space to store the return value of the original function // we pass a pointer to this allocation as the StructRet param, and then @@ -189,15 +187,17 @@ bool fixupX86StructRetCalls(llvm::Module &module) { ->setName("new_func_ptr_load_cast"); // load the new function address ready for a jump llvm::LoadInst *new_func_addr_load = - new llvm::LoadInst(new_func_ptr, "load_func_pointer", call_inst); + new llvm::LoadInst(new_func_ptr->getType()->getPointerElementType(), + new_func_ptr, "load_func_pointer", call_inst); // and create a callinstruction from it llvm::CallInst *new_call_inst = llvm::CallInst::Create(new_func_type, new_func_addr_load, new_call_args, "new_func_call", call_inst); new_call_inst->setCallingConv(call_inst->getCallingConv()); new_call_inst->setTailCall(call_inst->isTailCall()); - llvm::LoadInst *lldb_save_result_address = - new llvm::LoadInst(return_value_alloc, "save_return_val", call_inst); + llvm::LoadInst *lldb_save_result_address = new llvm::LoadInst( + return_value_alloc->getType()->getPointerElementType(), + return_value_alloc, "save_return_val", call_inst); // Now remove the old broken call call_inst->replaceAllUsesWith(lldb_save_result_address); diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h index a5efc999aea4..7836fff4a3a9 100644 --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_RENDERSCRIPT_X86_H -#define LLDB_RENDERSCRIPT_X86_H +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H #include "llvm/IR/Module.h" |