Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for BPF arch #144

Merged
merged 4 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions capstone-rs/src/arch/bpf.rs
Original file line number Diff line number Diff line change
@@ -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;
);
17 changes: 17 additions & 0 deletions capstone-rs/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,16 @@ macro_rules! arch_info_base {
( syntax: )
( both_endian: false )
]
[
( bpf, BPF )
( mode:
Cbpf,
Ebpf,
)
( extra_modes: )
( syntax: )
( both_endian: true )
]
);
};
}
Expand Down Expand Up @@ -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
tmfink marked this conversation as resolved.
Show resolved Hide resolved
=> arch_name = bpf,
]
);
};
}
Expand Down
6 changes: 6 additions & 0 deletions capstone-rs/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down Expand Up @@ -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;
);
Expand Down
1 change: 1 addition & 0 deletions capstone-rs/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ impl<'a> InsnDetail<'a> {
[TMS320C64X, Tms320c64xDetail, Tms320c64xInsnDetail, tms320c64x]
[X86, X86Detail, X86InsnDetail, x86]
[XCORE, XcoreDetail, XcoreInsnDetail, xcore]
[BPF, BpfDetail, BpfInsnDetail, bpf]
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion capstone-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
3 changes: 2 additions & 1 deletion capstone-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -282,7 +283,7 @@ fn write_bindgen_bindings(
bindings
.write_to_file(&out_bindings_path)
.expect("Unable to write bindings");

// Parse bindings and impl fn to cast u32 to <arch>_insn, write output to file
let bindings_impl_str = impl_insid_to_insenum(&bindings.to_string());
let mut bindings_impl = File::create(&out_impl_path).expect("Unable to open file");
Expand Down
4 changes: 4 additions & 0 deletions capstone-sys/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Loading