Implement an objc tagged-pointer info command that will provide information about what LLDB thinks an ObjC tagged pointer represents

llvm-svn: 237322
This commit is contained in:
Enrico Granata 2015-05-14 00:46:47 +00:00
parent 23d8d0338e
commit b2d643146f
3 changed files with 166 additions and 20 deletions

View File

@ -310,6 +310,30 @@ public:
std::unordered_set<std::string> 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<EncodingToType> EncodingToTypeSP;
virtual EncodingToTypeSP

View File

@ -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("<unknown>"));
}
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 <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("info", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter)));
}
virtual
~CommandObjectMultiwordObjC_TaggedPointer ()
{
}
};
class CommandObjectMultiwordObjC : public CommandObjectMultiword
{
public:
@ -538,6 +658,7 @@ public:
"objc <subcommand> [<subcommand-options>]")
{
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),

View File

@ -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);
};