Skip to content

About

Read custom binary sections from every loaded image. The reading half of SE-0492, as a library.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

SwiftSections

CI MIT license Swift 6.3+ macOS, iOS, Linux, Windows

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.

Install

.package(url: "https://github.com/OlafAndreas/swift-sections.git", from: "0.2.1")

Requires Swift 6.3 or later. No dependencies, no macros.

How it works, and what only the runtime can fix

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.

Rules for observe handlers

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.

Who uses it

swift-discovery builds keyed type discovery on it, and swift-mediator finds its handlers through that.

License

MIT. See LICENSE.

About

Read custom binary sections from every loaded image. The reading half of SE-0492, as a library.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages