blob: f3531f5711493da4170be3e3f083dc10cb205ef1 [file] [log] [blame]
// 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<UnsafePointer<CChar>?>) -> 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<GetImageHook?>) -> 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")