Read custom binary sections from every loaded image. The reading half of SE-0492.
import SwiftSections
#if canImport(Darwin)
let handlers = SectionName("__DATA_CONST,__swift5_hndlr")
#elseif os(Windows)
let handlers = SectionName(".hndlr$B")
#else
let handlers = SectionName("swift5_hndlr")
#endif
for buffer in SectionContents.loaded(handlers) {
for record in buffer.bindMemory(to: HandlerRecord.self) { register(record) }
}
let token = SectionContents.observe(handlers) { buffer in
// Called for each image already loaded, then for each image loaded later (Mach-O).
}SE-0492 lets a @section @used global land in a named section. It leaves reading the
section back to each library. This package is that reading half, as a dependency-free
prototype of the runtime API pitched on the Swift Forums:
[Pitch] Runtime enumeration of custom sections.
.package(url: "https://github.com/OlafAndreas/swift-sections.git", from: "0.2.1")Requires Swift 6.3 or later. No dependencies, no macros.
| Images | Late images | Mechanism | |
|---|---|---|---|
| Mach-O | all | observed | dyld add-image callback, then getsectiondata. The same registration the Swift runtime uses, so no racy _dyld_image_count walk. |
| ELF | all | on next call | dl_iterate_phdr, then each image's section headers are re-read from its file on disk, because ELF does not map them. The Swift 6.4 toolchain does not emit SE-0492's swift5_sections index, so there is nothing in memory to read. |
| COFF | all | on next call | Lists the process's modules and walks each module's section table at its base address, where Windows maps the headers. Records go in a $-group such as .hndlr$B, which the linker merges into the image section .hndlr; PE limits image section names to 8 bytes. |
The ELF path works but is the clearest argument for doing this in the runtime: it opens and
parses every loaded image's file to recover addresses the linker knew. swiftrt.o could
record them once at link time, as it already does for Swift's own metadata sections.
Handlers may run on the thread that loaded an image, under the loader's lock. Do not load images, do not block on work that might, copy what you need and return. On ELF and Windows the handler runs for the images loaded at the time of the call and is never called again.
swift-discovery builds keyed type discovery on it, and swift-mediator finds its handlers through that.
MIT. See LICENSE.