From f6c76acd75fe5946a0882939e9463a4b5d05b40c Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 17 Feb 2017 15:36:23 -0800 Subject: [PATCH] Adapt lldb to the new swift weak reference representation. --- include/lldb/Target/SwiftLanguageRuntime.h | 4 +- .../Plugins/Language/Swift/SwiftOptional.cpp | 3 +- .../ObjC/AppleObjCRuntime/AppleObjCRuntime.h | 2 + .../AppleObjCRuntime/AppleObjCRuntimeV2.h | 2 +- source/Target/SwiftLanguageRuntime.cpp | 89 ++++++++++++++++--- 5 files changed, 87 insertions(+), 13 deletions(-) diff --git a/include/lldb/Target/SwiftLanguageRuntime.h b/include/lldb/Target/SwiftLanguageRuntime.h index 191f4c60b7ef..6d311c4692d3 100644 --- a/include/lldb/Target/SwiftLanguageRuntime.h +++ b/include/lldb/Target/SwiftLanguageRuntime.h @@ -354,7 +354,9 @@ class SwiftLanguageRuntime : public LanguageRuntime { // to record useful runtime information // This API's task is to strip those bits if necessary and return // a pure pointer (or a tagged pointer) - lldb::addr_t MaybeMaskNonTrivialReferencePointer(lldb::addr_t); + lldb::addr_t MaybeMaskNonTrivialReferencePointer( + lldb::addr_t, + SwiftASTContext::NonTriviallyManagedReferenceStrategy strategy); ConstString GetErrorBackstopName(); diff --git a/source/Plugins/Language/Swift/SwiftOptional.cpp b/source/Plugins/Language/Swift/SwiftOptional.cpp index 328956eb7c9f..c41f0f4a0fcb 100644 --- a/source/Plugins/Language/Swift/SwiftOptional.cpp +++ b/source/Plugins/Language/Swift/SwiftOptional.cpp @@ -74,7 +74,8 @@ ExtractSomeIfAny(ValueObject *optional, lldb::addr_t original_ptr = value_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); lldb::addr_t tweaked_ptr = - swift_runtime->MaybeMaskNonTrivialReferencePointer(original_ptr); + swift_runtime->MaybeMaskNonTrivialReferencePointer(original_ptr, + strategy); if (original_ptr != tweaked_ptr) { CompilerType value_type(value_sp->GetCompilerType()); DataBufferSP buffer_sp( diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 5856f858f1ea..8df69395615e 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -104,6 +104,8 @@ class AppleObjCRuntime : public lldb_private::ObjCLanguageRuntime { virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false); + + virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; } protected: // Call CreateInstance instead. diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index bb78453f5d28..94e0d58b97c5 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -94,7 +94,7 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime { EncodingToTypeSP GetEncodingToType() override; - bool IsTaggedPointer(lldb::addr_t ptr); + bool IsTaggedPointer(lldb::addr_t ptr) override; TaggedPointerVendor *GetTaggedPointerVendor() override { return m_tagged_pointer_vendor_ap.get(); diff --git a/source/Target/SwiftLanguageRuntime.cpp b/source/Target/SwiftLanguageRuntime.cpp index 96bca9fd5f6d..82f0846f7673 100644 --- a/source/Target/SwiftLanguageRuntime.cpp +++ b/source/Target/SwiftLanguageRuntime.cpp @@ -3327,8 +3327,16 @@ SwiftLanguageRuntime::MaskMaybeBridgedPointer(lldb::addr_t addr, } lldb::addr_t -SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer(lldb::addr_t addr) { - if (auto objc_runtime = GetObjCRuntime()) { +SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer( + lldb::addr_t addr, + SwiftASTContext::NonTriviallyManagedReferenceStrategy strategy) { + + if (addr == 0) + return addr; + + AppleObjCRuntime *objc_runtime = GetObjCRuntime(); + + if (objc_runtime) { // tagged pointers don't perform any masking if (objc_runtime->IsTaggedPointer(addr)) return addr; @@ -3372,16 +3380,77 @@ SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer(lldb::addr_t addr) { lldb::addr_t mask = 0; - if (is_arm && is_64) - mask = SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS; - else if (is_intel && is_64) - mask = SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS; - else - mask = SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS; + if (strategy == SwiftASTContext::NonTriviallyManagedReferenceStrategy::eWeak) { + bool is_indirect = true; + + // On non-objc platforms, the weak reference pointer always pointed to a + // runtime structure. + // For ObjC platforms, the masked value determines whether it is indirect. + + uint32_t value = 0; + + if (objc_runtime) + { + + if (is_intel) { + if (is_64) { + mask = SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_MASK; + value = SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_VALUE; + } else { + mask = SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_MASK; + value = SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_VALUE; + } + } else if (is_arm) { + if (is_64) { + mask = SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_MASK; + value = SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_VALUE; + } else { + mask = SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_MASK; + value = SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_VALUE; + } + } + } else { + // This name is a little confusing. The "DEFAULT" marking in System.h + // is supposed to mean: the value for non-ObjC platforms. So + // DEFAULT_OBJC here actually means "non-ObjC". + mask = SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_MASK; + value = SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_VALUE; + } + + is_indirect = ((addr & mask) == value); + + if (!is_indirect) + return addr; + + // The masked value of address is a pointer to the runtime structure. + // The first field of the structure is the actual pointer. + Process *process = GetProcess(); + Error error; + + lldb::addr_t masked_addr = addr & ~mask; + lldb::addr_t isa_addr = process->ReadPointerFromMemory(masked_addr, error); + if (error.Fail()) + { + // FIXME: do some logging here. + return addr; + } + return isa_addr; + + + } else { + if (is_arm && is_64) + mask = SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS; + else if (is_intel && is_64) + mask = SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS; + else + mask = SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS; - mask = (1 << mask) | (1 << (mask + 1)); + mask = (1 << mask) | (1 << (mask + 1)); - return addr & ~mask; + return addr & ~mask; + } + + return addr; } ConstString SwiftLanguageRuntime::GetErrorBackstopName() {