@@ -21,28 +21,38 @@ the testing library are stored in dedicated platform-specific sections:
2121
2222| Platform | Binary Format | Section Name |
2323| -| :-:| -|
24- | macOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
25- | iOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
26- | watchOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
27- | tvOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
28- | visionOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
29- | Linux | ELF | ` PT_NOTE ` [ ^ 1 ] |
30- | FreeBSD | ELF | ` PT_NOTE ` [ ^ 1 ] |
31- | Android | ELF | ` PT_NOTE ` [ ^ 1 ] |
24+ | macOS, iOS, watchOS, tvOS, visionOS | Mach-O | ` __DATA_CONST,__swift5_tests ` |
25+ | Linux, FreeBSD, Android | ELF | ` PT_NOTE ` [ ^ 1 ] |
3226| WASI | Statically Linked | ` swift5_tests ` |
3327| Windows | PE/COFF | ` .sw5test ` |
3428
3529[ ^ 1 ] : On platforms that use the ELF binary format natively, test content records
3630 are stored in ELF program headers of type ` PT_NOTE ` . Take care not to
3731 remove these program headers (for example, by invoking [ ` strip(1) ` ] ( https://www.man7.org/linux/man-pages/man1/strip.1.html ) .)
3832
39- ### Determining the type of test content
33+ ### Record headers
4034
4135Regardless of platform, all test content records created and discoverable by the
42- testing library start have the name ` "Swift Testing" ` stored in the implied
43- ` n_name ` field of their underlying ELF Notes. Each record's _ type_ (stored in
44- the underlying ELF Note's ` n_type ` field) determines how the record will be
45- interpreted at runtime:
36+ testing library have the following structure:
37+
38+ ``` c
39+ struct SWTTestContentHeader {
40+ int32_t n_namesz;
41+ int32_t n_descsz;
42+ int32_t n_type;
43+ char n_name[ n_namesz] ;
44+ // ...
45+ };
46+
47+ The size of `n_name` is dynamic and cannot be statically computed. The testing
48+ library always generates the name `" Swift Testing" ` and specifies an `n_namesz`
49+ value of `20 ` (the string being null-padded to the correct length), but other
50+ content may be present in the same section whose header content differs. For
51+ more information about this structure such as its alignment requirements, see
52+ the documentation for the [ELF format](https:// man7.org/linux/man-pages/man5/elf.5.html).
53+
54+ Each record' s _kind_ (stored in the `n_type` field) determines how the record
55+ will be interpreted at runtime:
4656
4757| Type Value | Interpretation |
4858|-:|-|
@@ -54,18 +64,27 @@ interpreted at runtime:
5464<!-- When adding cases to this enumeration, be sure to also update the
5565corresponding enumeration in Discovery.h and TestContentGeneration.swift. -->
5666
57- ### Loading test content from a record
67+ ### Record contents
5868
59- For all currently-defined record types, the header and name are followed by a
60- structure of the following form:
69+ For all currently-defined record types, the header structure is immediately
70+ followed by the actual content of the record. A test content record currently
71+ contains an `accessor` function to load the corresponding Swift content and a
72+ `flags` field whose value depends on the type of record. The overall structure
73+ of a record therefore looks like:
6174
6275```c
6376struct SWTTestContent {
77+ SWTTestContentHeader header;
6478 bool (* accessor)(void *);
6579 uint64_t flags;
6680};
6781```
6882
83+ This structure may grow in the future as needed. Check the `header.n_descsz`
84+ field to determine if there are additional fields present. Do not assume that
85+ the size of this structure will remain fixed over time or that all discovered
86+ test content records are the same size.
87+
6988#### The accessor field
7089
7190The function `accessor` is a C function whose signature in Swift can be restated
@@ -80,19 +99,20 @@ Swift type and returns `true`, or returns `false` if it could not generate the
8099relevant content. On successful return, the caller is responsible for
81100deinitializing the memory at `outValue` when done with it.
82101
83- The concrete Swift type of ` accessor ` 's result depends on the type of record:
102+ The concrete Swift type of the value written to `outValue` depends on the type
103+ of record:
84104
85105| Type Value | Return Type |
86106|-:|-|
87107| < `0` | Undefined (**do not use**) |
88- | ` 0 ` ... ` 99 ` | ` nil ` |
108+ | `0` ... `99` | Reserved (**do not use**) |
89109| `100` | `@Sendable () async -> Test`[^2] |
90- | ` 101 ` | ` ExitTest ` (owned by caller) |
110+ | `101` | `ExitTest` (consumed by caller) |
91111
92112[^2]: This signature is not the signature of `accessor`, but of the Swift
93- function reference it returns . This level of indirection is necessary
94- because loading a test or suite declaration is an asynchronous operation,
95- but C functions cannot be ` async ` .
113+ function reference it writes to `outValue` . This level of indirection is
114+ necessary because loading a test or suite declaration is an asynchronous
115+ operation, but C functions cannot be `async`.
96116
97117#### The flags field
98118
0 commit comments