metasm 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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