From 7f3e3d2070b1854d041bc8c8030bd5a4c01050e5 Mon Sep 17 00:00:00 2001 From: Christophe Bronner Date: Thu, 4 Jun 2026 21:56:37 -0400 Subject: [PATCH 1/3] Support SwiftPM and add Swift bindings --- Package.swift | 49 +++++++ bindings/swift/CapstoneKit.swift | 231 +++++++++++++++++++++++++++++++ include/Capstone.apinotes | 174 +++++++++++++++++++++++ include/module.modulemap | 4 + 4 files changed, 458 insertions(+) create mode 100644 Package.swift create mode 100644 bindings/swift/CapstoneKit.swift create mode 100644 include/Capstone.apinotes create mode 100644 include/module.modulemap diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000000..30e3616fec --- /dev/null +++ b/Package.swift @@ -0,0 +1,49 @@ +// swift-tools-version: 6.2 + +import PackageDescription + +let architectures = [ + "ARM", "AARCH64", "M68K", "MIPS", "POWERPC", "SPARC", "SYSTEMZ", "XCORE", "X86", "TMS320C64X", "M680X", "EVM", "MOS65XX", "WASM", "BPF", "RISCV", "SH", "TRICORE", "ALPHA", "HPPA", "LOONGARCH", "XTENSA", "ARC" +] + +var traits: Set = Set(architectures.map { Trait(name: $0) }) +traits.insert(.default(enabledTraits: Set(architectures))) + +let package = Package( + name: "capstone", + products: [ + .library(name: "CapstoneKit", targets: ["CapstoneKit"]), + .library(name: "capstone", targets: ["capstone"]), + ], + traits: traits, + targets: [ + .target( + name: "CapstoneKit", + dependencies: ["capstone"], + path: "bindings/swift", + swiftSettings: [ + .enableExperimentalFeature("SafeInteropWrappers"), + ] + ), + .target( + name: "capstone", + path: ".", + sources: [ + "arch", + "cs.c", + "Mapping.c", + "MCInst.c", + "MCInstPrinter.c", + "MCInstrDesc.c", + "MCRegisterInfo.c", + "SStream.c", + "utils.c", + ], + cSettings: [ + .define("CAPSTONE_USE_SYS_DYN_MEM"), + .disableWarning("shorten-64-to-32"), + ] + architectures + .map { CSetting.define("CAPSTONE_HAS_\($0)") } + ), + ] +) diff --git a/bindings/swift/CapstoneKit.swift b/bindings/swift/CapstoneKit.swift new file mode 100644 index 0000000000..6cbca6f5f8 --- /dev/null +++ b/bindings/swift/CapstoneKit.swift @@ -0,0 +1,231 @@ +// +// CapstoneKit.swift +// capstone +// +// Created by Christophe Bronner on 2026-06-04. +// + +public import capstone + +public struct Capstone: ~Copyable { + public let handle: csh + + @inlinable @_transparent + public init(handle: csh) { + self.handle = handle + } + + @inlinable @_transparent + public init( + arch: CapstoneArch, + mode: CapstoneMode + ) throws(CapstoneError) { + var handle: csh = .init(0) + let err = cs_open(arch, mode, &handle) + guard err == .CS_ERR_OK else { throw err } + self.handle = handle + } + + deinit { + var handle = handle + cs_close(&handle) + } +} + +public extension Capstone { + /// See ``cs_option`` with ``CS_OPT_DETAIL``. + func withDetailedInstructions(_ value: Bool) { + let value = value ? CapstoneOptionValue.CS_OPT_ON : [] + set(option: .detail, to: value) + } + + /// See ``cs_option``. + @inlinable @_transparent + func set(option: CapstoneOptionKind, to value: some FixedWidthInteger) { + cs_option(handle, option, UInt(value)) + } + + /// See ``cs_option``. + @inlinable @_transparent + func set(option: CapstoneOptionKind, to value: some RawRepresentable) { + set(option: option, to: value.rawValue) + } + + /// See ``cs_support``. + @inlinable + static func support(_ query: CInt) -> Bool { + cs_support(query) + } + + /// Throws the last error of an API function fail. See ``cs_errno``. + @inlinable + func errno() throws(CapstoneError) { + throw cs_errno(handle) + } + + /// See ``cs_disasm``. + @available(macOS 10.14.4, *) + @inlinable + func disassemble( + code: Span, + address: UInt64, + count: Int = 0 + ) throws(CapstoneError) -> CapstoneInstructionBuffer { + var output: UnsafeMutablePointer! + let result = code.withUnsafeBufferPointer { + cs_disasm(handle, $0.baseAddress, $0.count, address, count, &output) + } + if result == 0 { + throw cs_errno(handle) + } + let buffer = UnsafeMutableBufferPointer(start: output, count: count) + return CapstoneInstructionBuffer(buffer) + } + + /// See ``cs_disasm_iter``. + @available(macOS 10.14.4, *) + @inlinable + func disassemble( + _ code: inout Span, + at address: inout UInt64, + ) throws(CapstoneError) -> CapstoneInstructionBox { + var result = CapstoneInstructionBox(using: self) + var size = code.count + + let success = code.withUnsafeBufferPointer { + var base = $0.baseAddress + return cs_disasm_iter(handle, &base, &size, &address, &result.pointee) + } + code = code.extracting(droppingFirst: code.count - size) + if !success { + throw cs_errno(handle) + } + return result + } + + /// See ``cs_regs_access``. + @available(macOS 10.14.4, *) + @inlinable + func access( + regsOf insn: borrowing CapstoneInstruction, + read: inout MutableSpan, + write: inout MutableSpan, + ) throws(CapstoneError) { + let cs_regs_count = MemoryLayout.size / MemoryLayout.size + precondition(read.count >= cs_regs_count && write.count >= cs_regs_count) + var rcount = 0 + var wcount = 0 + let err = withUnsafePointer(to: insn) { insn in + read.withUnsafeMutableBufferPointer { readp in + write.withUnsafeMutableBufferPointer { writep in + cs_regs_access(handle, insn, readp.baseAddress, &rcount, writep.baseAddress, &wcount) + } + } + } + read = read.extracting(first: rcount) + write = write.extracting(first: rcount) + try err.check() + } + + /// See ``cs_insn_group``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, in group: InstructionGroup) -> Bool { + withUnsafePointer(to: instr) { instr in + cs_insn_group(handle, instr, group.rawValue) + } + } + + /// See ``cs_insn_name``. + @inlinable + func instruction(name id: some RawRepresentable) -> String { + guard let name = cs_insn_name(handle, id.rawValue) else { return "" } + return String(cString: name) + } +} + +public extension CapstoneError { + /// Throws an error if the result wasn't a success. + @inlinable @_transparent + func check() throws(CapstoneError) { + guard self != .CS_ERR_OK else { return } + throw self + } +} + +extension CapstoneError: @retroactive CustomStringConvertible { + public var description: String { + String(cString: cs_strerror(self)) + } +} + +public extension CapstoneInstruction { + /// See ``cs_insn``. + @inlinable @_transparent + var detail: Detail { + @inlinable @_transparent + _read { + if let unsafeMutableDetailPointer { + yield unsafeMutableDetailPointer.pointee + } else { + yield .init() + } + } + } +} + +public struct CapstoneInstructionBox: ~Copyable { + @usableFromInline let ptr: UnsafeMutablePointer! + + @inlinable @_transparent + public init(using capstone: borrowing Capstone) { + ptr = cs_malloc(capstone.handle) + } + + deinit { + cs_free(ptr, 1) + } + + @inlinable @_transparent + public var pointee: CapstoneInstruction { + _read { yield ptr.pointee } + _modify { yield &ptr.pointee } + } +} + +public struct CapstoneInstructionBuffer: ~Copyable { + @usableFromInline let buffer: UnsafeMutableBufferPointer! + + @inlinable @_transparent + public init(_ buffer: UnsafeMutableBufferPointer) { + self.buffer = buffer + } + + deinit { + cs_free(buffer.baseAddress, buffer.count) + } + + @inlinable @_transparent + public var count: Int { buffer.count } + + @inlinable @_transparent + public func withUnsafeBufferPointer( + do action: (UnsafeBufferPointer) -> R + ) -> R { + action(UnsafeBufferPointer(buffer)) + } + + @inlinable @_transparent + public func withUnsafeMutableBufferPointer( + do action: (UnsafeMutableBufferPointer) -> R + ) -> R { + action(buffer) + } + + @inlinable + public subscript(index: Int) -> CapstoneInstruction { + @_transparent + _read { yield buffer[index] } + @_transparent + _modify { yield &buffer[index] } + } +} diff --git a/include/Capstone.apinotes b/include/Capstone.apinotes new file mode 100644 index 0000000000..0c07659862 --- /dev/null +++ b/include/Capstone.apinotes @@ -0,0 +1,174 @@ +--- +Name: Capstone +Enumerators: +# cs_ac_type +- Name: CS_AC_INVALID + SwiftName: invalid +- Name: CS_AC_READ + SwiftName: read +- Name: CS_AC_READ_WRITE + SwiftName: readWrite +- Name: CS_AC_WRITE + SwiftName: write +# cs_arch +- Name: CS_ARCH_ARM + SwiftName: arm +- Name: CS_ARCH_ARM64 + SwiftName: arm64 +- Name: CS_ARCH_AARCH64 + SwiftName: aarch64 +- Name: CS_ARCH_SYSZ + SwiftName: sysz +- Name: CS_ARCH_SYSTEMZ + SwiftName: systemZ +- Name: CS_ARCH_MIPS + SwiftName: mips +- Name: CS_ARCH_X86 + SwiftName: x86 +- Name: CS_ARCH_PPC + SwiftName: ppc +# CS_ARCH_SPARC, ///< Sparc architecture +# CS_ARCH_XCORE, ///< XCore architecture +# CS_ARCH_M68K, ///< 68K architecture +# CS_ARCH_TMS320C64X, ///< TMS320C64x architecture +# CS_ARCH_M680X, ///< 680X architecture +# CS_ARCH_EVM, ///< Ethereum architecture +# CS_ARCH_MOS65XX, ///< MOS65XX architecture (including MOS6502) +# CS_ARCH_WASM, ///< WebAssembly architecture +# CS_ARCH_BPF, ///< Berkeley Packet Filter architecture (including eBPF) +# CS_ARCH_RISCV, ///< RISCV architecture +# CS_ARCH_SH, ///< SH architecture +# CS_ARCH_TRICORE, ///< TriCore architecture +# CS_ARCH_ALPHA, ///< Alpha architecture +# CS_ARCH_HPPA, ///< HPPA architecture +# CS_ARCH_LOONGARCH, ///< LoongArch architecture +# CS_ARCH_XTENSA, ///< Xtensa architecture +# CS_ARCH_ARC, ///< ARC architecture +# CS_ARCH_MAX, +# CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() +# cs_group_type +- Name: CS_GRP_INVALID + SwiftName: invalid +- Name: CS_GRP_JUMP + SwiftName: jump +- Name: CS_GRP_CALL + SwiftName: call +- Name: CS_GRP_RET + SwiftName: ret +- Name: CS_GRP_INT + SwiftName: int +- Name: CS_GRP_IRET + SwiftName: iret +- Name: CS_GRP_PRIVILEGE + SwiftName: privilege +- Name: CS_GRP_BRANCH_RELATIVE + SwiftName: branchRelative +# cs_opt_type +- Name: CS_OPT_INVALID + SwiftName: invalid +- Name: CS_OPT_SYNTAX + SwiftName: syntax +- Name: CS_OPT_DETAIL + SwiftName: detail +- Name: CS_OPT_MODE + SwiftName: mode +- Name: CS_OPT_MEM + SwiftName: mem +- Name: CS_OPT_SKIPDATA + SwiftName: skipData +- Name: CS_OPT_SKIPDATA_SETUP + SwiftName: skipDataSetup +- Name: CS_OPT_MNEMONIC + SwiftName: mnemonic +- Name: CS_OPT_UNSIGNED + SwiftName: unsigned +- Name: CS_OPT_ONLY_OFFSET_BRANCH + SwiftName: onlyOffsetBranch +- Name: CS_OPT_LITBASE + SwiftName: litbase +# x86_opt_type +- Name: X86_OP_INVALID + SwiftName: invalid +- Name: X86_OP_REG + SwiftName: reg +- Name: X86_OP_IMM + SwiftName: imm +- Name: X86_OP_MEM + SwiftName: mem +Tags: +- Name: aarch64_insn + SwiftName: AArch64.InstructionId + EnumExtensibility: closed +- Name: aarch64_op_type + SwiftName: AArch64.OperandType + EnumExtensibility: closed +- Name: aarch64_reg + SwiftName: AArch64.Register + EnumExtensibility: closed +- Name: x86_insn + SwiftName: X86.InstructionId + EnumExtensibility: closed +- Name: x86_op_type + SwiftName: X86.OperandType + EnumExtensibility: closed +- Name: x86_reg + SwiftName: X86.Register + EnumExtensibility: closed +- Name: cs_aarch64 + SwiftName: AArch64 +- Name: cs_aarch64_op + SwiftName: AArch64.Operand +- Name: cs_ac_type + SwiftName: AccessSet + EnumKind: NSOptions +- Name: cs_arch + SwiftName: CapstoneArch + EnumExtensibility: closed +- Name: cs_detail + SwiftName: CapstoneInstruction.Detail +- Name: cs_err + SwiftName: CapstoneError + EnumExtensibility: closed + SwiftConformsTo: Swift.Error +- Name: cs_group_type + SwiftName: InstructionGroup + EnumExtensibility: closed +- Name: cs_insn + SwiftName: CapstoneInstruction + Fields: + - Name: detail + SwiftName: unsafeMutableDetailPointer +- Name: cs_mode + SwiftName: CapstoneMode + EnumKind: NSOptions +- Name: cs_opt_type + SwiftName: CapstoneOptionKind + EnumExtensibility: closed +- Name: cs_opt_value + SwiftName: CapstoneOptionValue + EnumKind: NSOptions +- Name: cs_opt + SwiftName: CapstoneOption +- Name: cs_x86 + SwiftName: X86 +- Name: cs_x86_op + SwiftName: X86.Operand +Functions: +- Name: cs_disasm + Parameters: + - Position: 1 + BoundsSafety: + Kind: counted_by + BoundedBy: "code_size" +- Name: cs_open + SwiftSafety: unsafe +- Name: cs_close + SwiftSafety: unsafe +- Name: cs_strerror + ResultType: "const char * _Nonnull" +Typedefs: +#- Name: csh +# SwiftName: CapstoneHandle +# SwiftWrapper: struct +# SwiftCopyable: false +# SwiftDestroyOp: cs_close diff --git a/include/module.modulemap b/include/module.modulemap new file mode 100644 index 0000000000..d81ec55211 --- /dev/null +++ b/include/module.modulemap @@ -0,0 +1,4 @@ +module capstone { + umbrella header "capstone/capstone.h" + export * +} From 15ce3a930d94bd363e655b811748dd356b73f14e Mon Sep 17 00:00:00 2001 From: Christophe Bronner Date: Sun, 7 Jun 2026 17:46:47 -0400 Subject: [PATCH 2/3] CapstoneKit re-exports capstone, add to ApiNotes --- bindings/swift/CapstoneKit.swift | 2 +- include/Capstone.apinotes | 190 +++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 1 deletion(-) diff --git a/bindings/swift/CapstoneKit.swift b/bindings/swift/CapstoneKit.swift index 6cbca6f5f8..422f012b3c 100644 --- a/bindings/swift/CapstoneKit.swift +++ b/bindings/swift/CapstoneKit.swift @@ -5,7 +5,7 @@ // Created by Christophe Bronner on 2026-06-04. // -public import capstone +@_exported public import capstone public struct Capstone: ~Copyable { public let handle: csh diff --git a/include/Capstone.apinotes b/include/Capstone.apinotes index 0c07659862..f9778f9dad 100644 --- a/include/Capstone.apinotes +++ b/include/Capstone.apinotes @@ -96,6 +96,46 @@ Enumerators: - Name: X86_OP_MEM SwiftName: mem Tags: +# AArch64 +- Name: aarch64_imm_range + SwiftName: AArch64.ImmRange +- Name: aarch64_op_mem + SwiftName: AArch64.MemoryOp +- Name: aarch64_op_pred + SwiftName: AArch64.PredOp +- Name: aarch64_op_sme + SwiftName: AArch64.SmeOp +- Name: aarch64_suppl_info + SwiftName: AArch64.SupplInfo +- Name: aarch64_sysop + SwiftName: AArch64.SysOp +- Name: aarch64_sysop_alias + SwiftName: AArch64.SysOp.Alias +- Name: aarch64_sysop_imm + SwiftName: AArch64.SysOp.Imm +- Name: aarch64_sysop_reg + SwiftName: AArch64.SysOp.Reg +- Name: aarch64_at + SwiftName: AArch64.At + EnumExtensibility: closed +- Name: aarch64_bti + SwiftName: AArch64.Bti + EnumExtensibility: closed +- Name: aarch64_dbnxs + SwiftName: AArch64.Dbnxs + EnumExtensibility: closed +- Name: aarch64_db + SwiftName: AArch64.Db + EnumExtensibility: closed +- Name: aarch64_dc + SwiftName: AArch64.Dc + EnumExtensibility: closed +- Name: aarch64_exactfpimm + SwiftName: AArch64.ExactFpImm + EnumExtensibility: closed +- Name: aarch64_extender + SwiftName: AArch64.Extender + EnumExtensibility: closed - Name: aarch64_insn SwiftName: AArch64.InstructionId EnumExtensibility: closed @@ -105,6 +145,154 @@ Tags: - Name: aarch64_reg SwiftName: AArch64.Register EnumExtensibility: closed +- Name: aarch64_insn_group + SwiftName: AArch64.InstructionGroup + EnumExtensibility: closed +- Name: aarch64_ic + SwiftName: AArch64.Ic + EnumExtensibility: closed +- Name: aarch64_isb + SwiftName: AArch64.Isb + EnumExtensibility: closed +- Name: aarch64_prfm + SwiftName: AArch64.Prfm + EnumExtensibility: closed +- Name: aarch64_psb + SwiftName: AArch64.Psb + EnumExtensibility: closed +- Name: aarch64_pstateimm0_15 + SwiftName: AArch64.PStateImm0_15 + EnumExtensibility: closed +- Name: aarch64_pstateimm0_1 + SwiftName: AArch64.PStateImm0_1 + EnumExtensibility: closed +- Name: aarch64_rprfm + SwiftName: AArch64.Rprfm + EnumExtensibility: closed +- Name: aarch64_shifter + SwiftName: AArch64.Shifter + EnumExtensibility: closed +- Name: aarch64_sme_op_type + SwiftName: AArch64.SmeOpType + EnumExtensibility: closed +- Name: aarch64_svcr + SwiftName: AArch64.Svcr + EnumExtensibility: closed +- Name: aarch64_svepredpat + SwiftName: AArch64.SvePredPat + EnumExtensibility: closed +- Name: aarch64_sveprfm + SwiftName: AArch64.SvePrfm + EnumExtensibility: closed +- Name: aarch64_sveveclenspecifier + SwiftName: AArch64.SveVecLenSpecifier + EnumExtensibility: closed +- Name: aarch64_sysreg + SwiftName: AArch64.SystemRegister + EnumExtensibility: closed +- Name: aarch64_tlbi + SwiftName: AArch64.Tlbi + EnumExtensibility: closed +- Name: aarch64_tsb + SwiftName: AArch64.Tsb + EnumExtensibility: closed +- Name: AArch64CondCode + SwiftName: AArch64.ConditionCode + EnumExtensibility: closed +- Name: cs_arc + SwiftName: Arc +- Name: arc_op_type + SwiftName: Arc.OperandType + EnumExtensibility: closed +- Name: arc_insn_group + SwiftName: Arc.InstructionGroup + EnumExtensibility: closed +- Name: arc_insn + SwiftName: Arc.InstructionId + EnumExtensibility: closed +- Name: arc_reg + SwiftName: Arc.Register + EnumExtensibility: closed +- Name: cs_arm + SwiftName: Arm +- Name: arm_op_mem + SwiftName: Arm.MemoryOp +- Name: CondCodes + SwiftName: Arm.ConditionCode + EnumExtensibility: closed +- Name: arm_bankedreg + SwiftName: Arm.BankedRegister + EnumExtensibility: closed +- Name: arm_cpsflag_type + SwiftName: Arm.CpsFlagType + EnumExtensibility: closed +- Name: arm_cpsmode_type + SwiftName: Arm.CpsModeType + EnumExtensibility: closed +- Name: arm_insn_group + SwiftName: Arm.InstructionGroup + EnumExtensibility: closed +- Name: arm_spsr_cpsr_bits + SwiftName: Arm.SpsrCpsrBits + EnumExtensibility: closed +- Name: arm_insn + SwiftName: Arm.InstructionId + EnumExtensibility: closed +- Name: arm_sysreg + SwiftName: Arm.SystemRegister + EnumExtensibility: closed +- Name: arm_op_type + SwiftName: Arm.OperandType + EnumExtensibility: closed +- Name: arm_reg + SwiftName: Arm.Register + EnumExtensibility: closed +- Name: arm_vectordata_type + SwiftName: Arm.VectorDataType +- Name: cs_alpha + SwiftName: Alpha + EnumExtensibility: closed +- Name: alpha_op_type + SwiftName: Alpha.OperandType + EnumExtensibility: closed +- Name: alpha_insn_group + SwiftName: Alpha.InstructionGroup + EnumExtensibility: closed +- Name: alpha_insn + SwiftName: Alpha.InstructionId + EnumExtensibility: closed +- Name: alpha_reg + SwiftName: Alpha.Register + EnumExtensibility: closed +- Name: cs_bpf + SwiftName: Bpf +- Name: bpf_insn_group + SwiftName: Bpf.InstructionGroup + EnumExtensibility: closed +- Name: bpf_insn + SwiftName: Bpf.InstructionId + EnumExtensibility: closed +- Name: bpf_reg + SwiftName: Bpf.Register + EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed +#- Name: <#c name#> +# SwiftName: <#swift name#> +# EnumExtensibility: closed - Name: x86_insn SwiftName: X86.InstructionId EnumExtensibility: closed @@ -166,6 +354,8 @@ Functions: SwiftSafety: unsafe - Name: cs_strerror ResultType: "const char * _Nonnull" +- Name: VectorLayout + SwiftName: AArch64.VectorLayout Typedefs: #- Name: csh # SwiftName: CapstoneHandle From 4d3e54dccd9ba3308469f486c103522bcfcd52ee Mon Sep 17 00:00:00 2001 From: Christophe Bronner Date: Fri, 12 Jun 2026 07:49:56 -0400 Subject: [PATCH 3/3] Adjust bindings, add test target --- Package.swift | 7 +- bindings/swift/CapstoneKit.swift | 231 ---------- bindings/swift/Sources/CapstoneKit.swift | 358 +++++++++++++++ bindings/swift/Tests/CapstoneTests.swift | 4 + include/Capstone.apinotes | 537 +++++++++++++++++++---- 5 files changed, 818 insertions(+), 319 deletions(-) delete mode 100644 bindings/swift/CapstoneKit.swift create mode 100644 bindings/swift/Sources/CapstoneKit.swift create mode 100644 bindings/swift/Tests/CapstoneTests.swift diff --git a/Package.swift b/Package.swift index 30e3616fec..9ef1bf0ae8 100644 --- a/Package.swift +++ b/Package.swift @@ -20,11 +20,16 @@ let package = Package( .target( name: "CapstoneKit", dependencies: ["capstone"], - path: "bindings/swift", + path: "bindings/swift/Sources", swiftSettings: [ .enableExperimentalFeature("SafeInteropWrappers"), ] ), + .testTarget( + name: "CapstoneKitTests", + dependencies: ["CapstoneKit"], + path: "bindings/swift/Tests" + ), .target( name: "capstone", path: ".", diff --git a/bindings/swift/CapstoneKit.swift b/bindings/swift/CapstoneKit.swift deleted file mode 100644 index 422f012b3c..0000000000 --- a/bindings/swift/CapstoneKit.swift +++ /dev/null @@ -1,231 +0,0 @@ -// -// CapstoneKit.swift -// capstone -// -// Created by Christophe Bronner on 2026-06-04. -// - -@_exported public import capstone - -public struct Capstone: ~Copyable { - public let handle: csh - - @inlinable @_transparent - public init(handle: csh) { - self.handle = handle - } - - @inlinable @_transparent - public init( - arch: CapstoneArch, - mode: CapstoneMode - ) throws(CapstoneError) { - var handle: csh = .init(0) - let err = cs_open(arch, mode, &handle) - guard err == .CS_ERR_OK else { throw err } - self.handle = handle - } - - deinit { - var handle = handle - cs_close(&handle) - } -} - -public extension Capstone { - /// See ``cs_option`` with ``CS_OPT_DETAIL``. - func withDetailedInstructions(_ value: Bool) { - let value = value ? CapstoneOptionValue.CS_OPT_ON : [] - set(option: .detail, to: value) - } - - /// See ``cs_option``. - @inlinable @_transparent - func set(option: CapstoneOptionKind, to value: some FixedWidthInteger) { - cs_option(handle, option, UInt(value)) - } - - /// See ``cs_option``. - @inlinable @_transparent - func set(option: CapstoneOptionKind, to value: some RawRepresentable) { - set(option: option, to: value.rawValue) - } - - /// See ``cs_support``. - @inlinable - static func support(_ query: CInt) -> Bool { - cs_support(query) - } - - /// Throws the last error of an API function fail. See ``cs_errno``. - @inlinable - func errno() throws(CapstoneError) { - throw cs_errno(handle) - } - - /// See ``cs_disasm``. - @available(macOS 10.14.4, *) - @inlinable - func disassemble( - code: Span, - address: UInt64, - count: Int = 0 - ) throws(CapstoneError) -> CapstoneInstructionBuffer { - var output: UnsafeMutablePointer! - let result = code.withUnsafeBufferPointer { - cs_disasm(handle, $0.baseAddress, $0.count, address, count, &output) - } - if result == 0 { - throw cs_errno(handle) - } - let buffer = UnsafeMutableBufferPointer(start: output, count: count) - return CapstoneInstructionBuffer(buffer) - } - - /// See ``cs_disasm_iter``. - @available(macOS 10.14.4, *) - @inlinable - func disassemble( - _ code: inout Span, - at address: inout UInt64, - ) throws(CapstoneError) -> CapstoneInstructionBox { - var result = CapstoneInstructionBox(using: self) - var size = code.count - - let success = code.withUnsafeBufferPointer { - var base = $0.baseAddress - return cs_disasm_iter(handle, &base, &size, &address, &result.pointee) - } - code = code.extracting(droppingFirst: code.count - size) - if !success { - throw cs_errno(handle) - } - return result - } - - /// See ``cs_regs_access``. - @available(macOS 10.14.4, *) - @inlinable - func access( - regsOf insn: borrowing CapstoneInstruction, - read: inout MutableSpan, - write: inout MutableSpan, - ) throws(CapstoneError) { - let cs_regs_count = MemoryLayout.size / MemoryLayout.size - precondition(read.count >= cs_regs_count && write.count >= cs_regs_count) - var rcount = 0 - var wcount = 0 - let err = withUnsafePointer(to: insn) { insn in - read.withUnsafeMutableBufferPointer { readp in - write.withUnsafeMutableBufferPointer { writep in - cs_regs_access(handle, insn, readp.baseAddress, &rcount, writep.baseAddress, &wcount) - } - } - } - read = read.extracting(first: rcount) - write = write.extracting(first: rcount) - try err.check() - } - - /// See ``cs_insn_group``. - @inlinable - func instruction(_ instr: borrowing CapstoneInstruction, in group: InstructionGroup) -> Bool { - withUnsafePointer(to: instr) { instr in - cs_insn_group(handle, instr, group.rawValue) - } - } - - /// See ``cs_insn_name``. - @inlinable - func instruction(name id: some RawRepresentable) -> String { - guard let name = cs_insn_name(handle, id.rawValue) else { return "" } - return String(cString: name) - } -} - -public extension CapstoneError { - /// Throws an error if the result wasn't a success. - @inlinable @_transparent - func check() throws(CapstoneError) { - guard self != .CS_ERR_OK else { return } - throw self - } -} - -extension CapstoneError: @retroactive CustomStringConvertible { - public var description: String { - String(cString: cs_strerror(self)) - } -} - -public extension CapstoneInstruction { - /// See ``cs_insn``. - @inlinable @_transparent - var detail: Detail { - @inlinable @_transparent - _read { - if let unsafeMutableDetailPointer { - yield unsafeMutableDetailPointer.pointee - } else { - yield .init() - } - } - } -} - -public struct CapstoneInstructionBox: ~Copyable { - @usableFromInline let ptr: UnsafeMutablePointer! - - @inlinable @_transparent - public init(using capstone: borrowing Capstone) { - ptr = cs_malloc(capstone.handle) - } - - deinit { - cs_free(ptr, 1) - } - - @inlinable @_transparent - public var pointee: CapstoneInstruction { - _read { yield ptr.pointee } - _modify { yield &ptr.pointee } - } -} - -public struct CapstoneInstructionBuffer: ~Copyable { - @usableFromInline let buffer: UnsafeMutableBufferPointer! - - @inlinable @_transparent - public init(_ buffer: UnsafeMutableBufferPointer) { - self.buffer = buffer - } - - deinit { - cs_free(buffer.baseAddress, buffer.count) - } - - @inlinable @_transparent - public var count: Int { buffer.count } - - @inlinable @_transparent - public func withUnsafeBufferPointer( - do action: (UnsafeBufferPointer) -> R - ) -> R { - action(UnsafeBufferPointer(buffer)) - } - - @inlinable @_transparent - public func withUnsafeMutableBufferPointer( - do action: (UnsafeMutableBufferPointer) -> R - ) -> R { - action(buffer) - } - - @inlinable - public subscript(index: Int) -> CapstoneInstruction { - @_transparent - _read { yield buffer[index] } - @_transparent - _modify { yield &buffer[index] } - } -} diff --git a/bindings/swift/Sources/CapstoneKit.swift b/bindings/swift/Sources/CapstoneKit.swift new file mode 100644 index 0000000000..cd8fdf6fc6 --- /dev/null +++ b/bindings/swift/Sources/CapstoneKit.swift @@ -0,0 +1,358 @@ +// Public domain +// SPDX-License-Identifier: CC0 +// CapstoneKit + +@_exported public import capstone + +public struct Capstone: ~Copyable { + public let handle: csh + + @inlinable + public init(handle: csh) { + self.handle = handle + } + + /// See ``cs_open``. + @inlinable + public init( + arch: CapstoneArch, + mode: CapstoneMode + ) throws(CapstoneError) { + var handle = csh(0) + try cs_open(arch, mode, &handle).check() + self.handle = handle + } + + @inlinable + deinit { + var handle = handle + cs_close(&handle) + } +} + +public extension Capstone { + /// See ``cs_close``. Called automatically once this instance is no longer used. + @inlinable + consuming func close() { + var handle = handle + cs_close(&handle) + } + + /// See ``cs_option`` with ``CS_OPT_DETAIL``. + @inlinable @_transparent + func withDetailedInstructions(_ value: Bool) { + let value: CapstoneOption.Value = value ? .on : .off + set(option: .detail, to: value) + } + + /// See ``cs_option``. + @inlinable + func set(option: CapstoneOption.Kind, to value: some FixedWidthInteger) { + cs_option(handle, option, UInt(value)) + } + + /// See ``cs_option``. + @inlinable @_transparent + func set(option: CapstoneOption) { + set(option: option.type, to: option.val) + } + + /// See ``cs_option``. + @inlinable @_transparent + func set(option: CapstoneOption.Kind, to value: some RawRepresentable) { + set(option: option, to: value.rawValue) + } + + /// See ``cs_support``. + @inlinable + static func support(_ query: CInt) -> Bool { + cs_support(query) + } + + /// Throws the last error of an API function fail. See ``capstone/cs_errno``. + @inlinable + func errno() throws(CapstoneError) { + throw cs_errno(handle) + } + + /// See ``cs_disasm``. + @available(macOS 10.14.4, *) + @inlinable + func disassemble( + code: Span, + address: UInt64, + count: Int = 0 + ) throws(CapstoneError) -> CapstoneInstructionBuffer { + var output: UnsafeMutablePointer! + let result = code.withUnsafeBufferPointer { + cs_disasm(handle, $0.baseAddress, $0.count, address, count, &output) + } + if result == 0 { + throw cs_errno(handle) + } + let buffer = UnsafeMutableBufferPointer(start: output, count: count) + return CapstoneInstructionBuffer(managing: buffer) + } + + /// See ``cs_disasm_iter``. + @available(macOS 10.14.4, *) + @inlinable + func disassemble( + _ code: inout Span, + at address: inout UInt64, + ) throws(CapstoneError) -> CapstoneInstructionBox { + var result = CapstoneInstructionBox(using: self) + var size = code.count + + let success = code.withUnsafeBufferPointer { + var base = $0.baseAddress + return cs_disasm_iter(handle, &base, &size, &address, &result.pointee) + } + code = code.extracting(droppingFirst: code.count - size) + if !success { + throw cs_errno(handle) + } + return result + } + + /// See ``cs_regs_access``. + @available(macOS 10.14.4, *) + @inlinable + func access( + regsOf insn: borrowing CapstoneInstruction, + read: inout MutableSpan, + write: inout MutableSpan, + ) throws(CapstoneError) { + let cs_regs_count = MemoryLayout.size / MemoryLayout.size + precondition(read.count >= cs_regs_count && write.count >= cs_regs_count) + var rcount = 0 + var wcount = 0 + let err = withUnsafePointer(to: insn) { insn in + read.withUnsafeMutableBufferPointer { readp in + write.withUnsafeMutableBufferPointer { writep in + cs_regs_access(handle, insn, readp.baseAddress, &rcount, writep.baseAddress, &wcount) + } + } + } + read = read.extracting(first: rcount) + write = write.extracting(first: rcount) + try err.check() + } + + /// See ``cs_insn_group``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, in group: some FixedWidthInteger) -> Bool { + withUnsafePointer(to: instr) { instr in + cs_insn_group(handle, instr, UInt32(group)) + } + } + + /// See ``cs_insn_group``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, in group: some RawRepresentable) -> Bool { + instruction(instr, in: group.rawValue) + } + + /// See ``cs_insn_group``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, in group: InstructionGroup) -> Bool { + instruction(instr, in: group.rawValue) + } + + /// See ``cs_reg_read``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, read reg: some FixedWidthInteger) -> Bool { + withUnsafePointer(to: instr) { + cs_reg_read(handle, $0, UInt32(reg)) + } + } + + /// See ``cs_reg_read``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, read reg: some RawRepresentable) -> Bool { + instruction(instr, read: reg.rawValue) + } + + /// See ``cs_reg_write``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, write reg: some FixedWidthInteger) -> Bool { + withUnsafePointer(to: instr) { + cs_reg_write(handle, $0, UInt32(reg)) + } + } + + /// See ``cs_reg_write``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, write reg: some RawRepresentable) -> Bool { + instruction(instr, write: reg.rawValue) + } + + /// See ``cs_op_count``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, opCountOf op_type: some FixedWidthInteger) -> Int32 { + withUnsafePointer(to: instr) { + cs_op_count(handle, $0, UInt32(op_type)) + } + } + + /// See ``cs_op_count``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, opCountOf op_type: some RawRepresentable) -> Int32 { + instruction(instr, opCountOf: op_type.rawValue) + } + + /// See ``cs_op_index``. + @inlinable + func instruction(_ instr: borrowing CapstoneInstruction, opIndexOf op_type: some FixedWidthInteger, at position: some FixedWidthInteger) -> Int32 { + withUnsafePointer(to: instr) { + cs_op_index(handle, $0, UInt32(op_type), UInt32(position)) + } + } + + /// See ``cs_op_index``. + @inlinable @_transparent + func instruction(_ instr: borrowing CapstoneInstruction, opIndexOf op_type: some RawRepresentable, at position: some FixedWidthInteger) -> Int32 { + instruction(instr, opIndexOf: op_type.rawValue, at: position) + } + + /// See ``cs_insn_name``. + @inlinable + func nameOf(instruction id: some FixedWidthInteger) -> String { + guard let name = cs_insn_name(handle, UInt32(id)) else { return "" } + return String(cString: name) + } + + /// See ``cs_insn_name``. + @inlinable @_transparent + func nameOf(instruction id: some RawRepresentable) -> String { + nameOf(instruction: id.rawValue) + } + + /// See ``cs_group_name``. + @inlinable + func nameOf(group id: some FixedWidthInteger) -> String { + guard let name = cs_group_name(handle, UInt32(id)) else { return "" } + return String(cString: name) + } + + /// See ``cs_group_name``. + @inlinable @_transparent + func nameOf(group id: some RawRepresentable) -> String { + nameOf(group: id.rawValue) + } + + /// See ``cs_insn_name``. + @inlinable + func nameOf(register id: some FixedWidthInteger) -> String { + guard let name = cs_reg_name(handle, UInt32(id)) else { return "" } + return String(cString: name) + } + + /// See ``cs_insn_name``. + @inlinable @_transparent + func nameOf(register id: some RawRepresentable) -> String { + nameOf(register: id.rawValue) + } +} + +public extension CapstoneError { + /// Throws an error if the result wasn't a success. + @inlinable + func check() throws(CapstoneError) { + guard self != .ok else { return } + throw self + } +} + +extension CapstoneError: @retroactive CustomStringConvertible { + public var description: String { + String(cString: cs_strerror(self)) + } +} + +public extension CapstoneInstruction { + /// See ``cs_insn``. + @inlinable + var detail: Detail { + @inlinable + _read { + if let unsafeMutableDetailPointer { + yield unsafeMutableDetailPointer.pointee + } else { + yield .init() + } + } + } +} + +/// Represents an instruction managed by Capstone. +public struct CapstoneInstructionBox: ~Copyable { + @usableFromInline let ptr: UnsafeMutablePointer! + + /// Manage an instruction allocated with ``cs_malloc``. + /// The instruction will be freed once this instance goes out of scope. + /// - Parameter ptr: The instruction pointer to manage. + @inlinable + public init(managing ptr: UnsafeMutablePointer) { + self.ptr = ptr + } + + /// Allocates a new instruction using Capstone's memory allocator. + /// - Parameter capstone: The Capstone instance to use for allocating the instruction. + @inlinable + public init(using capstone: borrowing Capstone) { + ptr = cs_malloc(capstone.handle) + } + + deinit { + cs_free(ptr, 1) + } + + @inlinable + public var pointee: CapstoneInstruction { + _read { yield ptr.pointee } + _modify { yield &ptr.pointee } + } +} + +/// Represents a list of instructions managed by Capstone. +public struct CapstoneInstructionBuffer: ~Copyable { + @usableFromInline let buffer: UnsafeMutableBufferPointer! + + /// Manage an instruction list allocated by ``cs_disasm``. + /// The list and all its instructions will be freed once this instance goes out of scope. + /// - Parameter buffer: The instruction buffer to manage. + @inlinable + public init(managing buffer: UnsafeMutableBufferPointer) { + self.buffer = buffer + } + + deinit { + cs_free(buffer.baseAddress, buffer.count) + } + + @inlinable + public var count: Int { buffer.count } + + @inlinable @_transparent + public func withUnsafeBufferPointer( + do action: (UnsafeBufferPointer) -> R + ) -> R { + action(UnsafeBufferPointer(buffer)) + } + + @inlinable @_transparent + public func withUnsafeMutableBufferPointer( + do action: (UnsafeMutableBufferPointer) -> R + ) -> R { + action(buffer) + } + + @inlinable + public subscript(index: Int) -> CapstoneInstruction { + @_transparent + _read { yield buffer[index] } + @_transparent + _modify { yield &buffer[index] } + } +} diff --git a/bindings/swift/Tests/CapstoneTests.swift b/bindings/swift/Tests/CapstoneTests.swift new file mode 100644 index 0000000000..d70504fcd2 --- /dev/null +++ b/bindings/swift/Tests/CapstoneTests.swift @@ -0,0 +1,4 @@ +// Public domain +// SPDX-License-Identifier: CC0 +// CapstoneKit + diff --git a/include/Capstone.apinotes b/include/Capstone.apinotes index f9778f9dad..90b0ed26ab 100644 --- a/include/Capstone.apinotes +++ b/include/Capstone.apinotes @@ -1,7 +1,8 @@ --- -Name: Capstone +Name: capstone +#MARK: - Enumerators Enumerators: -# cs_ac_type +#MARK: cs_ac_type - Name: CS_AC_INVALID SwiftName: invalid - Name: CS_AC_READ @@ -10,7 +11,7 @@ Enumerators: SwiftName: readWrite - Name: CS_AC_WRITE SwiftName: write -# cs_arch +#MARK: cs_arch - Name: CS_ARCH_ARM SwiftName: arm - Name: CS_ARCH_ARM64 @@ -27,26 +28,74 @@ Enumerators: SwiftName: x86 - Name: CS_ARCH_PPC SwiftName: ppc -# CS_ARCH_SPARC, ///< Sparc architecture -# CS_ARCH_XCORE, ///< XCore architecture -# CS_ARCH_M68K, ///< 68K architecture -# CS_ARCH_TMS320C64X, ///< TMS320C64x architecture -# CS_ARCH_M680X, ///< 680X architecture -# CS_ARCH_EVM, ///< Ethereum architecture -# CS_ARCH_MOS65XX, ///< MOS65XX architecture (including MOS6502) -# CS_ARCH_WASM, ///< WebAssembly architecture -# CS_ARCH_BPF, ///< Berkeley Packet Filter architecture (including eBPF) -# CS_ARCH_RISCV, ///< RISCV architecture -# CS_ARCH_SH, ///< SH architecture -# CS_ARCH_TRICORE, ///< TriCore architecture -# CS_ARCH_ALPHA, ///< Alpha architecture -# CS_ARCH_HPPA, ///< HPPA architecture -# CS_ARCH_LOONGARCH, ///< LoongArch architecture -# CS_ARCH_XTENSA, ///< Xtensa architecture -# CS_ARCH_ARC, ///< ARC architecture -# CS_ARCH_MAX, -# CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() -# cs_group_type +- Name: CS_ARCH_SPARC + SwiftName: sparc +- Name: CS_ARCH_XCORE + SwiftName: xcore +- Name: CS_ARCH_M68K + SwiftName: m68k +- Name: CS_ARCH_TMS320C64X + SwiftName: tms320c64x +- Name: CS_ARCH_M680X + SwiftName: m680x +- Name: CS_ARCH_MOS65XX + SwiftName: mos65xx +- Name: CS_ARCH_WASM + SwiftName: wasm +- Name: CS_ARCH_BPF + SwiftName: bpf +- Name: CS_ARCH_RISCV + SwiftName: riscv +- Name: CS_ARCH_SH + SwiftName: sh +- Name: CS_ARCH_TRICORE + SwiftName: tricore +- Name: CS_ARCH_ALPHA + SwiftName: alpha +- Name: CS_ARCH_HPPA + SwiftName: hppa +- Name: CS_ARCH_LOONGARCH + SwiftName: loongarch +- Name: CS_ARCH_XTENSA + SwiftName: xtensa +- Name: CS_ARCH_ARC + SwiftName: arc +- Name: CS_ARCH_MAX + SwiftName: count +- Name: CS_ARCH_ALL + SwiftName: all +#MARK: cs_err +- Name: CS_ERR_OK + SwiftName: ok +- Name: CS_ERR_MEM + SwiftName: mem +- Name: CS_ERR_ARCH + SwiftName: arch +- Name: CS_ERR_HANDLE + SwiftName: handle +- Name: CS_ERR_CSH + SwiftName: csh +- Name: CS_ERR_MODE + SwiftName: mode +- Name: CS_ERR_OPTION + SwiftName: option +- Name: CS_ERR_DETAIL + SwiftName: detail +- Name: CS_ERR_MEMSETUP + SwiftName: memSetup +- Name: CS_ERR_VERSION + SwiftName: version +- Name: CS_ERR_DIET + SwiftName: diet +- Name: CS_ERR_SKIPDATA + SwiftName: skipData +- Name: CS_ERR_X86_ATT + SwiftName: x86_att +- Name: CS_ERR_X86_INTEL + SwiftName: x86_intel +- Name: CS_ERR_X86_MASM + SwiftName: x86_masm +#MARK: cs_group_type - Name: CS_GRP_INVALID SwiftName: invalid - Name: CS_GRP_JUMP @@ -63,7 +112,7 @@ Enumerators: SwiftName: privilege - Name: CS_GRP_BRANCH_RELATIVE SwiftName: branchRelative -# cs_opt_type +#MARK: cs_opt_type - Name: CS_OPT_INVALID SwiftName: invalid - Name: CS_OPT_SYNTAX @@ -86,7 +135,12 @@ Enumerators: SwiftName: onlyOffsetBranch - Name: CS_OPT_LITBASE SwiftName: litbase -# x86_opt_type +#MARK: cs_opt_value +- Name: CS_OPT_OFF + SwiftName: off +- Name: CS_OPT_ON + SwiftName: on +#MARK: x86_opt_type - Name: X86_OP_INVALID SwiftName: invalid - Name: X86_OP_REG @@ -95,8 +149,57 @@ Enumerators: SwiftName: imm - Name: X86_OP_MEM SwiftName: mem +#MARK: - Tags Tags: -# AArch64 +- Name: cs_ac_type + SwiftName: AccessSet + EnumKind: NSOptions +- Name: cs_arch + SwiftName: CapstoneArch + EnumExtensibility: closed +- Name: cs_detail + SwiftName: CapstoneInstruction.Detail +- Name: cs_err + SwiftName: CapstoneError + EnumExtensibility: closed + SwiftConformsTo: Swift.Error +- Name: cs_group_type + SwiftName: InstructionGroup + EnumExtensibility: closed +- Name: cs_insn + SwiftName: CapstoneInstruction + Fields: + - Name: detail + SwiftName: unsafeMutableDetailPointer +- Name: cs_mode + SwiftName: CapstoneMode + EnumKind: NSOptions +- Name: cs_op_type + SwiftName: CapstoneOpKind + EnumExtensibility: closed +- Name: cs_opt + SwiftName: CapstoneOption +- Name: cs_opt_mem + SwiftName: CapstoneOption.Allocator +- Name: cs_opt_mnem + SwiftName: CapstoneOption.Mnemonic +- Name: cs_opt_skipdata + SwiftName: CapstoneOption.SkipData +- Name: cs_opt_type + SwiftName: CapstoneOption.Kind + EnumExtensibility: closed +- Name: cs_opt_value + SwiftName: CapstoneOption.Value + EnumKind: NSOptions +#MARK: AArch64 +- Name: cs_aarch64 + SwiftName: AArch64 + #NOTE: trying to get rid of the typedef by pointing at the tag directly crashes clang +# Fields: +# - Name: cc +# Type: "enum AArch64CondCode" +- Name: cs_aarch64_op + SwiftName: AArch64.Operand - Name: aarch64_imm_range SwiftName: AArch64.ImmRange - Name: aarch64_op_mem @@ -199,8 +302,14 @@ Tags: - Name: AArch64CondCode SwiftName: AArch64.ConditionCode EnumExtensibility: closed +- Name: VectorLayout + SwiftName: AArch64.VectorLayout + EnumExtensibility: closed +#MARK: Arc - Name: cs_arc SwiftName: Arc +- Name: cs_arc_op + SwiftName: Arc.Operand - Name: arc_op_type SwiftName: Arc.OperandType EnumExtensibility: closed @@ -213,8 +322,11 @@ Tags: - Name: arc_reg SwiftName: Arc.Register EnumExtensibility: closed +#MARK: Arm - Name: cs_arm SwiftName: Arm +- Name: cs_arm_op + SwiftName: Arm.Operand - Name: arm_op_mem SwiftName: Arm.MemoryOp - Name: CondCodes @@ -232,26 +344,45 @@ Tags: - Name: arm_insn_group SwiftName: Arm.InstructionGroup EnumExtensibility: closed -- Name: arm_spsr_cpsr_bits - SwiftName: Arm.SpsrCpsrBits - EnumExtensibility: closed - Name: arm_insn SwiftName: Arm.InstructionId EnumExtensibility: closed -- Name: arm_sysreg - SwiftName: Arm.SystemRegister - EnumExtensibility: closed - Name: arm_op_type SwiftName: Arm.OperandType EnumExtensibility: closed - Name: arm_reg SwiftName: Arm.Register EnumExtensibility: closed +- Name: arm_setend_type + SwiftName: Arm.SetEndKind + EnumExtensibility: closed +- Name: arm_shifter + SwiftName: Arm.Shifter + EnumExtensibility: closed +- Name: arm_spsr_cpsr_bits + SwiftName: Arm.SpsrCpsrBits + EnumExtensibility: closed +- Name: arm_sysreg + SwiftName: Arm.SystemRegister + EnumExtensibility: closed - Name: arm_vectordata_type SwiftName: Arm.VectorDataType + EnumExtensibility: closed +- Name: PredBlockMask + SwiftName: Arm.PredBlockMask + EnumKind: NSOptions +- Name: MemBOpt + SwiftName: Arm.MemoryBarrierOption + EnumExtensibility: closed +- Name: VPTCodes + SwiftName: Arm.VptCodes + EnumExtensibility: closed +#MARK: Alpha - Name: cs_alpha SwiftName: Alpha EnumExtensibility: closed +- Name: cs_alpha_op + SwiftName: Alpha.Operand - Name: alpha_op_type SwiftName: Alpha.OperandType EnumExtensibility: closed @@ -264,8 +395,11 @@ Tags: - Name: alpha_reg SwiftName: Alpha.Register EnumExtensibility: closed +#MARK: BPF - Name: cs_bpf SwiftName: Bpf +- Name: cs_bpf_op + SwiftName: Bpf.Operand - Name: bpf_insn_group SwiftName: Bpf.InstructionGroup EnumExtensibility: closed @@ -275,24 +409,246 @@ Tags: - Name: bpf_reg SwiftName: Bpf.Register EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed -#- Name: <#c name#> -# SwiftName: <#swift name#> -# EnumExtensibility: closed +- Name: bpf_ext_type + SwiftName: Bpf.Extension + EnumExtensibility: closed +- Name: bpf_op_type + SwiftName: Bpf.Extension + EnumExtensibility: closed +#MARK: EVM +- Name: cs_evm + SwiftName: Evm +- Name: evm_insn_group + SwiftName: Evm.InstructionGroup + EnumExtensibility: closed +- Name: evm_insn + SwiftName: Evm.InstructionId + EnumExtensibility: closed +- Name: evm_reg + SwiftName: Evm.Register + EnumExtensibility: closed +#MARK: HPPA +- Name: cs_hppa + SwiftName: Hppa +- Name: cs_hppa_op + SwiftName: Hppa.Operand +- Name: hppa_insn_group + SwiftName: Hppa.InstructionGroup + EnumExtensibility: closed +- Name: hppa_insn + SwiftName: Hppa.InstructionId + EnumExtensibility: closed +- Name: hppa_reg + SwiftName: Hppa.Register + EnumExtensibility: closed +#MARK: LoongArch +- Name: cs_loongarch + SwiftName: LoongArch +- Name: cs_loongarch_op + SwiftName: LoongArch.Operand +- Name: loongarch_insn_group + SwiftName: LoongArch.InstructionGroup + EnumExtensibility: closed +- Name: loongarch_insn + SwiftName: LoongArch.InstructionId + EnumExtensibility: closed +- Name: loongarch_insn_form + SwiftName: LoongArch.InstructionForm + EnumExtensibility: closed +- Name: loongarch_reg + SwiftName: LoongArch.Register + EnumExtensibility: closed +#MARK: m680x +- Name: cs_m680x + SwiftName: M680x +- Name: cs_m680x_op + SwiftName: M680x.Operand +- Name: mos65xx_group_type + SwiftName: M680x.GroupKind + EnumExtensibility: closed +- Name: m680x_insn_group + SwiftName: M680x.InstructionGroup + EnumExtensibility: closed +- Name: m680x_insn + SwiftName: M680x.InstructionId + EnumExtensibility: closed +- Name: m680x_reg + SwiftName: M680x.Register + EnumExtensibility: closed +#MARK: m68k +- Name: cs_m68k + SwiftName: M68k +- Name: cs_m68k_op + SwiftName: M68k.Operand +- Name: cs_m68k_op_reg_pair + SwiftName: M68k.RegisterPair +- Name: m68k_insn_group + SwiftName: M68k.InstructionGroup + EnumExtensibility: closed +- Name: m68k_insn + SwiftName: M68k.InstructionId + EnumExtensibility: closed +- Name: m68k_reg + SwiftName: M68k.Register + EnumExtensibility: closed +#MARK: Mips +- Name: cs_mips + SwiftName: Mips +- Name: cs_mips_op + SwiftName: Mips.Operand +- Name: mips_insn_group + SwiftName: Mips.InstructionGroup + EnumExtensibility: closed +- Name: mips_insn + SwiftName: Mips.InstructionId + EnumExtensibility: closed +- Name: mips_reg + SwiftName: Mips.Register + EnumExtensibility: closed +#MARK: MOS65xx +- Name: cs_mos65xx + SwiftName: Mos65xx +- Name: cs_mos65xx_op + SwiftName: Mos65xx.Operand +- Name: mos65xx_insn_group + SwiftName: Mos65xx.InstructionGroup + EnumExtensibility: closed +- Name: mos65xx_insn + SwiftName: Mos65xx.InstructionId + EnumExtensibility: closed +- Name: mos65xx_reg + SwiftName: Mos65xx.Register + EnumExtensibility: closed +#MARK: PowerPC +- Name: cs_ppc + SwiftName: PowerPC +- Name: cs_ppc_op + SwiftName: PowerPC.Operand +- Name: ppc_insn + SwiftName: PowerPC.InstructionId + EnumExtensibility: closed +- Name: ppc_insn_form + SwiftName: PowerPC.InstructionForm + EnumExtensibility: closed +- Name: ppc_insn_group + SwiftName: PowerPC.InstructionGroup + EnumExtensibility: closed +- Name: ppc_pred + SwiftName: PowerPC.Predicate + EnumKind: NSOptions +- Name: ppc_reg + SwiftName: PowerPC.Register + EnumExtensibility: closed +#MARK: RiscV +- Name: cs_riscv + SwiftName: RiscV +- Name: cs_riscv_op + SwiftName: RiscV.Operand +- Name: riscv_insn_group + SwiftName: RiscV.InstructionGroup + EnumExtensibility: closed +- Name: riscv_insn + SwiftName: RiscV.InstructionId + EnumExtensibility: closed +- Name: riscv_reg + SwiftName: RiscV.Register + EnumExtensibility: closed +- Name: riscv_sysreg + SwiftName: RiscV.SystemRegister + EnumExtensibility: closed +#MARK: SH +- Name: cs_sh + SwiftName: Sh +- Name: cs_sh_op + SwiftName: Sh.Operand +- Name: sh_insn_group + SwiftName: Sh.InstructionGroup + EnumExtensibility: closed +- Name: sh_insn + SwiftName: Sh.InstructionId + EnumExtensibility: closed +- Name: sh_reg + SwiftName: Sh.Register + EnumExtensibility: closed +#MARK: Sparc +- Name: cs_sparc + SwiftName: Sparc +- Name: cs_sparc_op + SwiftName: Sparc.Operand +- Name: sparc_insn_group + SwiftName: Sparc.InstructionGroup + EnumExtensibility: closed +- Name: sparc_insn + SwiftName: Sparc.InstructionId + EnumExtensibility: closed +- Name: sparc_reg + SwiftName: Sparc.Register + EnumExtensibility: closed +#MARK: SystemZ +- Name: cs_systemz + SwiftName: SystemZ +- Name: cs_systemz_op + SwiftName: SystemZ.Operand +- Name: systemz_insn_group + SwiftName: SystemZ.InstructionGroup + EnumExtensibility: closed +- Name: systemz_insn + SwiftName: SystemZ.InstructionId + EnumExtensibility: closed +- Name: systemz_reg + SwiftName: SystemZ.Register + EnumExtensibility: closed +#MARK: TMS320c64x +- Name: cs_tms320c64x + SwiftName: Tms320c64x +- Name: cs_tms320c64x_op + SwiftName: Tms320c64x.Operand +- Name: tms320c64x_insn_group + SwiftName: Tms320c64x.InstructionGroup + EnumExtensibility: closed +- Name: tms320c64x_insn + SwiftName: Tms320c64x.InstructionId + EnumExtensibility: closed +- Name: tms320c64x_reg + SwiftName: Tms320c64x.Register + EnumExtensibility: closed +#MARK: Tricore +- Name: cs_tricore + SwiftName: Tricore +- Name: cs_tricore_op + SwiftName: Tricore.Operand +- Name: tricore_insn_group + SwiftName: Tricore.InstructionGroup + EnumExtensibility: closed +- Name: tricore_insn + SwiftName: Tricore.InstructionId + EnumExtensibility: closed +- Name: tricore_reg + SwiftName: Tricore.Register + EnumExtensibility: closed +#MARK: Wasm +- Name: cs_wasm + SwiftName: Wasm +- Name: cs_wasm_op + SwiftName: Wasm.Operand +- Name: cs_wasm_brtable + SwiftName: Wasm.BrTable +- Name: wasm_insn_group + SwiftName: Wasm.InstructionGroup + EnumExtensibility: closed +- Name: wasm_insn + SwiftName: Wasm.InstructionId + EnumExtensibility: closed +- Name: wasm_reg + SwiftName: Wasm.Register + EnumExtensibility: closed +#MARK: x86 +- Name: cs_x86 + SwiftName: X86 +- Name: cs_x86_op + SwiftName: X86.Operand +- Name: cs_x86_encoding + SwiftName: X86.Encoding - Name: x86_insn SwiftName: X86.InstructionId EnumExtensibility: closed @@ -302,45 +658,40 @@ Tags: - Name: x86_reg SwiftName: X86.Register EnumExtensibility: closed -- Name: cs_aarch64 - SwiftName: AArch64 -- Name: cs_aarch64_op - SwiftName: AArch64.Operand -- Name: cs_ac_type - SwiftName: AccessSet - EnumKind: NSOptions -- Name: cs_arch - SwiftName: CapstoneArch +#MARK: Xcore +- Name: cs_xcore + SwiftName: Xcore +- Name: cs_xcore_op + SwiftName: Xcore.Operand +- Name: xcore_insn_group + SwiftName: Xcore.InstructionGroup EnumExtensibility: closed -- Name: cs_detail - SwiftName: CapstoneInstruction.Detail -- Name: cs_err - SwiftName: CapstoneError +- Name: xcore_insn + SwiftName: Xcore.InstructionId EnumExtensibility: closed - SwiftConformsTo: Swift.Error -- Name: cs_group_type - SwiftName: InstructionGroup +- Name: xcore_reg + SwiftName: Xcore.Register EnumExtensibility: closed -- Name: cs_insn - SwiftName: CapstoneInstruction - Fields: - - Name: detail - SwiftName: unsafeMutableDetailPointer -- Name: cs_mode - SwiftName: CapstoneMode - EnumKind: NSOptions -- Name: cs_opt_type - SwiftName: CapstoneOptionKind +#MARK: Xtensa +- Name: cs_xtensa + SwiftName: Xtensa +- Name: cs_xtensa_op + SwiftName: Xtensa.Operand +- Name: cs_xtensa_op_mem + SwiftName: Xtensa.Operand.Memory +- Name: cs_xtensa_op_type + SwiftName: Xtensa.Operand.Kind EnumExtensibility: closed -- Name: cs_opt_value - SwiftName: CapstoneOptionValue - EnumKind: NSOptions -- Name: cs_opt - SwiftName: CapstoneOption -- Name: cs_x86 - SwiftName: X86 -- Name: cs_x86_op - SwiftName: X86.Operand +- Name: xtensa_insn_group + SwiftName: Xtensa.InstructionGroup + EnumExtensibility: closed +- Name: xtensa_insn + SwiftName: Xtensa.InstructionId + EnumExtensibility: closed +- Name: xtensa_reg + SwiftName: Xtensa.Register + EnumExtensibility: closed +#MARK: - Functions Functions: - Name: cs_disasm Parameters: @@ -354,9 +705,21 @@ Functions: SwiftSafety: unsafe - Name: cs_strerror ResultType: "const char * _Nonnull" -- Name: VectorLayout - SwiftName: AArch64.VectorLayout +#MARK: - Typedefs Typedefs: +#NOTE: Making those private prevents navigating through them via docs, maybe use Type to switch fields to its tag representation? +#- Name: AArch64CC_CondCode +# SwiftPrivate: true +#- Name: AArch64Layout_VectorLayout +# SwiftPrivate: true +#- Name: ARMCC_CondCodes +# SwiftPrivate: true +#- Name: ARMVCC_VPTCodes +# SwiftPrivate: true +#- Name: ARM_PredBlockMask +# SwiftPrivate: true +#- Name: arm_mem_bo_opt +# SwiftPrivate: true #- Name: csh # SwiftName: CapstoneHandle # SwiftWrapper: struct