Add a distinct hook for `swift_willThrowTypedImpl()`.
This PR adds a hook for `swift_willThrowTypedImpl()` that is distinct from
`swift_willThrow()`. The current implementation of `swift_willThrowTypedImpl()` creates a
temporary existential box for the thrown error and calls the `_swift_willThrow` hook that
is set by XCTest and swift-testing. Unfortunately, this temporary existential box isn't
very useful because its address is not expected to be stable.
Instead, expose a separate hook, `_swift_willThrowTypedImpl`, whose signature matches
that of the new ABI function. This hook can then be used by XCTest and swift-testing to
distinguish between typed throws and untyped throws and avoids creating a temporary
existential box when it won't be useful.
As implemented, if `_swift_willThrowTypedImpl` is not set but `_swift_willThrow` is, the
`swift_willThrowTypedImpl()` will fall back to calling `_swift_willThrow` with a temporary
existential box. We might decide this is unnecessary, but I figured it would allow us more
time to stage adoption of the new hook in the testing libraries.
Resolves rdar://122824443.
We shouldn't call `__cxa_begin_catch` if built with `-fno-exceptions`,
because it's possible that the environment we're in won't include
the `__cxa_begin_catch` routine.
rdar://122995672
Use exports, not symbols, when emitting a pointer target. Exports are what the linker can actually work with.
When searching for a nearby export to use for a pointer target, accept anything within the same segment, not just the same section. Only segments can be rearranged relative to each other, not sections within a segment, so this is safe and allows for more possible targets.
Disallow pointer targets with no export within the same segment. We attempted to emit a target that's relative to the section starting point in this case, but that didn't work. We'll revisit if it looks useful to do so.
In order to make this work, we resolve the export when writing a pointer instead of when emitting JSON, and make the writePointer functions failable. If writePointer fails, we'll fail to build the metadata and skip it.
Correctly handle the case where the names JSON contains a metadata we already constructed as part of a prior name. Previously we'd emit it twice, now it checks to see if it's already been built and do nothing in that case. Also save errors when a metadata can't be built, so subsequent attempts to build it can fail immediately.
When emitting fixups with ptrauth attributes, use the correct target kind "arm64_auth_ptr".
Fix the VerifyExternalMetadata.swift test not to load an arm64e runtime slice when testing arm64. That's normally fine, but we depend on loading the exact same dylib that we built prespecializations for.
rdar://122968337
This adds in hooks so that the new hash/isEqual interop
(which bridges Obj-C hash/isEqual: calls to the corresponding
Swift Hashable/Equatable conformances) can be selectively
disabled based on the OS and/or client.
For now, enable the new semantics everywhere except Apple platforms
(which have legacy apps that may be relying on the old semantics).
Rather than just on or off, I've changed it to allow "off", "fast",
or "full". "fast" means that we'll do symbol lookup, but we won't
try to find inline frames and we won't run line number programs
(those are the things that are taking considerable time in some
cases).
rdar://122302117
The other new runtime functions appear to have a leading underscore.
It makes sense in this case because we don't expect anything to call
this directly (other than the unwinder).
rdar://120952971
The previous approach was effectively to catch the exception and then
run a trap instruction. That has the unfortunate feature that we end
up with a crash at the catch site, not at the throw site, which leaves
us with very little information about which exception was thrown or
where from.
(Strictly we do have the exception pointer and could obtain exception
information, but it still won't tell us what threw it.)
Instead of that, set a personality function for Swift functions that
call potentially throwing code, and have that personality function
trap the exception during phase 1 (i.e. *before* the original stack
has been unwound).
rdar://120952971
`swift_willThrow` is called with an error right before it is thrown.
This existing entrypoint requires an already-boxed error existential;
with typed errors, we don't have the error existential on hand, so we
would need to allocate the box to throw a typed error. That's not okay.
Introduce a new `swift_willThrowTypedImpl` entry point into the runtime
that will first check for the presence of an error handler and, if one
is present, box the error to provide to the error handler. This
maintains the no-allocations path for typed errors while still
allowing existing error handlers to work.
This new entrypoint isn't available on older Swift runtimes, so create
a back-deployable shim called by the compiler. On new-enough platforms,
this will call through to `swift_willThrowTypedImpl`. On older
platforms, we drop the error and don't call the registered will-throw
handler at all. This is a compromise that avoids boxing when throwing
typed errors, at the cost of a slightly different experience for this
new feature on older runtimes.
Fixes rdar://119828459.
Symbolication can take some time, depending on the binaries involved.
In certain contexts it's better for the backtrace to finish quickly,
and then symbolication could be done offline.
rdar://122302117
rdar://117083470
An existential can contain a different type than the one that is being assigned, so we have to check the types and handle the values accordingly.
We run the builder, then use a small program that converts the JSON output into C code that generates the data. Compile that into a bundle, then load it as the prespecializations library. Then scan all the entries in the table and compare them with what the runtime builds dynamically.
We were doing a linear scan of the table contents as a stopgap. Stop doing that, and compute the proper key for the lookup, matching the one used in the builder.
Not quite NFC because apparently the representation bleeds into what's
accepted in some situations where we're supposed to be warning about
conflicts and then making an arbitrary choice. But what we're doing
is nonsense, so we definitely need to break behavior here.
This is setting up for isolated(any) and isolated(caller). I tried
to keep that out of the patch as much as possible, though.
This library uses GenericMetadataBuilder with a ReaderWriter that can read data and resolve pointers from MachO files, and emit a JSON representation of a dylib containing the built metadata.
We use LLVM's binary file readers to parse the MachO files and resolve fixups so we can follow pointers. This code is somewhat MachO specific, but could be generalized to other formats that LLVM supports.
rdar://116592577
ASL is deprecated in macOS 10.12. It may be time to transition to os_log now
that deployment targets have been raised to 10.12, but until that project
starts these warnings are just pollution.
Filed rdar://121066531 to track adoption of `os_log()` if appropriate.
Create a version of the metadata specialization code which is abstracted so that it can work in different contexts, such as building specialized metadata from dylibs on disk rather than from inside a running process.
The GenericMetadataBuilder class is templatized on a ReaderWriter. The ReaderWriter abstracts out everything that's different between in-process and external construction of this data. Instead of reading and writing pointers directly, the builder calls the ReaderWriter to resolve and write pointers. The ReaderWriter also handles symbol lookups and looking up other Swift types by name.
This is accompanied by a simple implementation of the ReaderWriter which works in-process. The abstracted calls to resolve and write pointers are implemented using standard pointer dereferencing.
A new SWIFT_DEBUG_VALIDATE_EXTERNAL_GENERIC_METADATA_BUILDER environment variable uses the in-process ReaderWriter to validate the builder by running it in parallel with the existing metadata builder code in the runtime. When enabled, the GenericMetadataBuilder is used to build a second copy of metadata built by the runtime, and the two are compared to ensure that they match. When this environment variable is not set, the new builder code is inactive.
The builder is incomplete, and this initial version only works on structs. Any unsupported type produces an error, and skips the validation.
rdar://116592420
For calloc, the variable denoting the of elements comes first,
then the variable denoting the size of each element. However, both
arguments are swapped when calling this function in many places in this codebase.
We can't use `malloc_type_aligned_alloc()` because `aligned_alloc()` requires
that `size` be a multiple of `alignment`, which isn't something we expect here.
rdar://119137861
In the event that the backtracer fails to suspend a thread, it emits a
warning message. Unfortunately the exact meaning of this message isn't
obvious and it doesn't make clear that it's a secondary problem (that is,
you've already crashed at this point).
Update the message to make things clearer.
rdar://116593541
The static bridgeableProtocol inherits the ptrauth_struct attribute which uses the B key, and that's not allowed on global data in the shared cache. Pass the value directly as a parameter instead.