diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 151c30d919362..78888e0f039a7 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -202,6 +202,7 @@ class MetadataReader { StoredPointer TaggedPointerExtendedSlotShift; StoredPointer TaggedPointerExtendedSlotMask; StoredPointer TaggedPointerExtendedClasses; + StoredPointer TaggedPointerObfuscator; Demangle::NodeFactory Factory; @@ -502,14 +503,14 @@ class MetadataReader { if (!readObjCClassName(MetadataAddress, className)) return BuiltType(); - auto BuiltObjCClass = Builder.createObjCClassType(std::move(className)); + BuiltType BuiltObjCClass = Builder.createObjCClassType(std::move(className)); if (!BuiltObjCClass) { // Try the superclass. if (!classMeta->Superclass) return BuiltType(); - return readTypeFromMetadata(classMeta->Superclass, - skipArtificialSubclasses); + BuiltObjCClass = readTypeFromMetadata(classMeta->Superclass, + skipArtificialSubclasses); } TypeCache[MetadataAddress] = BuiltObjCClass; @@ -711,7 +712,7 @@ class MetadataReader { if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended) return false; - return objectAddress & TaggedPointerMask; + return (objectAddress ^ TaggedPointerObfuscator) & TaggedPointerMask; } /// Read the isa pointer of an Object-C tagged pointer value. @@ -728,8 +729,8 @@ class MetadataReader { // Extended pointers have a tag of 0b111, using 8 additional bits // to specify the class. - if (TaggedPointerExtendedMask != 0 && - ((objectAddress & TaggedPointerExtendedMask) + if (TaggedPointerExtendedMask != 0 && + (((objectAddress ^ TaggedPointerObfuscator) & TaggedPointerExtendedMask) == TaggedPointerExtendedMask)) { auto tag = ((objectAddress >> TaggedPointerExtendedSlotShift) & TaggedPointerExtendedSlotMask); @@ -2436,6 +2437,9 @@ class MetadataReader { TaggedPointerExtendedClasses = TaggedPointerExtendedClassesAddr.getAddressData(); + tryFindAndReadSymbol(TaggedPointerObfuscator, + "objc_debug_taggedpointer_obfuscator"); + # undef tryFindSymbol # undef tryReadSymbol # undef tryFindAndReadSymbol diff --git a/test/RemoteAST/existentials_objc.swift b/test/RemoteAST/existentials_objc.swift index 01ac9a5b9363d..131c6af29051a 100644 --- a/test/RemoteAST/existentials_objc.swift +++ b/test/RemoteAST/existentials_objc.swift @@ -12,5 +12,22 @@ func printDynamicTypeAndAddressForExistential(_: T) // CHECK: NSObject printDynamicTypeAndAddressForExistential(NSObject() as AnyObject) +// Print tagged pointer types three times to ensure the caching works. + +// CHECK: NSNumber +printDynamicTypeAndAddressForExistential(NSNumber(123) as AnyObject) + +// CHECK: NSNumber +printDynamicTypeAndAddressForExistential(NSNumber(123) as AnyObject) + // CHECK: NSNumber printDynamicTypeAndAddressForExistential(NSNumber(123) as AnyObject) + +// CHECK: NSString +printDynamicTypeAndAddressForExistential(NSString("hello") as AnyObject) + +// CHECK: NSString +printDynamicTypeAndAddressForExistential(NSString("hello") as AnyObject) + +// CHECK: NSString +printDynamicTypeAndAddressForExistential(NSString("hello") as AnyObject) diff --git a/tools/swift-remoteast-test/swift-remoteast-test.cpp b/tools/swift-remoteast-test/swift-remoteast-test.cpp index 54d00292f275d..60fe9cb6c4f82 100644 --- a/tools/swift-remoteast-test/swift-remoteast-test.cpp +++ b/tools/swift-remoteast-test/swift-remoteast-test.cpp @@ -40,15 +40,24 @@ using namespace swift::remoteAST; /// The context for the code we're running. Set by the observer. static ASTContext *Context = nullptr; +/// The RemoteAST for the code we're running. +std::shared_ptr reader; +std::unique_ptr remoteContext; + +static RemoteASTContext &getRemoteASTContext() { + if (remoteContext) + return *remoteContext; + + std::shared_ptr reader(new InProcessMemoryReader()); + remoteContext.reset(new RemoteASTContext(*Context, std::move(reader))); + return *remoteContext; +} + // FIXME: swiftcall /// func printType(forMetadata: Any.Type) LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI printMetadataType(const Metadata *typeMetadata) { - assert(Context && "context was not set"); - - std::shared_ptr reader(new InProcessMemoryReader()); - RemoteASTContext remoteAST(*Context, std::move(reader)); - + auto &remoteAST = getRemoteASTContext(); auto &out = llvm::outs(); auto result = @@ -66,11 +75,7 @@ printMetadataType(const Metadata *typeMetadata) { /// func printDynamicType(_: AnyObject) LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI printHeapMetadataType(void *object) { - assert(Context && "context was not set"); - - std::shared_ptr reader(new InProcessMemoryReader()); - RemoteASTContext remoteAST(*Context, std::move(reader)); - + auto &remoteAST = getRemoteASTContext(); auto &out = llvm::outs(); auto metadataResult = @@ -94,11 +99,7 @@ printHeapMetadataType(void *object) { static void printMemberOffset(const Metadata *typeMetadata, StringRef memberName, bool passMetadata) { - assert(Context && "context was not set"); - - std::shared_ptr reader(new InProcessMemoryReader()); - RemoteASTContext remoteAST(*Context, std::move(reader)); - + auto &remoteAST = getRemoteASTContext(); auto &out = llvm::outs(); // The first thing we have to do is get the type. @@ -147,10 +148,7 @@ printTypeMetadataMemberOffset(const Metadata *typeMetadata, LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI printDynamicTypeAndAddressForExistential(void *object, const Metadata *typeMetadata) { - assert(Context && "context was not set"); - std::shared_ptr reader(new InProcessMemoryReader()); - RemoteASTContext remoteAST(*Context, std::move(reader)); - + auto &remoteAST = getRemoteASTContext(); auto &out = llvm::outs(); // First, retrieve the static type of the existential, so we can understand