@@ -21,28 +21,39 @@ the testing library are stored in dedicated platform-specific sections:
21
21
22
22
| Platform | Binary Format | Section Name |
23
23
| -| :-:| -|
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 ] |
32
26
| WASI | Statically Linked | ` swift5_tests ` |
33
27
| Windows | PE/COFF | ` .sw5test ` |
34
28
35
29
[ ^ 1 ] : On platforms that use the ELF binary format natively, test content records
36
30
are stored in ELF program headers of type ` PT_NOTE ` . Take care not to
37
31
remove these program headers (for example, by invoking [ ` strip(1) ` ] ( https://www.man7.org/linux/man-pages/man1/strip.1.html ) .)
38
32
39
- ### Determining the type of test content
33
+ ### Record headers
40
34
41
35
Regardless 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:
46
57
47
58
| Type Value | Interpretation |
48
59
| -:| -|
@@ -54,18 +65,28 @@ interpreted at runtime:
54
65
<!-- When adding cases to this enumeration, be sure to also update the
55
66
corresponding enumeration in Discovery.h and TestContentGeneration.swift. -->
56
67
57
- ### Loading test content from a record
68
+ ### Record contents
58
69
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:
61
75
62
76
``` c
63
77
struct SWTTestContent {
78
+ SWTTestContentHeader header;
64
79
bool (* accessor)(void * );
65
- uint64_t flags;
80
+ uint32_t flags;
81
+ uint32_t reserved;
66
82
};
67
83
```
68
84
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
+
69
90
#### The accessor field
70
91
71
92
The 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
80
101
relevant content. On successful return, the caller is responsible for
81
102
deinitializing the memory at ` outValue ` when done with it.
82
103
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:
84
106
85
107
| Type Value | Return Type |
86
108
| -:| -|
87
109
| < ` 0 ` | Undefined (** do not use** ) |
88
- | ` 0 ` ... ` 99 ` | ` nil ` |
110
+ | ` 0 ` ... ` 99 ` | Reserved ( ** do not use ** ) |
89
111
| ` 100 ` | ` @Sendable () async -> Test ` [ ^ 2 ] |
90
- | ` 101 ` | ` ExitTest ` (owned by caller) |
112
+ | ` 101 ` | ` ExitTest ` (consumed by caller) |
91
113
92
114
[ ^ 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 ` .
96
118
97
119
#### The flags field
98
120
@@ -105,6 +127,10 @@ For test or suite declarations (type `100`), the following flags are defined:
105
127
106
128
For exit test declarations (type ` 101 ` ), no flags are currently defined.
107
129
130
+ #### The reserved field
131
+
132
+ This field is reserved for future use. Always set it to ` 0 ` .
133
+
108
134
## Third-party test content
109
135
110
136
TODO: elaborate how tools can reuse the same ` n_name ` and ` n_type ` fields to
0 commit comments