metasm 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.hgtags +3 -0
- data/Gemfile +1 -0
- data/INSTALL +61 -0
- data/LICENCE +458 -0
- data/README +29 -21
- data/Rakefile +10 -0
- data/TODO +10 -12
- data/doc/code_organisation.txt +2 -0
- data/doc/core/DynLdr.txt +247 -0
- data/doc/core/ExeFormat.txt +43 -0
- data/doc/core/Expression.txt +220 -0
- data/doc/core/GNUExports.txt +27 -0
- data/doc/core/Ia32.txt +236 -0
- data/doc/core/SerialStruct.txt +108 -0
- data/doc/core/VirtualString.txt +145 -0
- data/doc/core/WindowsExports.txt +61 -0
- data/doc/core/index.txt +1 -0
- data/doc/style.css +6 -3
- data/doc/usage/debugger.txt +327 -0
- data/doc/usage/index.txt +1 -0
- data/doc/use_cases.txt +2 -2
- data/metasm.gemspec +22 -0
- data/{lib/metasm.rb → metasm.rb} +11 -3
- data/{lib/metasm → metasm}/compile_c.rb +13 -7
- data/metasm/cpu/arc.rb +8 -0
- data/metasm/cpu/arc/decode.rb +425 -0
- data/metasm/cpu/arc/main.rb +191 -0
- data/metasm/cpu/arc/opcodes.rb +588 -0
- data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
- data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
- data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
- data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
- data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
- data/metasm/cpu/arm/opcodes.rb +324 -0
- data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
- data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
- data/metasm/cpu/arm64.rb +15 -0
- data/metasm/cpu/arm64/debug.rb +38 -0
- data/metasm/cpu/arm64/decode.rb +289 -0
- data/metasm/cpu/arm64/encode.rb +41 -0
- data/metasm/cpu/arm64/main.rb +105 -0
- data/metasm/cpu/arm64/opcodes.rb +232 -0
- data/metasm/cpu/arm64/parse.rb +20 -0
- data/metasm/cpu/arm64/render.rb +95 -0
- data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
- data/metasm/cpu/bpf/decode.rb +142 -0
- data/metasm/cpu/bpf/main.rb +60 -0
- data/metasm/cpu/bpf/opcodes.rb +81 -0
- data/metasm/cpu/bpf/render.rb +41 -0
- data/metasm/cpu/cy16.rb +9 -0
- data/metasm/cpu/cy16/decode.rb +253 -0
- data/metasm/cpu/cy16/main.rb +63 -0
- data/metasm/cpu/cy16/opcodes.rb +78 -0
- data/metasm/cpu/cy16/render.rb +41 -0
- data/metasm/cpu/dalvik.rb +11 -0
- data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
- data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
- data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
- data/metasm/cpu/ia32.rb +17 -0
- data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
- data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
- data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
- data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
- data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
- data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
- data/metasm/cpu/ia32/opcodes.rb +1424 -0
- data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
- data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
- data/metasm/cpu/mips.rb +14 -0
- data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
- data/metasm/cpu/mips/debug.rb +42 -0
- data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
- data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
- data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
- data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
- data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
- data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
- data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
- data/metasm/cpu/msp430/decode.rb +247 -0
- data/metasm/cpu/msp430/main.rb +62 -0
- data/metasm/cpu/msp430/opcodes.rb +101 -0
- data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
- data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
- data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
- data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
- data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
- data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
- data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
- data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
- data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
- data/metasm/cpu/ppc/parse.rb +55 -0
- data/metasm/cpu/python.rb +8 -0
- data/metasm/cpu/python/decode.rb +136 -0
- data/metasm/cpu/python/main.rb +36 -0
- data/metasm/cpu/python/opcodes.rb +180 -0
- data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
- data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
- data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
- data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
- data/metasm/cpu/x86_64.rb +15 -0
- data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
- data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
- data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
- data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
- data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
- data/metasm/cpu/x86_64/opcodes.rb +136 -0
- data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
- data/metasm/cpu/x86_64/render.rb +35 -0
- data/metasm/cpu/z80.rb +9 -0
- data/metasm/cpu/z80/decode.rb +313 -0
- data/metasm/cpu/z80/main.rb +67 -0
- data/metasm/cpu/z80/opcodes.rb +224 -0
- data/metasm/cpu/z80/render.rb +59 -0
- data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
- data/{lib/metasm → metasm}/decode.rb +35 -4
- data/{lib/metasm → metasm}/decompile.rb +15 -16
- data/{lib/metasm → metasm}/disassemble.rb +201 -45
- data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
- data/{lib/metasm → metasm}/dynldr.rb +220 -133
- data/{lib/metasm → metasm}/encode.rb +10 -1
- data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
- data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
- data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
- data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
- data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
- data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
- data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
- data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
- data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
- data/metasm/exe_format/gb.rb +65 -0
- data/metasm/exe_format/javaclass.rb +424 -0
- data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
- data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
- data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
- data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
- data/metasm/exe_format/pyc.rb +167 -0
- data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
- data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
- data/metasm/exe_format/shellcode_rwx.rb +114 -0
- data/metasm/exe_format/swf.rb +205 -0
- data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
- data/metasm/exe_format/zip.rb +335 -0
- data/metasm/gui.rb +13 -0
- data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
- data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
- data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
- data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
- data/metasm/gui/dasm_graph.rb +1695 -0
- data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
- data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
- data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
- data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
- data/{lib/metasm → metasm}/gui/debug.rb +93 -27
- data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
- data/{lib/metasm → metasm}/gui/qt.rb +12 -2
- data/{lib/metasm → metasm}/gui/win32.rb +179 -42
- data/{lib/metasm → metasm}/gui/x11.rb +59 -59
- data/{lib/metasm → metasm}/main.rb +389 -264
- data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
- data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
- data/{lib/metasm → metasm}/os/linux.rb +628 -151
- data/metasm/os/main.rb +330 -0
- data/{lib/metasm → metasm}/os/windows.rb +132 -42
- data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
- data/{lib/metasm → metasm}/parse.rb +26 -24
- data/{lib/metasm → metasm}/parse_c.rb +221 -116
- data/{lib/metasm → metasm}/preprocessor.rb +55 -40
- data/{lib/metasm → metasm}/render.rb +14 -38
- data/misc/hexdump.rb +2 -1
- data/misc/lint.rb +58 -0
- data/misc/txt2html.rb +9 -7
- data/samples/bindiff.rb +3 -4
- data/samples/dasm-plugins/bindiff.rb +15 -0
- data/samples/dasm-plugins/bookmark.rb +133 -0
- data/samples/dasm-plugins/c_constants.rb +57 -0
- data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
- data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
- data/samples/dasm-plugins/dasm_all.rb +70 -0
- data/samples/dasm-plugins/demangle_cpp.rb +31 -0
- data/samples/dasm-plugins/deobfuscate.rb +251 -0
- data/samples/dasm-plugins/dump_text.rb +35 -0
- data/samples/dasm-plugins/export_graph_svg.rb +86 -0
- data/samples/dasm-plugins/findgadget.rb +75 -0
- data/samples/dasm-plugins/hl_opcode.rb +32 -0
- data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
- data/samples/dasm-plugins/imm2off.rb +34 -0
- data/samples/dasm-plugins/match_libsigs.rb +93 -0
- data/samples/dasm-plugins/patch_file.rb +95 -0
- data/samples/dasm-plugins/scanfuncstart.rb +36 -0
- data/samples/dasm-plugins/scanxrefs.rb +26 -0
- data/samples/dasm-plugins/selfmodify.rb +197 -0
- data/samples/dasm-plugins/stringsxrefs.rb +28 -0
- data/samples/dasmnavig.rb +1 -1
- data/samples/dbg-apihook.rb +24 -9
- data/samples/dbg-plugins/heapscan.rb +283 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
- data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
- data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
- data/samples/dbg-plugins/heapscan/winheap.h +174 -0
- data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
- data/samples/dbg-plugins/trace_func.rb +214 -0
- data/samples/disassemble-gui.rb +35 -5
- data/samples/disassemble.rb +31 -6
- data/samples/dump_upx.rb +24 -12
- data/samples/dynamic_ruby.rb +12 -3
- data/samples/exeencode.rb +6 -5
- data/samples/factorize-headers-peimports.rb +1 -1
- data/samples/lindebug.rb +175 -381
- data/samples/metasm-shell.rb +1 -2
- data/samples/peldr.rb +2 -2
- data/tests/all.rb +1 -1
- data/tests/arc.rb +26 -0
- data/tests/dynldr.rb +22 -4
- data/tests/expression.rb +55 -0
- data/tests/graph_layout.rb +285 -0
- data/tests/ia32.rb +79 -26
- data/tests/mips.rb +9 -2
- data/tests/x86_64.rb +66 -18
- metadata +330 -218
- data/lib/metasm/arm/opcodes.rb +0 -177
- data/lib/metasm/gui.rb +0 -23
- data/lib/metasm/gui/dasm_graph.rb +0 -1354
- data/lib/metasm/ia32.rb +0 -14
- data/lib/metasm/ia32/opcodes.rb +0 -873
- data/lib/metasm/ppc/parse.rb +0 -52
- data/lib/metasm/x86_64.rb +0 -12
- data/lib/metasm/x86_64/opcodes.rb +0 -118
- data/samples/gdbclient.rb +0 -583
- data/samples/rubstop.rb +0 -399
data/lib/metasm/ia32.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
-
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
-
#
|
4
|
-
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
-
|
6
|
-
|
7
|
-
require 'metasm/main'
|
8
|
-
require 'metasm/ia32/parse'
|
9
|
-
require 'metasm/ia32/encode'
|
10
|
-
require 'metasm/ia32/decode'
|
11
|
-
require 'metasm/ia32/render'
|
12
|
-
require 'metasm/ia32/compile_c'
|
13
|
-
require 'metasm/ia32/decompile'
|
14
|
-
require 'metasm/ia32/debug'
|
data/lib/metasm/ia32/opcodes.rb
DELETED
@@ -1,873 +0,0 @@
|
|
1
|
-
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
-
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
-
#
|
4
|
-
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
-
|
6
|
-
|
7
|
-
require 'metasm/ia32/main'
|
8
|
-
|
9
|
-
module Metasm
|
10
|
-
class Ia32
|
11
|
-
def init_cpu_constants
|
12
|
-
@opcode_list ||= []
|
13
|
-
@fields_mask.update :w => 1, :s => 1, :d => 1, :modrm => 0xc7,
|
14
|
-
:reg => 7, :eeec => 7, :eeed => 7, :eeet => 7, :seg2 => 3, :seg3 => 7,
|
15
|
-
:regfp => 7, :regmmx => 7, :regxmm => 7
|
16
|
-
@fields_mask[:seg2A] = @fields_mask[:seg2]
|
17
|
-
@fields_mask[:seg3A] = @fields_mask[:seg3]
|
18
|
-
@fields_mask[:modrmA] = @fields_mask[:modrm]
|
19
|
-
|
20
|
-
@valid_args.concat [:i, :i8, :u8, :u16, :reg, :seg2, :seg2A,
|
21
|
-
:seg3, :seg3A, :eeec, :eeed, :eeet, :modrm, :modrmA, :mrm_imm,
|
22
|
-
:farptr, :imm_val1, :imm_val3, :reg_cl, :reg_eax,
|
23
|
-
:reg_dx, :regfp, :regfp0, :modrmmmx, :regmmx,
|
24
|
-
:modrmxmm, :regxmm] - @valid_args
|
25
|
-
|
26
|
-
@valid_props.concat [:strop, :stropz, :opsz, :argsz, :setip,
|
27
|
-
:stopexec, :saveip, :unsigned_imm, :random, :needpfx,
|
28
|
-
:xmmx] - @valid_props
|
29
|
-
end
|
30
|
-
|
31
|
-
# only most common instructions from the 386 instruction set
|
32
|
-
# inexhaustive list :
|
33
|
-
# no aaa, arpl, mov crX, call/jmp/ret far, in/out, bts, xchg...
|
34
|
-
def init_386_common_only
|
35
|
-
init_cpu_constants
|
36
|
-
|
37
|
-
addop_macro1 'adc', 2
|
38
|
-
addop_macro1 'add', 0
|
39
|
-
addop_macro1 'and', 4, :u
|
40
|
-
addop 'bswap', [0x0F, 0xC8], :reg
|
41
|
-
addop 'call', [0xE8], nil, {}, :stopexec, :setip, :i, :saveip
|
42
|
-
addop 'call', [0xFF], 2, {}, :stopexec, :setip, :saveip
|
43
|
-
addop('cbw', [0x98]) { |o| o.props[:opsz] = 16 }
|
44
|
-
addop('cwde', [0x98]) { |o| o.props[:opsz] = 32 }
|
45
|
-
addop('cdqe', [0x98]) { |o| o.props[:opsz] = 64 }
|
46
|
-
addop('cwd', [0x99]) { |o| o.props[:opsz] = 16 }
|
47
|
-
addop('cdq', [0x99]) { |o| o.props[:opsz] = 32 }
|
48
|
-
addop('cqo', [0x99]) { |o| o.props[:opsz] = 64 }
|
49
|
-
addop_macro1 'cmp', 7
|
50
|
-
addop_macrostr 'cmps', [0xA6], :stropz
|
51
|
-
addop 'dec', [0x48], :reg
|
52
|
-
addop 'dec', [0xFE], 1, {:w => [0, 0]}
|
53
|
-
addop 'div', [0xF6], 6, {:w => [0, 0]}
|
54
|
-
addop 'enter', [0xC8], nil, {}, :u16, :u8
|
55
|
-
addop 'idiv', [0xF6], 7, {:w => [0, 0]}
|
56
|
-
addop 'imul', [0xF6], 5, {:w => [0, 0]}, :reg_eax
|
57
|
-
addop 'imul', [0x0F, 0xAF], :mrm
|
58
|
-
addop 'imul', [0x69], :mrm, {:s => [0, 1]}, :i
|
59
|
-
addop 'inc', [0x40], :reg
|
60
|
-
addop 'inc', [0xFE], 0, {:w => [0, 0]}
|
61
|
-
addop 'int', [0xCC], nil, {}, :imm_val3, :stopexec
|
62
|
-
addop 'int', [0xCD], nil, {}, :u8
|
63
|
-
addop_macrotttn 'j', [0x70], nil, {}, :setip, :i8
|
64
|
-
addop_macrotttn 'j', [0x0F, 0x80], nil, {}, :setip, :i
|
65
|
-
addop 'jmp', [0xE9], nil, {:s => [0, 1]}, :setip, :i, :stopexec
|
66
|
-
addop 'jmp', [0xFF], 4, {}, :setip, :stopexec
|
67
|
-
addop 'lea', [0x8D], :mrmA
|
68
|
-
addop 'leave', [0xC9]
|
69
|
-
addop_macrostr 'lods', [0xAC], :strop
|
70
|
-
addop 'loop', [0xE2], nil, {}, :setip, :i8
|
71
|
-
addop 'loopz', [0xE1], nil, {}, :setip, :i8
|
72
|
-
addop 'loope', [0xE1], nil, {}, :setip, :i8
|
73
|
-
addop 'loopnz',[0xE0], nil, {}, :setip, :i8
|
74
|
-
addop 'loopne',[0xE0], nil, {}, :setip, :i8
|
75
|
-
addop 'mov', [0xA0], nil, {:w => [0, 0], :d => [0, 1]}, :mrm_imm, :reg_eax
|
76
|
-
addop 'mov', [0x88], :mrmw,{:d => [0, 1]}
|
77
|
-
addop 'mov', [0xB0], :reg, {:w => [0, 3]}, :u
|
78
|
-
addop 'mov', [0xC6], 0, {:w => [0, 0]}, :u
|
79
|
-
addop_macrostr 'movs', [0xA4], :strop
|
80
|
-
addop 'movsx', [0x0F, 0xBE], :mrmw
|
81
|
-
addop 'movzx', [0x0F, 0xB6], :mrmw
|
82
|
-
addop 'mul', [0xF6], 4, {:w => [0, 0]}
|
83
|
-
addop 'neg', [0xF6], 3, {:w => [0, 0]}
|
84
|
-
addop 'nop', [0x90]
|
85
|
-
addop 'not', [0xF6], 2, {:w => [0, 0]}
|
86
|
-
addop_macro1 'or', 1, :u
|
87
|
-
addop 'pop', [0x58], :reg
|
88
|
-
addop 'pop', [0x8F], 0
|
89
|
-
addop 'push', [0x50], :reg
|
90
|
-
addop 'push', [0xFF], 6
|
91
|
-
addop 'push', [0x68], nil, {:s => [0, 1]}, :u
|
92
|
-
addop 'ret', [0xC3], nil, {}, :stopexec, :setip
|
93
|
-
addop 'ret', [0xC2], nil, {}, :stopexec, :u16, :setip
|
94
|
-
addop_macro3 'rol', 0
|
95
|
-
addop_macro3 'ror', 1
|
96
|
-
addop_macro3 'sar', 7
|
97
|
-
addop_macro1 'sbb', 3
|
98
|
-
addop_macrostr 'scas', [0xAE], :stropz
|
99
|
-
addop_macrotttn('set', [0x0F, 0x90], 0) { |o| o.props[:argsz] = 8 }
|
100
|
-
addop_macrotttn('set', [0x0F, 0x90], :mrm) { |o| o.props[:argsz] = 8 ; o.args.reverse! } # :reg field is unused
|
101
|
-
addop_macro3 'shl', 4
|
102
|
-
addop_macro3 'sal', 6
|
103
|
-
addop 'shld', [0x0F, 0xA4], :mrm, {}, :u8
|
104
|
-
addop 'shld', [0x0F, 0xA5], :mrm, {}, :reg_cl
|
105
|
-
addop_macro3 'shr', 5
|
106
|
-
addop 'shrd', [0x0F, 0xAC], :mrm, {}, :u8
|
107
|
-
addop 'shrd', [0x0F, 0xAD], :mrm, {}, :reg_cl
|
108
|
-
addop_macrostr 'stos', [0xAA], :strop
|
109
|
-
addop_macro1 'sub', 5
|
110
|
-
addop 'test', [0x84], :mrmw
|
111
|
-
addop 'test', [0xA8], nil, {:w => [0, 0]}, :reg_eax, :u
|
112
|
-
addop 'test', [0xF6], 0, {:w => [0, 0]}, :u
|
113
|
-
addop 'xchg', [0x90], :reg, {}, :reg_eax
|
114
|
-
addop('xchg', [0x90], :reg, {}, :reg_eax) { |o| o.args.reverse! } # xchg eax, ebx == xchg ebx, eax)
|
115
|
-
addop 'xchg', [0x86], :mrmw
|
116
|
-
addop('xchg', [0x86], :mrmw) { |o| o.args.reverse! }
|
117
|
-
addop_macro1 'xor', 6, :u
|
118
|
-
end
|
119
|
-
|
120
|
-
def init_386_only
|
121
|
-
init_cpu_constants
|
122
|
-
|
123
|
-
addop 'aaa', [0x37]
|
124
|
-
addop 'aad', [0xD5, 0x0A]
|
125
|
-
addop 'aam', [0xD4, 0x0A]
|
126
|
-
addop 'aas', [0x3F]
|
127
|
-
addop('arpl', [0x63], :mrm) { |o| o.props[:argsz] = 16 ; o.args.reverse! }
|
128
|
-
addop 'bound', [0x62], :mrmA
|
129
|
-
addop 'bsf', [0x0F, 0xBC], :mrm
|
130
|
-
addop 'bsr', [0x0F, 0xBD], :mrm
|
131
|
-
addop_macro2 'bt' , 0
|
132
|
-
addop_macro2 'btc', 3
|
133
|
-
addop_macro2 'btr', 2
|
134
|
-
addop_macro2 'bts', 1
|
135
|
-
addop 'call', [0x9A], nil, {}, :stopexec, :setip, :farptr, :saveip
|
136
|
-
addop 'callf', [0x9A], nil, {}, :stopexec, :setip, :farptr, :saveip
|
137
|
-
addop 'callf', [0xFF], 3, {}, :stopexec, :setip, :saveip
|
138
|
-
addop 'clc', [0xF8]
|
139
|
-
addop 'cld', [0xFC]
|
140
|
-
addop 'cli', [0xFA]
|
141
|
-
addop 'clts', [0x0F, 0x06]
|
142
|
-
addop 'cmc', [0xF5]
|
143
|
-
addop('cmpxchg',[0x0F, 0xB0], :mrmw) { |o| o.args.reverse! }
|
144
|
-
addop 'cpuid', [0x0F, 0xA2]
|
145
|
-
addop 'daa', [0x27]
|
146
|
-
addop 'das', [0x2F]
|
147
|
-
addop 'hlt', [0xF4], nil, {}, :stopexec
|
148
|
-
addop 'in', [0xE4], nil, {:w => [0, 0]}, :reg_eax, :u8
|
149
|
-
addop 'in', [0xE4], nil, {:w => [0, 0]}, :u8
|
150
|
-
addop 'in', [0xEC], nil, {:w => [0, 0]}, :reg_eax, :reg_dx
|
151
|
-
addop 'in', [0xEC], nil, {:w => [0, 0]}, :reg_eax
|
152
|
-
addop 'in', [0xEC], nil, {:w => [0, 0]}
|
153
|
-
addop_macrostr 'ins', [0x6C], :strop
|
154
|
-
addop 'into', [0xCE]
|
155
|
-
addop 'invd', [0x0F, 0x08]
|
156
|
-
addop 'invlpg',[0x0F, 0x01, 7<<3], :modrmA
|
157
|
-
addop 'iret', [0xCF], nil, {}, :stopexec, :setip
|
158
|
-
addop 'iretd', [0xCF], nil, {}, :stopexec, :setip
|
159
|
-
addop('jcxz', [0xE3], nil, {}, :setip, :i8) { |o| o.props[:opsz] = 16 }
|
160
|
-
addop('jecxz', [0xE3], nil, {}, :setip, :i8) { |o| o.props[:opsz] = 32 }
|
161
|
-
addop 'jmp', [0xEA], nil, {}, :farptr, :setip, :stopexec
|
162
|
-
addop 'jmpf', [0xEA], nil, {}, :farptr, :setip, :stopexec
|
163
|
-
addop 'jmpf', [0xFF], 5, {}, :stopexec, :setip # reg ?
|
164
|
-
addop 'lahf', [0x9F]
|
165
|
-
addop 'lar', [0x0F, 0x02], :mrm
|
166
|
-
addop 'lds', [0xC5], :mrmA
|
167
|
-
addop 'les', [0xC4], :mrmA
|
168
|
-
addop 'lfs', [0x0F, 0xB4], :mrmA
|
169
|
-
addop 'lgs', [0x0F, 0xB5], :mrmA
|
170
|
-
addop 'lgdt', [0x0F, 0x01], 2
|
171
|
-
addop 'lidt', [0x0F, 0x01, 3<<3], :modrmA
|
172
|
-
addop 'lldt', [0x0F, 0x00], 2
|
173
|
-
addop 'lmsw', [0x0F, 0x01], 6
|
174
|
-
# prefix addop 'lock', [0xF0]
|
175
|
-
addop 'lsl', [0x0F, 0x03], :mrm
|
176
|
-
addop 'lss', [0x0F, 0xB2], :mrmA
|
177
|
-
addop 'ltr', [0x0F, 0x00], 3
|
178
|
-
addop('mov', [0x0F, 0x20, 0xC0], :reg, {:d => [1, 1], :eeec => [2, 3]}, :eeec) { |op| op.args.reverse! }
|
179
|
-
addop('mov', [0x0F, 0x21, 0xC0], :reg, {:d => [1, 1], :eeed => [2, 3]}, :eeed) { |op| op.args.reverse! }
|
180
|
-
addop('mov', [0x0F, 0x24, 0xC0], :reg, {:d => [1, 1], :eeet => [2, 3]}, :eeet) { |op| op.args.reverse! }
|
181
|
-
addop('mov', [0x8C], 0, {:d => [0, 1], :seg3 => [1, 3]}, :seg3) { |op| op.args.reverse! }
|
182
|
-
addop 'out', [0xE6], nil, {:w => [0, 0]}, :u8, :reg_eax
|
183
|
-
addop 'out', [0xE6], nil, {:w => [0, 0]}, :reg_eax, :u8
|
184
|
-
addop 'out', [0xE6], nil, {:w => [0, 0]}, :u8
|
185
|
-
addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_dx, :reg_eax
|
186
|
-
addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_eax, :reg_dx
|
187
|
-
addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_eax # implicit arguments
|
188
|
-
addop 'out', [0xEE], nil, {:w => [0, 0]}
|
189
|
-
addop_macrostr 'outs', [0x6E], :strop
|
190
|
-
addop 'pop', [0x07], nil, {:seg2A => [0, 3]}, :seg2A
|
191
|
-
addop 'pop', [0x0F, 0x81], nil, {:seg3A => [1, 3]}, :seg3A
|
192
|
-
addop('popa', [0x61]) { |o| o.props[:opsz] = 16 }
|
193
|
-
addop('popad', [0x61]) { |o| o.props[:opsz] = 32 }
|
194
|
-
addop('popf', [0x9D]) { |o| o.props[:opsz] = 16 }
|
195
|
-
addop('popfd', [0x9D]) { |o| o.props[:opsz] = 32 }
|
196
|
-
addop 'push', [0x06], nil, {:seg2 => [0, 3]}, :seg2
|
197
|
-
addop 'push', [0x0F, 0x80], nil, {:seg3A => [1, 3]}, :seg3A
|
198
|
-
addop('pusha', [0x60]) { |o| o.props[:opsz] = 16 }
|
199
|
-
addop('pushad',[0x60]) { |o| o.props[:opsz] = 32 }
|
200
|
-
addop('pushf', [0x9C]) { |o| o.props[:opsz] = 16 }
|
201
|
-
addop('pushfd',[0x9C]) { |o| o.props[:opsz] = 32 }
|
202
|
-
addop_macro3 'rcl', 2
|
203
|
-
addop_macro3 'rcr', 3
|
204
|
-
addop 'rdmsr', [0x0F, 0x32]
|
205
|
-
addop 'rdpmc', [0x0F, 0x33]
|
206
|
-
addop 'rdtsc', [0x0F, 0x31], nil, {}, :random
|
207
|
-
addop 'retf', [0xCB], nil, {}, :stopexec, :setip
|
208
|
-
addop 'retf', [0xCA], nil, {}, :stopexec, :u16, :setip
|
209
|
-
addop 'rsm', [0x0F, 0xAA], nil, {}, :stopexec
|
210
|
-
addop 'sahf', [0x9E]
|
211
|
-
addop 'sgdt', [0x0F, 0x01, 0<<3], :modrmA
|
212
|
-
addop 'sidt', [0x0F, 0x01, 1<<3], :modrmA
|
213
|
-
addop 'sldt', [0x0F, 0x00], 0
|
214
|
-
addop 'smsw', [0x0F, 0x01], 4
|
215
|
-
addop 'stc', [0xF9]
|
216
|
-
addop 'std', [0xFD]
|
217
|
-
addop 'sti', [0xFB]
|
218
|
-
addop 'str', [0x0F, 0x00], 1
|
219
|
-
addop 'ud2', [0x0F, 0x0B]
|
220
|
-
addop 'verr', [0x0F, 0x00], 4
|
221
|
-
addop 'verw', [0x0F, 0x00], 5
|
222
|
-
addop 'wait', [0x9B]
|
223
|
-
addop 'wbinvd',[0x0F, 0x09]
|
224
|
-
addop 'wrmsr', [0x0F, 0x30]
|
225
|
-
addop('xadd', [0x0F, 0xC0], :mrmw) { |o| o.args.reverse! }
|
226
|
-
addop 'xlat', [0xD7]
|
227
|
-
|
228
|
-
# pfx: addrsz = 0x67, lock = 0xf0, opsz = 0x66, repnz = 0xf2, rep/repz = 0xf3
|
229
|
-
# cs/nojmp = 0x2E, ds/jmp = 0x3E, es = 0x26, fs = 0x64, gs = 0x65, ss = 0x36
|
230
|
-
# undocumented opcodes
|
231
|
-
# TODO put these in the right place (486/P6/...)
|
232
|
-
addop 'aam', [0xD4], nil, {}, :u8
|
233
|
-
addop 'aad', [0xD5], nil, {}, :u8
|
234
|
-
addop 'setalc', [0xD6]
|
235
|
-
addop 'salc', [0xD6]
|
236
|
-
addop 'icebp', [0xF1]
|
237
|
-
#addop 'loadall',[0x0F, 0x07] # conflict with syscall
|
238
|
-
addop 'ud2', [0x0F, 0xB9]
|
239
|
-
addop 'umov', [0x0F, 0x10], :mrmw,{:d => [1, 1]}
|
240
|
-
end
|
241
|
-
|
242
|
-
def init_387_only
|
243
|
-
init_cpu_constants
|
244
|
-
|
245
|
-
addop 'f2xm1', [0xD9, 0xF0]
|
246
|
-
addop 'fabs', [0xD9, 0xE1]
|
247
|
-
addop_macrofpu1 'fadd', 0
|
248
|
-
addop 'faddp', [0xDE, 0xC0], :regfp
|
249
|
-
addop 'faddp', [0xDE, 0xC1]
|
250
|
-
addop('fbld', [0xDF, 4<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
|
251
|
-
addop('fbstp', [0xDF, 6<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
|
252
|
-
addop 'fchs', [0xD9, 0xE0], nil, {}, :regfp0
|
253
|
-
addop 'fnclex', [0xDB, 0xE2]
|
254
|
-
addop_macrofpu1 'fcom', 2
|
255
|
-
addop_macrofpu1 'fcomp', 3
|
256
|
-
addop 'fcompp',[0xDE, 0xD9]
|
257
|
-
addop 'fcomip',[0xDF, 0xF0], :regfp
|
258
|
-
addop 'fcos', [0xD9, 0xFF], nil, {}, :regfp0
|
259
|
-
addop 'fdecstp', [0xD9, 0xF6]
|
260
|
-
addop_macrofpu1 'fdiv', 6
|
261
|
-
addop_macrofpu1 'fdivr', 7
|
262
|
-
addop 'fdivp', [0xDE, 0xF8], :regfp
|
263
|
-
addop 'fdivp', [0xDE, 0xF9]
|
264
|
-
addop 'fdivrp',[0xDE, 0xF0], :regfp
|
265
|
-
addop 'fdivrp',[0xDE, 0xF1]
|
266
|
-
addop 'ffree', [0xDD, 0xC0], nil, {:regfp => [1, 0]}, :regfp
|
267
|
-
addop_macrofpu2 'fiadd', 0
|
268
|
-
addop_macrofpu2 'fimul', 1
|
269
|
-
addop_macrofpu2 'ficom', 2
|
270
|
-
addop_macrofpu2 'ficomp',3
|
271
|
-
addop_macrofpu2 'fisub', 4
|
272
|
-
addop_macrofpu2 'fisubr',5
|
273
|
-
addop_macrofpu2 'fidiv', 6
|
274
|
-
addop_macrofpu2 'fidivr',7
|
275
|
-
addop 'fincstp', [0xD9, 0xF7]
|
276
|
-
addop 'fninit', [0xDB, 0xE3]
|
277
|
-
addop_macrofpu2 'fist', 2, 1
|
278
|
-
addop_macrofpu3 'fild', 0
|
279
|
-
addop_macrofpu3 'fistp',3
|
280
|
-
addop('fld', [0xD9, 0<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
|
281
|
-
addop('fld', [0xDD, 0<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
|
282
|
-
addop('fld', [0xDB, 5<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
|
283
|
-
addop 'fld', [0xD9, 0xC0], :regfp
|
284
|
-
|
285
|
-
addop('fldcw', [0xD9, 5<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
286
|
-
addop 'fldenv', [0xD9, 4<<3], :modrmA
|
287
|
-
addop 'fld1', [0xD9, 0xE8]
|
288
|
-
addop 'fldl2t', [0xD9, 0xE9]
|
289
|
-
addop 'fldl2e', [0xD9, 0xEA]
|
290
|
-
addop 'fldpi', [0xD9, 0xEB]
|
291
|
-
addop 'fldlg2', [0xD9, 0xEC]
|
292
|
-
addop 'fldln2', [0xD9, 0xED]
|
293
|
-
addop 'fldz', [0xD9, 0xEE]
|
294
|
-
addop_macrofpu1 'fmul', 1
|
295
|
-
addop 'fmulp', [0xDE, 0xC8], :regfp
|
296
|
-
addop 'fmulp', [0xDE, 0xC9]
|
297
|
-
addop 'fnop', [0xD9, 0xD0]
|
298
|
-
addop 'fpatan', [0xD9, 0xF3]
|
299
|
-
addop 'fprem', [0xD9, 0xF8]
|
300
|
-
addop 'fprem1', [0xD9, 0xF5]
|
301
|
-
addop 'fptan', [0xD9, 0xF2]
|
302
|
-
addop 'frndint',[0xD9, 0xFC]
|
303
|
-
addop 'frstor', [0xDD, 4<<3], :modrmA
|
304
|
-
addop 'fnsave', [0xDD, 6<<3], :modrmA
|
305
|
-
addop('fnstcw', [0xD9, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
306
|
-
addop 'fnstenv',[0xD9, 6<<3], :modrmA
|
307
|
-
addop 'fnstsw', [0xDF, 0xE0]
|
308
|
-
addop('fnstsw', [0xDD, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
309
|
-
addop 'fscale', [0xD9, 0xFD]
|
310
|
-
addop 'fsin', [0xD9, 0xFE]
|
311
|
-
addop 'fsincos',[0xD9, 0xFB]
|
312
|
-
addop 'fsqrt', [0xD9, 0xFA]
|
313
|
-
addop('fst', [0xD9, 2<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
|
314
|
-
addop('fst', [0xDD, 2<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
|
315
|
-
addop 'fst', [0xD9, 0xD0], :regfp
|
316
|
-
addop('fstp', [0xD9, 3<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
|
317
|
-
addop('fstp', [0xDD, 3<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
|
318
|
-
addop('fstp', [0xDB, 7<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
|
319
|
-
addop 'fstp', [0xDD, 0xD8], :regfp
|
320
|
-
addop_macrofpu1 'fsub', 4
|
321
|
-
addop 'fsubp', [0xDE, 0xE8], :regfp
|
322
|
-
addop 'fsubp', [0xDE, 0xE9]
|
323
|
-
addop_macrofpu1 'fsubp', 5
|
324
|
-
addop 'fsubrp', [0xDE, 0xE0], :regfp
|
325
|
-
addop 'fsubrp', [0xDE, 0xE1]
|
326
|
-
addop 'ftst', [0xD9, 0xE4]
|
327
|
-
addop 'fucom', [0xDD, 0xE0], :regfp
|
328
|
-
addop 'fucomp', [0xDD, 0xE8], :regfp
|
329
|
-
addop 'fucompp',[0xDA, 0xE9]
|
330
|
-
addop 'fucomi', [0xDB, 0xE8], :regfp
|
331
|
-
addop 'fxam', [0xD9, 0xE5]
|
332
|
-
addop 'fxch', [0xD9, 0xC8], :regfp
|
333
|
-
addop 'fxtract',[0xD9, 0xF4]
|
334
|
-
addop 'fyl2x', [0xD9, 0xF1]
|
335
|
-
addop 'fyl2xp1',[0xD9, 0xF9]
|
336
|
-
# fwait prefix
|
337
|
-
addop 'fclex', [0x9B, 0xDB, 0xE2]
|
338
|
-
addop 'finit', [0x9B, 0xDB, 0xE3]
|
339
|
-
addop 'fsave', [0x9B, 0xDD, 6<<3], :modrmA
|
340
|
-
addop('fstcw', [0x9B, 0xD9, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
341
|
-
addop 'fstenv', [0x9B, 0xD9, 6<<3], :modrmA
|
342
|
-
addop 'fstsw', [0x9B, 0xDF, 0xE0]
|
343
|
-
addop('fstsw', [0x9B, 0xDD, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
344
|
-
addop 'fwait', [0x9B]
|
345
|
-
end
|
346
|
-
|
347
|
-
def init_486_only
|
348
|
-
init_cpu_constants
|
349
|
-
# TODO add new segments (fs/gs) ?
|
350
|
-
end
|
351
|
-
|
352
|
-
def init_pentium_only
|
353
|
-
init_cpu_constants
|
354
|
-
|
355
|
-
addop 'cmpxchg8b', [0x0F, 0xC7], 1
|
356
|
-
# lock cmpxchg8b eax
|
357
|
-
#addop 'f00fbug', [0xF0, 0x0F, 0xC7, 0xC8]
|
358
|
-
|
359
|
-
# mmx
|
360
|
-
addop 'emms', [0x0F, 0x77]
|
361
|
-
addop('movd', [0x0F, 0x6E], :mrmmmx, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmmmx)] = :modrm ; o.args.reverse! }
|
362
|
-
addop('movq', [0x0F, 0x6F], :mrmmmx, {:d => [1, 4]}) { |o| o.args.reverse! }
|
363
|
-
addop 'packssdw', [0x0F, 0x6B], :mrmmmx
|
364
|
-
addop 'packsswb', [0x0F, 0x63], :mrmmmx
|
365
|
-
addop 'packuswb', [0x0F, 0x67], :mrmmmx
|
366
|
-
addop_macrogg 0..2, 'padd', [0x0F, 0xFC], :mrmmmx
|
367
|
-
addop_macrogg 0..1, 'padds', [0x0F, 0xEC], :mrmmmx
|
368
|
-
addop_macrogg 0..1, 'paddus',[0x0F, 0xDC], :mrmmmx
|
369
|
-
addop 'pand', [0x0F, 0xDB], :mrmmmx
|
370
|
-
addop 'pandn', [0x0F, 0xDF], :mrmmmx
|
371
|
-
addop_macrogg 0..2, 'pcmpeq',[0x0F, 0x74], :mrmmmx
|
372
|
-
addop_macrogg 0..2, 'pcmpgt',[0x0F, 0x64], :mrmmmx
|
373
|
-
addop 'pmaddwd', [0x0F, 0xF5], :mrmmmx
|
374
|
-
addop 'pmulhuw', [0x0F, 0xE4], :mrmmmx
|
375
|
-
addop 'pmulhw',[0x0F, 0xE5], :mrmmmx
|
376
|
-
addop 'pmullw',[0x0F, 0xD5], :mrmmmx
|
377
|
-
addop 'por', [0x0F, 0xEB], :mrmmmx
|
378
|
-
addop_macrommx 1..3, 'psll', 3
|
379
|
-
addop_macrommx 1..2, 'psra', 2
|
380
|
-
addop_macrommx 1..3, 'psrl', 1
|
381
|
-
addop_macrogg 0..2, 'psub', [0x0F, 0xF8], :mrmmmx
|
382
|
-
addop_macrogg 0..1, 'psubs', [0x0F, 0xE8], :mrmmmx
|
383
|
-
addop_macrogg 0..1, 'psubus',[0x0F, 0xD8], :mrmmmx
|
384
|
-
addop_macrogg 1..3, 'punchkh', [0x0F, 0x68], :mrmmmx
|
385
|
-
addop_macrogg 1..3, 'punpckl', [0x0F, 0x60], :mrmmmx
|
386
|
-
addop 'pxor', [0x0F, 0xEF], :mrmmmx
|
387
|
-
end
|
388
|
-
|
389
|
-
def init_p6_only
|
390
|
-
addop_macrotttn 'cmov', [0x0F, 0x40], :mrm
|
391
|
-
|
392
|
-
%w{b e be u}.each_with_index { |tt, i|
|
393
|
-
addop 'fcmov' + tt, [0xDA, 0xC0 | (i << 3)], :regfp
|
394
|
-
addop 'fcmovn'+ tt, [0xDB, 0xC0 | (i << 3)], :regfp
|
395
|
-
}
|
396
|
-
addop 'fcomi', [0xDB, 0xF0], :regfp
|
397
|
-
addop('fxrstor', [0x0F, 0xAE, 1<<3], :modrmA) { |o| o.props[:argsz] = 512*8 }
|
398
|
-
addop('fxsave', [0x0F, 0xAE, 0<<3], :modrmA) { |o| o.props[:argsz] = 512*8 }
|
399
|
-
addop 'sysenter',[0x0F, 0x34]
|
400
|
-
addop 'sysexit', [0x0F, 0x35]
|
401
|
-
|
402
|
-
addop 'syscall', [0x0F, 0x05] # AMD
|
403
|
-
addop 'sysret', [0x0F, 0x07] # AMD
|
404
|
-
end
|
405
|
-
|
406
|
-
def init_3dnow_only
|
407
|
-
init_cpu_constants
|
408
|
-
|
409
|
-
[['pavgusb', 0xBF], ['pfadd', 0x9E], ['pfsub', 0x9A],
|
410
|
-
['pfsubr', 0xAA], ['pfacc', 0xAE], ['pfcmpge', 0x90],
|
411
|
-
['pfcmpgt', 0xA0], ['fpcmpeq', 0xB0], ['pfmin', 0x94],
|
412
|
-
['pfmax', 0xA4], ['pi2fd', 0x0D], ['pf2id', 0x1D],
|
413
|
-
['pfrcp', 0x96], ['pfrsqrt', 0x97], ['pfmul', 0xB4],
|
414
|
-
['pfrcpit1', 0xA6], ['pfrsqit1', 0xA7], ['pfrcpit2', 0xB6],
|
415
|
-
['pmulhrw', 0xB7]].each { |str, bin|
|
416
|
-
addop str, [0x0F, 0x0F, bin], :mrmmmx
|
417
|
-
}
|
418
|
-
# 3dnow prefix fallback
|
419
|
-
addop '3dnow', [0x0F, 0x0F], :mrmmmx, {}, :u8
|
420
|
-
|
421
|
-
addop 'femms', [0x0F, 0x0E]
|
422
|
-
addop 'prefetch', [0x0F, 0x0D, 0<<3], :modrmA
|
423
|
-
addop 'prefetchw', [0x0F, 0x0D, 1<<3], :modrmA
|
424
|
-
end
|
425
|
-
|
426
|
-
def init_sse_only
|
427
|
-
init_cpu_constants
|
428
|
-
|
429
|
-
addop_macrossps 'addps', [0x0F, 0xA8], :mrmxmm
|
430
|
-
addop 'andnps', [0x0F, 0xAA], :mrmxmm
|
431
|
-
addop 'andps', [0x0F, 0xA4], :mrmxmm
|
432
|
-
addop_macrossps 'cmpps', [0x0F, 0xC2], :mrmxmm
|
433
|
-
addop 'comiss', [0x0F, 0x2F], :mrmxmm
|
434
|
-
|
435
|
-
[['pi2ps', 0x2A], ['ps2pi', 0x2D], ['tps2pi', 0x2C]].each { |str, bin|
|
436
|
-
addop('cvt' << str, [0x0F, bin], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrmmmx }
|
437
|
-
addop('cvt' << str.tr('p', 's'), [0x0F, bin], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrm ; o.props[:needpfx] = 0xF3 }
|
438
|
-
}
|
439
|
-
|
440
|
-
addop_macrossps 'divps', [0x0F, 0x5E], :mrmxmm
|
441
|
-
addop 'ldmxcsr', [0x0F, 0xAE, 2<<3], :modrmA
|
442
|
-
addop_macrossps 'maxps', [0x0F, 0x5F], :mrmxmm
|
443
|
-
addop_macrossps 'minps', [0x0F, 0x5D], :mrmxmm
|
444
|
-
addop('movaps', [0x0F, 0x28], :mrmxmm, {:d => [1, 0]}) { |o| o.args.reverse! }
|
445
|
-
addop('movd', [0x0F, 0x6E], :mrmxmm, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmxmm)] = :modrm ; o.args.reverse! ; o.props[:needpfx] = 0x66 }
|
446
|
-
addop('movdqa', [0x0F, 0x6F], :mrmxmm, {:d => [1, 4]}) { |o| o.args.reverse! ; o.props[:needpfx] = 0x66 }
|
447
|
-
|
448
|
-
# movhlps(reg, reg){nomem} == movlps(reg, mrm){no restriction}...
|
449
|
-
addop 'movhlps', [0x0F, 0x12], :mrmxmm, {:d => [1, 0]}
|
450
|
-
addop 'movlps', [0x0F, 0x12], :mrmxmm, {:d => [1, 0]}
|
451
|
-
addop 'movlhps', [0x0F, 0x16], :mrmxmm, {:d => [1, 0]}
|
452
|
-
addop 'movhps', [0x0F, 0x16], :mrmxmm, {:d => [1, 0]}
|
453
|
-
|
454
|
-
addop 'movmskps',[0x0F, 0x50, 0xC0], nil, {:reg => [2, 3], :regxmm => [2, 0]}, :regxmm, :reg
|
455
|
-
addop('movss', [0x0F, 0x10], :mrmxmm, {:d => [1, 0]}) { |o| o.props[:needpfx] = 0xF3 }
|
456
|
-
addop 'movups', [0x0F, 0x10], :mrmxmm, {:d => [1, 0]}
|
457
|
-
addop_macrossps 'mulps', [0x0F, 0x59], :mrmxmm
|
458
|
-
addop 'orps', [0x0F, 0x56], :mrmxmm
|
459
|
-
addop_macrossps 'rcpps', [0x0F, 0x53], :mrmxmm
|
460
|
-
addop_macrossps 'rsqrtps',[0x0F, 0x52], :mrmxmm
|
461
|
-
addop 'shufps', [0x0F, 0xC6], :mrmxmm, {}, :u8
|
462
|
-
addop_macrossps 'sqrtps', [0x0F, 0x51], :mrmxmm
|
463
|
-
addop 'stmxcsr', [0x0F, 0xAE, 3<<3], :modrmA
|
464
|
-
addop_macrossps 'subps', [0x0F, 0x5C], :mrmxmm
|
465
|
-
addop 'ucomiss', [0x0F, 0x2E], :mrmxmm
|
466
|
-
addop 'unpckhps',[0x0F, 0x15], :mrmxmm
|
467
|
-
addop 'unpcklps',[0x0F, 0x14], :mrmxmm
|
468
|
-
addop 'xorps', [0x0F, 0x57], :mrmxmm
|
469
|
-
|
470
|
-
# start of integer instruction (accept opsz override prefix to access xmm)
|
471
|
-
addop('pavgb', [0x0F, 0xE0], :mrmmmx) { |o| o.props[:xmmx] = true }
|
472
|
-
addop('pavgw', [0x0F, 0xE3], :mrmmmx) { |o| o.props[:xmmx] = true }
|
473
|
-
# TODO addop('pextrw', [0x0F, 0xC5], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } { |o| o.props[:xmmx] = true ; o.args << :u8 }
|
474
|
-
# addop('pinsrw', [0x0F, 0xC4], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } { |o| o.props[:xmmx] = true ; o.args << :u8 }
|
475
|
-
addop('pmaxsw', [0x0F, 0xEE], :mrmmmx) { |o| o.props[:xmmx] = true }
|
476
|
-
addop('pmaxub', [0x0F, 0xDE], :mrmmmx) { |o| o.props[:xmmx] = true }
|
477
|
-
addop('pminsw', [0x0F, 0xEA], :mrmmmx) { |o| o.props[:xmmx] = true }
|
478
|
-
addop('pminub', [0x0F, 0xDA], :mrmmmx) { |o| o.props[:xmmx] = true }
|
479
|
-
# addop('pmovmskb',[0x0F, 0xD4], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } ) { |o| o.props[:xmmx] = true } # no mem ref in the mrm
|
480
|
-
addop('pmulhuw', [0x0F, 0xE4], :mrmmmx) { |o| o.props[:xmmx] = true }
|
481
|
-
addop('psadbw', [0x0F, 0xF6], :mrmmmx) { |o| o.props[:xmmx] = true }
|
482
|
-
addop('pshufw', [0x0F, 0x70], :mrmmmx) { |o| o.props[:xmmx] = true ; o.args << :u8 }
|
483
|
-
addop('maskmovq',[0x0F, 0xF7], :mrmmmx) { |o| o.props[:xmmx] = true } # nomem
|
484
|
-
addop('movntq', [0x0F, 0xE7], :mrmmmx) { |o| o.props[:xmmx] = true }
|
485
|
-
addop 'movntps', [0x0F, 0x2B], :mrmxmm
|
486
|
-
addop 'prefetcht0', [0x0F, 0x18, 1<<3], :modrmA
|
487
|
-
addop 'prefetcht1', [0x0F, 0x18, 2<<3], :modrmA
|
488
|
-
addop 'prefetcht2', [0x0F, 0x18, 3<<3], :modrmA
|
489
|
-
addop 'prefetchnta',[0x0F, 0x18, 0<<3], :modrmA
|
490
|
-
addop 'sfence', [0x0F, 0xAE, 0xF8]
|
491
|
-
end
|
492
|
-
|
493
|
-
# XXX must be done after init_sse (patches :regmmx opcodes)
|
494
|
-
# TODO complete the list
|
495
|
-
def init_sse2_only
|
496
|
-
init_cpu_constants
|
497
|
-
|
498
|
-
@opcode_list.each { |o| o.props[:xmmx] = true if o.args.include? :regmmx and o.args.include? :modrmmmx }
|
499
|
-
|
500
|
-
# TODO <..blabla...integer...blabla..>
|
501
|
-
|
502
|
-
# nomem
|
503
|
-
addop('clflush', [0x0F, 0xAE, 7<<3], :modrmA) { |o| o.props[:argsz] = 8 }
|
504
|
-
addop('maskmovdqu', [0x0F, 0xF7], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
505
|
-
addop('movntpd', [0x0F, 0x2B], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
506
|
-
addop('movntdq', [0x0F, 0xE7], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
507
|
-
addop 'movnti', [0x0F, 0xC3], :mrm
|
508
|
-
addop('pause', [0x90]) { |o| o.props[:needpfx] = 0xF3 }
|
509
|
-
addop 'lfence', [0x0F, 0xAE, 0xE8]
|
510
|
-
addop 'mfence', [0x0F, 0xAE, 0xF0]
|
511
|
-
end
|
512
|
-
|
513
|
-
def init_sse3_only
|
514
|
-
init_cpu_constants
|
515
|
-
|
516
|
-
addop('addsubpd', [0x0F, 0xD0], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
517
|
-
addop('addsubps', [0x0F, 0xD0], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
|
518
|
-
addop('haddpd', [0x0F, 0x7C], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
519
|
-
addop('haddps', [0x0F, 0x7C], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
|
520
|
-
addop('hsubpd', [0x0F, 0x7D], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
521
|
-
addop('hsubps', [0x0F, 0x7D], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
|
522
|
-
|
523
|
-
addop 'monitor', [0x0F, 0x01, 0xC8]
|
524
|
-
addop 'mwait', [0x0F, 0x01, 0xC9]
|
525
|
-
|
526
|
-
addop('fisttp', [0xDF, 1<<3], :modrmA) { |o| o.props[:argsz] = 16 }
|
527
|
-
addop('fisttp', [0xDB, 1<<3], :modrmA) { |o| o.props[:argsz] = 32 }
|
528
|
-
addop('fisttp', [0xDD, 1<<3], :modrmA) { |o| o.props[:argsz] = 64 }
|
529
|
-
addop('lddqu', [0x0F, 0xF0], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrmA ; o.props[:needpfx] = 0xF2 }
|
530
|
-
addop('movddup', [0x0F, 0x12], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
|
531
|
-
addop('movshdup', [0x0F, 0x16], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
|
532
|
-
addop('movsldup', [0x0F, 0x12], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
|
533
|
-
end
|
534
|
-
|
535
|
-
def init_vmx_only
|
536
|
-
init_cpu_constants
|
537
|
-
|
538
|
-
addop 'vmcall', [0x0F, 0x01, 0xC1]
|
539
|
-
addop 'vmlaunch', [0x0F, 0x01, 0xC2]
|
540
|
-
addop 'vmresume', [0x0F, 0x01, 0xC3]
|
541
|
-
addop 'vmxoff', [0x0F, 0x01, 0xC4]
|
542
|
-
addop 'vmread', [0x0F, 0x78], :mrm
|
543
|
-
addop 'vmwrite', [0x0F, 0x79], :mrm
|
544
|
-
addop('vmclear', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 ; o.props[:needpfx] = 0x66 }
|
545
|
-
addop('vmxon', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 ; o.props[:needpfx] = 0xF3 }
|
546
|
-
addop('vmptrld', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 }
|
547
|
-
addop('vmptrrst', [0x0F, 0xC7, 7<<3], :modrmA) { |o| o.props[:argsz] = 64 }
|
548
|
-
addop('invept', [0x0F, 0x38, 0x80], :mrmA) { |o| o.props[:needpfx] = 0x66 }
|
549
|
-
addop('invvpid', [0x0F, 0x38, 0x81], :mrmA) { |o| o.props[:needpfx] = 0x66 }
|
550
|
-
|
551
|
-
addop 'getsec', [0x0F, 0x37]
|
552
|
-
|
553
|
-
addop('movbe', [0x0F, 0x38, 0xF0], :mrm, { :d => [2, 0] }) { |o| o.args.reverse! }
|
554
|
-
addop 'xgetbv', [0x0F, 0x01, 0xD0]
|
555
|
-
addop 'xsetbv', [0x0F, 0x01, 0xD1]
|
556
|
-
addop 'rdtscp', [0x0F, 0x01, 0xF9]
|
557
|
-
addop 'xrstor', [0x0F, 0xAE, 5<<3], :modrmA
|
558
|
-
addop 'xsave', [0x0F, 0xAE, 4<<3], :modrmA
|
559
|
-
addop 'nop', [0x0F, 0x1F], 0 # which family does this belong to ?
|
560
|
-
end
|
561
|
-
|
562
|
-
def init_sse42_only
|
563
|
-
init_cpu_constants
|
564
|
-
|
565
|
-
addop('crc32', [0x0F, 0x38, 0xF0], :mrmw) { |o| o.props[:needpfx] = 0xF2 }
|
566
|
-
addop('pcmpestrm', [0x0F, 0x3A, 0x60], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
|
567
|
-
addop('pcmpestri', [0x0F, 0x3A, 0x61], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
|
568
|
-
addop('pcmpistrm', [0x0F, 0x3A, 0x62], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
|
569
|
-
addop('pcmpistri', [0x0F, 0x3A, 0x63], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
|
570
|
-
addop('pcmpgtq', [0x0F, 0x38, 0x37], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
|
571
|
-
addop('popcnt', [0x0F, 0xB8], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
|
572
|
-
end
|
573
|
-
|
574
|
-
|
575
|
-
#
|
576
|
-
# CPU family dependencies
|
577
|
-
#
|
578
|
-
|
579
|
-
def init_386_common
|
580
|
-
init_386_common_only
|
581
|
-
end
|
582
|
-
|
583
|
-
def init_386
|
584
|
-
init_386_common
|
585
|
-
init_386_only
|
586
|
-
end
|
587
|
-
|
588
|
-
def init_387
|
589
|
-
init_387_only
|
590
|
-
end
|
591
|
-
|
592
|
-
def init_486
|
593
|
-
init_386
|
594
|
-
init_387
|
595
|
-
init_486_only
|
596
|
-
end
|
597
|
-
|
598
|
-
def init_pentium
|
599
|
-
init_486
|
600
|
-
init_pentium_only
|
601
|
-
end
|
602
|
-
|
603
|
-
def init_3dnow
|
604
|
-
init_pentium
|
605
|
-
init_3dnow_only
|
606
|
-
end
|
607
|
-
|
608
|
-
def init_p6
|
609
|
-
init_pentium
|
610
|
-
init_p6_only
|
611
|
-
end
|
612
|
-
|
613
|
-
def init_sse
|
614
|
-
init_p6
|
615
|
-
init_sse_only
|
616
|
-
end
|
617
|
-
|
618
|
-
def init_sse2
|
619
|
-
init_sse
|
620
|
-
init_sse2_only
|
621
|
-
end
|
622
|
-
|
623
|
-
def init_sse3
|
624
|
-
init_sse2
|
625
|
-
init_sse3_only
|
626
|
-
end
|
627
|
-
|
628
|
-
def init_vmx
|
629
|
-
init_sse3
|
630
|
-
init_vmx_only
|
631
|
-
end
|
632
|
-
|
633
|
-
def init_all
|
634
|
-
init_vmx
|
635
|
-
init_sse42_only
|
636
|
-
init_3dnow_only
|
637
|
-
end
|
638
|
-
|
639
|
-
alias init_latest init_all
|
640
|
-
|
641
|
-
|
642
|
-
#
|
643
|
-
# addop_* macros
|
644
|
-
#
|
645
|
-
|
646
|
-
def addop_macro1(name, num, immtype=:i)
|
647
|
-
addop name, [(num << 3) | 4], nil, {:w => [0, 0]}, :reg_eax, immtype
|
648
|
-
addop name, [num << 3], :mrmw, {:d => [0, 1]}
|
649
|
-
addop name, [0x80], num, {:w => [0, 0], :s => [0, 1]}, immtype
|
650
|
-
end
|
651
|
-
def addop_macro2(name, num)
|
652
|
-
addop name, [0x0F, 0xBA], (4 | num), {}, :u8
|
653
|
-
addop(name, [0x0F, 0xA3 | (num << 3)], :mrm) { |op| op.args.reverse! }
|
654
|
-
end
|
655
|
-
def addop_macro3(name, num)
|
656
|
-
addop name, [0xD0], num, {:w => [0, 0]}, :imm_val1
|
657
|
-
addop name, [0xD2], num, {:w => [0, 0]}, :reg_cl
|
658
|
-
addop name, [0xC0], num, {:w => [0, 0]}, :u8
|
659
|
-
end
|
660
|
-
|
661
|
-
def addop_macrotttn(name, bin, hint, fields = {}, *props, &blk)
|
662
|
-
[%w{o}, %w{no}, %w{b nae c}, %w{nb ae nc},
|
663
|
-
%w{z e}, %w{nz ne}, %w{be na}, %w{nbe a},
|
664
|
-
%w{s}, %w{ns}, %w{p pe}, %w{np po},
|
665
|
-
%w{l nge}, %w{nl ge}, %w{le ng}, %w{nle g}].each_with_index { |e, i|
|
666
|
-
b = bin.dup
|
667
|
-
if b[0] == 0x0F
|
668
|
-
b[1] |= i
|
669
|
-
else
|
670
|
-
b[0] |= i
|
671
|
-
end
|
672
|
-
|
673
|
-
e.each { |k| addop(name + k, b.dup, hint, fields.dup, *props, &blk) }
|
674
|
-
}
|
675
|
-
end
|
676
|
-
|
677
|
-
def addop_macrostr(name, bin, type)
|
678
|
-
# addop(name, bin.dup, {:w => [0, 0]}) { |o| o.props[type] = true } # TODO allow segment override
|
679
|
-
addop(name+'b', bin) { |o| o.props[:opsz] = 16 ; o.props[type] = true }
|
680
|
-
addop(name+'b', bin) { |o| o.props[:opsz] = 32 ; o.props[type] = true }
|
681
|
-
bin = bin.dup
|
682
|
-
bin[0] |= 1
|
683
|
-
addop(name+'w', bin) { |o| o.props[:opsz] = 16 ; o.props[type] = true }
|
684
|
-
addop(name+'d', bin) { |o| o.props[:opsz] = 32 ; o.props[type] = true }
|
685
|
-
end
|
686
|
-
|
687
|
-
def addop_macrofpu1(name, n)
|
688
|
-
addop(name, [0xD8, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
|
689
|
-
addop(name, [0xDC, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
|
690
|
-
addop name, [0xD8, 0xC0|(n<<3)], :regfp, {:d => [0, 2]}
|
691
|
-
end
|
692
|
-
def addop_macrofpu2(name, n, n2=0)
|
693
|
-
addop(name, [0xDE|n2, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 16 }
|
694
|
-
addop(name, [0xDA|n2, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
|
695
|
-
end
|
696
|
-
def addop_macrofpu3(name, n)
|
697
|
-
addop_macrofpu2 name, n, 1
|
698
|
-
addop(name, [0xDF, 0x28|(n<<3)], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
|
699
|
-
end
|
700
|
-
|
701
|
-
def addop_macrogg(ggrng, name, bin, *args, &blk)
|
702
|
-
ggrng.each { |gg|
|
703
|
-
bindup = bin.dup
|
704
|
-
bindup[1] |= gg
|
705
|
-
sfx = %w(b w d q)[gg]
|
706
|
-
addop name+sfx, bindup, *args, &blk
|
707
|
-
}
|
708
|
-
end
|
709
|
-
|
710
|
-
def addop_macrommx(ggrng, name, val)
|
711
|
-
addop_macrogg ggrng, name, [0x0F, 0xC0 | (val << 4)], :mrmmmx
|
712
|
-
addop_macrogg ggrng, name, [0x0F, 0x70, 0xC0 | (val << 4)], nil, {:regmmx => [2, 0]}, :u8
|
713
|
-
end
|
714
|
-
|
715
|
-
def addop_macrossps(name, bin, hint)
|
716
|
-
# don't allow fields argument, as this will be modified by addop (.dup it if needed)
|
717
|
-
addop name, bin, hint
|
718
|
-
addop(name.tr('p', 's'), bin, hint) { |o| o.props[:needpfx] = 0xF3 }
|
719
|
-
end
|
720
|
-
|
721
|
-
# helper function: creates a new Opcode based on the arguments, eventually
|
722
|
-
# yields it for further customisation, and append it to the instruction set
|
723
|
-
# is responsible of the creation of disambiguating opcodes if necessary (:s flag hardcoding)
|
724
|
-
def addop(name, bin, hint=nil, fields={}, *argprops)
|
725
|
-
op = Opcode.new name, bin
|
726
|
-
op.fields.replace fields
|
727
|
-
|
728
|
-
case hint
|
729
|
-
when nil
|
730
|
-
|
731
|
-
when :mrm, :mrmw, :mrmA
|
732
|
-
h = (hint == :mrmA ? :modrmA : :modrm)
|
733
|
-
op.fields[:reg] = [bin.length, 3]
|
734
|
-
op.fields[h] = [bin.length, 0]
|
735
|
-
op.fields[:w] = [bin.length - 1, 0] if hint == :mrmw
|
736
|
-
argprops.unshift :reg, h
|
737
|
-
op.bin << 0
|
738
|
-
when :reg
|
739
|
-
op.fields[:reg] = [bin.length-1, 0]
|
740
|
-
argprops.unshift :reg
|
741
|
-
when :regfp
|
742
|
-
op.fields[:regfp] = [bin.length-1, 0]
|
743
|
-
argprops.unshift :regfp, :regfp0
|
744
|
-
when :modrmA
|
745
|
-
op.fields[:modrmA] = [bin.length-1, 0]
|
746
|
-
argprops << :modrmA
|
747
|
-
|
748
|
-
when Integer # mod/m, reg == opcode extension = hint
|
749
|
-
op.fields[:modrm] = [bin.length, 0]
|
750
|
-
op.bin << (hint << 3)
|
751
|
-
argprops.unshift :modrm
|
752
|
-
|
753
|
-
when :mrmmmx
|
754
|
-
op.fields[:regmmx] = [bin.length, 3]
|
755
|
-
op.fields[:modrm] = [bin.length, 0]
|
756
|
-
bin << 0
|
757
|
-
argprops.unshift :regmmx, :modrmmmx
|
758
|
-
when :mrmxmm
|
759
|
-
op.fields[:regxmm] = [bin.length, 3]
|
760
|
-
op.fields[:modrm] = [bin.length, 0]
|
761
|
-
bin << 0
|
762
|
-
argprops.unshift :regxmm, :modrmxmm
|
763
|
-
else
|
764
|
-
raise SyntaxError, "invalid hint #{hint.inspect} for #{name}"
|
765
|
-
end
|
766
|
-
|
767
|
-
if argprops.index(:u)
|
768
|
-
argprops << :unsigned_imm
|
769
|
-
argprops[argprops.index(:u)] = :i
|
770
|
-
end
|
771
|
-
|
772
|
-
(argprops & @valid_props).each { |p| op.props[p] = true }
|
773
|
-
argprops -= @valid_props
|
774
|
-
|
775
|
-
op.args.concat(argprops & @valid_args)
|
776
|
-
argprops -= @valid_args
|
777
|
-
|
778
|
-
raise "Invalid opcode definition: #{name}: unknown #{argprops.inspect}" unless argprops.empty?
|
779
|
-
|
780
|
-
yield op if block_given?
|
781
|
-
|
782
|
-
argprops = (op.props.keys - @valid_props) + (op.args - @valid_args) + (op.fields.keys - @fields_mask.keys)
|
783
|
-
raise "Invalid opcode customisation: #{name}: #{argprops.inspect}" unless argprops.empty?
|
784
|
-
|
785
|
-
addop_post(op)
|
786
|
-
end
|
787
|
-
|
788
|
-
# this recursive method is in charge of Opcode duplication (eg to hardcode some flag)
|
789
|
-
def addop_post(op)
|
790
|
-
dupe = lambda { |o|
|
791
|
-
dop = Opcode.new o.name.dup
|
792
|
-
dop.bin, dop.fields, dop.props, dop.args = o.bin.dup, o.fields.dup, o.props.dup, o.args.dup
|
793
|
-
dop
|
794
|
-
}
|
795
|
-
if df = op.fields.delete(:d)
|
796
|
-
# hardcode the bit
|
797
|
-
dop = dupe[op]
|
798
|
-
dop.args.reverse!
|
799
|
-
addop_post dop
|
800
|
-
|
801
|
-
op.bin[df[0]] |= 1 << df[1]
|
802
|
-
addop_post op
|
803
|
-
|
804
|
-
return
|
805
|
-
elsif wf = op.fields.delete(:w)
|
806
|
-
# hardcode the bit
|
807
|
-
dop = dupe[op]
|
808
|
-
dop.props[:argsz] = 8
|
809
|
-
addop_post dop
|
810
|
-
|
811
|
-
op.bin[wf[0]] |= 1 << wf[1]
|
812
|
-
addop_post op
|
813
|
-
|
814
|
-
return
|
815
|
-
elsif sf = op.fields.delete(:s)
|
816
|
-
# add explicit choice versions, with lower precedence (so that disassembling will return the general version)
|
817
|
-
# eg "jmp", "jmp.i8", "jmp.i"
|
818
|
-
# also hardcode the bit
|
819
|
-
op32 = op
|
820
|
-
addop_post op32
|
821
|
-
|
822
|
-
op8 = dupe[op]
|
823
|
-
op8.bin[sf[0]] |= 1 << sf[1]
|
824
|
-
op8.args.map! { |arg| arg == :i ? :i8 : arg }
|
825
|
-
addop_post op8
|
826
|
-
|
827
|
-
op32 = dupe[op32]
|
828
|
-
op32.name << '.i'
|
829
|
-
addop_post op32
|
830
|
-
|
831
|
-
op8 = dupe[op8]
|
832
|
-
op8.name << '.i8'
|
833
|
-
addop_post op8
|
834
|
-
|
835
|
-
return
|
836
|
-
elsif op.args.first == :regfp0
|
837
|
-
dop = dupe[op]
|
838
|
-
dop.args.delete :regfp0
|
839
|
-
addop_post dop
|
840
|
-
end
|
841
|
-
|
842
|
-
if op.props[:needpfx] and @opcode_list.find { |oo| oo.name == op.name and not oo.props[:needpfx] }
|
843
|
-
@opcode_list.unshift op
|
844
|
-
else
|
845
|
-
@opcode_list << op
|
846
|
-
end
|
847
|
-
|
848
|
-
if op.args == [:i] or op.args == [:farptr] or op.name[0, 3] == 'ret'
|
849
|
-
# define opsz-override version for ambiguous opcodes
|
850
|
-
op16 = dupe[op]
|
851
|
-
op16.name << '.i16'
|
852
|
-
op16.props[:opsz] = 16
|
853
|
-
@opcode_list << op16
|
854
|
-
op32 = dupe[op]
|
855
|
-
op32.name << '.i32'
|
856
|
-
op32.props[:opsz] = 32
|
857
|
-
@opcode_list << op32
|
858
|
-
elsif op.props[:strop] or op.props[:stropz] or op.args.include? :mrm_imm or
|
859
|
-
op.args.include? :modrm or op.args.include? :modrmA or op.name =~ /loop|xlat/
|
860
|
-
# define adsz-override version for ambiguous opcodes (TODO allow movsd edi / movsd di syntax)
|
861
|
-
# XXX loop pfx 67 = eip+cx, 66 = ip+ecx
|
862
|
-
op16 = dupe[op]
|
863
|
-
op16.name << '.a16'
|
864
|
-
op16.props[:adsz] = 16
|
865
|
-
@opcode_list << op16
|
866
|
-
op32 = dupe[op]
|
867
|
-
op32.name << '.a32'
|
868
|
-
op32.props[:adsz] = 32
|
869
|
-
@opcode_list << op32
|
870
|
-
end
|
871
|
-
end
|
872
|
-
end
|
873
|
-
end
|