metasm 1.0.1 → 1.0.2

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.
Files changed (235) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.hgtags +3 -0
  4. data/Gemfile +1 -0
  5. data/INSTALL +61 -0
  6. data/LICENCE +458 -0
  7. data/README +29 -21
  8. data/Rakefile +10 -0
  9. data/TODO +10 -12
  10. data/doc/code_organisation.txt +2 -0
  11. data/doc/core/DynLdr.txt +247 -0
  12. data/doc/core/ExeFormat.txt +43 -0
  13. data/doc/core/Expression.txt +220 -0
  14. data/doc/core/GNUExports.txt +27 -0
  15. data/doc/core/Ia32.txt +236 -0
  16. data/doc/core/SerialStruct.txt +108 -0
  17. data/doc/core/VirtualString.txt +145 -0
  18. data/doc/core/WindowsExports.txt +61 -0
  19. data/doc/core/index.txt +1 -0
  20. data/doc/style.css +6 -3
  21. data/doc/usage/debugger.txt +327 -0
  22. data/doc/usage/index.txt +1 -0
  23. data/doc/use_cases.txt +2 -2
  24. data/metasm.gemspec +22 -0
  25. data/{lib/metasm.rb → metasm.rb} +11 -3
  26. data/{lib/metasm → metasm}/compile_c.rb +13 -7
  27. data/metasm/cpu/arc.rb +8 -0
  28. data/metasm/cpu/arc/decode.rb +425 -0
  29. data/metasm/cpu/arc/main.rb +191 -0
  30. data/metasm/cpu/arc/opcodes.rb +588 -0
  31. data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
  32. data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
  33. data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
  34. data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
  35. data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
  36. data/metasm/cpu/arm/opcodes.rb +324 -0
  37. data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
  38. data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
  39. data/metasm/cpu/arm64.rb +15 -0
  40. data/metasm/cpu/arm64/debug.rb +38 -0
  41. data/metasm/cpu/arm64/decode.rb +289 -0
  42. data/metasm/cpu/arm64/encode.rb +41 -0
  43. data/metasm/cpu/arm64/main.rb +105 -0
  44. data/metasm/cpu/arm64/opcodes.rb +232 -0
  45. data/metasm/cpu/arm64/parse.rb +20 -0
  46. data/metasm/cpu/arm64/render.rb +95 -0
  47. data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
  48. data/metasm/cpu/bpf/decode.rb +142 -0
  49. data/metasm/cpu/bpf/main.rb +60 -0
  50. data/metasm/cpu/bpf/opcodes.rb +81 -0
  51. data/metasm/cpu/bpf/render.rb +41 -0
  52. data/metasm/cpu/cy16.rb +9 -0
  53. data/metasm/cpu/cy16/decode.rb +253 -0
  54. data/metasm/cpu/cy16/main.rb +63 -0
  55. data/metasm/cpu/cy16/opcodes.rb +78 -0
  56. data/metasm/cpu/cy16/render.rb +41 -0
  57. data/metasm/cpu/dalvik.rb +11 -0
  58. data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
  59. data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
  60. data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
  61. data/metasm/cpu/ia32.rb +17 -0
  62. data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
  63. data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
  64. data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
  65. data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
  66. data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
  67. data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
  68. data/metasm/cpu/ia32/opcodes.rb +1424 -0
  69. data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
  70. data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
  71. data/metasm/cpu/mips.rb +14 -0
  72. data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
  73. data/metasm/cpu/mips/debug.rb +42 -0
  74. data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
  75. data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
  76. data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
  77. data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
  78. data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
  79. data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
  80. data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
  81. data/metasm/cpu/msp430/decode.rb +247 -0
  82. data/metasm/cpu/msp430/main.rb +62 -0
  83. data/metasm/cpu/msp430/opcodes.rb +101 -0
  84. data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
  85. data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
  86. data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
  87. data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
  88. data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
  89. data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
  90. data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
  91. data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
  92. data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
  93. data/metasm/cpu/ppc/parse.rb +55 -0
  94. data/metasm/cpu/python.rb +8 -0
  95. data/metasm/cpu/python/decode.rb +136 -0
  96. data/metasm/cpu/python/main.rb +36 -0
  97. data/metasm/cpu/python/opcodes.rb +180 -0
  98. data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
  99. data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
  100. data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
  101. data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
  102. data/metasm/cpu/x86_64.rb +15 -0
  103. data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
  104. data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
  105. data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
  106. data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
  107. data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
  108. data/metasm/cpu/x86_64/opcodes.rb +136 -0
  109. data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
  110. data/metasm/cpu/x86_64/render.rb +35 -0
  111. data/metasm/cpu/z80.rb +9 -0
  112. data/metasm/cpu/z80/decode.rb +313 -0
  113. data/metasm/cpu/z80/main.rb +67 -0
  114. data/metasm/cpu/z80/opcodes.rb +224 -0
  115. data/metasm/cpu/z80/render.rb +59 -0
  116. data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
  117. data/{lib/metasm → metasm}/decode.rb +35 -4
  118. data/{lib/metasm → metasm}/decompile.rb +15 -16
  119. data/{lib/metasm → metasm}/disassemble.rb +201 -45
  120. data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
  121. data/{lib/metasm → metasm}/dynldr.rb +220 -133
  122. data/{lib/metasm → metasm}/encode.rb +10 -1
  123. data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
  124. data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
  125. data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
  126. data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
  127. data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
  128. data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
  129. data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
  130. data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
  131. data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
  132. data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
  133. data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
  134. data/metasm/exe_format/gb.rb +65 -0
  135. data/metasm/exe_format/javaclass.rb +424 -0
  136. data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
  137. data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
  138. data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
  139. data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
  140. data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
  141. data/metasm/exe_format/pyc.rb +167 -0
  142. data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
  143. data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
  144. data/metasm/exe_format/shellcode_rwx.rb +114 -0
  145. data/metasm/exe_format/swf.rb +205 -0
  146. data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
  147. data/metasm/exe_format/zip.rb +335 -0
  148. data/metasm/gui.rb +13 -0
  149. data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
  150. data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
  151. data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
  152. data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
  153. data/metasm/gui/dasm_graph.rb +1695 -0
  154. data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
  155. data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
  156. data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
  157. data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
  158. data/{lib/metasm → metasm}/gui/debug.rb +93 -27
  159. data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
  160. data/{lib/metasm → metasm}/gui/qt.rb +12 -2
  161. data/{lib/metasm → metasm}/gui/win32.rb +179 -42
  162. data/{lib/metasm → metasm}/gui/x11.rb +59 -59
  163. data/{lib/metasm → metasm}/main.rb +389 -264
  164. data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
  165. data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
  166. data/{lib/metasm → metasm}/os/linux.rb +628 -151
  167. data/metasm/os/main.rb +330 -0
  168. data/{lib/metasm → metasm}/os/windows.rb +132 -42
  169. data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
  170. data/{lib/metasm → metasm}/parse.rb +26 -24
  171. data/{lib/metasm → metasm}/parse_c.rb +221 -116
  172. data/{lib/metasm → metasm}/preprocessor.rb +55 -40
  173. data/{lib/metasm → metasm}/render.rb +14 -38
  174. data/misc/hexdump.rb +2 -1
  175. data/misc/lint.rb +58 -0
  176. data/misc/txt2html.rb +9 -7
  177. data/samples/bindiff.rb +3 -4
  178. data/samples/dasm-plugins/bindiff.rb +15 -0
  179. data/samples/dasm-plugins/bookmark.rb +133 -0
  180. data/samples/dasm-plugins/c_constants.rb +57 -0
  181. data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
  182. data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
  183. data/samples/dasm-plugins/dasm_all.rb +70 -0
  184. data/samples/dasm-plugins/demangle_cpp.rb +31 -0
  185. data/samples/dasm-plugins/deobfuscate.rb +251 -0
  186. data/samples/dasm-plugins/dump_text.rb +35 -0
  187. data/samples/dasm-plugins/export_graph_svg.rb +86 -0
  188. data/samples/dasm-plugins/findgadget.rb +75 -0
  189. data/samples/dasm-plugins/hl_opcode.rb +32 -0
  190. data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
  191. data/samples/dasm-plugins/imm2off.rb +34 -0
  192. data/samples/dasm-plugins/match_libsigs.rb +93 -0
  193. data/samples/dasm-plugins/patch_file.rb +95 -0
  194. data/samples/dasm-plugins/scanfuncstart.rb +36 -0
  195. data/samples/dasm-plugins/scanxrefs.rb +26 -0
  196. data/samples/dasm-plugins/selfmodify.rb +197 -0
  197. data/samples/dasm-plugins/stringsxrefs.rb +28 -0
  198. data/samples/dasmnavig.rb +1 -1
  199. data/samples/dbg-apihook.rb +24 -9
  200. data/samples/dbg-plugins/heapscan.rb +283 -0
  201. data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
  202. data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
  203. data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
  204. data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
  205. data/samples/dbg-plugins/heapscan/winheap.h +174 -0
  206. data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
  207. data/samples/dbg-plugins/trace_func.rb +214 -0
  208. data/samples/disassemble-gui.rb +35 -5
  209. data/samples/disassemble.rb +31 -6
  210. data/samples/dump_upx.rb +24 -12
  211. data/samples/dynamic_ruby.rb +12 -3
  212. data/samples/exeencode.rb +6 -5
  213. data/samples/factorize-headers-peimports.rb +1 -1
  214. data/samples/lindebug.rb +175 -381
  215. data/samples/metasm-shell.rb +1 -2
  216. data/samples/peldr.rb +2 -2
  217. data/tests/all.rb +1 -1
  218. data/tests/arc.rb +26 -0
  219. data/tests/dynldr.rb +22 -4
  220. data/tests/expression.rb +55 -0
  221. data/tests/graph_layout.rb +285 -0
  222. data/tests/ia32.rb +79 -26
  223. data/tests/mips.rb +9 -2
  224. data/tests/x86_64.rb +66 -18
  225. metadata +330 -218
  226. data/lib/metasm/arm/opcodes.rb +0 -177
  227. data/lib/metasm/gui.rb +0 -23
  228. data/lib/metasm/gui/dasm_graph.rb +0 -1354
  229. data/lib/metasm/ia32.rb +0 -14
  230. data/lib/metasm/ia32/opcodes.rb +0 -873
  231. data/lib/metasm/ppc/parse.rb +0 -52
  232. data/lib/metasm/x86_64.rb +0 -12
  233. data/lib/metasm/x86_64/opcodes.rb +0 -118
  234. data/samples/gdbclient.rb +0 -583
  235. data/samples/rubstop.rb +0 -399
