crabstone 3.0.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGES.md +45 -42
- data/README.md +16 -33
- data/lib/crabstone.rb +5 -557
- data/lib/crabstone/arch.rb +37 -0
- data/lib/{arch → crabstone/arch/3}/arm.rb +28 -49
- data/lib/crabstone/arch/3/arm64.rb +124 -0
- data/lib/{arch → crabstone/arch/3}/arm64_const.rb +45 -86
- data/lib/{arch → crabstone/arch/3}/arm_const.rb +19 -47
- data/lib/crabstone/arch/3/mips.rb +57 -0
- data/lib/{arch → crabstone/arch/3}/mips_const.rb +18 -38
- data/lib/crabstone/arch/3/ppc.rb +73 -0
- data/lib/{arch → crabstone/arch/3}/ppc_const.rb +27 -43
- data/lib/crabstone/arch/3/sparc.rb +60 -0
- data/lib/{arch → crabstone/arch/3}/sparc_const.rb +49 -67
- data/lib/crabstone/arch/3/sysz.rb +67 -0
- data/lib/{arch → crabstone/arch/3}/sysz_const.rb +11 -25
- data/lib/crabstone/arch/3/x86.rb +82 -0
- data/lib/{arch → crabstone/arch/3}/x86_const.rb +15 -36
- data/lib/crabstone/arch/3/xcore.rb +59 -0
- data/lib/{arch → crabstone/arch/3}/xcore_const.rb +10 -22
- data/lib/crabstone/arch/4/arm.rb +110 -0
- data/lib/crabstone/arch/4/arm64.rb +125 -0
- data/lib/crabstone/arch/4/arm64_const.rb +1016 -0
- data/lib/crabstone/arch/4/arm_const.rb +785 -0
- data/lib/crabstone/arch/4/evm.rb +20 -0
- data/lib/crabstone/arch/4/evm_const.rb +161 -0
- data/lib/crabstone/arch/4/m680x.rb +106 -0
- data/lib/crabstone/arch/4/m680x_const.rb +426 -0
- data/lib/crabstone/arch/4/m68k.rb +129 -0
- data/lib/crabstone/arch/4/m68k_const.rb +496 -0
- data/lib/crabstone/arch/4/mips.rb +57 -0
- data/lib/crabstone/arch/4/mips_const.rb +869 -0
- data/lib/crabstone/arch/4/ppc.rb +73 -0
- data/lib/crabstone/arch/4/ppc_const.rb +1375 -0
- data/lib/crabstone/arch/4/sparc.rb +60 -0
- data/lib/crabstone/arch/4/sparc_const.rb +439 -0
- data/lib/crabstone/arch/4/sysz.rb +67 -0
- data/lib/crabstone/arch/4/sysz_const.rb +763 -0
- data/lib/crabstone/arch/4/tms320c64x.rb +87 -0
- data/lib/crabstone/arch/4/tms320c64x_const.rb +287 -0
- data/lib/crabstone/arch/4/x86.rb +91 -0
- data/lib/crabstone/arch/4/x86_const.rb +1972 -0
- data/lib/crabstone/arch/4/xcore.rb +59 -0
- data/lib/crabstone/arch/4/xcore_const.rb +171 -0
- data/lib/crabstone/arch/extension.rb +27 -0
- data/lib/crabstone/arch/register.rb +36 -0
- data/lib/crabstone/binding.rb +60 -0
- data/lib/crabstone/binding/3/detail.rb +36 -0
- data/lib/crabstone/binding/3/instruction.rb +23 -0
- data/lib/crabstone/binding/4/detail.rb +40 -0
- data/lib/crabstone/binding/4/instruction.rb +23 -0
- data/lib/crabstone/binding/structs.rb +32 -0
- data/lib/crabstone/constants.rb +110 -0
- data/lib/crabstone/cs_version.rb +49 -0
- data/lib/crabstone/disassembler.rb +153 -0
- data/lib/crabstone/error.rb +60 -0
- data/lib/crabstone/instruction.rb +183 -0
- data/lib/crabstone/version.rb +5 -0
- metadata +128 -324
- data/MANIFEST +0 -312
- data/Rakefile +0 -27
- data/bin/genconst +0 -66
- data/bin/genreg +0 -99
- data/crabstone.gemspec +0 -27
- data/examples/hello_world.rb +0 -43
- data/lib/arch/arm64.rb +0 -167
- data/lib/arch/arm64_registers.rb +0 -295
- data/lib/arch/arm_registers.rb +0 -149
- data/lib/arch/mips.rb +0 -78
- data/lib/arch/mips_registers.rb +0 -208
- data/lib/arch/ppc.rb +0 -90
- data/lib/arch/ppc_registers.rb +0 -209
- data/lib/arch/sparc.rb +0 -79
- data/lib/arch/sparc_registers.rb +0 -121
- data/lib/arch/systemz.rb +0 -79
- data/lib/arch/sysz_registers.rb +0 -66
- data/lib/arch/x86.rb +0 -107
- data/lib/arch/x86_registers.rb +0 -265
- data/lib/arch/xcore.rb +0 -78
- data/lib/arch/xcore_registers.rb +0 -57
- data/test/MC/AArch64/basic-a64-instructions.s.cs +0 -2014
- data/test/MC/AArch64/gicv3-regs.s.cs +0 -111
- data/test/MC/AArch64/neon-2velem.s.cs +0 -113
- data/test/MC/AArch64/neon-3vdiff.s.cs +0 -143
- data/test/MC/AArch64/neon-aba-abd.s.cs +0 -28
- data/test/MC/AArch64/neon-across.s.cs +0 -40
- data/test/MC/AArch64/neon-add-pairwise.s.cs +0 -11
- data/test/MC/AArch64/neon-add-sub-instructions.s.cs +0 -21
- data/test/MC/AArch64/neon-bitwise-instructions.s.cs +0 -17
- data/test/MC/AArch64/neon-compare-instructions.s.cs +0 -136
- data/test/MC/AArch64/neon-crypto.s.cs +0 -15
- data/test/MC/AArch64/neon-extract.s.cs +0 -3
- data/test/MC/AArch64/neon-facge-facgt.s.cs +0 -13
- data/test/MC/AArch64/neon-frsqrt-frecp.s.cs +0 -7
- data/test/MC/AArch64/neon-halving-add-sub.s.cs +0 -25
- data/test/MC/AArch64/neon-max-min-pairwise.s.cs +0 -37
- data/test/MC/AArch64/neon-max-min.s.cs +0 -37
- data/test/MC/AArch64/neon-mla-mls-instructions.s.cs +0 -19
- data/test/MC/AArch64/neon-mov.s.cs +0 -74
- data/test/MC/AArch64/neon-mul-div-instructions.s.cs +0 -24
- data/test/MC/AArch64/neon-perm.s.cs +0 -43
- data/test/MC/AArch64/neon-rounding-halving-add.s.cs +0 -13
- data/test/MC/AArch64/neon-rounding-shift.s.cs +0 -15
- data/test/MC/AArch64/neon-saturating-add-sub.s.cs +0 -29
- data/test/MC/AArch64/neon-saturating-rounding-shift.s.cs +0 -15
- data/test/MC/AArch64/neon-saturating-shift.s.cs +0 -15
- data/test/MC/AArch64/neon-scalar-abs.s.cs +0 -8
- data/test/MC/AArch64/neon-scalar-add-sub.s.cs +0 -3
- data/test/MC/AArch64/neon-scalar-by-elem-mla.s.cs +0 -13
- data/test/MC/AArch64/neon-scalar-by-elem-mul.s.cs +0 -13
- data/test/MC/AArch64/neon-scalar-by-elem-saturating-mla.s.cs +0 -15
- data/test/MC/AArch64/neon-scalar-by-elem-saturating-mul.s.cs +0 -18
- data/test/MC/AArch64/neon-scalar-compare.s.cs +0 -12
- data/test/MC/AArch64/neon-scalar-cvt.s.cs +0 -34
- data/test/MC/AArch64/neon-scalar-dup.s.cs +0 -23
- data/test/MC/AArch64/neon-scalar-extract-narrow.s.cs +0 -10
- data/test/MC/AArch64/neon-scalar-fp-compare.s.cs +0 -21
- data/test/MC/AArch64/neon-scalar-mul.s.cs +0 -13
- data/test/MC/AArch64/neon-scalar-neg.s.cs +0 -6
- data/test/MC/AArch64/neon-scalar-recip.s.cs +0 -11
- data/test/MC/AArch64/neon-scalar-reduce-pairwise.s.cs +0 -3
- data/test/MC/AArch64/neon-scalar-rounding-shift.s.cs +0 -3
- data/test/MC/AArch64/neon-scalar-saturating-add-sub.s.cs +0 -25
- data/test/MC/AArch64/neon-scalar-saturating-rounding-shift.s.cs +0 -9
- data/test/MC/AArch64/neon-scalar-saturating-shift.s.cs +0 -9
- data/test/MC/AArch64/neon-scalar-shift-imm.s.cs +0 -42
- data/test/MC/AArch64/neon-scalar-shift.s.cs +0 -3
- data/test/MC/AArch64/neon-shift-left-long.s.cs +0 -13
- data/test/MC/AArch64/neon-shift.s.cs +0 -22
- data/test/MC/AArch64/neon-simd-copy.s.cs +0 -42
- data/test/MC/AArch64/neon-simd-ldst-multi-elem.s.cs +0 -197
- data/test/MC/AArch64/neon-simd-ldst-one-elem.s.cs +0 -129
- data/test/MC/AArch64/neon-simd-misc.s.cs +0 -213
- data/test/MC/AArch64/neon-simd-post-ldst-multi-elem.s.cs +0 -107
- data/test/MC/AArch64/neon-simd-shift.s.cs +0 -151
- data/test/MC/AArch64/neon-tbl.s.cs +0 -21
- data/test/MC/AArch64/trace-regs.s.cs +0 -383
- data/test/MC/ARM/arm-aliases.s.cs +0 -7
- data/test/MC/ARM/arm-arithmetic-aliases.s.cs +0 -50
- data/test/MC/ARM/arm-it-block.s.cs +0 -2
- data/test/MC/ARM/arm-memory-instructions.s.cs +0 -138
- data/test/MC/ARM/arm-shift-encoding.s.cs +0 -50
- data/test/MC/ARM/arm-thumb-trustzone.s.cs +0 -3
- data/test/MC/ARM/arm-trustzone.s.cs +0 -3
- data/test/MC/ARM/arm_addrmode2.s.cs +0 -15
- data/test/MC/ARM/arm_addrmode3.s.cs +0 -9
- data/test/MC/ARM/arm_instructions.s.cs +0 -25
- data/test/MC/ARM/basic-arm-instructions-v8.s.cs +0 -10
- data/test/MC/ARM/basic-arm-instructions.s.cs +0 -997
- data/test/MC/ARM/basic-thumb-instructions.s.cs +0 -130
- data/test/MC/ARM/basic-thumb2-instructions-v8.s.cs +0 -1
- data/test/MC/ARM/basic-thumb2-instructions.s.cs +0 -1242
- data/test/MC/ARM/crc32-thumb.s.cs +0 -7
- data/test/MC/ARM/crc32.s.cs +0 -7
- data/test/MC/ARM/dot-req.s.cs +0 -3
- data/test/MC/ARM/fp-armv8.s.cs +0 -52
- data/test/MC/ARM/idiv-thumb.s.cs +0 -3
- data/test/MC/ARM/idiv.s.cs +0 -3
- data/test/MC/ARM/load-store-acquire-release-v8-thumb.s.cs +0 -15
- data/test/MC/ARM/load-store-acquire-release-v8.s.cs +0 -15
- data/test/MC/ARM/mode-switch.s.cs +0 -7
- data/test/MC/ARM/neon-abs-encoding.s.cs +0 -15
- data/test/MC/ARM/neon-absdiff-encoding.s.cs +0 -39
- data/test/MC/ARM/neon-add-encoding.s.cs +0 -119
- data/test/MC/ARM/neon-bitcount-encoding.s.cs +0 -15
- data/test/MC/ARM/neon-bitwise-encoding.s.cs +0 -126
- data/test/MC/ARM/neon-cmp-encoding.s.cs +0 -88
- data/test/MC/ARM/neon-convert-encoding.s.cs +0 -27
- data/test/MC/ARM/neon-crypto.s.cs +0 -16
- data/test/MC/ARM/neon-dup-encoding.s.cs +0 -13
- data/test/MC/ARM/neon-minmax-encoding.s.cs +0 -57
- data/test/MC/ARM/neon-mov-encoding.s.cs +0 -76
- data/test/MC/ARM/neon-mul-accum-encoding.s.cs +0 -39
- data/test/MC/ARM/neon-mul-encoding.s.cs +0 -72
- data/test/MC/ARM/neon-neg-encoding.s.cs +0 -15
- data/test/MC/ARM/neon-pairwise-encoding.s.cs +0 -47
- data/test/MC/ARM/neon-reciprocal-encoding.s.cs +0 -13
- data/test/MC/ARM/neon-reverse-encoding.s.cs +0 -13
- data/test/MC/ARM/neon-satshift-encoding.s.cs +0 -75
- data/test/MC/ARM/neon-shift-encoding.s.cs +0 -238
- data/test/MC/ARM/neon-shiftaccum-encoding.s.cs +0 -97
- data/test/MC/ARM/neon-shuffle-encoding.s.cs +0 -59
- data/test/MC/ARM/neon-sub-encoding.s.cs +0 -82
- data/test/MC/ARM/neon-table-encoding.s.cs +0 -9
- data/test/MC/ARM/neon-v8.s.cs +0 -38
- data/test/MC/ARM/neon-vld-encoding.s.cs +0 -213
- data/test/MC/ARM/neon-vst-encoding.s.cs +0 -120
- data/test/MC/ARM/neon-vswp.s.cs +0 -3
- data/test/MC/ARM/neont2-abs-encoding.s.cs +0 -15
- data/test/MC/ARM/neont2-absdiff-encoding.s.cs +0 -39
- data/test/MC/ARM/neont2-add-encoding.s.cs +0 -65
- data/test/MC/ARM/neont2-bitcount-encoding.s.cs +0 -15
- data/test/MC/ARM/neont2-bitwise-encoding.s.cs +0 -15
- data/test/MC/ARM/neont2-cmp-encoding.s.cs +0 -17
- data/test/MC/ARM/neont2-convert-encoding.s.cs +0 -19
- data/test/MC/ARM/neont2-dup-encoding.s.cs +0 -19
- data/test/MC/ARM/neont2-minmax-encoding.s.cs +0 -57
- data/test/MC/ARM/neont2-mov-encoding.s.cs +0 -58
- data/test/MC/ARM/neont2-mul-accum-encoding.s.cs +0 -41
- data/test/MC/ARM/neont2-mul-encoding.s.cs +0 -31
- data/test/MC/ARM/neont2-neg-encoding.s.cs +0 -15
- data/test/MC/ARM/neont2-pairwise-encoding.s.cs +0 -43
- data/test/MC/ARM/neont2-reciprocal-encoding.s.cs +0 -13
- data/test/MC/ARM/neont2-reverse-encoding.s.cs +0 -13
- data/test/MC/ARM/neont2-satshift-encoding.s.cs +0 -75
- data/test/MC/ARM/neont2-shift-encoding.s.cs +0 -80
- data/test/MC/ARM/neont2-shiftaccum-encoding.s.cs +0 -97
- data/test/MC/ARM/neont2-shuffle-encoding.s.cs +0 -23
- data/test/MC/ARM/neont2-sub-encoding.s.cs +0 -23
- data/test/MC/ARM/neont2-table-encoding.s.cs +0 -9
- data/test/MC/ARM/neont2-vld-encoding.s.cs +0 -51
- data/test/MC/ARM/neont2-vst-encoding.s.cs +0 -48
- data/test/MC/ARM/simple-fp-encoding.s.cs +0 -157
- data/test/MC/ARM/thumb-fp-armv8.s.cs +0 -51
- data/test/MC/ARM/thumb-hints.s.cs +0 -12
- data/test/MC/ARM/thumb-neon-crypto.s.cs +0 -16
- data/test/MC/ARM/thumb-neon-v8.s.cs +0 -38
- data/test/MC/ARM/thumb-shift-encoding.s.cs +0 -19
- data/test/MC/ARM/thumb.s.cs +0 -19
- data/test/MC/ARM/thumb2-b.w-encodingT4.s.cs +0 -2
- data/test/MC/ARM/thumb2-branches.s.cs +0 -85
- data/test/MC/ARM/thumb2-mclass.s.cs +0 -41
- data/test/MC/ARM/thumb2-narrow-dp.ll.cs +0 -379
- data/test/MC/ARM/thumb2-pldw.s.cs +0 -2
- data/test/MC/ARM/vfp4-thumb.s.cs +0 -13
- data/test/MC/ARM/vfp4.s.cs +0 -13
- data/test/MC/ARM/vpush-vpop-thumb.s.cs +0 -9
- data/test/MC/ARM/vpush-vpop.s.cs +0 -9
- data/test/MC/Mips/hilo-addressing.s.cs +0 -4
- data/test/MC/Mips/micromips-alu-instructions-EB.s.cs +0 -33
- data/test/MC/Mips/micromips-alu-instructions.s.cs +0 -33
- data/test/MC/Mips/micromips-branch-instructions-EB.s.cs +0 -11
- data/test/MC/Mips/micromips-branch-instructions.s.cs +0 -11
- data/test/MC/Mips/micromips-expansions.s.cs +0 -20
- data/test/MC/Mips/micromips-jump-instructions-EB.s.cs +0 -5
- data/test/MC/Mips/micromips-jump-instructions.s.cs +0 -6
- data/test/MC/Mips/micromips-loadstore-instructions-EB.s.cs +0 -9
- data/test/MC/Mips/micromips-loadstore-instructions.s.cs +0 -9
- data/test/MC/Mips/micromips-loadstore-unaligned-EB.s.cs +0 -5
- data/test/MC/Mips/micromips-loadstore-unaligned.s.cs +0 -5
- data/test/MC/Mips/micromips-movcond-instructions-EB.s.cs +0 -5
- data/test/MC/Mips/micromips-movcond-instructions.s.cs +0 -5
- data/test/MC/Mips/micromips-multiply-instructions-EB.s.cs +0 -5
- data/test/MC/Mips/micromips-multiply-instructions.s.cs +0 -5
- data/test/MC/Mips/micromips-shift-instructions-EB.s.cs +0 -9
- data/test/MC/Mips/micromips-shift-instructions.s.cs +0 -9
- data/test/MC/Mips/micromips-trap-instructions-EB.s.cs +0 -13
- data/test/MC/Mips/micromips-trap-instructions.s.cs +0 -13
- data/test/MC/Mips/mips-alu-instructions.s.cs +0 -53
- data/test/MC/Mips/mips-control-instructions-64.s.cs +0 -33
- data/test/MC/Mips/mips-control-instructions.s.cs +0 -33
- data/test/MC/Mips/mips-coprocessor-encodings.s.cs +0 -17
- data/test/MC/Mips/mips-dsp-instructions.s.cs +0 -43
- data/test/MC/Mips/mips-expansions.s.cs +0 -20
- data/test/MC/Mips/mips-fpu-instructions.s.cs +0 -93
- data/test/MC/Mips/mips-jump-instructions.s.cs +0 -1
- data/test/MC/Mips/mips-memory-instructions.s.cs +0 -17
- data/test/MC/Mips/mips-register-names.s.cs +0 -33
- data/test/MC/Mips/mips64-alu-instructions.s.cs +0 -47
- data/test/MC/Mips/mips64-instructions.s.cs +0 -3
- data/test/MC/Mips/mips64-register-names.s.cs +0 -33
- data/test/MC/Mips/mips_directives.s.cs +0 -12
- data/test/MC/Mips/nabi-regs.s.cs +0 -12
- data/test/MC/Mips/set-at-directive.s.cs +0 -6
- data/test/MC/Mips/test_2r.s.cs +0 -16
- data/test/MC/Mips/test_2rf.s.cs +0 -33
- data/test/MC/Mips/test_3r.s.cs +0 -243
- data/test/MC/Mips/test_3rf.s.cs +0 -83
- data/test/MC/Mips/test_bit.s.cs +0 -49
- data/test/MC/Mips/test_cbranch.s.cs +0 -11
- data/test/MC/Mips/test_ctrlregs.s.cs +0 -33
- data/test/MC/Mips/test_elm.s.cs +0 -16
- data/test/MC/Mips/test_elm_insert.s.cs +0 -4
- data/test/MC/Mips/test_elm_insve.s.cs +0 -5
- data/test/MC/Mips/test_i10.s.cs +0 -5
- data/test/MC/Mips/test_i5.s.cs +0 -45
- data/test/MC/Mips/test_i8.s.cs +0 -11
- data/test/MC/Mips/test_lsa.s.cs +0 -5
- data/test/MC/Mips/test_mi10.s.cs +0 -24
- data/test/MC/Mips/test_vec.s.cs +0 -8
- data/test/MC/PowerPC/ppc64-encoding-bookII.s.cs +0 -25
- data/test/MC/PowerPC/ppc64-encoding-bookIII.s.cs +0 -35
- data/test/MC/PowerPC/ppc64-encoding-ext.s.cs +0 -535
- data/test/MC/PowerPC/ppc64-encoding-fp.s.cs +0 -110
- data/test/MC/PowerPC/ppc64-encoding-vmx.s.cs +0 -170
- data/test/MC/PowerPC/ppc64-encoding.s.cs +0 -202
- data/test/MC/PowerPC/ppc64-operands.s.cs +0 -32
- data/test/MC/README +0 -6
- data/test/MC/Sparc/sparc-alu-instructions.s.cs +0 -47
- data/test/MC/Sparc/sparc-atomic-instructions.s.cs +0 -7
- data/test/MC/Sparc/sparc-ctrl-instructions.s.cs +0 -11
- data/test/MC/Sparc/sparc-fp-instructions.s.cs +0 -59
- data/test/MC/Sparc/sparc-mem-instructions.s.cs +0 -25
- data/test/MC/Sparc/sparc-vis.s.cs +0 -2
- data/test/MC/Sparc/sparc64-alu-instructions.s.cs +0 -13
- data/test/MC/Sparc/sparc64-ctrl-instructions.s.cs +0 -102
- data/test/MC/Sparc/sparcv8-instructions.s.cs +0 -7
- data/test/MC/Sparc/sparcv9-instructions.s.cs +0 -1
- data/test/MC/SystemZ/insn-good-z196.s.cs +0 -589
- data/test/MC/SystemZ/insn-good.s.cs +0 -2265
- data/test/MC/SystemZ/regs-good.s.cs +0 -45
- data/test/MC/X86/3DNow.s.cs +0 -29
- data/test/MC/X86/address-size.s.cs +0 -5
- data/test/MC/X86/avx512-encodings.s.cs +0 -12
- data/test/MC/X86/intel-syntax-encoding.s.cs +0 -30
- data/test/MC/X86/x86-32-avx.s.cs +0 -833
- data/test/MC/X86/x86-32-fma3.s.cs +0 -169
- data/test/MC/X86/x86-32-ms-inline-asm.s.cs +0 -27
- data/test/MC/X86/x86_64-avx-clmul-encoding.s.cs +0 -11
- data/test/MC/X86/x86_64-avx-encoding.s.cs +0 -1058
- data/test/MC/X86/x86_64-bmi-encoding.s.cs +0 -51
- data/test/MC/X86/x86_64-encoding.s.cs +0 -59
- data/test/MC/X86/x86_64-fma3-encoding.s.cs +0 -169
- data/test/MC/X86/x86_64-fma4-encoding.s.cs +0 -98
- data/test/MC/X86/x86_64-hle-encoding.s.cs +0 -3
- data/test/MC/X86/x86_64-imm-widths.s.cs +0 -27
- data/test/MC/X86/x86_64-rand-encoding.s.cs +0 -13
- data/test/MC/X86/x86_64-rtm-encoding.s.cs +0 -4
- data/test/MC/X86/x86_64-sse4a.s.cs +0 -1
- data/test/MC/X86/x86_64-tbm-encoding.s.cs +0 -40
- data/test/MC/X86/x86_64-xop-encoding.s.cs +0 -152
- data/test/README +0 -6
- data/test/test.rb +0 -205
- data/test/test.rb.SPEC +0 -235
- data/test/test_arm.rb +0 -202
- data/test/test_arm.rb.SPEC +0 -275
- data/test/test_arm64.rb +0 -150
- data/test/test_arm64.rb.SPEC +0 -116
- data/test/test_detail.rb +0 -228
- data/test/test_detail.rb.SPEC +0 -322
- data/test/test_exhaustive.rb +0 -80
- data/test/test_mips.rb +0 -118
- data/test/test_mips.rb.SPEC +0 -91
- data/test/test_ppc.rb +0 -137
- data/test/test_ppc.rb.SPEC +0 -84
- data/test/test_sanity.rb +0 -83
- data/test/test_skipdata.rb +0 -111
- data/test/test_skipdata.rb.SPEC +0 -58
- data/test/test_sparc.rb +0 -113
- data/test/test_sparc.rb.SPEC +0 -116
- data/test/test_sysz.rb +0 -111
- data/test/test_sysz.rb.SPEC +0 -61
- data/test/test_x86.rb +0 -189
- data/test/test_x86.rb.SPEC +0 -579
- data/test/test_xcore.rb +0 -100
- data/test/test_xcore.rb.SPEC +0 -75
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# THIS FILE WAS AUTO-GENERATED -- DO NOT EDIT!
|
4
|
+
|
5
|
+
require 'ffi'
|
6
|
+
|
7
|
+
require_relative 'detail'
|
8
|
+
|
9
|
+
module Crabstone
|
10
|
+
module Binding
|
11
|
+
class Instruction < FFI::ManagedStruct
|
12
|
+
layout(
|
13
|
+
:id, :uint32,
|
14
|
+
:address, :uint64,
|
15
|
+
:size, :uint16,
|
16
|
+
:bytes, [:uint8, 16],
|
17
|
+
:mnemonic, [:char, 32],
|
18
|
+
:op_str, [:char, 160],
|
19
|
+
:detail, Detail.by_ref
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
require 'crabstone/cs_version'
|
6
|
+
Crabstone.version_require 'crabstone/binding/%v/instruction'
|
7
|
+
|
8
|
+
module Crabstone
|
9
|
+
module Binding
|
10
|
+
# This is because JRuby FFI on x64 Windows thinks size_t is 32 bit
|
11
|
+
typedef(FFI::Platform::ADDRESS_SIZE == 32 ? :ulong : :ulong_long, :size_t)
|
12
|
+
|
13
|
+
# If one day these definitions change, move them to <version>/ dir.
|
14
|
+
|
15
|
+
typedef :size_t, :csh
|
16
|
+
typedef :size_t, :cs_opt_value
|
17
|
+
typedef :uint, :cs_opt_type
|
18
|
+
typedef :uint, :cs_err
|
19
|
+
typedef :uint, :cs_arch
|
20
|
+
typedef :uint, :cs_mode
|
21
|
+
|
22
|
+
callback :skipdata_cb, %i[pointer size_t size_t pointer], :size_t
|
23
|
+
|
24
|
+
class SkipdataConfig < FFI::Struct
|
25
|
+
layout(
|
26
|
+
:mnemonic, :pointer,
|
27
|
+
:callback, :skipdata_cb,
|
28
|
+
:unused, :pointer
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# XXX: Auto-gerneate this file?
|
4
|
+
# Constants in this file might be added in a newer Capstone version,
|
5
|
+
# but I expect they are always backward compatible.
|
6
|
+
|
7
|
+
require 'crabstone/version'
|
8
|
+
|
9
|
+
module Crabstone
|
10
|
+
# API version
|
11
|
+
BINDING_MAJ = VERSION.split('.').first.to_i
|
12
|
+
|
13
|
+
# architectures
|
14
|
+
ARCH_ARM = 0
|
15
|
+
ARCH_ARM64 = 1
|
16
|
+
ARCH_MIPS = 2
|
17
|
+
ARCH_X86 = 3
|
18
|
+
ARCH_PPC = 4
|
19
|
+
ARCH_SPARC = 5
|
20
|
+
ARCH_SYSZ = 6
|
21
|
+
ARCH_XCORE = 7
|
22
|
+
ARCH_M68K = 8
|
23
|
+
ARCH_TMS320C64X = 9
|
24
|
+
ARCH_M680X = 10
|
25
|
+
ARCH_EVM = 11
|
26
|
+
ARCH_MAX = 12
|
27
|
+
ARCH_ALL = 0xFFFF
|
28
|
+
|
29
|
+
# disasm mode
|
30
|
+
MODE_LITTLE_ENDIAN = 0 # little-endian mode (default mode)
|
31
|
+
MODE_ARM = 0 # 32-bit ARM
|
32
|
+
MODE_16 = 1 << 1 # 16-bit mode (X86)
|
33
|
+
MODE_32 = 1 << 2 # 32-bit mode (X86)
|
34
|
+
MODE_64 = 1 << 3 # 64-bit mode (X86, PPC)
|
35
|
+
MODE_THUMB = 1 << 4 # ARM's Thumb mode, including Thumb-2
|
36
|
+
MODE_MCLASS = 1 << 5 # ARM's Cortex-M series
|
37
|
+
MODE_V8 = 1 << 6 # ARMv8 A32 encodings for ARM
|
38
|
+
MODE_MICRO = 1 << 4 # MicroMips mode (MIPS)
|
39
|
+
MODE_MIPS3 = 1 << 5 # Mips III ISA
|
40
|
+
MODE_MIPS32R6 = 1 << 6 # Mips32r6 ISA
|
41
|
+
MODE_MIPSGP64 = 1 << 7 # General Purpose Registers are 64-bit wide (MIPS)
|
42
|
+
MODE_MODE_MIPS2 = 1 << 7 # Mips II ISA
|
43
|
+
MODE_V9 = 1 << 4 # SparcV9 mode (Sparc)
|
44
|
+
MODE_QPX = 1 << 4 # Quad Processing eXtensions mode (PPC)
|
45
|
+
MODE_M68K_000 = 1 << 1 # M68K 68000 mode
|
46
|
+
MODE_M68K_010 = 1 << 2 # M68K 68010 mode
|
47
|
+
MODE_M68K_020 = 1 << 3 # M68K 68020 mode
|
48
|
+
MODE_M68K_030 = 1 << 4 # M68K 68030 mode
|
49
|
+
MODE_M68K_040 = 1 << 5 # M68K 68040 mode
|
50
|
+
MODE_M68K_060 = 1 << 6 # M68K 68060 mode
|
51
|
+
MODE_BIG_ENDIAN = 1 << 31 # big-endian mode
|
52
|
+
MODE_MIPS32 = MODE_32 # Mips32 ISA (Mips)
|
53
|
+
MODE_MIPS64 = MODE_64 # Mips64 ISA (Mips)
|
54
|
+
MODE_M680X_6301 = 1 << 1 # M680X HD6301/3 mode
|
55
|
+
MODE_M680X_6309 = 1 << 2 # M680X HD6309 mode
|
56
|
+
MODE_M680X_6800 = 1 << 3 # M680X M6800/2 mode
|
57
|
+
MODE_M680X_6801 = 1 << 4 # M680X M6801/3 mode
|
58
|
+
MODE_M680X_6805 = 1 << 5 # M680X M6805 mode
|
59
|
+
MODE_M680X_6808 = 1 << 6 # M680X M68HC08 mode
|
60
|
+
MODE_M680X_6809 = 1 << 7 # M680X M6809 mode
|
61
|
+
MODE_M680X_6811 = 1 << 8 # M680X M68HC11 mode
|
62
|
+
MODE_M680X_CPU12 = 1 << 9 # M680X CPU12 mode
|
63
|
+
MODE_M680X_HCS08 = 1 << 10 # M680X HCS08 mode
|
64
|
+
|
65
|
+
# Capstone option type
|
66
|
+
OPT_SYNTAX = 1 # Intel X86 asm syntax (ARCH_X86 arch)
|
67
|
+
OPT_DETAIL = 2 # Break down instruction structure into details
|
68
|
+
OPT_MODE = 3 # Change engine's mode at run-time
|
69
|
+
OPT_MEM = 4 # Change engine's mode at run-time
|
70
|
+
OPT_SKIPDATA = 5 # Skip data when disassembling
|
71
|
+
OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option
|
72
|
+
OPT_MNEMONIC = 7 # Customize instruction mnemonic
|
73
|
+
OPT_UNSIGNED = 8 # Print immediate in unsigned form
|
74
|
+
|
75
|
+
# Capstone option value
|
76
|
+
OPT_OFF = 0 # Turn OFF an option - default option of OPT_DETAIL
|
77
|
+
OPT_ON = 3 # Turn ON an option (OPT_DETAIL)
|
78
|
+
|
79
|
+
# Common instruction operand types - to be consistent across all architectures.
|
80
|
+
OP_INVALID = 0
|
81
|
+
OP_REG = 1
|
82
|
+
OP_IMM = 2
|
83
|
+
OP_MEM = 3
|
84
|
+
OP_FP = 4
|
85
|
+
|
86
|
+
# Common instruction groups - to be consistent across all architectures.
|
87
|
+
GRP_INVALID = 0 # uninitialized/invalid group.
|
88
|
+
GRP_JUMP = 1 # all jump instructions (conditional+direct+indirect jumps)
|
89
|
+
GRP_CALL = 2 # all call instructions
|
90
|
+
GRP_RET = 3 # all return instructions
|
91
|
+
GRP_INT = 4 # all interrupt instructions (int+syscall)
|
92
|
+
GRP_IRET = 5 # all interrupt return instructions
|
93
|
+
GRP_PRIVILEGE = 6 # all privileged instructions
|
94
|
+
|
95
|
+
# Access types for instruction operands.
|
96
|
+
AC_INVALID = 0 # Invalid/unitialized access type.
|
97
|
+
AC_READ = 1 << 0 # Operand that is read from.
|
98
|
+
AC_WRITE = 1 << 1 # Operand that is written to.
|
99
|
+
|
100
|
+
# Capstone syntax value
|
101
|
+
OPT_SYNTAX_DEFAULT = 0 # Default assembly syntax of all platforms (OPT_SYNTAX)
|
102
|
+
OPT_SYNTAX_INTEL = 1 # Intel X86 asm syntax - default syntax on X86 (OPT_SYNTAX, ARCH_X86)
|
103
|
+
OPT_SYNTAX_ATT = 2 # ATT asm syntax (OPT_SYNTAX, ARCH_X86)
|
104
|
+
OPT_SYNTAX_NOREGNAME = 3 # Asm syntax prints register name with only number - (OPT_SYNTAX, ARCH_PPC, ARCH_ARM)
|
105
|
+
OPT_SYNTAX_MASM = 4 # MASM syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
|
106
|
+
|
107
|
+
# query id for cs_support()
|
108
|
+
SUPPORT_DIET = ARCH_ALL + 1
|
109
|
+
SUPPORT_X86_REDUCE = ARCH_ALL + 2
|
110
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
require 'crabstone/version'
|
6
|
+
|
7
|
+
module Crabstone
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# Since some constants/structures are different in different Capstone versions,
|
11
|
+
# some scripts in Crabstone use this method to require the version-sensitive Ruby scripts.
|
12
|
+
# @param [String] path_tpl
|
13
|
+
# @return [Boolean]
|
14
|
+
# @example
|
15
|
+
# version_require 'crabstone/binding/%v/structs'
|
16
|
+
# # equivalent to "require 'crabstone/binding/4/structs'" if Capstone is version 4.
|
17
|
+
def version_require(path_tpl)
|
18
|
+
version_compatitable!
|
19
|
+
path = path_tpl.gsub('%v', cs_major_version.to_s)
|
20
|
+
require path
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get the major version of capstone library.
|
24
|
+
#
|
25
|
+
# @return [Integer]
|
26
|
+
# Returns the major version of Capstone.
|
27
|
+
def cs_major_version
|
28
|
+
return @cs_major_version if defined?(@cs_major_version)
|
29
|
+
|
30
|
+
maj = FFI::MemoryPointer.new(:int)
|
31
|
+
min = FFI::MemoryPointer.new(:int)
|
32
|
+
Binding.cs_version(maj, min)
|
33
|
+
@cs_major_version = maj.read_int
|
34
|
+
end
|
35
|
+
|
36
|
+
# Checks the cs_major is less or equal to Crabstone::VERSION.
|
37
|
+
def version_compatitable!
|
38
|
+
@version_compatitable ||=
|
39
|
+
cs_major_version <= Crabstone::VERSION.split('.').first.to_i && cs_major_version >= 3
|
40
|
+
end
|
41
|
+
|
42
|
+
# @private
|
43
|
+
module Binding
|
44
|
+
extend FFI::Library
|
45
|
+
ffi_lib ['capstone', 'libcapstone.so.4', 'libcapstone.so.3']
|
46
|
+
|
47
|
+
attach_function :cs_version, %i[pointer pointer], :uint
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
require 'crabstone/binding'
|
6
|
+
require 'crabstone/error'
|
7
|
+
require 'crabstone/instruction'
|
8
|
+
require 'crabstone/version'
|
9
|
+
|
10
|
+
module Crabstone
|
11
|
+
class Disassembler
|
12
|
+
SYNTAX = {
|
13
|
+
intel: 1,
|
14
|
+
att: 2,
|
15
|
+
no_regname: 3 # for PPC only
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
DETAIL = {
|
19
|
+
true => 3, # trololol
|
20
|
+
false => 0
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
SKIPDATA = {
|
24
|
+
true => 3, # trololol
|
25
|
+
false => 0
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
attr_reader :arch, :mode, :csh, :syntax, :decomposer
|
29
|
+
|
30
|
+
def initialize(arch, mode)
|
31
|
+
maj, min = version
|
32
|
+
raise "FATAL: Crabstone v#{VERSION} doesn't support binding Capstone v#{maj}.#{min}" if maj > BINDING_MAJ
|
33
|
+
|
34
|
+
@arch = arch
|
35
|
+
@mode = mode
|
36
|
+
@p_csh = FFI::MemoryPointer.new(:ulong_long)
|
37
|
+
safe { Binding.cs_open(arch, mode, @p_csh) }
|
38
|
+
|
39
|
+
@csh = @p_csh.read_ulong_long
|
40
|
+
end
|
41
|
+
|
42
|
+
# After you close the engine, don't use it anymore. Can't believe I even
|
43
|
+
# have to write this.
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
def close
|
47
|
+
safe { Binding.cs_close(@p_csh) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def syntax=(new_stx)
|
51
|
+
Crabstone::Error.raise!(ErrOption) unless SYNTAX[new_stx]
|
52
|
+
set_raw_option(OPT_SYNTAX, SYNTAX[new_stx])
|
53
|
+
@syntax = new_stx
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [Boolean] new_val
|
57
|
+
def decomposer=(new_val)
|
58
|
+
Crabstone::Error.raise!(ErrOption) unless DETAIL[new_val]
|
59
|
+
set_raw_option(OPT_DETAIL, DETAIL[new_val])
|
60
|
+
@decomposer = new_val
|
61
|
+
end
|
62
|
+
|
63
|
+
def version
|
64
|
+
maj = FFI::MemoryPointer.new(:int)
|
65
|
+
min = FFI::MemoryPointer.new(:int)
|
66
|
+
Binding.cs_version(maj, min)
|
67
|
+
[maj.read_int, min.read_int]
|
68
|
+
end
|
69
|
+
|
70
|
+
def diet?
|
71
|
+
DIET_MODE
|
72
|
+
end
|
73
|
+
|
74
|
+
def errno
|
75
|
+
Binding.cs_errno(@csh)
|
76
|
+
end
|
77
|
+
|
78
|
+
def skipdata(mnemonic = '.byte')
|
79
|
+
cfg = Binding::SkipdataConfig.new
|
80
|
+
cfg[:mnemonic] = FFI::MemoryPointer.from_string(mnemonic.to_s)
|
81
|
+
|
82
|
+
if block_given?
|
83
|
+
cfg[:callback] = FFI::Function.new(
|
84
|
+
:size_t,
|
85
|
+
%i[pointer size_t size_t pointer]
|
86
|
+
) do |code, sz, offset, _|
|
87
|
+
code = code.read_array_of_uchar(sz).pack('c*')
|
88
|
+
begin
|
89
|
+
Integer(yield(code, offset))
|
90
|
+
rescue StandardError
|
91
|
+
warn "Error in skipdata callback: #{$ERROR_INFO}"
|
92
|
+
# It will go on to crash, but now at least there's more info :)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
set_raw_option(OPT_SKIPDATA_SETUP, cfg.pointer.address)
|
98
|
+
set_raw_option(OPT_SKIPDATA, SKIPDATA[true])
|
99
|
+
end
|
100
|
+
|
101
|
+
def skipdata_off
|
102
|
+
set_raw_option(OPT_SKIPDATA, SKIPDATA[false])
|
103
|
+
end
|
104
|
+
|
105
|
+
def reg_name(regid)
|
106
|
+
Crabstone::Error.raise!(ErrDiet) if DIET_MODE
|
107
|
+
name = Binding.cs_reg_name(csh, regid)
|
108
|
+
Crabstone::Error.raise!(ErrCsh) unless name
|
109
|
+
name
|
110
|
+
end
|
111
|
+
|
112
|
+
# @return [Array<Crabstone::Instruction>]
|
113
|
+
def disasm(code, offset, count = 0)
|
114
|
+
return [] if code.empty?
|
115
|
+
|
116
|
+
insn_ptr = FFI::MemoryPointer.new(:pointer)
|
117
|
+
insn_count = Binding.cs_disasm(
|
118
|
+
@csh,
|
119
|
+
code,
|
120
|
+
code.bytesize,
|
121
|
+
offset,
|
122
|
+
count,
|
123
|
+
insn_ptr
|
124
|
+
)
|
125
|
+
Crabstone::Error.raise_errno!(errno) if insn_count.zero?
|
126
|
+
|
127
|
+
convert_disasm_result(insn_ptr, insn_count).tap { Binding.free(insn_ptr.read_pointer) }
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_raw_option(opt, val)
|
131
|
+
safe { Binding.cs_option(csh, opt, val) }
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
# Convert the insn_ptr from cs_disasm into Ruby instruction objects.
|
137
|
+
# @param [FFI::MemoryPointer] insn_ptr
|
138
|
+
# @param [Integer] insn_count
|
139
|
+
# @return [Array<Crabstone::Instruction>]
|
140
|
+
def convert_disasm_result(insn_ptr, insn_count)
|
141
|
+
insn_sz = Binding::Instruction.size
|
142
|
+
Array.new(insn_count) do |i|
|
143
|
+
cs_insn_ptr = Binding.malloc(insn_sz)
|
144
|
+
Binding.memcpy(cs_insn_ptr, insn_ptr.read_pointer + i * insn_sz, insn_sz)
|
145
|
+
Crabstone::Instruction.new(@csh, Binding::Instruction.new(cs_insn_ptr), @arch)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def safe
|
150
|
+
yield.tap { |res| Crabstone.raise_errno(res) unless res.zero? }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# XXX: Auto-gerneate this file?
|
4
|
+
# Error classes might be added in a newer Capstone version,
|
5
|
+
# but this should not be frequent, currently this file is updated manually.
|
6
|
+
|
7
|
+
module Crabstone
|
8
|
+
# @private
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
class ErrArch < Error; end
|
12
|
+
class ErrCsh < Error; end
|
13
|
+
class ErrHandle < Error; end
|
14
|
+
class ErrMem < Error; end
|
15
|
+
class ErrMode < Error; end
|
16
|
+
class ErrOK < Error; end
|
17
|
+
class ErrOption < Error; end
|
18
|
+
class ErrDetail < Error; end
|
19
|
+
class ErrMemSetup < Error; end
|
20
|
+
class ErrVersion < Error; end
|
21
|
+
class ErrDiet < Error; end
|
22
|
+
class ErrSkipData < Error; end
|
23
|
+
class ErrX86ATT < Error; end
|
24
|
+
class ErrX86Intel < Error; end
|
25
|
+
class ErrX86MASM < Error; end
|
26
|
+
|
27
|
+
class Error
|
28
|
+
ERRNO = {
|
29
|
+
0 => ErrOK,
|
30
|
+
1 => ErrMem,
|
31
|
+
2 => ErrArch,
|
32
|
+
3 => ErrHandle,
|
33
|
+
4 => ErrCsh,
|
34
|
+
5 => ErrMode,
|
35
|
+
6 => ErrOption,
|
36
|
+
7 => ErrDetail,
|
37
|
+
8 => ErrMemSetup,
|
38
|
+
9 => ErrVersion,
|
39
|
+
10 => ErrDiet,
|
40
|
+
11 => ErrSkipData,
|
41
|
+
12 => ErrX86ATT,
|
42
|
+
13 => ErrX86Intel,
|
43
|
+
14 => ErrX86MASM
|
44
|
+
}.freeze
|
45
|
+
|
46
|
+
def self.raise_errno!(errno)
|
47
|
+
err_klass = ERRNO[errno]
|
48
|
+
raise 'Internal Error: Tried to raise unknown errno' unless err_klass
|
49
|
+
|
50
|
+
err_str = Binding.cs_strerror(errno)
|
51
|
+
raise err_klass, err_str
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.raise!(klass)
|
55
|
+
raise "Invalid error class: #{klass}" unless klass.superclass == self
|
56
|
+
|
57
|
+
raise_errno!(ERRNO.invert[klass])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'crabstone/arch'
|
4
|
+
require 'crabstone/binding'
|
5
|
+
require 'crabstone/constants'
|
6
|
+
require 'crabstone/error'
|
7
|
+
|
8
|
+
module Crabstone
|
9
|
+
class Instruction
|
10
|
+
attr_reader :csh, :raw_insn
|
11
|
+
|
12
|
+
def initialize(csh, insn, arch)
|
13
|
+
@arch_module = Arch.module_of(arch)
|
14
|
+
@csh = csh
|
15
|
+
@raw_insn = insn
|
16
|
+
init_detail(insn[:detail]) if detailed?
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
raise_if_diet
|
21
|
+
name = Binding.cs_insn_name(csh, id)
|
22
|
+
Crabstone::Error.raise!(ErrCsh) unless name
|
23
|
+
name
|
24
|
+
end
|
25
|
+
|
26
|
+
def group_name(grp)
|
27
|
+
raise_if_diet
|
28
|
+
name = Binding.cs_group_name(csh, Integer(grp))
|
29
|
+
Crabstone::Error.raise!(ErrCsh) unless name
|
30
|
+
name
|
31
|
+
end
|
32
|
+
|
33
|
+
# It's more informative to raise if CS_DETAIL is off than just return nil
|
34
|
+
def detailed?
|
35
|
+
!@raw_insn[:detail].pointer.null?
|
36
|
+
end
|
37
|
+
|
38
|
+
def detail
|
39
|
+
raise_unless_detailed
|
40
|
+
@detail
|
41
|
+
end
|
42
|
+
|
43
|
+
def regs_read
|
44
|
+
raise_unless_detailed
|
45
|
+
raise_if_diet
|
46
|
+
@regs_read
|
47
|
+
end
|
48
|
+
|
49
|
+
def regs_write
|
50
|
+
raise_unless_detailed
|
51
|
+
raise_if_diet
|
52
|
+
@regs_write
|
53
|
+
end
|
54
|
+
|
55
|
+
def groups
|
56
|
+
raise_unless_detailed
|
57
|
+
raise_if_diet
|
58
|
+
@groups
|
59
|
+
end
|
60
|
+
|
61
|
+
def group?(group_id)
|
62
|
+
raise_unless_detailed
|
63
|
+
raise_if_diet
|
64
|
+
Binding.cs_insn_group(csh, raw_insn, group_id)
|
65
|
+
end
|
66
|
+
|
67
|
+
def reads_reg?(reg)
|
68
|
+
raise_unless_detailed
|
69
|
+
raise_if_diet
|
70
|
+
Binding.cs_reg_read(csh, raw_insn, @arch_module.register(reg))
|
71
|
+
end
|
72
|
+
|
73
|
+
def writes_reg?(reg)
|
74
|
+
raise_unless_detailed
|
75
|
+
raise_if_diet
|
76
|
+
Binding.cs_reg_write(csh, raw_insn, @arch_module.register(reg))
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [{:regs_read => Array<Integer>, :regs_write => Array<Integer>}]
|
80
|
+
def regs_access
|
81
|
+
raise_unless_detailed
|
82
|
+
raise_if_diet
|
83
|
+
|
84
|
+
# XXX: Becare of if `typedef uint16_t cs_regs[64];` changes
|
85
|
+
regs_read = FFI::MemoryPointer.new(:uint16, 64)
|
86
|
+
regs_read_count = FFI::MemoryPointer.new(:uint8)
|
87
|
+
regs_write = FFI::MemoryPointer.new(:uint16, 64)
|
88
|
+
regs_write_count = FFI::MemoryPointer.new(:uint8)
|
89
|
+
err = Binding.cs_regs_access(csh, raw_insn, regs_read, regs_read_count, regs_write, regs_write_count)
|
90
|
+
Crabstone::Error.raise_errno(err) if err.nonzero?
|
91
|
+
{
|
92
|
+
regs_read: regs_read.read_array_of_short(regs_read_count.read_int8),
|
93
|
+
regs_write: regs_write.read_array_of_short(regs_write_count.read_int8)
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def mnemonic
|
98
|
+
raise_if_diet
|
99
|
+
raw_insn[:mnemonic]
|
100
|
+
end
|
101
|
+
|
102
|
+
def op_str
|
103
|
+
raise_if_diet
|
104
|
+
raw_insn[:op_str]
|
105
|
+
end
|
106
|
+
|
107
|
+
def op_count(op_type = nil)
|
108
|
+
raise_unless_detailed
|
109
|
+
if op_type
|
110
|
+
Binding.cs_op_count(csh, raw_insn, op_type)
|
111
|
+
else
|
112
|
+
operands.size
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def bytes
|
117
|
+
raw_insn[:bytes].first(raw_insn[:size])
|
118
|
+
end
|
119
|
+
|
120
|
+
# So an Instruction should respond to all the methods in Instruction, and
|
121
|
+
# all the methods in the Arch specific Instruction class. The methods /
|
122
|
+
# members that have special handling for detail mode or diet mode are
|
123
|
+
# handled above. The rest is dynamically dispatched below.
|
124
|
+
def method_missing(meth, *args)
|
125
|
+
if raw_insn.members.include?(meth)
|
126
|
+
# Dispatch to toplevel Instruction class ( this file )
|
127
|
+
raw_insn[meth]
|
128
|
+
else
|
129
|
+
# Nothing else is available without details.
|
130
|
+
unless detailed?
|
131
|
+
raise(
|
132
|
+
NoMethodError,
|
133
|
+
"Either CS_DETAIL is off, or #{self.class} doesn't implement #{meth}"
|
134
|
+
)
|
135
|
+
end
|
136
|
+
# Dispatch to the architecture specific Instruction ( in arch/ )
|
137
|
+
if @arch_insn.respond_to?(meth)
|
138
|
+
@arch_insn.__send__(meth, *args)
|
139
|
+
elsif @arch_insn.members.include?(meth)
|
140
|
+
@arch_insn[meth]
|
141
|
+
else
|
142
|
+
super
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def respond_to_missing?(meth, include_private = true)
|
148
|
+
return true if raw_insn.members.include?(meth)
|
149
|
+
return super unless detailed?
|
150
|
+
return true if @arch_insn.respond_to?(meth)
|
151
|
+
return true if @arch_insn.members.include?(meth)
|
152
|
+
|
153
|
+
super
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def raise_unless_detailed
|
159
|
+
Crabstone::Error.raise!(ErrDetail) unless detailed?
|
160
|
+
end
|
161
|
+
|
162
|
+
def raise_if_diet
|
163
|
+
Crabstone::Error.raise!(ErrDiet) if DIET_MODE
|
164
|
+
end
|
165
|
+
|
166
|
+
def init_detail(detail)
|
167
|
+
@detail = detail
|
168
|
+
@arch_insn = @detail[:arch][arch_field]
|
169
|
+
@regs_read = @detail[:regs_read].first(@detail[:regs_read_count])
|
170
|
+
@regs_write = @detail[:regs_write].first(@detail[:regs_write_count])
|
171
|
+
@groups = @detail[:groups].first(@detail[:groups_count])
|
172
|
+
end
|
173
|
+
|
174
|
+
# Find the field name of Architecture.
|
175
|
+
def arch_field
|
176
|
+
klass = @arch_module.const_get(:Instruction)
|
177
|
+
obj = Binding::Architecture.new
|
178
|
+
Binding::Architecture.members.find do |sym|
|
179
|
+
obj[sym].instance_of?(klass)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|