#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"
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)
{
}
};
+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:
}
};
+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:
"objc <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("class-table", CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter)));
+ LoadSubCommand ("tagged-pointer", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter)));
}
virtual
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());
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),
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);
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
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
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);
};