@@ -4,8 +4,8 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ia32/opcodes'
8
- require 'metasm/ia32/encode'
7
+ require 'metasm/cpu/ia32/opcodes'
8
+ require 'metasm/cpu/ia32/encode'
9
9
  require 'metasm/parse'
10
10
 
11
11
  module Metasm
@@ -99,14 +99,18 @@ class ModRM
99
99
  else
100
100
  b = o
101
101
  end
102
+ when SimdReg
103
+ raise otok, 'mrm: too many regs' if i
104
+ i = o
105
+ s = 1
102
106
  when Expression
103
- if o.op == :* and (o.rexpr.kind_of? Reg or o.lexpr.kind_of? Reg)
107
+ if o.op == :* and (o.rexpr.kind_of?(Reg) or o.lexpr.kind_of?(Reg))
104
108
  # scaled index
105
109
  raise otok, 'mrm: too many indexes' if i
106
110
  s = o.lexpr
107
111
  i = o.rexpr
108
112
  s, i = i, s if s.kind_of? Reg
109
- raise otok, 'mrm: bad scale' unless s.kind_of? Integer
113
+ raise otok, "mrm: bad scale #{s}" unless [1, 2, 4, 8].include?(s)
110
114
  elsif o.op == :+
111
115
  # recurse
112
116
  walker[o.lexpr]
