//===--- Image.swift - Binary image protocol for Swift --------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2022 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // Defines a protocol for binary image files that allows us to fetch what // we need without knowing all of the gory details. // //===----------------------------------------------------------------------===// import Swift struct ImageSymbol { var name: String var offset: Int } internal protocol Image { associatedtype Source: ImageSource typealias UUID = [UInt8] typealias Address = Source.Address init(source: Source, baseAddress: Address, endAddress: Address) throws var baseAddress: Address { get set } var endAddress: Address { get set } var source: Source { get } var uuid: UUID? { get } var shouldByteSwap: Bool { get } func swapIfRequired(_ x: T) -> T func swapIfRequired(_ x: T) -> T func swapIfRequired(_ x: T) -> T func swapIfRequired(array: inout [T]) func swapIfRequired(array: inout [T]) func swapIfRequired(array: inout [T]) func swapIfRequired(buffer: UnsafeMutableBufferPointer) func swapIfRequired(buffer: UnsafeMutableBufferPointer) func swapIfRequired(buffer: UnsafeMutableBufferPointer) func swapIfRequired(pointer: UnsafeMutablePointer) func swapIfRequired(pointer: UnsafeMutablePointer) func swapIfRequired(pointer: UnsafeMutablePointer) func fetch(from addr: Address, into buffer: UnsafeMutableBufferPointer) throws func fetch(from addr: Address, into pointer: UnsafeMutablePointer) throws func fetch(from addr: Address, count: Int, as: T.Type) throws -> [T] func fetch(from addr: Address, as type: T.Type) throws -> T func fetchUnswapped(from addr: Address, into buffer: UnsafeMutableBufferPointer) throws func fetchUnswapped(from addr: Address, into pointer: UnsafeMutablePointer) throws func fetchUnswapped(from addr: Address, count: Int, as: T.Type) throws -> [T] func fetchUnswapped(from addr: Address, as type: T.Type) throws -> T func lookupSymbol(address: Address) -> ImageSymbol? } extension Image { public func swapIfRequired(_ x: T) -> T { if shouldByteSwap { return x.byteSwapped } return x } public func swapIfRequired(_ x: T) -> T { if shouldByteSwap { return x.byteSwapped } return x } public func swapIfRequired(_ x: T) -> T { return x } public func swapIfRequired(array: inout [T]) { if shouldByteSwap { array.swapBytes() } } public func swapIfRequired(array: inout [T]) { if shouldByteSwap { array.swapBytes() } } public func swapIfRequired(array: inout [T]) { // Nothing to do } public func swapIfRequired(buffer: UnsafeMutableBufferPointer) { if shouldByteSwap { buffer.swapBytes() } } public func swapIfRequired(buffer: UnsafeMutableBufferPointer) { if shouldByteSwap { buffer.swapBytes() } } public func swapIfRequired(buffer: UnsafeMutableBufferPointer) { // Nothing to do } public func swapIfRequired(pointer: UnsafeMutablePointer) { if shouldByteSwap { pointer.pointee = pointer.pointee.byteSwapped } } public func swapIfRequired(pointer: UnsafeMutablePointer) { if shouldByteSwap { pointer.pointee = pointer.pointee.byteSwapped } } public func swapIfRequired(pointer: UnsafeMutablePointer) { // Nothing to do } public func fetchUnswapped(from addr: Address, into buffer: UnsafeMutableBufferPointer) throws { return try source.fetch(from: addr, into: buffer) } public func fetchUnswapped(from addr: Address, into pointer: UnsafeMutablePointer) throws { return try source.fetch(from: addr, into: pointer) } public func fetchUnswapped(from addr: Address, count: Int, as type: T.Type) throws -> [T] { return try source.fetch(from: addr, count: count, as: type) } public func fetchUnswapped(from addr: Address, as type: T.Type) throws -> T { return try source.fetch(from: addr, as: type) } public func fetch(from addr: Address, into buffer: UnsafeMutableBufferPointer) throws { try fetchUnswapped(from: addr, into: buffer) swapIfRequired(buffer: buffer) } public func fetch(from addr: Address, into pointer: UnsafeMutablePointer) throws { try fetchUnswapped(from: addr, into: pointer) swapIfRequired(pointer: pointer) } public func fetch(from addr: Address, count: Int, as type: T.Type) throws -> [T]{ var result = try fetchUnswapped(from: addr, count: count, as: type) swapIfRequired(array: &result) return result } public func fetch(from addr: Address, as type: T.Type) throws -> T { return swapIfRequired(try fetchUnswapped(from: addr, as: type)) } }