Add logic to the ObjC runtime in LLDB to extract the pointer values of the two singleton (pairtons?) instances of __NSCFBoolean that represent true and false

This is useful because that knowledge will in turn allow no-code-running formatting of boolean NSNumbers; but that's a commit that will have to wait Monday..

llvm-svn: 279353
This commit is contained in:
Enrico Granata 2016-08-20 00:48:11 +00:00
parent c49b00a249
commit 3630a287a6
4 changed files with 63 additions and 1 deletions

View File

@ -350,6 +350,13 @@ AppleObjCRuntime::GetFoundationVersion ()
return m_Foundation_major.getValue();
}
void
AppleObjCRuntime::GetValuesForGlobalCFBooleans(lldb::addr_t& cf_true,
lldb::addr_t& cf_false)
{
cf_true = cf_false = LLDB_INVALID_ADDRESS;
}
bool
AppleObjCRuntime::IsModuleObjCLibrary (const ModuleSP &module_sp)
{

View File

@ -114,6 +114,10 @@ public:
uint32_t
GetFoundationVersion();
virtual void
GetValuesForGlobalCFBooleans(lldb::addr_t& cf_true,
lldb::addr_t& cf_false);
protected:
// Call CreateInstance instead.
AppleObjCRuntime(Process *process);

View File

@ -395,7 +395,8 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_mo
m_non_pointer_isa_cache_ap(NonPointerISACache::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)
m_noclasses_warning_emitted(false),
m_CFBoolean_values()
{
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
m_has_object_getClass =
@ -2577,3 +2578,44 @@ AppleObjCRuntimeV2::GetPointerISA (ObjCISA isa)
return ret;
}
bool
AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded ()
{
if (m_CFBoolean_values)
return true;
static ConstString g_kCFBooleanFalse("kCFBooleanFalse");
static ConstString g_kCFBooleanTrue("kCFBooleanTrue");
std::function<lldb::addr_t(ConstString)> get_symbol = [this] (ConstString sym) -> lldb::addr_t {
SymbolContextList sc_list;
if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(g_kCFBooleanFalse, lldb::eSymbolTypeData, sc_list) == 1)
{
SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
if (sc.symbol)
return sc.symbol->GetLoadAddress(&GetProcess()->GetTarget());
}
return LLDB_INVALID_ADDRESS;
};
lldb::addr_t false_addr = get_symbol(g_kCFBooleanFalse);
lldb::addr_t true_addr = get_symbol(g_kCFBooleanTrue);
return (m_CFBoolean_values = {false_addr,true_addr}).operator bool();
}
void
AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t& cf_true,
lldb::addr_t& cf_false)
{
if (GetCFBooleanValuesIfNeeded())
{
cf_true = m_CFBoolean_values->second;
cf_false = m_CFBoolean_values->first;
}
else
this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false);
}

View File

@ -114,6 +114,10 @@ public:
return m_tagged_pointer_vendor_ap.get();
}
void
GetValuesForGlobalCFBooleans(lldb::addr_t& cf_true,
lldb::addr_t& cf_false) override;
// none of these are valid ISAs - we use them to infer the type
// of tagged pointers - if we have something meaningful to say
// we report an actual type - otherwise, we just say tagged
@ -356,6 +360,9 @@ private:
lldb::addr_t
GetSharedCacheReadOnlyAddress();
bool
GetCFBooleanValuesIfNeeded ();
friend class ClassDescriptorV2;
std::unique_ptr<UtilityFunction> m_get_class_info_code;
@ -375,6 +382,8 @@ private:
std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_ap;
EncodingToTypeSP m_encoding_to_type_sp;
bool m_noclasses_warning_emitted;
llvm::Optional<std::pair<lldb::addr_t,
lldb::addr_t>> m_CFBoolean_values;
};
} // namespace lldb_private