@@ -125,7 +129,9 @@ class ModRM
125
129
  walker[regify[content.reduce]]
126
130
 
127
131
  # ensure found immediate is really an immediate
128
- raise otok, 'mrm: reg in imm' if imm.kind_of? Expression and not imm.externals.grep(Reg).empty?
132
+ raise otok, 'mrm: reg in imm' if imm.kind_of?(Expression) and not imm.externals.grep(Reg).empty?
133
+
134
+ raise otok, 'mrm: bad reg size' if b.kind_of?(Reg) and i.kind_of?(Reg) and b.sz != i.sz
129
135
 
130
136
  # find default address size
131
137
  adsz = b ? b.sz : i ? i.sz : nil
@@ -153,7 +159,6 @@ end
153
159
  end
154
160
 
155
161
  def parse_prefix(i, pfx)
156
- # XXX check for redefinition ?
157
162
  # implicit 'true' return value when assignment occur
158
163
  i.prefix ||= {}
159
164
  case pfx
@@ -163,6 +168,9 @@ end
163
168
  when 'repne', 'repnz'; i.prefix[:rep] = 'repnz'
164
169
  when 'code16'; i.prefix[:sz] = 16
165
170
  when 'code32'; i.prefix[:sz] = 32
171
+ when 'hintjmp', 'ht'; i.prefix[:jmphint] = 'hintjmp'
172
+ when 'hintnojmp', 'hnt';i.prefix[:jmphint] = 'hintnojmp'
173
+ when /^seg_([c-g]s)$/; i.prefix[:seg] = SegReg.new(SegReg.s_to_i[$1])
166
174
  end
167
175
  end
168
176
 
@@ -230,17 +238,30 @@ end
230
238
  # check if the argument matches the opcode's argument spec
231
239
  def parse_arg_valid?(o, spec, arg)
232
240
  if o.name == 'movsx' or o.name == 'movzx'
233
- if not arg.kind_of? Reg and not arg.kind_of? ModRM
234
- return
241
+ if not arg.kind_of?(Reg) and not arg.kind_of?(ModRM)
242
+ return
235
243
  elsif not arg.sz
236
244
  puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE
237
245
  return
238
246
  elsif spec == :reg # reg=dst, modrm=src (smaller)
239
- return (arg.kind_of? Reg and arg.sz >= 16)
247
+ return (arg.kind_of?(Reg) and arg.sz >= 16)
248
+ elsif o.props[:argsz]
249
+ return arg.sz == o.props[:argsz]
250
+ else
251
+ return arg.sz == 16
252
+ end
253
+ elsif o.name == 'crc32'
254
+ if not arg.kind_of?(Reg) and not arg.kind_of?(ModRM)
255
+ return
256
+ elsif not arg.sz
257
+ puts "ambiguous arg size for indirection in #{o.name}" if $VERBOSE
258
+ return
259
+ elsif spec == :reg
260
+ return (arg.kind_of?(Reg) and arg.sz >= 32)
240
261
  elsif o.props[:argsz]
241
262
  return arg.sz == o.props[:argsz]
242
263
  else
243
- return arg.sz <= 16
264
+ return arg.sz >= 16
244
265
  end
245
266
  end
246
267
 
@@ -254,7 +275,7 @@ end
254
275
  cond and
255
276
  case spec
256
277
  when :reg; arg.kind_of? Reg and (arg.sz >= 16 or o.props[:argsz])
257
- when :modrm; (arg.kind_of? ModRM or arg.kind_of? Reg) and (!arg.sz or arg.sz >= 16 or o.props[:argsz])
278
+ when :modrm; (arg.kind_of? ModRM or arg.kind_of? Reg) and (!arg.sz or arg.sz >= 16 or o.props[:argsz]) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? Reg)
258
279
  when :i; arg.kind_of? Expression
259
280
  when :imm_val1; arg.kind_of? Expression and arg.reduce == 1
260
281
  when :imm_val3; arg.kind_of? Expression and arg.reduce == 3
@@ -268,15 +289,21 @@ end
268
289
  when :eeec; arg.kind_of? CtrlReg
269
290
  when :eeed; arg.kind_of? DbgReg
