16
16
//
17
17
//===----------------------------------------------------------------------===//
18
18
19
- // FIXME: Make this work with Linux
20
-
21
- import MachO
22
- import Darwin
23
-
24
19
let RequestInstanceKind = " k "
25
20
let RequestInstanceAddress = " i "
26
21
let RequestReflectionInfos = " r "
@@ -31,56 +26,10 @@ let RequestStringLength = "l"
31
26
let RequestDone = " d "
32
27
let RequestPointerSize = " p "
33
28
34
- internal func debugLog( _ message: @autoclosure ( ) -> String ) {
35
- #if DEBUG_LOG
36
- fputs ( " Child: \( message ( ) ) \n " , stderr)
37
- fflush ( stderr)
38
- #endif
39
- }
40
-
41
- public enum InstanceKind : UInt8 {
42
- case None
43
- case Object
44
- case Existential
45
- case ErrorExistential
46
- case Closure
47
- case Enum
48
- case EnumValue
49
- }
50
-
51
- /// Represents a section in a loaded image in this process.
52
- internal struct Section {
53
- /// The absolute start address of the section's data in this address space.
54
- let startAddress : UnsafeRawPointer
55
-
56
- /// The size of the section in bytes.
57
- let size : UInt
58
- }
59
29
60
- /// Holds the addresses and sizes of sections related to reflection
61
- internal struct ReflectionInfo : Sequence {
62
- /// The name of the loaded image
63
- internal let imageName : String
64
-
65
- /// Reflection metadata sections
66
- internal let fieldmd : Section ?
67
- internal let assocty : Section ?
68
- internal let builtin : Section ?
69
- internal let capture : Section ?
70
- internal let typeref : Section ?
71
- internal let reflstr : Section ?
72
-
73
- internal func makeIterator( ) -> AnyIterator < Section ? > {
74
- return AnyIterator ( [
75
- fieldmd,
76
- assocty,
77
- builtin,
78
- capture,
79
- typeref,
80
- reflstr
81
- ] . makeIterator ( ) )
82
- }
83
- }
30
+ #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
31
+ import MachO
32
+ import Darwin
84
33
85
34
#if arch(x86_64) || arch(arm64)
86
35
typealias MachHeader = mach_header_64
@@ -105,6 +54,36 @@ internal func getSectionInfo(_ name: String,
105
54
return Section ( startAddress: nonNullAddress, size: size)
106
55
}
107
56
57
+ /// Get the TEXT segment location and size for a loaded image.
58
+ ///
59
+ /// - Parameter i: The index of the loaded image as reported by Dyld.
60
+ /// - Returns: The image name, address, and size.
61
+ internal func getAddressInfoForImage( atIndex i: UInt32 ) ->
62
+ ( name: String , address: UnsafeMutablePointer < UInt8 > ? , size: UInt ) {
63
+ debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
64
+ let header = unsafeBitCast ( _dyld_get_image_header ( i) ,
65
+ to: UnsafePointer< MachHeader> . self )
66
+ let name = String ( validatingUTF8: _dyld_get_image_name ( i) !) !
67
+ var size : UInt = 0
68
+ let address = getsegmentdata ( header, " __TEXT " , & size)
69
+ return ( name, address, size)
70
+ }
71
+
72
+ /// Send all loadedimages loaded in the current process.
73
+ internal func sendImages( ) {
74
+ debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
75
+ let infos = ( 0 ..< getImageCount ( ) ) . map ( getAddressInfoForImage)
76
+
77
+ debugLog ( " \( infos. count) reflection info bundles. " )
78
+ precondition ( infos. count >= 1 )
79
+ sendValue ( infos. count)
80
+ for (name, address, size) in infos {
81
+ debugLog ( " Sending info for \( name) " )
82
+ sendValue ( address)
83
+ sendValue ( size)
84
+ }
85
+ }
86
+
108
87
/// Get the Swift Reflection section locations for a loaded image.
109
88
///
110
89
/// An image of interest must have the following sections in the __TEXT
@@ -140,19 +119,100 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
140
119
reflstr: reflstr)
141
120
}
142
121
143
- /// Get the TEXT segment location and size for a loaded image.
144
- ///
145
- /// - Parameter i: The index of the loaded image as reported by Dyld.
146
- /// - Returns: The image name, address, and size.
147
- internal func getAddressInfoForImage( atIndex i: UInt32 ) ->
148
- ( name: String , address: UnsafeMutablePointer < UInt8 > ? , size: UInt ) {
149
- debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
150
- let header = unsafeBitCast ( _dyld_get_image_header ( i) ,
151
- to: UnsafePointer< MachHeader> . self )
152
- let name = String ( validatingUTF8: _dyld_get_image_name ( i) !) !
153
- var size : UInt = 0
154
- let address = getsegmentdata ( header, " __TEXT " , & size)
155
- return ( name, address, size)
122
+ internal func getImageCount( ) -> UInt32 {
123
+ return _dyld_image_count ( )
124
+ }
125
+
126
+ let rtldDefault = UnsafeMutableRawPointer ( bitPattern: Int ( - 2 ) )
127
+ #elseif !os(Windows)
128
+ import SwiftShims
129
+ import Glibc
130
+
131
+ let rtldDefault : UnsafeMutableRawPointer ? = nil
132
+
133
+ extension Section {
134
+ init ( range: MetadataSectionRange ) {
135
+ self . startAddress = UnsafeRawPointer ( bitPattern: range. start) !
136
+ self . size = UInt ( range. length)
137
+ }
138
+ }
139
+
140
+ internal func getReflectionInfoForImage( atIndex i: UInt32 ) -> ReflectionInfo ? {
141
+ return _getMetadataSection ( UInt ( i) ) . map { rawPointer in
142
+ let name = _getMetadataSectionName ( rawPointer)
143
+ let metadataSection = rawPointer. bindMemory ( to: MetadataSections . self, capacity: 1 ) . pointee
144
+ return ReflectionInfo ( imageName: String ( validatingUTF8: name) !,
145
+ fieldmd: Section ( range: metadataSection. swift5_fieldmd) ,
146
+ assocty: Section ( range: metadataSection. swift5_assocty) ,
147
+ builtin: Section ( range: metadataSection. swift5_builtin) ,
148
+ capture: Section ( range: metadataSection. swift5_capture) ,
149
+ typeref: Section ( range: metadataSection. swift5_typeref) ,
150
+ reflstr: Section ( range: metadataSection. swift5_reflstr) )
151
+ }
152
+ }
153
+
154
+ internal func getImageCount( ) -> UInt32 {
155
+ return UInt32 ( _getMetadataSectionCount ( ) )
156
+ }
157
+
158
+ internal func sendImages( ) {
159
+ preconditionFailure ( " Should only be called in macOS! " )
160
+ }
161
+
162
+
163
+ #else // os(Linux)
164
+ #error("SwiftReflectionTest does not currently support this OS.")
165
+ #endif
166
+
167
+ internal func debugLog( _ message: @autoclosure ( ) -> String ) {
168
+ #if DEBUG_LOG
169
+ fputs ( " Child: \( message ( ) ) \n " , stderr)
170
+ fflush ( stderr)
171
+ #endif
172
+ }
173
+
174
+ public enum InstanceKind : UInt8 {
175
+ case None
176
+ case Object
177
+ case Existential
178
+ case ErrorExistential
179
+ case Closure
180
+ case Enum
181
+ case EnumValue
182
+ }
183
+
184
+ /// Represents a section in a loaded image in this process.
185
+ internal struct Section {
186
+ /// The absolute start address of the section's data in this address space.
187
+ let startAddress : UnsafeRawPointer
188
+
189
+ /// The size of the section in bytes.
190
+ let size : UInt
191
+ }
192
+
193
+ /// Holds the addresses and sizes of sections related to reflection.
194
+ internal struct ReflectionInfo : Sequence {
195
+ /// The name of the loaded image.
196
+ internal let imageName : String
197
+
198
+ /// Reflection metadata sections.
199
+ internal let fieldmd : Section ?
200
+ internal let assocty : Section ?
201
+ internal let builtin : Section ?
202
+ internal let capture : Section ?
203
+ internal let typeref : Section ?
204
+ internal let reflstr : Section ?
205
+
206
+ internal func makeIterator( ) -> AnyIterator < Section ? > {
207
+ return AnyIterator ( [
208
+ fieldmd,
209
+ assocty,
210
+ builtin,
211
+ capture,
212
+ typeref,
213
+ reflstr
214
+ ] . makeIterator ( ) )
215
+ }
156
216
}
157
217
158
218
internal func sendBytes< T> ( from address: UnsafePointer < T > , count: Int ) {
@@ -197,7 +257,7 @@ internal func readUInt() -> UInt {
197
257
/// process.
198
258
internal func sendReflectionInfos( ) {
199
259
debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
200
- let infos = ( 0 ..< _dyld_image_count ( ) ) . compactMap ( getReflectionInfoForImage)
260
+ let infos = ( 0 ..< getImageCount ( ) ) . compactMap ( getReflectionInfoForImage)
201
261
202
262
var numInfos = infos. count
203
263
debugLog ( " \( numInfos) reflection info bundles. " )
@@ -212,21 +272,6 @@ internal func sendReflectionInfos() {
212
272
}
213
273
}
214
274
215
- /// Send all loadedimages loaded in the current process.
216
- internal func sendImages( ) {
217
- debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
218
- let infos = ( 0 ..< _dyld_image_count ( ) ) . map ( getAddressInfoForImage)
219
-
220
- debugLog ( " \( infos. count) reflection info bundles. " )
221
- precondition ( infos. count >= 1 )
222
- sendValue ( infos. count)
223
- for (name, address, size) in infos {
224
- debugLog ( " Sending info for \( name) " )
225
- sendValue ( address)
226
- sendValue ( size)
227
- }
228
- }
229
-
230
275
internal func printErrnoAndExit( ) {
231
276
debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
232
277
let errorCString = strerror ( errno) !
@@ -261,8 +306,7 @@ internal func sendSymbolAddress() {
261
306
debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
262
307
let name = readLine ( ) !
263
308
name. withCString {
264
- let handle = UnsafeMutableRawPointer ( bitPattern: Int ( - 2 ) ) !
265
- let symbol = dlsym ( handle, $0)
309
+ let symbol = dlsym ( rtldDefault, $0)
266
310
let symbolAddress = unsafeBitCast ( symbol, to: UInt . self)
267
311
sendValue ( symbolAddress)
268
312
}
0 commit comments