@frozen public struct ExceptionContext { public var x0: UInt64 public var x1: UInt64 public var x2: UInt64 public var x3: UInt64 public var x4: UInt64 public var x5: UInt64 public var x6: UInt64 public var x7: UInt64 public var x8: UInt64 public var x9: UInt64 public var x10: UInt64 public var x11: UInt64 public var x12: UInt64 public var x13: UInt64 public var x14: UInt64 public var x15: UInt64 public var x16: UInt64 public var x17: UInt64 public var x18: UInt64 public var x19: UInt64 public var x20: UInt64 public var x21: UInt64 public var x22: UInt64 public var x23: UInt64 public var x24: UInt64 public var x25: UInt64 public var x26: UInt64 public var x27: UInt64 public var x28: UInt64 public var x29: UInt64 // fp public var x30: UInt64 // lr public var elr_el1: UInt64 // pc public var spsr_el1: UInt64 // cpu status public var esr_el1: UInt64 // error reason } @frozen public enum ExceptionType: UInt64 { // curr el with sp0 (EL1t) // usually dont happen cuz we switch to sp_el1, but just in case case syncEL1t = 0 case irqEL1t = 1 case fiqEL1t = 2 case seErrorEL1t = 3 // curr el with sp1 (EL1h) // exception in kernel space case syncEL1h = 4 case irqEL1h = 5 case fiqEL1h = 6 case seErrorEL1h = 7 // lower EL 64-bit from userspace case syncEL0_64 = 8 case irqEL0_64 = 9 case fiqEL0_64 = 10 case seErrorEL0_64 = 11 // lower EL 32-bit from userspace case syncEL0_32 = 12 case irqEL0_32 = 13 case fiqEL0_32 = 14 case seErrorEL0_32 = 15 } @_cdecl("swift_trap_handler") public func trapHandler(context: UnsafeMutableRawPointer, rawType: UInt64) { let context = context.assumingMemoryBound(to: ExceptionContext.self) let type = ExceptionType(rawValue: rawType)! panic(context: context.pointee) }