270
291
  when :eeet; arg.kind_of? TstReg
271
- when :modrmA; arg.kind_of? ModRM
272
292
  when :mrm_imm; arg.kind_of? ModRM and not arg.s and not arg.i and not arg.b
273
293
  when :farptr; arg.kind_of? Farptr
274
294
  when :regfp; arg.kind_of? FpReg
275
295
  when :regfp0; arg.kind_of? FpReg and (arg.val == nil or arg.val == 0)
276
- when :modrmmmx; arg.kind_of? ModRM or (arg.kind_of? SimdReg and (arg.sz == 64 or (arg.sz == 128 and o.props[:xmmx])))
296
+ when :modrmmmx; arg.kind_of? ModRM or (arg.kind_of? SimdReg and (arg.sz == 64 or (arg.sz == 128 and o.props[:xmmx]))) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
277
297
  when :regmmx; arg.kind_of? SimdReg and (arg.sz == 64 or (arg.sz == 128 and o.props[:xmmx]))
278
- when :modrmxmm; arg.kind_of? ModRM or (arg.kind_of? SimdReg and arg.sz == 128)
298
+ when :modrmxmm; arg.kind_of? ModRM or (arg.kind_of? SimdReg and arg.sz == 128) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
279
299
  when :regxmm; arg.kind_of? SimdReg and arg.sz == 128
300
+ when :modrmymm; arg.kind_of? ModRM or (arg.kind_of? SimdReg and arg.sz == 256) and (!o.props[:modrmA] or arg.kind_of? ModRM) and (!o.props[:modrmR] or arg.kind_of? SimdReg)
301
+ when :regymm; arg.kind_of? SimdReg and arg.sz == 256
302
+
303
+ when :vexvreg; arg.kind_of? Reg and arg.sz == @size
304
+ when :vexvxmm, :i4xmm; arg.kind_of? SimdReg and arg.sz == 128
305
+ when :vexvymm, :i4ymm; arg.kind_of? SimdReg and arg.sz == 256
306
+
280
307
  when :i8, :u8, :u16
281
308
  arg.kind_of? Expression and
282
309
  (o.props[:setip] or Expression.in_range?(arg, spec) != false) # true or nil allowed
@@ -303,8 +330,8 @@ end
303
330
  else
304
331
  if r = i.args.grep(Reg).first
305
332
  m.sz = r.sz
306
- elsif opcode_list_byname[i.opname].all? { |o| o.props[:argsz] }
307
- m.sz = opcode_list_byname[i.opname].first.props[:argsz]
333
+ elsif l = opcode_list_byname[i.opname].map { |o| o.props[:argsz] }.uniq and l.length == 1 and l.first
334
+ m.sz = l.first
308
335
  else
309
336
  # this is also the size of ctrlreg/dbgreg etc
310
337
  # XXX fpu/simd ?
@@ -321,6 +348,10 @@ end
321
348
  end
322
349
  end
323
350
 
351
+ def check_reserved_name(name)
352
+ Reg.s_to_i[name]
353
+ end
354
+
324
355
  def instr_uncond_jump_to(target)
325
356
  parse_instruction("jmp #{target}")
326
357
  end
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ia32/opcodes'
7
+ require 'metasm/cpu/ia32/opcodes'
8
8
  require 'metasm/render'
9
9
 
10
10
  # XXX move context in another file ?
@@ -60,12 +60,18 @@ class Ia32
60
60
 
61
61
  def render_instruction(i)
62
62
  r = []
63
- r << 'lock ' if i.prefix and i.prefix[:lock]
64
- r << i.prefix[:rep] << ' ' if i.prefix and i.prefix[:rep]
63
+ if pfx = i.prefix
64
+ r << 'lock ' if pfx[:lock]
65
+ r << pfx[:rep] << ' ' if pfx[:rep]
66
+ r << pfx[:jmphint] << ' ' if pfx[:jmphint]
67
+ r << 'seg_' << pfx[:seg] << ' ' if pfx[:seg]
68
+ end
65
69
  r << i.opname
70
+ sep = ' '
66
71
  i.args.each { |a|
67
72
  a.instruction = i if a.kind_of? ModRM
68
- r << (r.last == i.opname ? ' ' : ', ') << a
73
+ r << sep << a
74
+ sep = ', '
69
75
  }
70
76
  r
71
77
  end
@@ -87,5 +93,26 @@ class Ia32
87
93
  h['toggle lock'] = lambda { (i.prefix ||= {})[:lock] = !i.prefix[:lock] }
88
94
  h
89
95
  end
96
+
97
+ def gui_hilight_word_regexp_init
98
+ ret = {}
99
+
100
+ %w[a b c d].each { |r|
101
+ ret["#{r}l"] = "e?#{r}x|#{r}l"
102
+ ret["#{r}h"] = "e?#{r}x|#{r}h"
103
+ ret["#{r}x"] = ret["e#{r}x"] = "e?#{r}x|#{r}[hl]"
104
+ }
105
+
106
+ %w[sp bp si di].each { |r|
107
+ ret[r] = ret["e#{r}"] = "e?#{r}"
108
+ }
109
+
110
+ ret
111
+ end
112
+
113
+ def gui_hilight_word_regexp(word)
114
+ @gui_hilight_word_hash ||= gui_hilight_word_regexp_init
115
+ @gui_hilight_word_hash[word] or super(word)
116
+ end
90
117
  end
91
118
  end
