From b2d643146fd7c8540e907ceb38d799a060de87fa Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Thu, 14 May 2015 00:46:47 +0000 Subject: [PATCH] Implement an objc tagged-pointer info command that will provide information about what LLDB thinks an ObjC tagged pointer represents llvm-svn: 237322 --- lldb/include/lldb/Target/ObjCLanguageRuntime.h | 24 ++++ .../ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 129 ++++++++++++++++++++- .../ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h | 33 +++--- 3 files changed, 166 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/lldb/include/lldb/Target/ObjCLanguageRuntime.h index fee62ee..88874c7 100644 --- a/lldb/include/lldb/Target/ObjCLanguageRuntime.h +++ b/lldb/include/lldb/Target/ObjCLanguageRuntime.h @@ -310,6 +310,30 @@ public: std::unordered_set m_class_names; }; + class TaggedPointerVendor + { + public: + virtual bool + IsPossibleTaggedPointer (lldb::addr_t ptr) = 0; + + virtual ObjCLanguageRuntime::ClassDescriptorSP + GetClassDescriptor (lldb::addr_t ptr) = 0; + + virtual + ~TaggedPointerVendor () { } + protected: + TaggedPointerVendor () = default; + + private: + DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor); + }; + + virtual TaggedPointerVendor* + GetTaggedPointerVendor () + { + return nullptr; + } + typedef std::shared_ptr EncodingToTypeSP; virtual EncodingToTypeSP diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 57a0507..10af3b6 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -32,6 +32,7 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/ClangUtilityFunction.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -363,7 +364,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, m_has_object_getClass (false), m_loaded_objc_opt (false), m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)), - m_tagged_pointer_vendor_ap(TaggedPointerVendor::CreateInstance(*this,objc_module_sp)), + m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this,objc_module_sp)), m_encoding_to_type_sp(), m_noclasses_warning_emitted(false) { @@ -508,6 +509,106 @@ protected: } }; +class CommandObjectMultiwordObjC_TaggedPointer_Info : public CommandObjectParsed +{ +public: + + CommandObjectMultiwordObjC_TaggedPointer_Info (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "info", + "Dump information on a tagged pointer.", + "language objc tagged-pointer info", + eFlagRequiresProcess | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) + { + CommandArgumentEntry arg; + CommandArgumentData index_arg; + + // Define the first (and only) variant of this arg. + index_arg.arg_type = eArgTypeAddress; + index_arg.arg_repetition = eArgRepeatPlus; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (index_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + ~CommandObjectMultiwordObjC_TaggedPointer_Info () + { + } + +protected: + bool + DoExecute (Args& command, CommandReturnObject &result) + { + if (command.GetArgumentCount() == 0) + { + result.AppendError("this command requires arguments"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + Process *process = m_exe_ctx.GetProcessPtr(); + ExecutionContext exe_ctx(process); + ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); + if (objc_runtime) + { + ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = objc_runtime->GetTaggedPointerVendor(); + if (tagged_ptr_vendor) + { + for (auto i = 0; + i < command.GetArgumentCount(); + i++) + { + const char *arg_str = command.GetArgumentAtIndex(i); + if (!arg_str) + continue; + Error error; + lldb::addr_t arg_addr = Args::StringToAddress(&exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); + if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) + continue; + auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); + if (!descriptor_sp) + continue; + uint64_t info_bits = 0; + uint64_t value_bits = 0; + uint64_t payload = 0; + if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) + { + result.GetOutputStream().Printf("0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 "\n\tclass = %s\n", + (uint64_t)arg_addr, + payload, + value_bits, + info_bits, + descriptor_sp->GetClassName().AsCString("")); + } + else + { + result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", (uint64_t)arg_addr); + } + } + } + else + { + result.AppendError("current process has no tagged pointer support"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); + return true; + } + else + { + result.AppendError("current process has no Objective-C runtime loaded"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + } +}; + class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword { public: @@ -527,6 +628,25 @@ public: } }; +class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword +{ +public: + + CommandObjectMultiwordObjC_TaggedPointer (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "tagged-pointer", + "A set of commands for operating on Objective-C tagged pointers.", + "class-table []") + { + LoadSubCommand ("info", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter))); + } + + virtual + ~CommandObjectMultiwordObjC_TaggedPointer () + { + } +}; + class CommandObjectMultiwordObjC : public CommandObjectMultiword { public: @@ -538,6 +658,7 @@ public: "objc []") { LoadSubCommand ("class-table", CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter))); + LoadSubCommand ("tagged-pointer", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter))); } virtual @@ -1846,8 +1967,8 @@ AppleObjCRuntimeV2::NonPointerISACache::CreateInstance (AppleObjCRuntimeV2& runt objc_debug_isa_magic_value); } -AppleObjCRuntimeV2::TaggedPointerVendor* -AppleObjCRuntimeV2::TaggedPointerVendor::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp) +AppleObjCRuntimeV2::TaggedPointerVendorV2* +AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp) { Process* process(runtime.GetProcess()); @@ -1990,7 +2111,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRunti uint32_t objc_debug_taggedpointer_payload_lshift, uint32_t objc_debug_taggedpointer_payload_rshift, lldb::addr_t objc_debug_taggedpointer_classes) : -TaggedPointerVendor(runtime), +TaggedPointerVendorV2(runtime), m_cache(), m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask), m_objc_debug_taggedpointer_slot_shift(objc_debug_taggedpointer_slot_shift), diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index 7fdaeeb..18b9aca 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -108,6 +108,12 @@ public: virtual EncodingToTypeSP GetEncodingToType (); + virtual TaggedPointerVendor* + GetTaggedPointerVendor () + { + return m_tagged_pointer_vendor_ap.get(); + } + protected: virtual lldb::BreakpointResolverSP CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp); @@ -162,34 +168,29 @@ private: DISALLOW_COPY_AND_ASSIGN(NonPointerISACache); }; - class TaggedPointerVendor + class TaggedPointerVendorV2 : public ObjCLanguageRuntime::TaggedPointerVendor { public: - static TaggedPointerVendor* + static TaggedPointerVendorV2* CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp); - virtual bool - IsPossibleTaggedPointer (lldb::addr_t ptr) = 0; - - virtual ObjCLanguageRuntime::ClassDescriptorSP - GetClassDescriptor (lldb::addr_t ptr) = 0; - virtual - ~TaggedPointerVendor () { } + ~TaggedPointerVendorV2 () { } protected: AppleObjCRuntimeV2& m_runtime; - TaggedPointerVendor (AppleObjCRuntimeV2& runtime) : + TaggedPointerVendorV2 (AppleObjCRuntimeV2& runtime) : + TaggedPointerVendor(), m_runtime(runtime) { } private: - DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor); + DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2); }; - class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendor + class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 { public: virtual bool @@ -216,12 +217,12 @@ private: uint32_t m_objc_debug_taggedpointer_payload_rshift; lldb::addr_t m_objc_debug_taggedpointer_classes; - friend class AppleObjCRuntimeV2::TaggedPointerVendor; + friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted); }; - class TaggedPointerVendorLegacy : public TaggedPointerVendor + class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 { public: virtual bool @@ -231,11 +232,11 @@ private: GetClassDescriptor (lldb::addr_t ptr); protected: TaggedPointerVendorLegacy (AppleObjCRuntimeV2& runtime) : - TaggedPointerVendor (runtime) + TaggedPointerVendorV2 (runtime) { } - friend class AppleObjCRuntimeV2::TaggedPointerVendor; + friend class AppleObjCRuntimeV2::TaggedPointerVendorV2; DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy); }; -- 2.7.4