metasm 1.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.
Files changed (192) hide show
  1. data/BUGS +11 -0
  2. data/CREDITS +17 -0
  3. data/README +270 -0
  4. data/TODO +114 -0
  5. data/doc/code_organisation.txt +146 -0
  6. data/doc/const_missing.txt +16 -0
  7. data/doc/core_classes.txt +75 -0
  8. data/doc/feature_list.txt +53 -0
  9. data/doc/index.txt +59 -0
  10. data/doc/install_notes.txt +170 -0
  11. data/doc/style.css +3 -0
  12. data/doc/use_cases.txt +18 -0
  13. data/lib/metasm.rb +80 -0
  14. data/lib/metasm/arm.rb +12 -0
  15. data/lib/metasm/arm/debug.rb +39 -0
  16. data/lib/metasm/arm/decode.rb +167 -0
  17. data/lib/metasm/arm/encode.rb +77 -0
  18. data/lib/metasm/arm/main.rb +75 -0
  19. data/lib/metasm/arm/opcodes.rb +177 -0
  20. data/lib/metasm/arm/parse.rb +130 -0
  21. data/lib/metasm/arm/render.rb +55 -0
  22. data/lib/metasm/compile_c.rb +1457 -0
  23. data/lib/metasm/dalvik.rb +8 -0
  24. data/lib/metasm/dalvik/decode.rb +196 -0
  25. data/lib/metasm/dalvik/main.rb +60 -0
  26. data/lib/metasm/dalvik/opcodes.rb +366 -0
  27. data/lib/metasm/decode.rb +213 -0
  28. data/lib/metasm/decompile.rb +2659 -0
  29. data/lib/metasm/disassemble.rb +2068 -0
  30. data/lib/metasm/disassemble_api.rb +1280 -0
  31. data/lib/metasm/dynldr.rb +1329 -0
  32. data/lib/metasm/encode.rb +333 -0
  33. data/lib/metasm/exe_format/a_out.rb +194 -0
  34. data/lib/metasm/exe_format/autoexe.rb +82 -0
  35. data/lib/metasm/exe_format/bflt.rb +189 -0
  36. data/lib/metasm/exe_format/coff.rb +455 -0
  37. data/lib/metasm/exe_format/coff_decode.rb +901 -0
  38. data/lib/metasm/exe_format/coff_encode.rb +1078 -0
  39. data/lib/metasm/exe_format/dex.rb +457 -0
  40. data/lib/metasm/exe_format/dol.rb +145 -0
  41. data/lib/metasm/exe_format/elf.rb +923 -0
  42. data/lib/metasm/exe_format/elf_decode.rb +979 -0
  43. data/lib/metasm/exe_format/elf_encode.rb +1375 -0
  44. data/lib/metasm/exe_format/macho.rb +827 -0
  45. data/lib/metasm/exe_format/main.rb +228 -0
  46. data/lib/metasm/exe_format/mz.rb +164 -0
  47. data/lib/metasm/exe_format/nds.rb +172 -0
  48. data/lib/metasm/exe_format/pe.rb +437 -0
  49. data/lib/metasm/exe_format/serialstruct.rb +246 -0
  50. data/lib/metasm/exe_format/shellcode.rb +114 -0
  51. data/lib/metasm/exe_format/xcoff.rb +167 -0
  52. data/lib/metasm/gui.rb +23 -0
  53. data/lib/metasm/gui/cstruct.rb +373 -0
  54. data/lib/metasm/gui/dasm_coverage.rb +199 -0
  55. data/lib/metasm/gui/dasm_decomp.rb +369 -0
  56. data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
  57. data/lib/metasm/gui/dasm_graph.rb +1354 -0
  58. data/lib/metasm/gui/dasm_hex.rb +543 -0
  59. data/lib/metasm/gui/dasm_listing.rb +599 -0
  60. data/lib/metasm/gui/dasm_main.rb +906 -0
  61. data/lib/metasm/gui/dasm_opcodes.rb +291 -0
  62. data/lib/metasm/gui/debug.rb +1228 -0
  63. data/lib/metasm/gui/gtk.rb +884 -0
  64. data/lib/metasm/gui/qt.rb +495 -0
  65. data/lib/metasm/gui/win32.rb +3004 -0
  66. data/lib/metasm/gui/x11.rb +621 -0
  67. data/lib/metasm/ia32.rb +14 -0
  68. data/lib/metasm/ia32/compile_c.rb +1523 -0
  69. data/lib/metasm/ia32/debug.rb +193 -0
  70. data/lib/metasm/ia32/decode.rb +1167 -0
  71. data/lib/metasm/ia32/decompile.rb +564 -0
  72. data/lib/metasm/ia32/encode.rb +314 -0
  73. data/lib/metasm/ia32/main.rb +233 -0
  74. data/lib/metasm/ia32/opcodes.rb +872 -0
  75. data/lib/metasm/ia32/parse.rb +327 -0
  76. data/lib/metasm/ia32/render.rb +91 -0
  77. data/lib/metasm/main.rb +1193 -0
  78. data/lib/metasm/mips.rb +11 -0
  79. data/lib/metasm/mips/compile_c.rb +7 -0
  80. data/lib/metasm/mips/decode.rb +253 -0
  81. data/lib/metasm/mips/encode.rb +51 -0
  82. data/lib/metasm/mips/main.rb +72 -0
  83. data/lib/metasm/mips/opcodes.rb +443 -0
  84. data/lib/metasm/mips/parse.rb +51 -0
  85. data/lib/metasm/mips/render.rb +43 -0
  86. data/lib/metasm/os/gnu_exports.rb +270 -0
  87. data/lib/metasm/os/linux.rb +1112 -0
  88. data/lib/metasm/os/main.rb +1686 -0
  89. data/lib/metasm/os/remote.rb +527 -0
  90. data/lib/metasm/os/windows.rb +2027 -0
  91. data/lib/metasm/os/windows_exports.rb +745 -0
  92. data/lib/metasm/parse.rb +876 -0
  93. data/lib/metasm/parse_c.rb +3938 -0
  94. data/lib/metasm/pic16c/decode.rb +42 -0
  95. data/lib/metasm/pic16c/main.rb +17 -0
  96. data/lib/metasm/pic16c/opcodes.rb +68 -0
  97. data/lib/metasm/ppc.rb +11 -0
  98. data/lib/metasm/ppc/decode.rb +264 -0
  99. data/lib/metasm/ppc/decompile.rb +251 -0
  100. data/lib/metasm/ppc/encode.rb +51 -0
  101. data/lib/metasm/ppc/main.rb +129 -0
  102. data/lib/metasm/ppc/opcodes.rb +410 -0
  103. data/lib/metasm/ppc/parse.rb +52 -0
  104. data/lib/metasm/preprocessor.rb +1277 -0
  105. data/lib/metasm/render.rb +130 -0
  106. data/lib/metasm/sh4.rb +8 -0
  107. data/lib/metasm/sh4/decode.rb +336 -0
  108. data/lib/metasm/sh4/main.rb +292 -0
  109. data/lib/metasm/sh4/opcodes.rb +381 -0
  110. data/lib/metasm/x86_64.rb +12 -0
  111. data/lib/metasm/x86_64/compile_c.rb +1025 -0
  112. data/lib/metasm/x86_64/debug.rb +59 -0
  113. data/lib/metasm/x86_64/decode.rb +268 -0
  114. data/lib/metasm/x86_64/encode.rb +264 -0
  115. data/lib/metasm/x86_64/main.rb +135 -0
  116. data/lib/metasm/x86_64/opcodes.rb +118 -0
  117. data/lib/metasm/x86_64/parse.rb +68 -0
  118. data/misc/bottleneck.rb +61 -0
  119. data/misc/cheader-findpppath.rb +58 -0
  120. data/misc/hexdiff.rb +74 -0
  121. data/misc/hexdump.rb +55 -0
  122. data/misc/metasm-all.rb +13 -0
  123. data/misc/objdiff.rb +47 -0
  124. data/misc/objscan.rb +40 -0
  125. data/misc/pdfparse.rb +661 -0
  126. data/misc/ppc_pdf2oplist.rb +192 -0
  127. data/misc/tcp_proxy_hex.rb +84 -0
  128. data/misc/txt2html.rb +440 -0
  129. data/samples/a.out.rb +31 -0
  130. data/samples/asmsyntax.rb +77 -0
  131. data/samples/bindiff.rb +555 -0
  132. data/samples/compilation-steps.rb +49 -0
  133. data/samples/cparser_makestackoffset.rb +55 -0
  134. data/samples/dasm-backtrack.rb +38 -0
  135. data/samples/dasmnavig.rb +318 -0
  136. data/samples/dbg-apihook.rb +228 -0
  137. data/samples/dbghelp.rb +143 -0
  138. data/samples/disassemble-gui.rb +102 -0
  139. data/samples/disassemble.rb +133 -0
  140. data/samples/dump_upx.rb +95 -0
  141. data/samples/dynamic_ruby.rb +1929 -0
  142. data/samples/elf_list_needed.rb +46 -0
  143. data/samples/elf_listexports.rb +33 -0
  144. data/samples/elfencode.rb +25 -0
  145. data/samples/exeencode.rb +128 -0
  146. data/samples/factorize-headers-elfimports.rb +77 -0
  147. data/samples/factorize-headers-peimports.rb +109 -0
  148. data/samples/factorize-headers.rb +43 -0
  149. data/samples/gdbclient.rb +583 -0
  150. data/samples/generate_libsigs.rb +102 -0
  151. data/samples/hotfix_gtk_dbg.rb +59 -0
  152. data/samples/install_win_env.rb +78 -0
  153. data/samples/lindebug.rb +924 -0
  154. data/samples/linux_injectsyscall.rb +95 -0
  155. data/samples/machoencode.rb +31 -0
  156. data/samples/metasm-shell.rb +91 -0
  157. data/samples/pe-hook.rb +69 -0
  158. data/samples/pe-ia32-cpuid.rb +203 -0
  159. data/samples/pe-mips.rb +35 -0
  160. data/samples/pe-shutdown.rb +78 -0
  161. data/samples/pe-testrelocs.rb +51 -0
  162. data/samples/pe-testrsrc.rb +24 -0
  163. data/samples/pe_listexports.rb +31 -0
  164. data/samples/peencode.rb +19 -0
  165. data/samples/peldr.rb +494 -0
  166. data/samples/preprocess-flatten.rb +19 -0
  167. data/samples/r0trace.rb +308 -0
  168. data/samples/rubstop.rb +399 -0
  169. data/samples/scan_pt_gnu_stack.rb +54 -0
  170. data/samples/scanpeexports.rb +62 -0
  171. data/samples/shellcode-c.rb +40 -0
  172. data/samples/shellcode-dynlink.rb +146 -0
  173. data/samples/source.asm +34 -0
  174. data/samples/struct_offset.rb +47 -0
  175. data/samples/testpe.rb +32 -0
  176. data/samples/testraw.rb +45 -0
  177. data/samples/win32genloader.rb +132 -0
  178. data/samples/win32hooker-advanced.rb +169 -0
  179. data/samples/win32hooker.rb +96 -0
  180. data/samples/win32livedasm.rb +33 -0
  181. data/samples/win32remotescan.rb +133 -0
  182. data/samples/wintrace.rb +92 -0
  183. data/tests/all.rb +8 -0
  184. data/tests/dasm.rb +39 -0
  185. data/tests/dynldr.rb +35 -0
  186. data/tests/encodeddata.rb +132 -0
  187. data/tests/ia32.rb +82 -0
  188. data/tests/mips.rb +116 -0
  189. data/tests/parse_c.rb +239 -0
  190. data/tests/preprocessor.rb +269 -0
  191. data/tests/x86_64.rb +62 -0
  192. metadata +255 -0