@@ -0,0 +1,14 @@
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
+ class Metasm::MIPS < Metasm::CPU
7
+ end
8
+
9
+ require 'metasm/main'
10
+ require 'metasm/cpu/mips/parse'
11
+ require 'metasm/cpu/mips/encode'
12
+ require 'metasm/cpu/mips/decode'
13
+ require 'metasm/cpu/mips/render'
14
+ require 'metasm/cpu/mips/debug'
@@ -3,5 +3,5 @@
3
3
  #
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
- require 'metasm/mips/parse'
6
+ require 'metasm/cpu/mips/parse'
7
7
  require 'metasm/compile_c'
@@ -0,0 +1,42 @@
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
+
9
+ module Metasm
10
+ class MIPS
11
+ def dbg_register_pc
12
+ @dbg_register_pc ||= :pc
13
+ end
14
+ def dbg_register_flags
15
+ @dbg_register_flags ||= :flags
16
+ end
17
+
18
+ def dbg_register_list
19
+ @dbg_register_list ||= %w[z0 at v0 v1 a0 a1 a2 a3
20
+ t0 t1 t2 t3 t4 t5 t6 t7
21
+ s0 s1 s2 s3 s4 s5 s6 s7
22
+ t8 t9 k0 k1 gp sp fp ra
23
+ sr mullo mulhi badva cause pc].map { |r| r.to_sym }
24
+ end
25
+
26
+ def dbg_flag_list
27
+ @dbg_flag_list ||= []
28
+ end
29
+
30
+ def dbg_register_size
31
+ @dbg_register_size ||= Hash.new(@size)
32
+ end
33
+
34
+ def dbg_need_stepover(dbg, addr, di)
35
+ di and di.opcode.props[:saveip]
36
+ end
37
+
38
+ def dbg_end_stepout(dbg, addr, di)
39
+ di and di.opcode.name == 'foobar' # TODO
40
+ end
41
+ end
42
+ end
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/mips/opcodes'
7
+ require 'metasm/cpu/mips/opcodes'
8
8
  require 'metasm/decode'
9
9
 
10
10
  module Metasm
@@ -35,30 +35,46 @@ class MIPS
35
35
  end
36
36
 
37
37
  def decode_findopcode(edata)
38
- return if edata.ptr >= edata.data.length
39
- # TODO handle relocations !!
40
38
  di = DecodedInstruction.new(self)
41
39
  val = edata.decode_imm(:u32, @endianness)
42
40
  edata.ptr -= 4
43
- di if di.opcode = @bin_lookaside[val >> 24].find { |op|
44
- (op.bin & op.bin_mask) == (val & op.bin_mask)
45
- }
41
+ if val.kind_of?(Expression)
42
+ # relocations
43
+ hval = Expression[val, :&, 0xff000000].reduce
44
+ if hval.kind_of?(Expression)
45
+ # reloc_i26
46
+ if hval.kind_of?(Expression) and pat = hval.match(Expression[['a', :&, 0x300_0000], :|, 'b'], 'a', 'b')
47
+ hval = pat['b']
48
+ end
49
+ end
50
+ di if di.opcode = @bin_lookaside[hval >> 24].find { |op|
51
+ (op.bin & op.bin_mask) == Expression[val, :&, op.bin_mask].reduce
52
+ }
53
+ else
54
+ di if di.opcode = @bin_lookaside[val >> 24].find { |op|
55
+ (op.bin & op.bin_mask) == (val & op.bin_mask)
56
+ }
57
+ end
46
58
  end
47
59
 
48
60
  def decode_instr_op(edata, di)
49
- # TODO handle relocations !!
50
61
  before_ptr = edata.ptr
51
62
  op = di.opcode
52
63
  di.instruction.opname = op.name
53
64
  val = edata.decode_imm(:u32, @endianness)
54
65
 
55
66
  field_val = lambda { |f|
56
- r = (val >> @fields_shift[f]) & @fields_mask[f]
57
- # XXX do that cleanly (Expr.decode_imm)
67
+ if val.kind_of?(Expression)
68
+ r = Expression[[val, :>>, @fields_shift[f]], :&, @fields_mask[f]].reduce
69
+ else
70
+ r = (val >> @fields_shift[f]) & @fields_mask[f]
71
+ end
72
+
73
+ next r if r.kind_of?(Expression)
58
74
  case f
59
- when :sa, :i16, :it; r = Expression.make_signed(r, 16)
75
+ when :msbd; r += 1
76
+ when :i16; r = Expression.make_signed(r, 16)
60
77
  when :i20; r = Expression.make_signed(r, 20)
61
- when :i26; r = Expression.make_signed(r, 26)
62
78
  else r
63
79
  end
64
80
  }
@@ -66,15 +82,23 @@ class MIPS
66
82
  op.args.each { |a|
67
83
  di.instruction.args << case a
68
84
  when :rs, :rt, :rd; Reg.new field_val[a]
69
- when :sa, :i16, :i20, :i26, :it; Expression[field_val[a]]
70
- when :rs_i16; Memref.new Reg.new(field_val[:rs]), Expression[field_val[:i16]]
85
+ when :sa, :i16, :i20, :i26, :it, :msbd, :sel, :idb; Expression[field_val[a]]
86
+ when :rs_i16
87
+ len = 32
88
+ len = 64 if op.props[:m64]
89
+ len = 16 if op.props[:mi16] or op.props[:mu16]
90
+ len = 8 if op.props[:mi8 ] or op.props[:mu8]
91
+ Memref.new Reg.new(field_val[:rs]), Expression[field_val[:i16]], len
71
92
  when :ft; FpReg.new field_val[a]
72
- when :idm1, :idb; Expression['unsupported']
93
+ when :idm1; Expression['unsupported']
73
94
  else raise SyntaxError, "Internal error: invalid argument #{a} in #{op.name}"
74
95
  end
75
96
  }
