diff --git a/capstone-rs/src/arch/bpf.rs b/capstone-rs/src/arch/bpf.rs new file mode 100644 index 0000000..b397135 --- /dev/null +++ b/capstone-rs/src/arch/bpf.rs @@ -0,0 +1,102 @@ +//! Contains bpf specific types + +use core::convert::From; +use core::{cmp, fmt, slice}; + +pub use capstone_sys::bpf_insn_group as BpfInsnGroup; +pub use capstone_sys::bpf_insn as BpfInsn; +pub use capstone_sys::bpf_reg as BpfReg; +use capstone_sys::{cs_bpf, cs_bpf_op, bpf_op_mem, bpf_op_type}; + +pub use crate::arch::arch_builder::bpf::*; +use crate::arch::DetailsArchInsn; +use crate::instruction::{RegId, RegIdInt}; + +/// Contains BPF-specific details for an instruction +pub struct BpfInsnDetail<'a>(pub(crate) &'a cs_bpf); + +impl_PartialEq_repr_fields!(BpfInsnDetail<'a> [ 'a ]; + operands +); + +/// BPF operand +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum BpfOperand { + /// Register + Reg(RegId), + + /// Immediate + Imm(u64), + + /// Memory + Mem(BpfOpMem), + + /// Offset + Off(u32), + + /// Mmem + Mmem(u32), + + /// Msh + Msh(u32), + + /// Ext + Ext(u32), + + /// Invalid + Invalid, +} + +impl Default for BpfOperand { + fn default() -> Self { + BpfOperand::Invalid + } +} + + +/// Bpf memory operand +#[derive(Debug, Copy, Clone)] +pub struct BpfOpMem(pub(crate) bpf_op_mem); + +impl BpfOpMem { + /// Base register + pub fn base(&self) -> RegId { + RegId(self.0.base as RegIdInt) + } + + /// Disp value + pub fn disp(&self) -> u32 { + self.0.disp + } +} + +impl_PartialEq_repr_fields!(BpfOpMem; + base, disp +); + +impl cmp::Eq for BpfOpMem {} + +impl<'a> From<&'a cs_bpf_op> for BpfOperand { + fn from(insn: &cs_bpf_op) -> BpfOperand { + match insn.type_ { + bpf_op_type::BPF_OP_EXT => BpfOperand::Ext(unsafe { insn.__bindgen_anon_1.ext }), + bpf_op_type::BPF_OP_INVALID => BpfOperand::Invalid, + bpf_op_type::BPF_OP_REG => BpfOperand::Reg(RegId(unsafe {insn.__bindgen_anon_1.reg} as RegIdInt)), + bpf_op_type::BPF_OP_IMM => BpfOperand::Imm(unsafe { insn.__bindgen_anon_1.imm }), + bpf_op_type::BPF_OP_MEM => BpfOperand::Mem(BpfOpMem(unsafe { insn.__bindgen_anon_1.mem})), + bpf_op_type::BPF_OP_OFF => BpfOperand::Off(unsafe { insn.__bindgen_anon_1.off }), + bpf_op_type::BPF_OP_MMEM => BpfOperand::Mmem(unsafe { insn.__bindgen_anon_1.mmem }), + bpf_op_type::BPF_OP_MSH => BpfOperand::Msh(unsafe { insn.__bindgen_anon_1.msh }), + } + } +} + +def_arch_details_struct!( + InsnDetail = BpfInsnDetail; + Operand = BpfOperand; + OperandIterator = BpfOperandIterator; + OperandIteratorLife = BpfOperandIterator<'a>; + [ pub struct BpfOperandIterator<'a>(slice::Iter<'a, cs_bpf_op>); ] + cs_arch_op = cs_bpf_op; + cs_arch = cs_bpf; +); diff --git a/capstone-rs/src/arch/mod.rs b/capstone-rs/src/arch/mod.rs index a2e5834..287d119 100644 --- a/capstone-rs/src/arch/mod.rs +++ b/capstone-rs/src/arch/mod.rs @@ -352,6 +352,16 @@ macro_rules! arch_info_base { ( syntax: ) ( both_endian: false ) ] + [ + ( bpf, BPF ) + ( mode: + Cbpf, + Ebpf, + ) + ( extra_modes: ) + ( syntax: ) + ( both_endian: true ) + ] ); }; } @@ -534,6 +544,13 @@ macro_rules! detail_arch_base { /// Returns the XCore details, if any => arch_name = xcore, ] + [ + detail = BpfDetail, + insn_detail = BpfInsnDetail<'a>, + op = BpfOperand, + /// Returns the XCore details, if any + => arch_name = bpf, + ] ); }; } diff --git a/capstone-rs/src/constants.rs b/capstone-rs/src/constants.rs index 0011f29..1d0c1c7 100644 --- a/capstone-rs/src/constants.rs +++ b/capstone-rs/src/constants.rs @@ -221,6 +221,8 @@ define_cs_enum_wrapper!( => EVM = CS_ARCH_EVM; /// RISC-V => RISCV = CS_ARCH_RISCV; + /// BPF + => BPF = CS_ARCH_BPF; ); define_cs_enum_wrapper!( @@ -286,6 +288,10 @@ define_cs_enum_wrapper!( => RiscV32 = CS_MODE_RISCV32; /// RISC-V 64-bit mode => RiscV64 = CS_MODE_RISCV64; + /// Classic BPF mode + => Cbpf = CS_MODE_BPF_CLASSIC; + /// Extended BPF mode + => Ebpf = CS_MODE_BPF_EXTENDED; /// Default mode for little-endian => Default = CS_MODE_LITTLE_ENDIAN; ); diff --git a/capstone-rs/src/instruction.rs b/capstone-rs/src/instruction.rs index aaa1242..cce01f0 100644 --- a/capstone-rs/src/instruction.rs +++ b/capstone-rs/src/instruction.rs @@ -440,6 +440,7 @@ impl<'a> InsnDetail<'a> { [TMS320C64X, Tms320c64xDetail, Tms320c64xInsnDetail, tms320c64x] [X86, X86Detail, X86InsnDetail, x86] [XCORE, XcoreDetail, XcoreInsnDetail, xcore] + [BPF, BpfDetail, BpfInsnDetail, bpf] ); } } diff --git a/capstone-rs/src/test.rs b/capstone-rs/src/test.rs index cb98c7d..a7c0b1d 100644 --- a/capstone-rs/src/test.rs +++ b/capstone-rs/src/test.rs @@ -17,6 +17,17 @@ use super::*; const X86_CODE: &[u8] = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"; const ARM_CODE: &[u8] = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"; +const CBPF_CODE: &[u8] = b"\x94\x09\x00\x00\x37\x13\x03\x00\ + \x87\x00\x00\x00\x00\x00\x00\x00\ + \x07\x00\x00\x00\x00\x00\x00\x00\ + \x16\x00\x00\x00\x00\x00\x00\x00\ + \x80\x00\x00\x00\x00\x00\x00\x00"; +const EBPF_CODE: &[u8] = b"\x97\x09\x00\x00\x37\x13\x03\x00\ + \xdc\x02\x00\x00\x20\x00\x00\x00\ + \x30\x00\x00\x00\x00\x00\x00\x00\ + \xdb\x3a\x00\x01\x00\x00\x00\x00\ + \x84\x02\x00\x00\x00\x00\x00\x00\ + \x6d\x33\x17\x02\x00\x00\x00\x00"; // Aliases for group types const JUMP: cs_group_type::Type = cs_group_type::CS_GRP_JUMP; @@ -3244,3 +3255,185 @@ fn test_owned_insn() { assert_eq!(format!("{:?}", insn), format!("{:?}", owned)); } } + +/// Print register names +fn reg_names(cs: &Capstone, regs: &[RegId]) -> String { + let names: Vec = regs.iter().map(|&x| cs.reg_name(x).unwrap()).collect(); + names.join(", ") +} + +/// Print instruction group names +fn group_names(cs: &Capstone, regs: &[InsnGroupId]) -> String { + let names: Vec = regs.iter().map(|&x| cs.group_name(x).unwrap()).collect(); + names.join(", ") +} + +#[test] +fn test_cbpf() { + let cs = Capstone::new() + .bpf() + .mode(bpf::ArchMode::Cbpf) + .endian(Endian::Little) + .detail(true) + .build() + .unwrap(); + let insns = cs.disasm_all(CBPF_CODE, 0x1000); + match insns { + Ok(ins) => { + for i in ins.as_ref() { + println!(); + eprintln!("{}", i); + + let detail: InsnDetail = cs.insn_detail(&i).expect("Failed to get insn detail"); + let arch_detail: ArchDetail = detail.arch_detail(); + let ops = arch_detail.operands(); + + let output: &[(&str, String)] = &[ + ("insn id:", format!("{:?}", i.id().0)), + ("bytes:", format!("{:?}", i.bytes())), + ("read regs:", reg_names(&cs, detail.regs_read())), + ("write regs:", reg_names(&cs, detail.regs_write())), + ("insn groups:", group_names(&cs, detail.groups())), + ]; + + for &(ref name, ref message) in output.iter() { + eprintln!("{:4}{:12} {}", "", name, message); + } + + println!("{:4}operands: {}", "", ops.len()); + for op in ops { + eprintln!("{:8}{:?}", "", op); + } + } + } + + Err(e) => { + eprintln!("{:?}", e); + assert!(false); + } + } +} + +#[test] +fn test_ebpf() { + let cs = Capstone::new() + .bpf() + .mode(bpf::ArchMode::Ebpf) + .endian(Endian::Little) + .detail(true) + .build() + .unwrap(); + let insns = cs.disasm_all(EBPF_CODE, 0x1000); + match insns { + Ok(ins) => { + for i in ins.as_ref() { + println!(); + eprintln!("{}", i); + + let detail: InsnDetail = cs.insn_detail(&i).expect("Failed to get insn detail"); + let arch_detail: ArchDetail = detail.arch_detail(); + let ops = arch_detail.operands(); + + let output: &[(&str, String)] = &[ + ("insn id:", format!("{:?}", i.id().0)), + ("bytes:", format!("{:?}", i.bytes())), + ("read regs:", reg_names(&cs, detail.regs_read())), + ("write regs:", reg_names(&cs, detail.regs_write())), + ("insn groups:", group_names(&cs, detail.groups())), + ]; + + for &(ref name, ref message) in output.iter() { + eprintln!("{:4}{:12} {}", "", name, message); + } + + println!("{:4}operands: {}", "", ops.len()); + for op in ops { + eprintln!("{:8}{:?}", "", op); + } + } + } + + Err(e) => { + eprintln!("{:?}", e); + assert!(false); + } + } +} + +#[test] +fn test_arch_bpf_detail() { + use crate::arch::bpf::BpfOperand::*; + use crate::arch::bpf::BpfReg::*; + use crate::arch::bpf::*; + use capstone_sys::*; + + test_arch_mode_endian_insns_detail( + &mut Capstone::new() + .bpf() + .mode(bpf::ArchMode::Ebpf) + .endian(Endian::Little) + .detail(true) + .build() + .unwrap(), + Arch::BPF, + Mode::Ebpf, + None, + &[], + &[ + // r1 = 0x1 + DII::new( + "mov64", + b"\xb7\x01\x00\x00\x01\x00\x00\x00", + &[Reg(RegId(BPF_REG_R1 as RegIdInt)), Imm(1)], + ), + // r0 = *(u32 *)(r10 - 0xc) + DII::new( + "ldxw", + b"\x61\xa0\xf4\xff\x00\x00\x00\x00", + &[ + Reg(RegId(BPF_REG_R0 as RegIdInt)), + Mem(BpfOpMem(bpf_op_mem { + base: BPF_REG_R10, + disp: 0xfff4, + })), + ], + ), + // *(u32 *)(r10 - 0xc) = r1 + DII::new( + "stxw", + b"\x63\x1a\xf4\xff\x00\x00\x00\x00", + &[ + Mem(BpfOpMem(bpf_op_mem { + base: BPF_REG_R10, + disp: 0xfff4, + })), + Reg(RegId(BPF_REG_R1 as RegIdInt)), + ], + ), + // exit + DII::new("exit", b"\x95\x00\x00\x00\x00\x00\x00\x00", &[]), + ], + ); + + test_arch_mode_endian_insns_detail( + &mut Capstone::new() + .bpf() + .mode(bpf::ArchMode::Cbpf) + .endian(Endian::Little) + .detail(true) + .build() + .unwrap(), + Arch::BPF, + Mode::Cbpf, + None, + &[], + &[ + DII::new("txa", b"\x87\x00\x00\x00\x00\x00\x00\x00", &[]), + DII::new( + "ret", + b"\x16\x00\x00\x00\x00\x00\x00\x00", + &[Reg(RegId(BPF_REG_A as RegIdInt))], + ), + ], + ); +} diff --git a/capstone-sys/Cargo.toml b/capstone-sys/Cargo.toml index 846b3e7..161b3c2 100644 --- a/capstone-sys/Cargo.toml +++ b/capstone-sys/Cargo.toml @@ -26,7 +26,7 @@ travis-ci = { repository = "capstone-rust/capstone-sys" } libc = { version = "0.2.59", default-features = false } [build-dependencies] -bindgen = { optional = true, version = "0.59.1" } +bindgen = { optional = true, version = "0.62.0" } regex = { optional = true, version = "1.3.1" } cc = "1.0" diff --git a/capstone-sys/build.rs b/capstone-sys/build.rs index ef1ae71..04fa699 100644 --- a/capstone-sys/build.rs +++ b/capstone-sys/build.rs @@ -132,6 +132,7 @@ fn build_capstone_cc() { .define("CAPSTONE_HAS_WASM", None) .define("CAPSTONE_HAS_X86", None) .define("CAPSTONE_HAS_XCORE", None) + .define("CAPSTONE_HAS_BPF", None) // No need to display any warnings from the C library .flag_if_supported("-w") .static_crt(use_static_crt); diff --git a/capstone-sys/common.rs b/capstone-sys/common.rs index 523a30b..a015821 100644 --- a/capstone-sys/common.rs +++ b/capstone-sys/common.rs @@ -77,6 +77,10 @@ pub static ARCH_INCLUDES: &[CapstoneArchInfo<'static>] = &[ header_name: "xcore.h", cs_name: "xcore", }, + CapstoneArchInfo { + header_name: "bpf.h", + cs_name: "bpf" + } ]; pub static BINDINGS_FILE: &str = "capstone.rs"; diff --git a/capstone-sys/pre_generated/capstone.rs b/capstone-sys/pre_generated/capstone.rs index f8df308..4350768 100644 --- a/capstone-sys/pre_generated/capstone.rs +++ b/capstone-sys/pre_generated/capstone.rs @@ -1,14 +1,6 @@ -/* automatically generated by rust-bindgen 0.59.2 */ +/* automatically generated by rust-bindgen 0.62.0 */ pub type va_list = __builtin_va_list; -pub type __int8_t = libc::c_schar; -pub type __uint8_t = libc::c_uchar; -pub type __int16_t = libc::c_short; -pub type __uint16_t = libc::c_ushort; -pub type __int32_t = libc::c_int; -pub type __uint32_t = libc::c_uint; -pub type __int64_t = libc::c_long; -pub type __uint64_t = libc::c_ulong; pub type csh = usize; #[repr(u32)] #[doc = " Architecture type"] @@ -950,7 +942,7 @@ impl Clone for cs_arm_op { } impl ::core::fmt::Debug for cs_arm_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_arm_op {{ vector_index: {:?}, shift: {:?}, type: {:?}, __bindgen_anon_1: {:?}, subtracted: {:?}, access: {:?}, neon_lane: {:?} }}" , self . vector_index , self . shift , self . type_ , self . __bindgen_anon_1 , self . subtracted , self . access , self . neon_lane) + write ! (f , "cs_arm_op {{ vector_index: {:?}, shift: {:?}, type: {:?}, __bindgen_anon_1: {:?}, subtracted: {:?} }}" , self . vector_index , self . shift , self . type_ , self . __bindgen_anon_1 , self . subtracted) } } #[doc = " Instruction structure"] @@ -988,7 +980,7 @@ impl Clone for cs_arm { } impl ::core::fmt::Debug for cs_arm { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_arm {{ usermode: {:?}, vector_size: {:?}, vector_data: {:?}, cps_mode: {:?}, cps_flag: {:?}, cc: {:?}, update_flags: {:?}, writeback: {:?}, mem_barrier: {:?}, op_count: {:?}, operands: [...] }}" , self . usermode , self . vector_size , self . vector_data , self . cps_mode , self . cps_flag , self . cc , self . update_flags , self . writeback , self . mem_barrier , self . op_count) + write ! (f , "cs_arm {{ usermode: {:?}, vector_size: {:?}, vector_data: {:?}, cps_mode: {:?}, cps_flag: {:?}, cc: {:?}, update_flags: {:?}, writeback: {:?}, mem_barrier: {:?}, operands: [...] }}" , self . usermode , self . vector_size , self . vector_data , self . cps_mode , self . cps_flag , self . cc , self . update_flags , self . writeback , self . mem_barrier) } } #[repr(u32)] @@ -3045,7 +3037,7 @@ impl Clone for cs_arm64_op { } impl ::core::fmt::Debug for cs_arm64_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_arm64_op {{ vector_index: {:?}, vas: {:?}, shift: {:?}, ext: {:?}, type: {:?}, __bindgen_anon_1: {:?}, access: {:?} }}" , self . vector_index , self . vas , self . shift , self . ext , self . type_ , self . __bindgen_anon_1 , self . access) + write ! (f , "cs_arm64_op {{ vector_index: {:?}, vas: {:?}, shift: {:?}, ext: {:?}, type: {:?}, __bindgen_anon_1: {:?} }}" , self . vector_index , self . vas , self . shift , self . ext , self . type_ , self . __bindgen_anon_1) } } #[doc = " Instruction structure"] @@ -3071,7 +3063,11 @@ impl Clone for cs_arm64 { } impl ::core::fmt::Debug for cs_arm64 { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_arm64 {{ cc: {:?}, update_flags: {:?}, writeback: {:?}, op_count: {:?}, operands: {:?} }}" , self . cc , self . update_flags , self . writeback , self . op_count , self . operands) + write!( + f, + "cs_arm64 {{ cc: {:?}, update_flags: {:?}, writeback: {:?}, operands: {:?} }}", + self.cc, self.update_flags, self.writeback, self.operands + ) } } #[repr(u32)] @@ -4301,7 +4297,7 @@ impl Clone for cs_m68k_op { } impl ::core::fmt::Debug for cs_m68k_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_m68k_op {{ __bindgen_anon_1: {:?}, mem: {:?}, br_disp: {:?}, register_bits: {:?}, type: {:?}, address_mode: {:?} }}" , self . __bindgen_anon_1 , self . mem , self . br_disp , self . register_bits , self . type_ , self . address_mode) + write ! (f , "cs_m68k_op {{ __bindgen_anon_1: {:?}, mem: {:?}, br_disp: {:?}, type: {:?}, address_mode: {:?} }}" , self . __bindgen_anon_1 , self . mem , self . br_disp , self . type_ , self . address_mode) } } #[repr(u32)] @@ -4395,8 +4391,8 @@ impl ::core::fmt::Debug for cs_m68k { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_m68k {{ operands: {:?}, op_size: {:?}, op_count: {:?} }}", - self.operands, self.op_size, self.op_count + "cs_m68k {{ operands: {:?}, op_size: {:?} }}", + self.operands, self.op_size ) } } @@ -5067,11 +5063,7 @@ impl Clone for cs_mips { } impl ::core::fmt::Debug for cs_mips { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!( - f, - "cs_mips {{ op_count: {:?}, operands: {:?} }}", - self.op_count, self.operands - ) + write!(f, "cs_mips {{ operands: {:?} }}", self.operands) } } #[repr(u32)] @@ -6147,8 +6139,8 @@ impl ::core::fmt::Debug for cs_ppc { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_ppc {{ bc: {:?}, bh: {:?}, update_cr0: {:?}, op_count: {:?}, operands: {:?} }}", - self.bc, self.bh, self.update_cr0, self.op_count, self.operands + "cs_ppc {{ bc: {:?}, bh: {:?}, update_cr0: {:?}, operands: {:?} }}", + self.bc, self.bh, self.update_cr0, self.operands ) } } @@ -8146,8 +8138,8 @@ impl ::core::fmt::Debug for cs_sparc { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_sparc {{ cc: {:?}, hint: {:?}, op_count: {:?}, operands: {:?} }}", - self.cc, self.hint, self.op_count, self.operands + "cs_sparc {{ cc: {:?}, hint: {:?}, operands: {:?} }}", + self.cc, self.hint, self.operands ) } } @@ -8693,8 +8685,8 @@ impl ::core::fmt::Debug for cs_sysz { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_sysz {{ cc: {:?}, op_count: {:?}, operands: {:?} }}", - self.cc, self.op_count, self.operands + "cs_sysz {{ cc: {:?}, operands: {:?} }}", + self.cc, self.operands ) } } @@ -11545,7 +11537,7 @@ impl Clone for cs_x86_op { } impl ::core::fmt::Debug for cs_x86_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_x86_op {{ type: {:?}, __bindgen_anon_1: {:?}, size: {:?}, access: {:?}, avx_bcast: {:?}, avx_zero_opmask: {:?} }}" , self . type_ , self . __bindgen_anon_1 , self . size , self . access , self . avx_bcast , self . avx_zero_opmask) + write ! (f , "cs_x86_op {{ type: {:?}, __bindgen_anon_1: {:?}, avx_bcast: {:?}, avx_zero_opmask: {:?} }}" , self . type_ , self . __bindgen_anon_1 , self . avx_bcast , self . avx_zero_opmask) } } #[repr(C)] @@ -11643,7 +11635,7 @@ impl Clone for cs_x86 { } impl ::core::fmt::Debug for cs_x86 { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_x86 {{ prefix: {:?}, opcode: {:?}, rex: {:?}, addr_size: {:?}, modrm: {:?}, sib: {:?}, disp: {:?}, sib_index: {:?}, sib_scale: {:?}, sib_base: {:?}, xop_cc: {:?}, sse_cc: {:?}, avx_cc: {:?}, avx_sae: {:?}, avx_rm: {:?}, __bindgen_anon_1: {:?}, op_count: {:?}, operands: {:?}, encoding: {:?} }}" , self . prefix , self . opcode , self . rex , self . addr_size , self . modrm , self . sib , self . disp , self . sib_index , self . sib_scale , self . sib_base , self . xop_cc , self . sse_cc , self . avx_cc , self . avx_sae , self . avx_rm , self . __bindgen_anon_1 , self . op_count , self . operands , self . encoding) + write ! (f , "cs_x86 {{ prefix: {:?}, opcode: {:?}, sib_index: {:?}, sib_base: {:?}, xop_cc: {:?}, sse_cc: {:?}, avx_cc: {:?}, avx_sae: {:?}, avx_rm: {:?}, __bindgen_anon_1: {:?}, operands: {:?}, encoding: {:?} }}" , self . prefix , self . opcode , self . sib_index , self . sib_base , self . xop_cc , self . sse_cc , self . avx_cc , self . avx_sae , self . avx_rm , self . __bindgen_anon_1 , self . operands , self . encoding) } } #[repr(u32)] @@ -13366,11 +13358,7 @@ impl Clone for cs_xcore { } impl ::core::fmt::Debug for cs_xcore { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!( - f, - "cs_xcore {{ op_count: {:?}, operands: {:?} }}", - self.op_count, self.operands - ) + write!(f, "cs_xcore {{ operands: {:?} }}", self.operands) } } #[repr(u32)] @@ -13649,7 +13637,11 @@ impl Clone for cs_tms320c64x { } impl ::core::fmt::Debug for cs_tms320c64x { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_tms320c64x {{ op_count: {:?}, operands: {:?}, condition: {:?}, funit: {:?}, parallel: {:?} }}" , self . op_count , self . operands , self . condition , self . funit , self . parallel) + write!( + f, + "cs_tms320c64x {{ operands: {:?}, condition: {:?}, funit: {:?}, parallel: {:?} }}", + self.operands, self.condition, self.funit, self.parallel + ) } } pub mod tms320c64x_reg { @@ -14104,8 +14096,8 @@ impl ::core::fmt::Debug for cs_m680x_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_m680x_op {{ type: {:?}, __bindgen_anon_1: {:?}, size: {:?}, access: {:?} }}", - self.type_, self.__bindgen_anon_1, self.size, self.access + "cs_m680x_op {{ type: {:?}, __bindgen_anon_1: {:?} }}", + self.type_, self.__bindgen_anon_1 ) } } @@ -14148,11 +14140,7 @@ impl Clone for cs_m680x { } impl ::core::fmt::Debug for cs_m680x { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!( - f, - "cs_m680x {{ flags: {:?}, op_count: {:?}, operands: {:?} }}", - self.flags, self.op_count, self.operands - ) + write!(f, "cs_m680x {{ operands: {:?} }}", self.operands) } } #[repr(u32)] @@ -14811,8 +14799,8 @@ impl ::core::fmt::Debug for cs_riscv { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_riscv {{ need_effective_addr: {:?}, op_count: {:?}, operands: {:?} }}", - self.need_effective_addr, self.op_count, self.operands + "cs_riscv {{ need_effective_addr: {:?}, operands: {:?} }}", + self.need_effective_addr, self.operands ) } } @@ -15303,8 +15291,8 @@ impl ::core::fmt::Debug for cs_wasm_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_wasm_op {{ type: {:?}, size: {:?}, __bindgen_anon_1: {:?} }}", - self.type_, self.size, self.__bindgen_anon_1 + "cs_wasm_op {{ type: {:?}, __bindgen_anon_1: {:?} }}", + self.type_, self.__bindgen_anon_1 ) } } @@ -15322,11 +15310,7 @@ impl Clone for cs_wasm { } impl ::core::fmt::Debug for cs_wasm { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!( - f, - "cs_wasm {{ op_count: {:?}, operands: {:?} }}", - self.op_count, self.operands - ) + write!(f, "cs_wasm {{ operands: {:?} }}", self.operands) } } #[repr(u32)] @@ -15485,8 +15469,8 @@ impl ::core::fmt::Debug for cs_mos65xx { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_mos65xx {{ am: {:?}, modifies_flags: {:?}, op_count: {:?}, operands: {:?} }}", - self.am, self.modifies_flags, self.op_count, self.operands + "cs_mos65xx {{ am: {:?}, modifies_flags: {:?}, operands: {:?} }}", + self.am, self.modifies_flags, self.operands ) } } @@ -15506,25 +15490,24 @@ pub enum bpf_op_type { #[doc = "< cBPF's extension (not eBPF)"] BPF_OP_EXT = 7, } -#[repr(u32)] -#[doc = " BPF registers"] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum bpf_reg { - BPF_REG_INVALID = 0, - BPF_REG_A = 1, - BPF_REG_X = 2, - BPF_REG_R0 = 3, - BPF_REG_R1 = 4, - BPF_REG_R2 = 5, - BPF_REG_R3 = 6, - BPF_REG_R4 = 7, - BPF_REG_R5 = 8, - BPF_REG_R6 = 9, - BPF_REG_R7 = 10, - BPF_REG_R8 = 11, - BPF_REG_R9 = 12, - BPF_REG_R10 = 13, - BPF_REG_ENDING = 14, +pub mod bpf_reg { + #[doc = " BPF registers"] + pub type Type = libc::c_uint; + pub const BPF_REG_INVALID: Type = 0; + pub const BPF_REG_A: Type = 1; + pub const BPF_REG_X: Type = 2; + pub const BPF_REG_R0: Type = 3; + pub const BPF_REG_R1: Type = 4; + pub const BPF_REG_R2: Type = 5; + pub const BPF_REG_R3: Type = 6; + pub const BPF_REG_R4: Type = 7; + pub const BPF_REG_R5: Type = 8; + pub const BPF_REG_R6: Type = 9; + pub const BPF_REG_R7: Type = 10; + pub const BPF_REG_R8: Type = 11; + pub const BPF_REG_R9: Type = 12; + pub const BPF_REG_R10: Type = 13; + pub const BPF_REG_ENDING: Type = 14; } #[doc = " Instruction's operand referring to memory"] #[doc = " This is associated with BPF_OP_MEM operand type above"] @@ -15532,7 +15515,7 @@ pub enum bpf_reg { #[derive(Debug, Copy)] pub struct bpf_op_mem { #[doc = "< base register"] - pub base: bpf_reg, + pub base: bpf_reg::Type, #[doc = "< offset value"] pub disp: u32, } @@ -15541,6 +15524,12 @@ impl Clone for bpf_op_mem { *self } } +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_ext_type { + BPF_EXT_INVALID = 0, + BPF_EXT_LEN = 1, +} #[doc = " Instruction operand"] #[repr(C)] #[derive(Copy)] @@ -15589,8 +15578,8 @@ impl ::core::fmt::Debug for cs_bpf_op { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!( f, - "cs_bpf_op {{ type: {:?}, __bindgen_anon_1: {:?}, access: {:?} }}", - self.type_, self.__bindgen_anon_1, self.access + "cs_bpf_op {{ type: {:?}, __bindgen_anon_1: {:?} }}", + self.type_, self.__bindgen_anon_1 ) } } @@ -15608,13 +15597,130 @@ impl Clone for cs_bpf { } impl ::core::fmt::Debug for cs_bpf { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!( - f, - "cs_bpf {{ op_count: {:?}, operands: {:?} }}", - self.op_count, self.operands - ) + write!(f, "cs_bpf {{ operands: {:?} }}", self.operands) } } +pub const BPF_INS_LD: bpf_insn = bpf_insn::BPF_INS_LDW; +pub const BPF_INS_LDX: bpf_insn = bpf_insn::BPF_INS_LDXW; +pub const BPF_INS_ST: bpf_insn = bpf_insn::BPF_INS_STW; +pub const BPF_INS_STX: bpf_insn = bpf_insn::BPF_INS_STXW; +#[repr(u32)] +#[doc = " BPF instruction"] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_insn { + BPF_INS_INVALID = 0, + BPF_INS_ADD = 1, + BPF_INS_SUB = 2, + BPF_INS_MUL = 3, + BPF_INS_DIV = 4, + BPF_INS_OR = 5, + BPF_INS_AND = 6, + BPF_INS_LSH = 7, + BPF_INS_RSH = 8, + BPF_INS_NEG = 9, + BPF_INS_MOD = 10, + BPF_INS_XOR = 11, + #[doc = "< eBPF only"] + BPF_INS_MOV = 12, + #[doc = "< eBPF only"] + BPF_INS_ARSH = 13, + BPF_INS_ADD64 = 14, + BPF_INS_SUB64 = 15, + BPF_INS_MUL64 = 16, + BPF_INS_DIV64 = 17, + BPF_INS_OR64 = 18, + BPF_INS_AND64 = 19, + BPF_INS_LSH64 = 20, + BPF_INS_RSH64 = 21, + BPF_INS_NEG64 = 22, + BPF_INS_MOD64 = 23, + BPF_INS_XOR64 = 24, + BPF_INS_MOV64 = 25, + BPF_INS_ARSH64 = 26, + BPF_INS_LE16 = 27, + BPF_INS_LE32 = 28, + BPF_INS_LE64 = 29, + BPF_INS_BE16 = 30, + BPF_INS_BE32 = 31, + BPF_INS_BE64 = 32, + #[doc = "< eBPF only"] + BPF_INS_LDW = 33, + BPF_INS_LDH = 34, + BPF_INS_LDB = 35, + #[doc = "< eBPF only: load 64-bit imm"] + BPF_INS_LDDW = 36, + #[doc = "< eBPF only"] + BPF_INS_LDXW = 37, + #[doc = "< eBPF only"] + BPF_INS_LDXH = 38, + #[doc = "< eBPF only"] + BPF_INS_LDXB = 39, + #[doc = "< eBPF only"] + BPF_INS_LDXDW = 40, + #[doc = "< eBPF only"] + BPF_INS_STW = 41, + #[doc = "< eBPF only"] + BPF_INS_STH = 42, + #[doc = "< eBPF only"] + BPF_INS_STB = 43, + #[doc = "< eBPF only"] + BPF_INS_STDW = 44, + #[doc = "< eBPF only"] + BPF_INS_STXW = 45, + #[doc = "< eBPF only"] + BPF_INS_STXH = 46, + #[doc = "< eBPF only"] + BPF_INS_STXB = 47, + #[doc = "< eBPF only"] + BPF_INS_STXDW = 48, + #[doc = "< eBPF only"] + BPF_INS_XADDW = 49, + #[doc = "< eBPF only"] + BPF_INS_XADDDW = 50, + BPF_INS_JMP = 51, + BPF_INS_JEQ = 52, + BPF_INS_JGT = 53, + BPF_INS_JGE = 54, + BPF_INS_JSET = 55, + #[doc = "< eBPF only"] + BPF_INS_JNE = 56, + #[doc = "< eBPF only"] + BPF_INS_JSGT = 57, + #[doc = "< eBPF only"] + BPF_INS_JSGE = 58, + #[doc = "< eBPF only"] + BPF_INS_CALL = 59, + #[doc = "< eBPF only"] + BPF_INS_EXIT = 60, + #[doc = "< eBPF only"] + BPF_INS_JLT = 61, + #[doc = "< eBPF only"] + BPF_INS_JLE = 62, + #[doc = "< eBPF only"] + BPF_INS_JSLT = 63, + #[doc = "< eBPF only"] + BPF_INS_JSLE = 64, + BPF_INS_RET = 65, + BPF_INS_TAX = 66, + BPF_INS_TXA = 67, + BPF_INS_ENDING = 68, +} +pub mod bpf_insn_group { + #[doc = " Group of BPF instructions"] + pub type Type = libc::c_uint; + #[doc = "< = CS_GRP_INVALID"] + pub const BPF_GRP_INVALID: Type = 0; + pub const BPF_GRP_LOAD: Type = 1; + pub const BPF_GRP_STORE: Type = 2; + pub const BPF_GRP_ALU: Type = 3; + pub const BPF_GRP_JUMP: Type = 4; + #[doc = "< eBPF only"] + pub const BPF_GRP_CALL: Type = 5; + pub const BPF_GRP_RETURN: Type = 6; + #[doc = "< cBPF only"] + pub const BPF_GRP_MISC: Type = 7; + pub const BPF_GRP_ENDING: Type = 8; +} #[doc = " NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON"] #[doc = " Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))"] #[doc = " by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c"] @@ -15691,7 +15797,7 @@ impl Clone for cs_detail { } impl ::core::fmt::Debug for cs_detail { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_detail {{ regs_read: {:?}, regs_read_count: {:?}, regs_write: {:?}, regs_write_count: {:?}, groups: {:?}, groups_count: {:?}, __bindgen_anon_1: {:?} }}" , self . regs_read , self . regs_read_count , self . regs_write , self . regs_write_count , self . groups , self . groups_count , self . __bindgen_anon_1) + write ! (f , "cs_detail {{ regs_read: {:?}, regs_write: {:?}, groups: {:?}, __bindgen_anon_1: {:?} }}" , self . regs_read , self . regs_write , self . groups , self . __bindgen_anon_1) } } #[doc = " Detail information of disassembled instruction"] @@ -15730,7 +15836,11 @@ pub struct cs_insn { } impl ::core::fmt::Debug for cs_insn { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write ! (f , "cs_insn {{ id: {:?}, address: {:?}, size: {:?}, bytes: {:?}, mnemonic: [...], op_str: [...], detail: {:?} }}" , self . id , self . address , self . size , self . bytes , self . detail) + write!( + f, + "cs_insn {{ id: {:?}, bytes: {:?}, mnemonic: [...], op_str: [...], detail: {:?} }}", + self.id, self.bytes, self.detail + ) } } pub mod cs_err { diff --git a/capstone-sys/pre_generated/capstone_archs_impl.rs b/capstone-sys/pre_generated/capstone_archs_impl.rs index 294e6c3..8bca33f 100644 --- a/capstone-sys/pre_generated/capstone_archs_impl.rs +++ b/capstone-sys/pre_generated/capstone_archs_impl.rs @@ -9396,3 +9396,79 @@ impl From for xcore_insn { } } } +impl From for bpf_insn { + fn from(id: u32) -> Self { + match id { + 0 => bpf_insn::BPF_INS_INVALID, + 1 => bpf_insn::BPF_INS_ADD, + 2 => bpf_insn::BPF_INS_SUB, + 3 => bpf_insn::BPF_INS_MUL, + 4 => bpf_insn::BPF_INS_DIV, + 5 => bpf_insn::BPF_INS_OR, + 6 => bpf_insn::BPF_INS_AND, + 7 => bpf_insn::BPF_INS_LSH, + 8 => bpf_insn::BPF_INS_RSH, + 9 => bpf_insn::BPF_INS_NEG, + 10 => bpf_insn::BPF_INS_MOD, + 11 => bpf_insn::BPF_INS_XOR, + 12 => bpf_insn::BPF_INS_MOV, + 13 => bpf_insn::BPF_INS_ARSH, + 14 => bpf_insn::BPF_INS_ADD64, + 15 => bpf_insn::BPF_INS_SUB64, + 16 => bpf_insn::BPF_INS_MUL64, + 17 => bpf_insn::BPF_INS_DIV64, + 18 => bpf_insn::BPF_INS_OR64, + 19 => bpf_insn::BPF_INS_AND64, + 20 => bpf_insn::BPF_INS_LSH64, + 21 => bpf_insn::BPF_INS_RSH64, + 22 => bpf_insn::BPF_INS_NEG64, + 23 => bpf_insn::BPF_INS_MOD64, + 24 => bpf_insn::BPF_INS_XOR64, + 25 => bpf_insn::BPF_INS_MOV64, + 26 => bpf_insn::BPF_INS_ARSH64, + 27 => bpf_insn::BPF_INS_LE16, + 28 => bpf_insn::BPF_INS_LE32, + 29 => bpf_insn::BPF_INS_LE64, + 30 => bpf_insn::BPF_INS_BE16, + 31 => bpf_insn::BPF_INS_BE32, + 32 => bpf_insn::BPF_INS_BE64, + 33 => bpf_insn::BPF_INS_LDW, + 34 => bpf_insn::BPF_INS_LDH, + 35 => bpf_insn::BPF_INS_LDB, + 36 => bpf_insn::BPF_INS_LDDW, + 37 => bpf_insn::BPF_INS_LDXW, + 38 => bpf_insn::BPF_INS_LDXH, + 39 => bpf_insn::BPF_INS_LDXB, + 40 => bpf_insn::BPF_INS_LDXDW, + 41 => bpf_insn::BPF_INS_STW, + 42 => bpf_insn::BPF_INS_STH, + 43 => bpf_insn::BPF_INS_STB, + 44 => bpf_insn::BPF_INS_STDW, + 45 => bpf_insn::BPF_INS_STXW, + 46 => bpf_insn::BPF_INS_STXH, + 47 => bpf_insn::BPF_INS_STXB, + 48 => bpf_insn::BPF_INS_STXDW, + 49 => bpf_insn::BPF_INS_XADDW, + 50 => bpf_insn::BPF_INS_XADDDW, + 51 => bpf_insn::BPF_INS_JMP, + 52 => bpf_insn::BPF_INS_JEQ, + 53 => bpf_insn::BPF_INS_JGT, + 54 => bpf_insn::BPF_INS_JGE, + 55 => bpf_insn::BPF_INS_JSET, + 56 => bpf_insn::BPF_INS_JNE, + 57 => bpf_insn::BPF_INS_JSGT, + 58 => bpf_insn::BPF_INS_JSGE, + 59 => bpf_insn::BPF_INS_CALL, + 60 => bpf_insn::BPF_INS_EXIT, + 61 => bpf_insn::BPF_INS_JLT, + 62 => bpf_insn::BPF_INS_JLE, + 63 => bpf_insn::BPF_INS_JSLT, + 64 => bpf_insn::BPF_INS_JSLE, + 65 => bpf_insn::BPF_INS_RET, + 66 => bpf_insn::BPF_INS_TAX, + 67 => bpf_insn::BPF_INS_TXA, + 68 => bpf_insn::BPF_INS_ENDING, + _ => bpf_insn::BPF_INS_INVALID, + } + } +}