@@ -0,0 +1,51 @@
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/ppc/opcodes'
8
+ require 'metasm/encode'
9
+
10
+ module Metasm
11
+ class PowerPC
12
+ private
13
+ def encode_instr_op(exe, instr, op)
14
+ base = op.bin
15
+ set_field = lambda { |f, v|
16
+ base |= (v & @fields_mask[f]) << @fields_shift[f]
17
+ }
18
+
19
+ val, mask, shift = 0, 0, 0
20
+
21
+ # TODO
22
+ # convert label name for jmp/call/loop to relative offset
23
+ if op.props[:setip] and op.name[0] != ?t and instr.args.last.kind_of? Expression
24
+ postlabel = exe.new_label('jmp_offset')
25
+ instr = instr.dup
26
+ instr.args[-1] = Expression[[instr.args[-1], :-, postlabel], :>>, 2]
27
+ postdata = EncodedData.new '', :export => {postlabel => 0}
28
+ else
29
+ postdata = ''
30
+ end
31
+
32
+ op.args.zip(instr.args).each { |sym, arg|
33
+ case sym
34
+ when :rs, :rt, :rd
35
+ set_field[sym, arg.i]
36
+ when :ft
37
+ set_field[sym, arg.i]
38
+ when :rs_i16
39
+ set_field[:rs, arg.base.i]
40
+ val, mask, shift = arg.offset, @fields_mask[:i16], @fields_shift[:i16]
41
+ when :sa, :i16, :i20
42
+ val, mask, shift = arg, @fields_mask[sym], @fields_shift[sym]
43
+ when :i26
44
+ val, mask, shift = Expression[arg, :>>, 2], @fields_mask[sym], @fields_shift[sym]
45
+ end
46
+ }
47
+
48
+ Expression[base, :+, [[val, :&, mask], :<<, shift]].encode(:u32, @endianness) << postdata
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,129 @@
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/render'
9
+
10
+ module Metasm
11
+ class PowerPC < CPU
12
+ class Reg
13
+ include Renderable
14
+
15
+ def ==(o)
16
+ o.class == self.class and (not respond_to?(:i) or o.i == i)
17
+ end
18
+ end
19
+
20
+ # general purpose reg
21
+ class GPR < Reg
22
+ attr_accessor :i
23
+ def initialize(i)
24
+ @i = i
25
+ end
26
+
27
+ Sym = (0..31).map { |i| "r#{i}".to_sym }
28
+ Sym[1] = :sp
29
+ def symbolic ; Sym[@i] end
30
+ def render ; [@i == 1 ? 'sp' : "r#@i"] end
31
+ end
32
+
33
+ # special purpose reg
34
+ class SPR < Reg
35
+ class << self
36
+ attr_accessor :s_to_i, :i_to_s
37
+ end
38
+ @s_to_i = {'xer' => 1, 'lr' => 8, 'ctr' => 9, 'dec' => 22, 'srr0' => 26, 'srr1' => 27,
39
+ 'sprg0' => 272, 'sprg1' => 273, 'sprg2' => 274, 'sprg3' => 275, 'pvr' => 287}
40
+ @i_to_s = @s_to_i.invert
41
+
42
+ attr_accessor :i
43
+ def initialize(i)
44
+ @i = i
45
+ end
46
+
47
+ Sym = @i_to_s.sort.inject({}) { |h, (k, v)| h.update k => v.to_sym }
48
+ def symbolic ; Sym[@i] end
49
+ def render ; [self.class.i_to_s[@i] || "spr#@i"] end
50
+ end
51
+
52
+ # floating point
53
+ class FPR
54
+ attr_accessor :i
55
+ def initialize(i)
56
+ @i = i
57
+ end
58
+
59
+ include Renderable
60
+ def render ; ["fp#@i"] end
61
+ end
62
+
63
+ # machine state reg
64
+ class MSR < Reg
65
+ def symbolic ; :msr end
66
+ def render ; ['msr'] end
67
+ end
68
+
69
+ # condition reg (7 regs * 4 bits : lt, gt, eq, of)
70
+ class CR < Reg
71
+ attr_accessor :i
72
+ def initialize(i)
73
+ @i = i
74
+ end
75
+
76
+ def symbolic ; "cr#@i".to_sym end
77
+ def render ; ["cr#@i"] end
78
+ end
79
+
80
+ # indirection : reg+reg or reg+16b_off
81
+ # r0 may mean 0 in some cases (stwx)
82
+ class Memref
83
+ attr_accessor :base, :offset
84
+ def initialize(base, offset)
85
+ @base, @offset = base, offset
86
+ end
87
+
88
+ def symbolic(orig)
89
+ b = @base.symbolic
90
+ b = nil if b == :r0 # XXX is it true ?
91
+ o = @offset
92
+ o = o.symbolic if o.kind_of? Reg
93
+ Indirection[Expression[b, :+, o].reduce, 4, orig]
94
+ end
95
+
96
+ include Renderable
97
+ def render
98
+ if @offset.kind_of? Reg
99
+ ['(', @base, ' + ', @offset, ')']
100
+ else
101
+ [@offset, '(', @base, ')']
102
+ end
103
+ end
104
+ end
105
+
106
+ def initialize
107
+ super()
108
+ @endianness = :big
109
+ @size = 32
110
+ end
111
+
112
+ def init_opcode_list
113
+ init
114
+ end
115
+
116
+ def render_instruction(i)
117
+ r = [i.opname]
118
+ if not i.args.empty?
119
+ r << ' '
120
+ i.args.each { |a|
121
+ r << a << ', '
122
+ }
123
+ r.pop
124
+ end
125
+ r
126
+ end
127
+ end
128
+ PPC = PowerPC
129
+ end
@@ -0,0 +1,410 @@
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/ppc/main'
8
+
9
+ module Metasm
10
+ class PowerPC
11
+ def addop(name, bin, *argprops)
12
+ o = Opcode.new name, bin
13
+ o.args.concat(argprops & @fields_mask.keys)
14
+ (argprops & @valid_props).each { |p| o.props[p] = true }
15
+ @opcode_list << o
16
+ end
17
+
18
+ # generate l/a variations, add :setip/:saveip, include lr/ctr in opname
19
+ def addop_branch(nbase, bin, *argprops)
20
+ nbase += 'ctr' if argprops.delete :ctr
21
+ nbase += 'lr' if argprops.delete :lr
22
+ addop(nbase, bin, :setip, *argprops)
23
+ addop(nbase+'l', bin|1, :setip, :saveip, *argprops)
24
+ return if nbase[-2, 2] == 'lr' or nbase[-3, 3] == 'ctr'
25
+
26
+ addop(nbase+'a', bin|2, :setip, *argprops)
27
+ addop(nbase+'la', bin|3, :setip, :saveip, *argprops)
28
+ end
29
+
30
+ # generate condition variations, passes to addop_branch
31
+ def addop_branchcond(nbase, bin, *argprops)
32
+ # :bi & 0b11100 is the condition register to use, shift&mask == :bfa. Defaults to cr0
33
+ # bo values
34
+ # no cc (10000 != 0)
35
+ addop_branch(nbase, bin|(0b10100<<21), :ign_bo_zzz, :stopexec, *argprops)
36
+ addop_branch(nbase+'dz', bin|(0b10010<<21), :ign_bo_at2, :stopexec, *argprops) if not argprops.include? :ctr
37
+ addop_branch(nbase+'dnz', bin|(0b10000<<21), :ign_bo_at2, :stopexec, *argprops) if not argprops.include? :ctr
38
+
39
+ # conditionnal
40
+ %w[lt gt eq so].each_with_index { |cd, i|
41
+ ncd = {'lt' => 'gte', 'gt' => 'lte', 'eq' => 'ne', 'so' => 'nso'}[cd]
42
+ addop_branch(nbase+cd, bin|(0b1100<<21)|(i<<16), :ign_bo_at, *argprops)
43
+ addop_branch(nbase+cd, bin|(0b1100<<21)|(i<<16), :ign_bo_at, :bfa, *argprops)
44
+ addop_branch(nbase+ncd, bin|(0b100<<21)|(i<<16), :ign_bo_at, *argprops)
45
+ addop_branch(nbase+ncd, bin|(0b100<<21)|(i<<16), :ign_bo_at, :bfa, *argprops)
46
+ next if argprops.include? :ctr
47
+
48
+ addop_branch(nbase+'dz'+cd, bin|(0b1010<<21)|(i<<16), :ign_bo_z, *argprops)
49
+ addop_branch(nbase+'dz'+cd, bin|(0b1010<<21)|(i<<16), :ign_bo_z, :bfa, *argprops)
50
+ addop_branch(nbase+'dnz'+cd, bin|(0b1000<<21)|(i<<16), :ign_bo_z, *argprops)
51
+ addop_branch(nbase+'dnz'+cd, bin|(0b1000<<21)|(i<<16), :ign_bo_z, :bfa, *argprops)
52
+ addop_branch(nbase+'dz'+ncd, bin|(0b010<<21)|(i<<16), :ign_bo_z, *argprops)
53
+ addop_branch(nbase+'dz'+ncd, bin|(0b010<<21)|(i<<16), :ign_bo_z, :bfa, *argprops)
54
+ addop_branch(nbase+'dnz'+ncd, bin|(0b000<<21)|(i<<16), :ign_bo_z, *argprops)
55
+ addop_branch(nbase+'dnz'+ncd, bin|(0b000<<21)|(i<<16), :ign_bo_z, :bfa, *argprops)
56
+ }
57
+ end
58
+
59
+ def addop_trap(nbase, bin, *argprops)
60
+ addop nbase+'trap', bin|(0b11111<<21), *argprops
61
+ addop nbase+'lt', bin|(0b10000<<21), *argprops
62
+ addop nbase+'le', bin|(0b10100<<21), *argprops
63
+ addop nbase+'eq', bin|(0b00100<<21), *argprops
64
+ addop nbase+'ge', bin|(0b01100<<21), *argprops
65
+ addop nbase+'gt', bin|(0b01000<<21), *argprops
66
+ addop nbase+'ne', bin|(0b11000<<21), *argprops
67
+ addop nbase+'llt', bin|(0b00010<<21), *argprops
68
+ addop nbase+'lle', bin|(0b00110<<21), *argprops
69
+ addop nbase+'lge', bin|(0b00101<<21), *argprops
70
+ addop nbase+'lgt', bin|(0b00001<<21), *argprops
71
+ end
72
+
73
+
74
+ # generate cmp variations (default cr0, w/d)
75
+ def addop_cmp(nbase, bin, *argprops)
76
+ addop nbase.sub(/(cmpl?)/, '\\1w'), bin, *(argprops-[:bf])
77
+ addop nbase.sub(/(cmpl?)/, '\\1w'), bin, *argprops
78
+ addop nbase.sub(/(cmpl?)/, '\\1d'), bin|(1<<@fields_shift[:l]), *(argprops-[:bf])
79
+ addop nbase.sub(/(cmpl?)/, '\\1d'), bin|(1<<@fields_shift[:l]), *argprops
80
+ end
81
+
82
+ # adds op and 'op.' with last bit of bin set
83
+ def addop_(base, bin, *argprops)
84
+ addop(base, bin, *argprops)
85
+ addop(base+'.', bin|1, *argprops)
86
+ end
87
+
88
+ # adds op and 'opo'
89
+ def addop_o(base, bin, *argprops)
90
+ addop(base, bin, *argprops)
91
+ addop(base+'o', bin|0x400, *argprops)
92
+ end
93
+
94
+ def init
95
+ @opcode_list = []
96
+ @fields_shift.update :aa => 1, :ba => 16, :bb => 11, :bd => 2, :bf => 23,
97
+ :bfa => 18, :bh => 11, :bt => 21, :d => 0, :dq => 4,
98
+ :ds => 2, :flm => 17, :fra => 16, :frb => 11, :frc => 6, :frs => 21,
99
+ :frt => 21, :fxm => 12, :l => 21, :l_ => 21, :l__ => 16, :lev => 5,
100
+ :li => 2, :lk => 0, :mb => 5, :mb_ => 6, :me => 5, :me_ => 1,
101
+ :nb => 11, :oe => 10, :ra => 16, :rb => 11, :rc => 0, :rs => 21,
102
+ :rt => 21, :sh => 11, :sh_ => 1, :si => 0, :spr => 11, :sr => 16,
103
+ :tbr => 11, :th => 21, :to => 21, :u => 12, :ui => 0,
104
+ :ign_bo_zzz => 16, :ign_bo_z => 21, :ign_bo_at => 21, :ign_bo_at2 => 16
105
+
106
+ @fields_mask.update :aa => 1, :ba => 31, :bb => 31, :bd => 0x3FFF, :bf => 7,
107
+ :bfa => 7, :bh => 3, :bt => 31, :d => 0xFFFF, :dq => 0xFFF,
108
+ :ds => 0x3FFF, :flm => 255, :fra => 31, :frb => 31, :frc => 31, :frs => 31,
109
+ :frt => 31, :fxm => 255, :l => 1, :l_ => 3, :l__ => 1, :lev => 127,
110
+ :li => 0xFFFFFF, :lk => 1, :mb => 63, :mb_ => 31, :me => 63, :me_ => 31,
111
+ :nb => 31, :oe => 1, :ra => 31, :rb => 31, :rc => 1, :rs => 31,
112
+ :rt => 31, :sh => 31, :sh_ => 1, :si => 0xFFFF, :spr => 0x3FF, :sr => 15,
113
+ :tbr => 0x3FF, :th => 15, :to => 31, :u => 15, :ui => 0xFFFF,
114
+ :ign_bo_zzz => 0b101111111, :ign_bo_z => 1, :ign_bo_at => 3, :ign_bo_at2 => 0b100111111
115
+
116
+ @fields_shift[:ra_i16] = @fields_shift[:ra_i16s] = @fields_shift[:ra_i16q] = 0
117
+ @fields_mask[:ra_i16] = (@fields_mask[:d] << @fields_shift[:d]) | (@fields_mask[:ra] << @fields_shift[:ra])
118
+ @fields_mask[:ra_i16s] = (@fields_mask[:ds] << @fields_shift[:d]) | (@fields_mask[:ra] << @fields_shift[:ra])
119
+ @fields_mask[:ra_i16q] = (@fields_mask[:dq] << @fields_shift[:d]) | (@fields_mask[:ra] << @fields_shift[:ra])
120
+
121
+
122
+ addop_branch 'b', 0x48000000, :li, :stopexec
123
+ addop_branchcond 'b', 0x40000000, :bd
124
+ addop_branchcond 'b', 0x4C000020, :lr
125
+ addop_branchcond 'b', 0x4C000420, :ctr
126
+
127
+ addop 'sc', 0x44000002, :lev
128
+ addop 'crand', 0x4C000202, :bt, :ba, :bb
129
+ addop 'crxor', 0x4C000182, :bt, :ba, :bb
130
+ # alias crclr bx -> crxor bx, bx, bx
131
+ addop 'cror', 0x4C000382, :bt, :ba, :bb
132
+ # alias crmove bx, by -> cror bx, by, by
133
+ addop 'crnand', 0x4C0001C2, :bt, :ba, :bb
134
+ addop 'crnor', 0x4C000042, :bt, :ba, :bb
135
+ # alias crnot bx, by -> crnor bx, by, by
136
+ addop 'crandc', 0x4C000102, :bt, :ba, :bb
137
+ addop 'creqv', 0x4C000242, :bt, :ba, :bb
138
+ # alias crset bx -> creqv bx, bx, bx
139
+ addop 'crorc', 0x4C000342, :bt, :ba, :bb
140
+ addop 'mcrf', 0x4C000000, :bf, :bfa
141
+ addop 'lbz', 0x88000000, :rt, :ra_i16
142
+ addop 'lbzu', 0x8C000000, :rt, :ra_i16
143
+ addop 'lbzx', 0x7C0000AE, :rt, :ra, :rb
144
+ addop 'lbzux', 0x7C0000EE, :rt, :ra, :rb
145
+ addop 'lhz', 0xA0000000, :rt, :ra_i16
146
+ addop 'lhzu', 0xA4000000, :rt, :ra_i16
147
+ addop 'lhzx', 0x7C00022E, :rt, :ra, :rb
148
+ addop 'lhzux', 0x7C00026E, :rt, :ra, :rb
149
+ addop 'lha', 0xA8000000, :rt, :ra_i16
150
+ addop 'lhau', 0xAC000000, :rt, :ra_i16
151
+ addop 'lhax', 0x7C0002AE, :rt, :ra, :rb
152
+ addop 'lhaux', 0x7C0002EE, :rt, :ra, :rb
153
+ addop 'lwz', 0x80000000, :rt, :ra_i16
154
+ addop 'lwzu', 0x84000000, :rt, :ra_i16
155
+ addop 'lwzx', 0x7C00002E, :rt, :ra, :rb
156
+ addop 'lwzux', 0x7C00006E, :rt, :ra, :rb
157
+ addop 'lwa', 0xE8000002, :rt, :ra_i16s
158
+ addop 'lwax', 0x7C0002AA, :rt, :ra, :rb
159
+ addop 'lwaux', 0x7C0002EA, :rt, :ra, :rb
160
+ addop 'ld', 0xE8000000, :rt, :ra_i16s
161
+ addop 'ldu', 0xE8000001, :rt, :ra_i16s
162
+ addop 'ldx', 0x7C00002A, :rt, :ra, :rb
163
+ addop 'ldux', 0x7C00006A, :rt, :ra, :rb
164
+ addop 'stb', 0x98000000, :rs, :ra_i16
165
+ addop 'stbu', 0x9C000000, :rs, :ra_i16
166
+ addop 'stbx', 0x7C0001AE, :rs, :ra, :rb
167
+ addop 'stbux', 0x7C0001EE, :rs, :ra, :rb
168
+ addop 'sth', 0xB0000000, :rs, :ra_i16
169
+ addop 'sthu', 0xB4000000, :rs, :ra_i16
170
+ addop 'sthx', 0x7C00032E, :rs, :ra, :rb
171
+ addop 'sthux', 0x7C00036E, :rs, :ra, :rb
172
+ addop 'stw', 0x90000000, :rs, :ra_i16
173
+ addop 'stwu', 0x94000000, :rs, :ra_i16
174
+ addop 'stwx', 0x7C00012E, :rs, :ra, :rb
175
+ addop 'stwux', 0x7C00016E, :rs, :ra, :rb
176
+ addop 'std', 0xF8000000, :rs, :ra_i16s
177
+ addop 'stdu', 0xF8000001, :rs, :ra_i16s
178
+ addop 'stdx', 0x7C00012A, :rs, :ra, :rb
179
+ addop 'stdux', 0x7C00016A, :rs, :ra, :rb
180
+ addop 'lhbrx', 0x7C00062C, :rt, :ra, :rb
181
+ addop 'lwbrx', 0x7C00042C, :rt, :ra, :rb
182
+ addop 'sthbrx', 0x7C00072C, :rs, :ra, :rb
183
+ addop 'stwbrx', 0x7C00052C, :rs, :ra, :rb
184
+ addop 'lmw', 0xB8000000, :rt, :ra_i16
185
+ addop 'stmw', 0xBC000000, :rs, :ra_i16
186
+ addop 'lswi', 0x7C0004AA, :rt, :ra, :nb
187
+ addop 'lswx', 0x7C00042A, :rt, :ra, :rb
188
+ addop 'stswi', 0x7C0005AA, :rs, :ra, :nb
189
+ addop 'stswx', 0x7C00052A, :rs, :ra, :rb
190
+ addop 'li', 0x38000000, :rt, :si # alias li rx, value -> addi rx, 0, value
191
+ addop 'addi', 0x38000000, :rt, :ra, :si
192
+ addop 'la', 0x38000000, :rt, :ra_i16 # alias la rx, disp(ry) -> addi rx, ry, disp
193
+ addop 'lis', 0x3C000000, :rt, :si # alias lis rx, value -> addis rx, 0, value
194
+ addop 'addis', 0x3C000000, :rt, :ra, :si
195
+ addop_o 'add', 0x7C000214, :rt, :ra, :rb
196
+ addop 'addic', 0x30000000, :rt, :ra, :si
197
+ addop_o 'sub', 0x7C000050, :rt, :rb, :ra # alias sub rx, ry, rz -> subf rx, rz, ry
198
+ addop_o 'subf', 0x7C000050, :rt, :ra, :rb
199
+ addop 'addic.', 0x34000000, :rt, :ra, :si
200
+ addop 'subfic', 0x20000000, :rt, :ra, :si
201
+ addop_o 'addc', 0x7C000014, :rt, :ra, :rb
202
+ addop_o 'subc', 0x7C000010, :rt, :rb, :ra # alias subc rx, ry, rz -> subfc rx, rz, ry
203
+ addop_o 'subfc',0x7C000010, :rt, :ra, :rb
204
+ addop_o 'adde', 0x7C000114, :rt, :ra, :rb
205
+ addop_o 'addme',0x7C0001D4, :rt, :ra
206
+ addop_o 'subfe',0x7C000110, :rt, :ra, :rb
207
+ addop_o 'subfme',0x7C0001D0,:rt, :ra
208
+ addop_o 'addze',0x7C000194, :rt, :ra
209
+ addop_o 'subfze',0x7C000190,:rt, :ra
210
+ addop_o 'neg', 0x7C0000D0, :rt, :ra
211
+ addop 'mulli', 0x1C000000, :rt, :ra, :si
212
+ addop_o 'mulld',0x7C0001D2, :rt, :ra, :rb
213
+ addop_o 'mullw',0x7C0001D6, :rt, :ra, :rb
214
+ addop_ 'mulhd', 0x7C000092, :rt, :ra, :rb
215
+ addop_ 'mulhdu',0x7C000012, :rt, :ra, :rb
216
+ addop_ 'mulhw', 0x7C000096, :rt, :ra, :rb
217
+ addop_ 'mulhwu',0x7C000016, :rt, :ra, :rb
218
+ addop_o 'divd', 0x7C0003D2, :rt, :ra, :rb
219
+ addop_o 'divw', 0x7C0003D6, :rt, :ra, :rb
220
+ addop_o 'divdu',0x7C000392, :rt, :ra, :rb
221
+ addop_o 'divwu',0x7C000396, :rt, :ra, :rb
222
+ addop_cmp 'cmpi', 0x2C000000, :bf, :ra, :si
223
+ addop_cmp 'cmp', 0x7C000000, :bf, :ra, :rb
224
+ addop_cmp 'cmpli', 0x28000000, :bf, :ra, :ui
225
+ addop_cmp 'cmpl', 0x7C000040, :bf, :ra, :rb
226
+ addop 'andi.', 0x70000000, :ra, :rs, :ui
227
+ addop 'andis.', 0x74000000, :ra, :rs, :ui
228
+ addop 'nop', 0x60000000
229
+ addop 'ori', 0x60000000, :ra, :rs, :ui
230
+ addop 'oris', 0x64000000, :ra, :rs, :ui
231
+ addop 'xori', 0x68000000, :ra, :rs, :ui
232
+ addop 'xoris', 0x6C000000, :ra, :rs, :ui
233
+ addop_ 'and', 0x7C000038, :ra, :rs, :rb
234
+ addop_ 'xor', 0x7C000278, :ra, :rs, :rb
235
+ addop_ 'or', 0x7C000378, :ra, :rs, :rb
236
+ # alias mr rx, ry -> or rx, ry, ry
237
+ addop_ 'nand', 0x7C0003B8, :ra, :rs, :rb
238
+ addop_ 'nor', 0x7C0000F8, :ra, :rs, :rb
239
+ # alias not rx, ry -> nor rx, ry, ry
240
+ addop_ 'andc', 0x7C000078, :ra, :rs, :rb
241
+ addop_ 'eqv', 0x7C000238, :ra, :rs, :rb
242
+ addop_ 'orc', 0x7C000338, :ra, :rs, :rb
243
+ addop_ 'extsb', 0x7C000774, :ra, :rs
244
+ addop_ 'extsw', 0x7C0007B4, :ra, :rs
245
+ addop_ 'extsh', 0x7C000734, :ra, :rs
246
+ addop_ 'cntlzd',0x7C000074, :ra, :rs
247
+ addop_ 'cntlzw',0x7C000034, :ra, :rs
248
+ addop 'popcntb',0x7C0000F4, :ra, :rs
249
+ addop 'clrldi', 0x78000000, :ra, :rs, :mb # alias clrldi rx, ry, n -> rldicl rx, ry, 0, n
250
+ addop_ 'rldicl',0x78000000, :ra, :rs, :sh, :mb, :sh_
251
+ # alias extrdi rx, ry, n, b -> rldicl rx, ry, b+n, 64 - n
252
+ # alias srdi rx, ry, n -> rldicl rx, ry, 64 - n, n
253
+ addop_ 'rldicr',0x78000004, :ra, :rs, :sh, :me, :sh_
254
+ # alias extldi rx, ry, n, b -> rldicr rx, ry, b, n - 1
255
+ # alias sldi rx, ry, n -> rldicr rx, ry, n, 63 - n
256
+ # alias clrrdi rx, ry, n -> rldicr rx, ry, 0, 63 - n
257
+ addop_ 'rldic', 0x78000008, :ra, :rs, :sh, :mb, :sh_
258
+ # alias clrlsldi rx, ry, b, n -> rldic rx, ry, n, b - n
259
+ addop_ 'rlwinm',0x54000000, :ra, :rs, :sh, :mb_, :me_
260
+ # alias extlwi rx, ry, n, b -> rlwinm rx, ry, b, 0, n - 1
261
+ # alias srwi rx, ry, n -> rlwinm rx, ry, 32 - n, n, 31
262
+ # alias clrrwi rx, ry, n -> rlwinm rx, ry, 0, 0, 31 - n
263
+ addop 'rotld', 0x78000010, :ra, :rs, :rb # alias rotld rx, ry, rz -> rldcl rx, ry, rz, 0
264
+ addop_ 'rldcl', 0x78000010, :ra, :rs, :rb, :mb
265
+ addop_ 'rldcr', 0x78000012, :ra, :rs, :rb, :me
266
+ addop 'rotlw', 0x5C000000|(31<<@fields_shift[:me_]), :ra, :rs, :rb # alias rotlw rx, ry, rz -> rlwnm rx, ry, rz, 0, 31
267
+ addop_ 'rlwnm', 0x5C000000, :ra, :rs, :rb, :mb_, :me_
268
+ addop_ 'rldimi',0x7800000C, :ra, :rs, :sh, :mb, :sh_
269
+ # alias insrdi rx, ry, n, b -> rldimi rx, ry, 64 - (b+n), b
270
+ addop_ 'rlwimi',0x50000000, :ra, :rs, :sh, :mb_, :me_
271
+ # alias inslwi rx, ry, n, b -> rlwimi rx, ry, 32-b, b, b+n - 1
272
+ addop_ 'sld', 0x7C000036, :ra, :rs, :rb
273
+ addop_ 'slw', 0x7C000030, :ra, :rs, :rb
274
+ addop_ 'srd', 0x7C000436, :ra, :rs, :rb
275
+ addop_ 'srw', 0x7C000430, :ra, :rs, :rb
276
+ addop_ 'sradi', 0x7C000674, :ra, :rs, :sh, :sh_
277
+ addop_ 'srawi', 0x7C000670, :ra, :rs, :sh
278
+ addop_ 'srad', 0x7C000634, :ra, :rs, :rb
279
+ addop_ 'sraw', 0x7C000630, :ra, :rs, :rb
280
+ #addop 'mtspr', 0x7C0003A6, :spr, :rs
281
+ addop 'mtxer', 0x7C0003A6|(1<<16), :rs
282
+ addop 'mtlr', 0x7C0003A6|(8<<16), :rs
283
+ addop 'mtctr', 0x7C0003A6|(9<<16), :rs
284
+ #addop 'mfspr', 0x7C0002A6, :rt, :spr
285
+ addop 'mfxer', 0x7C0002A6|(1<<16), :rt
286
+ addop 'mflr', 0x7C0002A6|(8<<16), :rt
287
+ addop 'mfctr', 0x7C0002A6|(9<<16), :rt
288
+ addop 'mtcrf', 0x7C000120, :fxm, :rs
289
+ # alias mtcr rx -> mtcrf 0xff, rx
290
+ addop 'mfcr', 0x7C000026, :rt
291
+ addop 'lfs', 0xC0000000, :frt, :ra_i16
292
+ addop 'lfsu', 0xC4000000, :frt, :ra_i16
293
+ addop 'lfsx', 0x7C00042E, :frt, :ra, :rb
294
+ addop 'lfsux', 0x7C00046E, :frt, :ra, :rb
295
+ addop 'lfd', 0xC8000000, :frt, :ra_i16
296
+ addop 'lfdu', 0xCC000000, :frt, :ra_i16
297
+ addop 'lfdx', 0x7C0004AE, :frt, :ra, :rb
298
+ addop 'lfdux', 0x7C0004EE, :frt, :ra, :rb
299
+ addop 'stfs', 0xD0000000, :frs, :ra_i16
300
+ addop 'stfsu', 0xD4000000, :frs, :ra_i16
301
+ addop 'stfsx', 0x7C00052E, :frs, :ra, :rb
302
+ addop 'stfsux', 0x7C00056E, :frs, :ra, :rb
303
+ addop 'stfd', 0xD8000000, :frs, :ra_i16
304
+ addop 'stfdu', 0xDC000000, :frs, :ra_i16
305
+ addop 'stfdx', 0x7C0005AE, :frs, :ra, :rb
306
+ addop 'stfdux', 0x7C0005EE, :frs, :ra, :rb
307
+ addop 'stfiwx', 0x7C0007AE, :frs, :ra, :rb
308
+ addop_ 'fmr', 0xFC000090, :frt, :frb
309
+ addop_ 'fabs', 0xFC000210, :frt, :frb
310
+ addop_ 'fneg', 0xFC000050, :frt, :frb
311
+ addop_ 'fnabs', 0xFC000110, :frt, :frb
312
+ addop_ 'fadd', 0xFC00002A, :frt, :fra, :frb
313
+ addop_ 'fadds', 0xEC00002A, :frt, :fra, :frb
314
+ addop_ 'fsub', 0xFC000028, :frt, :fra, :frb
315
+ addop_ 'fsubs', 0xEC000028, :frt, :fra, :frb
316
+ addop_ 'fmul', 0xFC000032, :frt, :fra, :frc
317
+ addop_ 'fmuls', 0xEC000032, :frt, :fra, :frc
318
+ addop_ 'fdiv', 0xFC000024, :frt, :fra, :frb
319
+ addop_ 'fdivs', 0xEC000024, :frt, :fra, :frb
320
+ addop_ 'fmadd', 0xFC00003A, :frt, :fra, :frc, :frb
321
+ addop_ 'fmadds',0xEC00003A, :frt, :fra, :frc, :frb
322
+ addop_ 'fmsub', 0xFC000038, :frt, :fra, :frc, :frb
323
+ addop_ 'fmsubs',0xEC000038, :frt, :fra, :frc, :frb
324
+ addop_ 'fnmadd',0xFC00003E, :frt, :fra, :frc, :frb
325
+ addop_ 'fnmadds',0xEC00003E,:frt, :fra, :frc, :frb
326
+ addop_ 'fnmsub',0xFC00003C, :frt, :fra, :frc, :frb
327
+ addop_ 'fnmsubs',0xEC00003C,:frt, :fra, :frc, :frb
328
+ addop_ 'frsp', 0xFC000018, :frt, :frb
329
+ addop_ 'fctid', 0xFC00065C, :frt, :frb
330
+ addop_ 'fctidz',0xFC00065E, :frt, :frb
331
+ addop_ 'fctiw', 0xFC00001C, :frt, :frb
332
+ addop_ 'fctiwz',0xFC00001E, :frt, :frb
333
+ addop_ 'fcfid', 0xFC00069C, :frt, :frb
334
+ addop 'fcmpu', 0xFC000000, :bf, :fra, :frb
335
+ addop 'fcmpo', 0xFC000040, :bf, :fra, :frb
336
+ addop_ 'mffs', 0xFC00048E, :frt
337
+ addop 'mcrfs', 0xFC000080, :bf, :bfa
338
+ addop_ 'mtfsfi',0xFC00010C, :bf, :u
339
+ addop_ 'mtfsf', 0xFC00058E, :flm, :frb
340
+ addop_ 'mtfsb0',0xFC00008C, :bt
341
+ addop_ 'mtfsb1',0xFC00004C, :bt
342
+ addop 'mtocrf', 0x7C100120, :fxm, :rs
343
+ addop_ 'fsqrt', 0xFC00002C, :frt, :frb
344
+ addop_ 'fsqrts',0xEC00002C, :frt, :frb
345
+ addop_ 'fre', 0xFC000030, :frt, :frb
346
+ addop_ 'fres', 0xEC000030, :frt, :frb
347
+ addop_ 'frsqrte',0xFC000034,:frt, :frb
348
+ addop_ 'frsqrtes',0xEC000034, :frt, :frb
349
+ addop_ 'fsel', 0xFC00002E, :frt, :fra, :frc, :frb
350
+ addop 'mcrxr', 0x7C000400, :bf
351
+ addop 'icbi', 0x7C0007AC, :ra, :rb
352
+ addop 'dcbt', 0x7C00022C, :ra, :rb
353
+ addop 'dcbtst', 0x7C0001EC, :ra, :rb
354
+ addop 'dcbz', 0x7C0007EC, :ra, :rb
355
+ addop 'dcbst', 0x7C00006C, :ra, :rb
356
+ addop 'dcbf', 0x7C0000AC, :ra, :rb
357
+ addop 'isync', 0x4C00012C
358
+ addop 'lwarx', 0x7C000028, :rt, :ra, :rb
359
+ addop 'ldarx', 0x7C0000A8, :rt, :ra, :rb
360
+ addop 'stwcx.', 0x7C00012D, :rs, :ra, :rb
361
+ addop 'stdcx.', 0x7C0001AD, :rs, :ra, :rb
362
+ addop 'sync', 0x7C0004AC, :l_
363
+ addop 'eieio', 0x7C0006AC
364
+ addop 'mftb', 0x7C0002E6, :rt, :tbr
365
+ addop 'eciwx', 0x7C00026C, :rt, :ra, :rb
366
+ addop 'ecowx', 0x7C00036C, :rs, :ra, :rb
367
+ addop 'dcbt', 0x7C00022C, :ra, :rb, :th
368
+ addop 'dcbf', 0x7C0000AC, :ra, :rb
369
+ addop 'dcbf', 0x7C0000AC, :ra, :rb, :l
370
+ addop 'sc', 0x44000002, :lev
371
+ addop 'rfid', 0x4C000024
372
+ addop 'hrfid', 0x4C000224
373
+ addop 'mtmsrd', 0x7C000164, :rs, :l__
374
+ addop 'mfmsr', 0x7C0000A6, :rt
375
+ addop 'slbie', 0x7C000364, :rb
376
+ addop 'slbmte', 0x7C000324, :rs, :rb
377
+ addop 'slbmfev',0x7C0006A6, :rt, :rb
378
+ addop 'slbmfee',0x7C000726, :rt, :rb
379
+ addop 'tlbie', 0x7C000264, :rb, :l
380
+ addop 'tlbiel', 0x7C000224, :rb, :l
381
+ addop 'tlbia', 0x7C0002E4
382
+ addop 'tlbsync',0x7C00046C
383
+ addop 'mtmsr', 0x7C000124, :rs, :l__
384
+ addop 'lq', 0xE0000000, :rt, :ra_i16q
385
+ addop 'stq', 0xF8000002, :rs, :ra_i16s
386
+ addop 'mtsr', 0x7C0001A4, :sr, :rs
387
+ addop 'mtsrin', 0x7C0001E4, :rs, :rb
388
+ addop 'mfsr', 0x7C0004A6, :rt, :sr
389
+ addop 'mfsrin', 0x7C000526, :rt, :rb
390
+
391
+ addop_trap 'tw', 0x7C000008, :ra, :rb
392
+ addop_trap 'twi', 0xC0000000, :ra, :si
393
+ addop_trap 'td', 0x7C000088, :ra, :rb
394
+ addop_trap 'tdi', 0x08000000, :ra, :si
395
+
396
+ # pseudo-instructions
397
+ addop 'mr', :pseudo, :ra, :rb
398
+ addop 'not', :pseudo, :ra
399
+ addop 'not', :pseudo, :ra, :rb
400
+ @opcode_list.each { |op|
401
+ if op.name =~ /^addi/
402
+ addop op.name.sub('add', 'sub'), :pseudo, *op.args
403
+ end
404
+ if op.name =~ /^(add|sub|xor|and|or|div|mul|nand)/ and op.args.length == 3
405
+ addop op.name, :pseudo, *op.args[1..-1]
406
+ end
407
+ }
408
+ end
409
+ end
410
+ end