97
+
76
98
  di.bin_length += edata.ptr - before_ptr
77
99
 
100
+ return false if edata.ptr > edata.length
101
+
78
102
  di
79
103
  end
80
104
 
@@ -86,7 +110,13 @@ class MIPS
86
110
  if di.opcode.props[:setip] and di.instruction.args.last.kind_of? Expression and di.opcode.name[0] != ?t
87
111
  delta = Expression[di.instruction.args.last, :<<, 2].reduce
88
112
  if di.opcode.args.include? :i26
89
- arg = Expression[[[addr, :+, di.bin_length], :&, 0xfc00_0000], :+, delta].reduce
113
+ # absolute jump in the 0x3ff_ffff region surrounding next_pc
114
+ if delta.kind_of? Expression and delta.op == :& and delta.rexpr == 0xfff_fffc
115
+ # relocated arg: assume the linker mapped so that instr&target are in the same region
116
+ arg = Expression[delta.lexpr].reduce
117
+ else
118
+ arg = Expression[[[addr, :+, di.bin_length], :&, 0xf000_0000], :+, delta].reduce
119
+ end
90
120
  else
91
121
  arg = Expression[[addr, :+, di.bin_length], :+, delta].reduce
92
122
  end
@@ -112,7 +142,7 @@ class MIPS
112
142
  { :$ra => Expression[Expression[di.address, :+, 2*di.bin_length].reduce] }
113
143
  }
114
144
  when 'nop', 'j', 'jr', /^b/; lambda { |di, *a| {} }
115
- when 'lui'; lambda { |di, a0, a1| { a0 => Expression[a1, :<<, 16] } }
145
+ when 'lui'; lambda { |di, a0, a1| { a0 => Expression[[a1, :&, 0xffff], :<<, 16] } }
116
146
  when 'add', 'addu', 'addi', 'addiu'; lambda { |di, a0, a1, a2| { a0 => Expression[a1, :+, a2] } } # XXX addiu $sp, -40h should be addiu $sp, 0xffc0 from the books, but..
117
147
  when 'sub', 'subu'; lambda { |di, a0, a1, a2| { a0 => Expression[a1, :-, a2] } }
118
148
  when 'slt', 'slti'; lambda { |di, a0, a1, a2| { a0 => Expression[a1, :<, a2] } }
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/mips/opcodes'
7
+ require 'metasm/cpu/mips/opcodes'
8
8
  require 'metasm/encode'
9
9
 
10
10
  module Metasm
@@ -40,12 +40,13 @@ class MIPS
40
40
  when :rs_i16
41
41
  set_field[:rs, arg.base.i]
42
42
  val, mask, shift = arg.offset, @fields_mask[:i16], @fields_shift[:i16]
43
- when :sa, :i16, :i20, :i26
43
+ when :sa, :i16, :i20, :i26, :it, :msbd, :sel, :idb
44
44
  val, mask, shift = arg, @fields_mask[sym], @fields_shift[sym]
45
+ val = Expression[val, :-, 1] if sym == :msbd
45
46
  end
46
47
  }
47
48
 
48
- Expression[base, :+, [[val, :&, mask], :<<, shift]].encode(:u32, @endianness) << postdata
49
+ Expression[base, :|, [[val, :&, mask], :<<, shift]].encode(:u32, @endianness) << postdata
49
50
  end
50
51
  end
51
52
  end
@@ -43,16 +43,16 @@ class MIPS < CPU
43
43
  end
44
44
 
45
45
  class Memref
46
- attr_accessor :base, :offset
47
- def initialize(base, offset)
48
- @base, @offset = base, offset
46
+ attr_accessor :base, :offset, :sz
47
+ def initialize(base, offset, sz=32)
48
+ @base, @offset, @sz = base, offset, sz
49
49
  end
50
50
 
51
51
  def symbolic(orig)
52
52
  p = nil
53
53
  p = Expression[p, :+, @base.symbolic] if base
54
54
  p = Expression[p, :+, @offset] if offset
55
- Indirection[p.reduce, 4, orig]
55
+ Indirection[p.reduce, @sz/8, orig]
56
56
  end
57
57
  end
58
58
 
@@ -68,5 +68,12 @@ class MIPS < CPU
68
68
  @opcode_list
69
69
  end
70
70
  end
71
+
72
+ class MIPS64 < MIPS
73
+ def initialize(endianness = :big, family = :latest)
74
+ super(endianness, family)
75
+ @size = 64
76
+ end
77
+ end
71
78
  end
72
79
 
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/mips/main'
7
+ require 'metasm/cpu/mips/main'
8
8
 
9
9
  # TODO coprocessors, floating point, 64bits, thumb mode
10
10
 
@@ -13,8 +13,10 @@ module Metasm
13
13
  class MIPS
14
14
  def addop(name, bin, *args)
15
15
  o = Opcode.new name, bin
16
- o.args.concat(args & @fields_mask.keys)
17
- (args & @valid_props).each { |p| o.props[p] = true }
16
+ args.each { |a|
17
+ o.args << a if @fields_mask[a]
18
+ o.props[a] = true if @valid_props[a]
19
+ }
18
20
  @opcode_list << o
