// RUN: %empty-directory(%t) // RUN: %target-build-swift -emit-library -o %t/libSimpleNSObjectSubclass.dylib %S/Inputs/SimpleNSObjectSubclass.swift -Xlinker -install_name -Xlinker @executable_path/libSimpleNSObjectSubclass.dylib // RUN: %target-codesign %t/libSimpleNSObjectSubclass.dylib // RUN: %target-build-swift %s -o %t/main -lSimpleNSObjectSubclass -L%t -import-objc-header %S/Inputs/class_getImageName-static-helper.h // RUN: %target-codesign %t/main // RUN: %target-run %t/main %t/libSimpleNSObjectSubclass.dylib // REQUIRES: executable_test // REQUIRES: objc_interop import Darwin import ObjectiveC // import SimpleNSObjectSubclass // Deliberately omitted in favor of dynamic loads. // Note: The following typealias uses AnyObject instead of AnyClass so that the // function type is trivially bridgeable to Objective-C. (The representation of // AnyClass is not the same as Objective-C's 'Class' type.) typealias GetImageHook = @convention(c) (AnyObject, UnsafeMutablePointer?>) -> ObjCBool var hook: GetImageHook? func checkThatSwiftHookWasNotInstalled() { // Check that the Swift hook did not get installed. guard let setHookPtr = dlsym(UnsafeMutableRawPointer(bitPattern: -2), getHookName()) else { // If the version of the ObjC runtime we're using doesn't have the hook, // we're good. return } let setHook = unsafeBitCast(setHookPtr, to: (@convention(c) (GetImageHook, UnsafeMutablePointer) -> Void).self) setHook({ hook!($0, $1) }, &hook) var info: Dl_info = .init() guard 0 != dladdr(unsafeBitCast(hook, to: UnsafeRawPointer.self), &info) else { fatalError("could not get dladdr info for objc_hook_getImageName") } precondition(String(cString: info.dli_fname).hasSuffix("libobjc.A.dylib"), "hook was replaced") } // It's important that this test does not register any Swift classes with the // Objective-C runtime---that's where Swift sets up its custom hook, and we want // to check the behavior /without/ that hook. That includes the buffer types for // String and Array. Therefore, we get C strings directly from a bridging // header. guard let theClass = objc_getClass(getNameOfClassToFind()) as! AnyClass? else { fatalError("could not find class") } guard let imageName = class_getImageName(theClass) else { fatalError("could not find image") } checkThatSwiftHookWasNotInstalled() // Okay, now we can use String. precondition(String(cString: imageName).hasSuffix("libSimpleNSObjectSubclass.dylib"), "found wrong image")