[ObjCRuntime] Add support for obfuscation in tagged pointers.

This is the default in MacOS Mojave. No testcases, as basically
we have a lot of coverage (and the testsuite fails quite a bit
without this change in Beta 3).

Thanks to Fred Riss for helping me with this patch (fixing
bugs/nondeterminism).

<rdar://problem/38305553>

llvm-svn: 336607
This commit is contained in:
Davide Italiano 2018-07-09 21:53:43 +00:00
parent d50f36ed77
commit 0eddbf8f95
4 changed files with 54 additions and 7 deletions

View File

@ -283,6 +283,10 @@ bool AppleObjCRuntimeV1::ClassDescriptorV1::Describe(
return false;
}
lldb::addr_t AppleObjCRuntimeV1::GetTaggedPointerObfuscator() {
return 0;
}
lldb::addr_t AppleObjCRuntimeV1::GetISAHashTablePointer() {
if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
ModuleSP objc_module_sp(GetObjCModule());

View File

@ -45,6 +45,8 @@ public:
}
}
lldb::addr_t GetTaggedPointerObfuscator();
class ClassDescriptorV1 : public ObjCLanguageRuntime::ClassDescriptor {
public:
ClassDescriptorV1(ValueObject &isa_pointer);

View File

@ -384,7 +384,9 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(),
m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_ap(),
m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(),
m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS),
m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
m_hash_signature(),
m_has_object_getClass(false), m_loaded_objc_opt(false),
m_non_pointer_isa_cache_ap(
NonPointerISACache::CreateInstance(*this, objc_module_sp)),
@ -1196,6 +1198,38 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
return objc_class_sp;
}
lldb::addr_t AppleObjCRuntimeV2::GetTaggedPointerObfuscator() {
if (m_tagged_pointer_obfuscator != LLDB_INVALID_ADDRESS)
return m_tagged_pointer_obfuscator;
Process *process = GetProcess();
ModuleSP objc_module_sp(GetObjCModule());
if (!objc_module_sp)
return LLDB_INVALID_ADDRESS;
static ConstString g_gdb_objc_obfuscator("objc_debug_taggedpointer_obfuscator");
const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
if (symbol) {
lldb::addr_t g_gdb_obj_obfuscator_ptr =
symbol->GetLoadAddress(&process->GetTarget());
if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
Status error;
m_tagged_pointer_obfuscator = process->ReadPointerFromMemory(
g_gdb_obj_obfuscator_ptr, error);
}
}
// If we don't have a correct value at this point, there must be no obfuscation.
if (m_tagged_pointer_obfuscator == LLDB_INVALID_ADDRESS)
m_tagged_pointer_obfuscator = 0;
return m_tagged_pointer_obfuscator;
}
lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() {
if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS) {
Process *process = GetProcess();
@ -2210,7 +2244,9 @@ AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor(
return ObjCLanguageRuntime::ClassDescriptorSP();
}
}
return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, ptr));
lldb::addr_t unobfuscated = ptr ^ m_runtime.GetTaggedPointerObfuscator();
return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, unobfuscated));
}
AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::
@ -2242,8 +2278,9 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
uint64_t data_payload;
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
if (!IsPossibleTaggedPointer(ptr))
if (!IsPossibleTaggedPointer(unobfuscated))
return ObjCLanguageRuntime::ClassDescriptorSP();
uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) &
@ -2269,7 +2306,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
}
data_payload =
(((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >>
(((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
m_objc_debug_taggedpointer_payload_rshift);
return ClassDescriptorSP(
@ -2326,11 +2363,12 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
lldb::addr_t ptr) {
ClassDescriptorSP actual_class_descriptor_sp;
uint64_t data_payload;
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
if (!IsPossibleTaggedPointer(ptr))
if (!IsPossibleTaggedPointer(unobfuscated))
return ObjCLanguageRuntime::ClassDescriptorSP();
if (!IsPossibleExtendedTaggedPointer(ptr))
if (!IsPossibleExtendedTaggedPointer(unobfuscated))
return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) &
@ -2356,7 +2394,7 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
}
data_payload =
(((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >>
(((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >>
m_objc_debug_taggedpointer_ext_payload_rshift);
return ClassDescriptorSP(

View File

@ -94,6 +94,8 @@ public:
return m_tagged_pointer_vendor_ap.get();
}
lldb::addr_t GetTaggedPointerObfuscator();
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
lldb::addr_t &cf_false) override;
@ -330,6 +332,7 @@ private:
std::mutex m_get_shared_cache_class_info_args_mutex;
std::unique_ptr<DeclVendor> m_decl_vendor_ap;
lldb::addr_t m_tagged_pointer_obfuscator;
lldb::addr_t m_isa_hash_table_ptr;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;