19
21
  end
20
22
 
@@ -45,10 +47,11 @@ class MIPS
45
47
  @opcode_list = []
46
48
  @fields_mask.update :rs => 0x1f, :rt => 0x1f, :rd => 0x1f, :sa => 0x1f,
47
49
  :i16 => 0xffff, :i26 => 0x3ffffff, :rs_i16 => 0x3e0ffff, :it => 0x1f,
48
- :ft => 0x1f, :idm1 => 0x1f, :idb => 0x1f, :sel => 7, :i20 => 0xfffff #, :i32 => 0
50
+ :ft => 0x1f, :idm1 => 0x1f, :idb => 0x1f, :sel => 7, :i20 => 0xfffff
49
51
  @fields_shift.update :rs => 21, :rt => 16, :rd => 11, :sa => 6,
50
52
  :i16 => 0, :i26 => 0, :rs_i16 => 0, :it => 16,
51
- :ft => 16, :idm1 => 11, :idb => 11, :sel => 0, :i20 => 6 #, :i32 => 0
53
+ :ft => 16, :idm1 => 11, :idb => 11, :sel => 0, :i20 => 6
54
+ @valid_props.update :mi8 => true, :mu8 => true, :mi16 => true, :mu16 => true
52
55
 
53
56
  init_mips32_obsolete
54
57
  init_mips32_reserved
@@ -58,12 +61,11 @@ class MIPS
58
61
 
59
62
  addop 'mov', 0b001000 << 26, :rt, :rs # rt <- rs+0
60
63
  addop 'addi', 0b001000 << 26, :rt, :rs, :i16 # add rt <- rs+i
61
- addop 'li', 0b001001 << 26, :rt, :i16 # add $0 # XXX liu ?
64
+ addop 'li', 0b001001 << 26, :rt, :i16 # addiu rt <- zero+i
62
65
  addop 'addiu',0b001001 << 26, :rt, :rs, :i16 # add unsigned
63
66
  addop 'slti', 0b001010 << 26, :rt, :rs, :i16 # set on less than
64
67
  addop 'sltiu',0b001011 << 26, :rt, :rs, :i16 # set on less than unsigned
65
68
  addop 'andi', 0b001100 << 26, :rt, :rs, :i16 # and
66
- addop 'li', 0b001101 << 26, :rt, :i16 # or $0
67
69
  addop 'ori', 0b001101 << 26, :rt, :rs, :i16 # or
68
70
  addop 'xori', 0b001110 << 26, :rt, :rs, :i16 # xor
69
71
  addop 'lui', 0b001111 << 26, :rt, :i16 # load upper
@@ -80,16 +82,16 @@ class MIPS
80
82
  addop 'blez', 0b000110 << 26, :rs, :i16, :setip # <= 0
81
83
  addop 'bgtz', 0b000111 << 26, :rs, :i16, :setip # > 0
82
84
 
83
- addop 'lb', 0b100000 << 26, :rt, :rs_i16 # load byte rs <- [rt+i]
84
- addop 'lh', 0b100001 << 26, :rt, :rs_i16 # load halfword
85
+ addop 'lb', 0b100000 << 26, :rt, :rs_i16, :mi8 # load byte rs <- [rt+i]
86
+ addop 'lh', 0b100001 << 26, :rt, :rs_i16, :mi16 # load halfword
85
87
  addop 'lwl', 0b100010 << 26, :rt, :rs_i16 # load word left
86
88
  addop 'lw', 0b100011 << 26, :rt, :rs_i16 # load word
87
- addop 'lbu', 0b100100 << 26, :rt, :rs_i16 # load byte unsigned
88
- addop 'lhu', 0b100101 << 26, :rt, :rs_i16 # load halfword unsigned
89
+ addop 'lbu', 0b100100 << 26, :rt, :rs_i16, :mu8 # load byte unsigned
90
+ addop 'lhu', 0b100101 << 26, :rt, :rs_i16, :mu16 # load halfword unsigned
89
91
  addop 'lwr', 0b100110 << 26, :rt, :rs_i16 # load word right
90
92
 
91
- addop 'sb', 0b101000 << 26, :rt, :rs_i16 # store byte
92
- addop 'sh', 0b101001 << 26, :rt, :rs_i16 # store halfword
93
+ addop 'sb', 0b101000 << 26, :rt, :rs_i16, :mi8 # store byte
94
+ addop 'sh', 0b101001 << 26, :rt, :rs_i16, :mi16 # store halfword
93
95
  addop 'swl', 0b101010 << 26, :rt, :rs_i16 # store word left
94
96
  addop 'sw', 0b101011 << 26, :rt, :rs_i16 # store word
95
97
  addop 'swr', 0b101110 << 26, :rt, :rs_i16 # store word right
@@ -195,10 +197,10 @@ class MIPS
195
197
 
196
198
 
197
199
  # cp0
198
- addop 'mfc0', (0b010000<<26) | (0b00000<<21), :rt, :rd
199
- addop 'mfc0', (0b010000<<26) | (0b00000<<21), :rt, :rd, :sel
200
- addop 'mtc0', (0b010000<<26) | (0b00100<<21), :rt, :rd
201
- addop 'mtc0', (0b010000<<26) | (0b00100<<21), :rt, :rd, :sel
200
+ addop 'mfc0', (0b010000<<26) | (0b00000<<21), :rt, :idb
201
+ addop 'mfc0', (0b010000<<26) | (0b00000<<21), :rt, :idb, :sel
202
+ addop 'mtc0', (0b010000<<26) | (0b00100<<21), :rt, :idb
203
+ addop 'mtc0', (0b010000<<26) | (0b00100<<21), :rt, :idb, :sel
202
204
 
