@@ -17,6 +17,17 @@ use super::*;
1717
1818const X86_CODE : & [ u8 ] = b"\x55 \x48 \x8b \x05 \xb8 \x13 \x00 \x00 " ;
1919const ARM_CODE : & [ u8 ] = b"\x55 \x48 \x8b \x05 \xb8 \x13 \x00 \x00 " ;
20+ const CBPF_CODE : & [ u8 ] = b"\x94 \x09 \x00 \x00 \x37 \x13 \x03 \x00 \
21+ \x87 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
22+ \x07 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
23+ \x16 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
24+ \x80 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ";
25+ const EBPF_CODE : & [ u8 ] = b"\x97 \x09 \x00 \x00 \x37 \x13 \x03 \x00 \
26+ \xdc \x02 \x00 \x00 \x20 \x00 \x00 \x00 \
27+ \x30 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \
28+ \xdb \x3a \x00 \x01 \x00 \x00 \x00 \x00 \
29+ \x84 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \
30+ \x6d \x33 \x17 \x02 \x00 \x00 \x00 \x00 ";
2031
2132// Aliases for group types
2233const JUMP : cs_group_type:: Type = cs_group_type:: CS_GRP_JUMP ;
@@ -3244,3 +3255,185 @@ fn test_owned_insn() {
32443255 assert_eq ! ( format!( "{:?}" , insn) , format!( "{:?}" , owned) ) ;
32453256 }
32463257}
3258+
3259+ /// Print register names
3260+ fn reg_names ( cs : & Capstone , regs : & [ RegId ] ) -> String {
3261+ let names: Vec < String > = regs. iter ( ) . map ( |& x| cs. reg_name ( x) . unwrap ( ) ) . collect ( ) ;
3262+ names. join ( ", " )
3263+ }
3264+
3265+ /// Print instruction group names
3266+ fn group_names ( cs : & Capstone , regs : & [ InsnGroupId ] ) -> String {
3267+ let names: Vec < String > = regs. iter ( ) . map ( |& x| cs. group_name ( x) . unwrap ( ) ) . collect ( ) ;
3268+ names. join ( ", " )
3269+ }
3270+
3271+ #[ test]
3272+ fn test_cbpf ( ) {
3273+ let cs = Capstone :: new ( )
3274+ . bpf ( )
3275+ . mode ( bpf:: ArchMode :: Cbpf )
3276+ . endian ( Endian :: Little )
3277+ . detail ( true )
3278+ . build ( )
3279+ . unwrap ( ) ;
3280+ let insns = cs. disasm_all ( CBPF_CODE , 0x1000 ) ;
3281+ match insns {
3282+ Ok ( ins) => {
3283+ for i in ins. as_ref ( ) {
3284+ println ! ( ) ;
3285+ eprintln ! ( "{}" , i) ;
3286+
3287+ let detail: InsnDetail = cs. insn_detail ( & i) . expect ( "Failed to get insn detail" ) ;
3288+ let arch_detail: ArchDetail = detail. arch_detail ( ) ;
3289+ let ops = arch_detail. operands ( ) ;
3290+
3291+ let output: & [ ( & str , String ) ] = & [
3292+ ( "insn id:" , format ! ( "{:?}" , i. id( ) . 0 ) ) ,
3293+ ( "bytes:" , format ! ( "{:?}" , i. bytes( ) ) ) ,
3294+ ( "read regs:" , reg_names ( & cs, detail. regs_read ( ) ) ) ,
3295+ ( "write regs:" , reg_names ( & cs, detail. regs_write ( ) ) ) ,
3296+ ( "insn groups:" , group_names ( & cs, detail. groups ( ) ) ) ,
3297+ ] ;
3298+
3299+ for & ( ref name, ref message) in output. iter ( ) {
3300+ eprintln ! ( "{:4}{:12} {}" , "" , name, message) ;
3301+ }
3302+
3303+ println ! ( "{:4}operands: {}" , "" , ops. len( ) ) ;
3304+ for op in ops {
3305+ eprintln ! ( "{:8}{:?}" , "" , op) ;
3306+ }
3307+ }
3308+ }
3309+
3310+ Err ( e) => {
3311+ eprintln ! ( "{:?}" , e) ;
3312+ assert ! ( false ) ;
3313+ }
3314+ }
3315+ }
3316+
3317+ #[ test]
3318+ fn test_ebpf ( ) {
3319+ let cs = Capstone :: new ( )
3320+ . bpf ( )
3321+ . mode ( bpf:: ArchMode :: Ebpf )
3322+ . endian ( Endian :: Little )
3323+ . detail ( true )
3324+ . build ( )
3325+ . unwrap ( ) ;
3326+ let insns = cs. disasm_all ( EBPF_CODE , 0x1000 ) ;
3327+ match insns {
3328+ Ok ( ins) => {
3329+ for i in ins. as_ref ( ) {
3330+ println ! ( ) ;
3331+ eprintln ! ( "{}" , i) ;
3332+
3333+ let detail: InsnDetail = cs. insn_detail ( & i) . expect ( "Failed to get insn detail" ) ;
3334+ let arch_detail: ArchDetail = detail. arch_detail ( ) ;
3335+ let ops = arch_detail. operands ( ) ;
3336+
3337+ let output: & [ ( & str , String ) ] = & [
3338+ ( "insn id:" , format ! ( "{:?}" , i. id( ) . 0 ) ) ,
3339+ ( "bytes:" , format ! ( "{:?}" , i. bytes( ) ) ) ,
3340+ ( "read regs:" , reg_names ( & cs, detail. regs_read ( ) ) ) ,
3341+ ( "write regs:" , reg_names ( & cs, detail. regs_write ( ) ) ) ,
3342+ ( "insn groups:" , group_names ( & cs, detail. groups ( ) ) ) ,
3343+ ] ;
3344+
3345+ for & ( ref name, ref message) in output. iter ( ) {
3346+ eprintln ! ( "{:4}{:12} {}" , "" , name, message) ;
3347+ }
3348+
3349+ println ! ( "{:4}operands: {}" , "" , ops. len( ) ) ;
3350+ for op in ops {
3351+ eprintln ! ( "{:8}{:?}" , "" , op) ;
3352+ }
3353+ }
3354+ }
3355+
3356+ Err ( e) => {
3357+ eprintln ! ( "{:?}" , e) ;
3358+ assert ! ( false ) ;
3359+ }
3360+ }
3361+ }
3362+
3363+ #[ test]
3364+ fn test_arch_bpf_detail ( ) {
3365+ use crate :: arch:: bpf:: BpfOperand :: * ;
3366+ use crate :: arch:: bpf:: BpfReg :: * ;
3367+ use crate :: arch:: bpf:: * ;
3368+ use capstone_sys:: * ;
3369+
3370+ test_arch_mode_endian_insns_detail (
3371+ & mut Capstone :: new ( )
3372+ . bpf ( )
3373+ . mode ( bpf:: ArchMode :: Ebpf )
3374+ . endian ( Endian :: Little )
3375+ . detail ( true )
3376+ . build ( )
3377+ . unwrap ( ) ,
3378+ Arch :: BPF ,
3379+ Mode :: Ebpf ,
3380+ None ,
3381+ & [ ] ,
3382+ & [
3383+ // r1 = 0x1
3384+ DII :: new (
3385+ "mov64" ,
3386+ b"\xb7 \x01 \x00 \x00 \x01 \x00 \x00 \x00 " ,
3387+ & [ Reg ( RegId ( BPF_REG_R1 as RegIdInt ) ) , Imm ( 1 ) ] ,
3388+ ) ,
3389+ // r0 = *(u32 *)(r10 - 0xc)
3390+ DII :: new (
3391+ "ldxw" ,
3392+ b"\x61 \xa0 \xf4 \xff \x00 \x00 \x00 \x00 " ,
3393+ & [
3394+ Reg ( RegId ( BPF_REG_R0 as RegIdInt ) ) ,
3395+ Mem ( BpfOpMem ( bpf_op_mem {
3396+ base : BPF_REG_R10 ,
3397+ disp : 0xfff4 ,
3398+ } ) ) ,
3399+ ] ,
3400+ ) ,
3401+ // *(u32 *)(r10 - 0xc) = r1
3402+ DII :: new (
3403+ "stxw" ,
3404+ b"\x63 \x1a \xf4 \xff \x00 \x00 \x00 \x00 " ,
3405+ & [
3406+ Mem ( BpfOpMem ( bpf_op_mem {
3407+ base : BPF_REG_R10 ,
3408+ disp : 0xfff4 ,
3409+ } ) ) ,
3410+ Reg ( RegId ( BPF_REG_R1 as RegIdInt ) ) ,
3411+ ] ,
3412+ ) ,
3413+ // exit
3414+ DII :: new ( "exit" , b"\x95 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " , & [ ] ) ,
3415+ ] ,
3416+ ) ;
3417+
3418+ test_arch_mode_endian_insns_detail (
3419+ & mut Capstone :: new ( )
3420+ . bpf ( )
3421+ . mode ( bpf:: ArchMode :: Cbpf )
3422+ . endian ( Endian :: Little )
3423+ . detail ( true )
3424+ . build ( )
3425+ . unwrap ( ) ,
3426+ Arch :: BPF ,
3427+ Mode :: Cbpf ,
3428+ None ,
3429+ & [ ] ,
3430+ & [
3431+ DII :: new ( "txa" , b"\x87 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " , & [ ] ) ,
3432+ DII :: new (
3433+ "ret" ,
3434+ b"\x16 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ,
3435+ & [ Reg ( RegId ( BPF_REG_A as RegIdInt ) ) ] ,
3436+ ) ,
3437+ ] ,
3438+ ) ;
3439+ }
0 commit comments