1616//
1717//===----------------------------------------------------------------------===//
1818
19- // FIXME: Make this work with Linux
20-
21- import MachO
22- import Darwin
23-
2419let RequestInstanceKind = " k "
2520let RequestInstanceAddress = " i "
2621let RequestReflectionInfos = " r "
@@ -31,56 +26,10 @@ let RequestStringLength = "l"
3126let RequestDone = " d "
3227let RequestPointerSize = " p "
3328
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- }
5929
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
8433
8534#if arch(x86_64) || arch(arm64)
8635typealias MachHeader = mach_header_64
@@ -105,6 +54,36 @@ internal func getSectionInfo(_ name: String,
10554 return Section ( startAddress: nonNullAddress, size: size)
10655}
10756
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+
10887/// Get the Swift Reflection section locations for a loaded image.
10988///
11089/// An image of interest must have the following sections in the __TEXT
@@ -140,19 +119,100 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
140119 reflstr: reflstr)
141120}
142121
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+ }
156216}
157217
158218internal func sendBytes< T> ( from address: UnsafePointer < T > , count: Int ) {
@@ -197,7 +257,7 @@ internal func readUInt() -> UInt {
197257/// process.
198258internal func sendReflectionInfos( ) {
199259 debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
200- let infos = ( 0 ..< _dyld_image_count ( ) ) . compactMap ( getReflectionInfoForImage)
260+ let infos = ( 0 ..< getImageCount ( ) ) . compactMap ( getReflectionInfoForImage)
201261
202262 var numInfos = infos. count
203263 debugLog ( " \( numInfos) reflection info bundles. " )
@@ -212,21 +272,6 @@ internal func sendReflectionInfos() {
212272 }
213273}
214274
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-
230275internal func printErrnoAndExit( ) {
231276 debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
232277 let errorCString = strerror ( errno) !
@@ -261,8 +306,7 @@ internal func sendSymbolAddress() {
261306 debugLog ( " BEGIN \( #function) " ) ; defer { debugLog ( " END \( #function) " ) }
262307 let name = readLine ( ) !
263308 name. withCString {
264- let handle = UnsafeMutableRawPointer ( bitPattern: Int ( - 2 ) ) !
265- let symbol = dlsym ( handle, $0)
309+ let symbol = dlsym ( rtldDefault, $0)
266310 let symbolAddress = unsafeBitCast ( symbol, to: UInt . self)
267311 sendValue ( symbolAddress)
268312 }
0 commit comments