203
205
  addop 'tlbr', (0b010000<<26) | (1<<25) | 0b000001
204
206
  addop 'tlbwi',(0b010000<<26) | (1<<25) | 0b000010
@@ -235,6 +237,73 @@ class MIPS
235
237
  end
236
238
  alias init_latest init_mips32r2
237
239
  end
240
+
241
+ class MIPS64
242
+ def init_mips64
243
+ init_mips32r2
244
+ @valid_props.update :mi64 => true
245
+
246
+ addop 'ld', 0b110111 << 26, :rt, :rs_i16, :m64
247
+ addop 'lwu', 0b100111 << 26, :rt, :rs_i16
248
+ addop 'sd', 0b111111 << 26, :rt, :rs_i16, :m64
249
+ addop 'scd', 0b111100 << 26, :rt, :rs_i16, :m64
250
+ addop 'ldl', 0b011010 << 26, :rt, :rs_i16
251
+ addop 'ldr', 0b011011 << 26, :rt, :rs_i16
252
+ addop 'sdl', 0b101100 << 26, :rt, :rs_i16
253
+ addop 'sdr', 0b101101 << 26, :rt, :rs_i16
254
+ addop 'lld', 0b110100 << 26, :rt, :rs_i16
255
+ addop 'daddi', 0b011000 << 26, :rt, :rs, :i16
256
+ addop 'daddiu', 0b011001 << 26, :rt, :rs, :i16
257
+
258
+ addop 'dclo', (0b011100 << 26) | (0b100101), :rd, :rt, :rs
259
+ addop 'dclz', (0b011100 << 26) | (0b100100), :rd, :rt, :rs
260
+
261
+ addop 'dadd', 0b101100, :rd, :rs, :rt
262
+ addop 'daddu', 0b101101, :rd, :rs, :rt
263
+ addop 'dsub', 0b101110, :rd, :rs, :rt
264
+ addop 'dsubu', 0b101111, :rd, :rs, :rt
265
+ addop 'dsll', 0b111000, :rd, :rt, :sa
266
+ addop 'dsll32', 0b111100, :rd, :rt, :sa
267
+ addop 'dsllv', 0b010100, :rd, :rt, :rs
268
+ addop 'dsra', 0b111011, :rd, :rt, :sa
269
+ addop 'dsra32', 0b111111, :rd, :rt, :sa
270
+ addop 'dsrav', 0b010111, :rd, :rt, :rs
271
+ addop 'dsrl', 0b111010, :rd, :rt, :sa
272
+ addop 'dsrl32', 0b111110, :rd, :rt, :sa
273
+ addop 'dsrlv', 0b010110, :rd, :rt, :rs
274
+ addop 'ddiv', 0b011110, :rs, :rt
275
+ addop 'ddivu', 0b011111, :rs, :rt
276
+ addop 'dmult', 0b011100, :rs, :rt
277
+ addop 'dmultu', 0b011101, :rs, :rt
278
+
279
+ addop 'dmfc0', (0b010000<<26) | (0b00001<<21), :rt, :idb
280
+ addop 'dmfc0', (0b010000<<26) | (0b00001<<21), :rt, :idb, :sel
281
+ addop 'dmtc0', (0b010000<<26) | (0b00101<<21), :rt, :idb
282
+ addop 'dmtc0', (0b010000<<26) | (0b00101<<21), :rt, :idb, :sel
283
+ end
284
+
285
+ def init_mips64r2
286
+ init_mips64
287
+ @fields_mask.update :msbd => 0x1f
288
+ @fields_shift.update :msbd => 11
289
+
290
+ addop 'dext', (0b011111 << 26) | 0b000011, :rt, :rs, :sa, :msbd # sa => lsb
291
+ addop 'dextm', (0b011111 << 26) | 0b000001, :rt, :rs, :sa, :msbd
292
+ addop 'dextu', (0b011111 << 26) | 0b000010, :rt, :rs, :sa, :msbd
293
+ addop 'dins', (0b011111 << 26) | 0b000111, :rt, :rs, :sa, :msbd
294
+ addop 'dinsm', (0b011111 << 26) | 0b000101, :rt, :rs, :sa, :msbd
295
+ addop 'dinsu', (0b011111 << 26) | 0b000110, :rt, :rs, :sa, :msbd
296
+
297
+ addop 'drotr', (1 << 21) | 0b111010, :rd, :rt, :sa
298
+ addop 'drotr32', (1 << 21) | 0b111110, :rd, :rt, :sa
299
+ addop 'drotrv', (1 << 6) | 0b010110, :rd, :rt, :rs
300
+
301
+ addop 'dsbh', (0b011111 << 26) | (0b00010 << 6) | 0b100100, :rd, :rt
302
+ addop 'dshd', (0b011111 << 26) | (0b00101 << 6) | 0b100100, :rd, :rt
303
+ end
304
+
305
+ alias init_latest init_mips64r2
306
+ end
238
307
  end
239
308
  __END__
240
309
  def macro_addop_cop1(name, bin, *aprops)