@@ -21,28 +21,39 @@ 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+
48+ The size of ` n_name ` is dynamic and cannot be statically computed. The testing
49+ library always generates the name ` "Swift Testing" ` and specifies an ` n_namesz `
50+ value of ` 20 ` (the string being null-padded to the correct length), but other
51+ content may be present in the same section whose header content differs. For
52+ more information about this structure such as its alignment requirements, see
53+ the documentation for the [ ELF format] ( https://man7.org/linux/man-pages/man5/elf.5.html ) .
54+
55+ Each record's _ kind_ (stored in the ` n_type ` field) determines how the record
56+ will be interpreted at runtime:
4657
4758| Type Value | Interpretation |
4859| -:| -|
@@ -54,18 +65,28 @@ interpreted at runtime:
5465<!-- When adding cases to this enumeration, be sure to also update the
5566corresponding enumeration in Discovery.h and TestContentGeneration.swift. -->
5667
57- ### Loading test content from a record
68+ ### Record contents
5869
59- For all currently-defined record types, the header and name are followed by a
60- structure of the following form:
70+ For all currently-defined record types, the header structure is immediately
71+ followed by the actual content of the record. A test content record currently
72+ contains an ` accessor ` function to load the corresponding Swift content and a
73+ ` flags ` field whose value depends on the type of record. The overall structure
74+ of a record therefore looks like:
6175
6276``` c
6377struct SWTTestContent {
78+ SWTTestContentHeader header;
6479 bool (* accessor)(void * );
65- uint64_t flags;
80+ uint32_t flags;
81+ uint32_t reserved;
6682};
6783```
6884
85+ This structure may grow in the future as needed. Check the ` header.n_descsz `
86+ field to determine if there are additional fields present. Do not assume that
87+ the size of this structure will remain fixed over time or that all discovered
88+ test content records are the same size.
89+
6990#### The accessor field
7091
7192The function ` accessor ` is a C function whose signature in Swift can be restated
@@ -80,19 +101,20 @@ Swift type and returns `true`, or returns `false` if it could not generate the
80101relevant content. On successful return, the caller is responsible for
81102deinitializing the memory at ` outValue ` when done with it.
82103
83- The concrete Swift type of ` accessor ` 's result depends on the type of record:
104+ The concrete Swift type of the value written to ` outValue ` depends on the type
105+ of record:
84106
85107| Type Value | Return Type |
86108| -:| -|
87109| < ` 0 ` | Undefined (** do not use** ) |
88- | ` 0 ` ... ` 99 ` | ` nil ` |
110+ | ` 0 ` ... ` 99 ` | Reserved ( ** do not use ** ) |
89111| ` 100 ` | ` @Sendable () async -> Test ` [ ^ 2 ] |
90- | ` 101 ` | ` ExitTest ` (owned by caller) |
112+ | ` 101 ` | ` ExitTest ` (consumed by caller) |
91113
92114[ ^ 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 ` .
115+ function reference it writes to ` outValue ` . This level of indirection is
116+ necessary because loading a test or suite declaration is an asynchronous
117+ operation, but C functions cannot be ` async ` .
96118
97119#### The flags field
98120
@@ -105,6 +127,10 @@ For test or suite declarations (type `100`), the following flags are defined:
105127
106128For exit test declarations (type ` 101 ` ), no flags are currently defined.
107129
130+ #### The reserved field
131+
132+ This field is reserved for future use. Always set it to ` 0 ` .
133+
108134## Third-party test content
109135
110136TODO: elaborate how tools can reuse the same ` n_name ` and ` n_type ` fields to
0 commit comments