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
@@ -0,0 +1,36 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2010 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ require 'metasm/main'
7
+
8
+ module Metasm
9
+ class Python < CPU
10
+ def initialize(prog = nil)
11
+ super()
12
+ @program = prog
13
+ @endianness = (prog.respond_to?(:endianness) ? prog.endianness : :little)
14
+ @size = (prog.respond_to?(:size) ? prog.size : 32)
15
+ end
16
+
17
+ class Var
18
+ include Renderable
19
+
20
+ attr_accessor :i
21
+
22
+ def initialize(i); @i = i end
23
+
24
+ def ==(o)
25
+ o.class == self.class and o.i == i
26
+ end
27
+
28
+ def symbolic; "var_#{@i}".to_sym end
29
+
30
+ def render
31
+ ["var_#@i"]
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,180 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2010 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ require 'metasm/cpu/python/main'
7
+
8
+ module Metasm
9
+ class Python
10
+ CMP_OP = %w[< <= == != > >= in not_in is is_not exch]
11
+
12
+ def addop(name, bin, *args)
13
+ o = Opcode.new(name)
14
+ o.bin = bin
15
+
16
+ args.each { |a|
17
+ o.args << a if @valid_args[a]
18
+ o.props[a] = true if @valid_props[a]
19
+ }
20
+ o.args << :i16 if o.bin >= 90 and o.props.empty? # HAVE_ARGUMENT
21
+
22
+ @opcode_list << o
23
+ end
24
+
25
+ def init_opcode_list
26
+ @opcode_list = []
27
+
28
+ @valid_args[:u8] = true
29
+ @valid_args[:i16] = true
30
+ @valid_args[:cmp] = true
31
+
32
+ addop 'STOP_CODE', 0, :stopexec
33
+ addop 'POP_TOP', 1
34
+ addop 'ROT_TWO', 2
35
+ addop 'ROT_THREE', 3
36
+ addop 'DUP_TOP', 4
37
+ addop 'ROT_FOUR', 5
38
+ addop 'NOP', 9
39
+
40
+ addop 'UNARY_POSITIVE', 10
41
+ addop 'UNARY_NEGATIVE', 11
42
+ addop 'UNARY_NOT', 12
43
+ addop 'UNARY_CONVERT', 13
44
+
45
+ addop 'UNARY_INVERT', 15
46
+
47
+ addop 'BINARY_POWER', 19
48
+
49
+ addop 'BINARY_MULTIPLY', 20
50
+ addop 'BINARY_DIVIDE', 21
51
+ addop 'BINARY_MODULO', 22
52
+ addop 'BINARY_ADD', 23
53
+ addop 'BINARY_SUBTRACT', 24
54
+ addop 'BINARY_SUBSCR', 25
55
+ addop 'BINARY_FLOOR_DIVIDE', 26
56
+ addop 'BINARY_TRUE_DIVIDE', 27
57
+ addop 'INPLACE_FLOOR_DIVIDE', 28
58
+ addop 'INPLACE_TRUE_DIVIDE', 29
59
+
60
+ addop 'SLICE', 30
61
+ addop 'SLICE_1', 31
62
+ addop 'SLICE_2', 32
63
+ addop 'SLICE_3', 33
64
+
65
+ addop 'STORE_SLICE', 40
66
+ addop 'STORE_SLICE_1', 41
67
+ addop 'STORE_SLICE_2', 42
68
+ addop 'STORE_SLICE_3', 43
69
+
70
+ addop 'DELETE_SLICE', 50
71
+ addop 'DELETE_SLICE_1', 51
72
+ addop 'DELETE_SLICE_2', 52
73
+ addop 'DELETE_SLICE_3', 53
74
+
75
+ addop 'STORE_MAP', 54
76
+ addop 'INPLACE_ADD', 55
77
+ addop 'INPLACE_SUBTRACT', 56
78
+ addop 'INPLACE_MULTIPLY', 57
79
+ addop 'INPLACE_DIVIDE', 58
80
+ addop 'INPLACE_MODULO', 59
81
+ addop 'STORE_SUBSCR', 60
82
+ addop 'DELETE_SUBSCR', 61
83
+
84
+ addop 'BINARY_LSHIFT', 62
85
+ addop 'BINARY_RSHIFT', 63
86
+ addop 'BINARY_AND', 64
87
+ addop 'BINARY_XOR', 65
88
+ addop 'BINARY_OR', 66
89
+ addop 'INPLACE_POWER', 67
90
+ addop 'GET_ITER', 68
91
+
92
+ addop 'PRINT_EXPR', 70
93
+ addop 'PRINT_ITEM', 71
94
+ addop 'PRINT_NEWLINE', 72
95
+ addop 'PRINT_ITEM_TO', 73
96
+ addop 'PRINT_NEWLINE_TO', 74
97
+ addop 'INPLACE_LSHIFT', 75
98
+ addop 'INPLACE_RSHIFT', 76
99
+ addop 'INPLACE_AND', 77
100
+ addop 'INPLACE_XOR', 78
101
+ addop 'INPLACE_OR', 79
102
+ addop 'BREAK_LOOP', 80
103
+ addop 'WITH_CLEANUP', 81
104
+ addop 'LOAD_LOCALS', 82
105
+ addop 'RETURN_VALUE', 83
106
+ addop 'IMPORT_STAR', 84
107
+ addop 'EXEC_STMT', 85
108
+ addop 'YIELD_VALUE', 86
109
+ addop 'POP_BLOCK', 87
110
+ addop 'END_FINALLY', 88
111
+ addop 'BUILD_CLASS', 89
112
+
113
+ #addop 'HAVE_ARGUMENT', 90 #/* Opcodes from here have an argument: */
114
+
115
+ addop 'STORE_NAME', 90 #/* Index in name list */
116
+ addop 'DELETE_NAME', 91 #/* "" */
117
+ addop 'UNPACK_SEQUENCE', 92 #/* Number of sequence items */
118
+ addop 'FOR_ITER', 93, :setip
119
+ addop 'LIST_APPEND', 94
120
+
121
+ addop 'STORE_ATTR', 95 #/* Index in name list */
122
+ addop 'DELETE_ATTR', 96 #/* "" */
123
+ addop 'STORE_GLOBAL', 97 #/* "" */
124
+ addop 'DELETE_GLOBAL', 98 #/* "" */
125
+ addop 'DUP_TOPX', 99 #/* number of items to duplicate */
126
+ addop 'LOAD_CONST', 100 #/* Index in const list */
127
+ addop 'LOAD_NAME', 101 #/* Index in name list */
128
+ addop 'BUILD_TUPLE', 102 #/* Number of tuple items */
129
+ addop 'BUILD_LIST', 103 #/* Number of list items */
130
+ addop 'BUILD_SET', 104 #/* Number of set items */
131
+ addop 'BUILD_MAP', 105 #/* Always zero for now */
132
+ addop 'LOAD_ATTR', 106 #/* Index in name list */
133
+ addop 'COMPARE_OP', 107, :cmp #/* Comparison operator */
134
+ addop 'IMPORT_NAME', 108 #/* Index in name list */
135
+ addop 'IMPORT_FROM', 109 #/* Index in name list */
136
+ addop 'JUMP_FORWARD', 110, :setip, :stopexec #/* Number of bytes to skip */
137
+
138
+ addop 'JUMP_IF_FALSE_OR_POP', 111, :setip #/* Target byte offset from beginning of code */
139
+ addop 'JUMP_IF_TRUE_OR_POP', 112, :setip #/* "" */
140
+ addop 'JUMP_ABSOLUTE', 113, :setip, :stopexec #/* "" */
141
+ addop 'POP_JUMP_IF_FALSE', 114, :setip #/* "" */
142
+ addop 'POP_JUMP_IF_TRUE', 115, :setip #/* "" */
143
+
144
+ addop 'LOAD_GLOBAL', 116 #/* Index in name list */
145
+
146
+ addop 'CONTINUE_LOOP', 119 #/* Start of loop (absolute) */
147
+ addop 'SETUP_LOOP', 120 #/* Target address (relative) */
148
+ addop 'SETUP_EXCEPT', 121 #/* "" */
149
+ addop 'SETUP_FINALLY', 122 #/* "" */
150
+
151
+ addop 'LOAD_FAST', 124 #/* Local variable number */
152
+ addop 'STORE_FAST', 125 #/* Local variable number */
153
+ addop 'DELETE_FAST', 126 #/* Local variable number */
154
+
155
+ addop 'RAISE_VARARGS', 130 #/* Number of raise arguments (1, 2 or 3) */
156
+ #/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
157
+ addop 'CALL_FUNCTION', 131, :u8, :u8, :setip #/* #args + (#kwargs<<8) */
158
+ addop 'MAKE_FUNCTION', 132 #/* #defaults */
159
+ addop 'BUILD_SLICE', 133 #/* Number of items */
160
+
161
+ addop 'MAKE_CLOSURE', 134 #/* #free vars */
162
+ addop 'LOAD_CLOSURE', 135 #/* Load free variable from closure */
163
+ addop 'LOAD_DEREF', 136 #/* Load and dereference from closure cell */
164
+ addop 'STORE_DEREF', 137 #/* Store into cell */
165
+
166
+ #/* The next 3 opcodes must be contiguous and satisfy (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */
167
+ addop 'CALL_FUNCTION_VAR', 140, :u8, :u8, :setip #/* #args + (#kwargs<<8) */
168
+ addop 'CALL_FUNCTION_KW', 141, :u8, :u8, :setip #/* #args + (#kwargs<<8) */
169
+ addop 'CALL_FUNCTION_VAR_KW', 142, :u8, :u8, :setip #/* #args + (#kwargs<<8) */
170
+
171
+ addop 'SETUP_WITH', 143
172
+
173
+ #/* Support for opargs more than 16 bits long */
174
+ addop 'EXTENDED_ARG', 145
175
+
176
+ addop 'SET_ADD', 146
177
+ addop 'MAP_ADD', 147
178
+ end
179
+ end
180
+ end
@@ -5,4 +5,4 @@
5
5
 
6
6
 
7
7
  require 'metasm/main'
8
- require 'metasm/sh4/decode'
8
+ require 'metasm/cpu/sh4/decode'
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
- require 'metasm/sh4/opcodes'
6
+ require 'metasm/cpu/sh4/opcodes'
7
7
  require 'metasm/decode'
8
8
 
9
9
  module Metasm
@@ -39,7 +39,7 @@ class Sh4
39
39
  end
40
40
 
41
41
  def decode_findopcode(edata)
42
- return if edata.ptr >= edata.data.length
42
+ return if edata.ptr >= edata.length
43
43
 
44
44
  di = DecodedInstruction.new(self)
45
45
  val = edata.decode_imm(:u16, @endianness)
@@ -110,7 +110,6 @@ class Sh4
110
110
  when :pr; PR.new
111
111
  when :fpul; FPUL.new
112
112
  when :fpscr; FPSCR.new
113
- when :dbr; DBR.new
114
113
  when :pc; PC.new
115
114
 
116
115
  when :@rm, :@rn, :@disppc
@@ -137,25 +136,49 @@ class Sh4
137
136
  }
138
137
 
139
138
  di.bin_length += edata.ptr - before_ptr
139
+
140
+ return if edata.ptr > edata.length
141
+
140
142
  di
141
143
  end
142
144
 
143
145
  def disassembler_default_func
144
146
  df = DecodedFunction.new
145
147
  df.backtrace_binding = {}
146
- 15.times { |i| df.backtrace_binding["r#{i}".to_sym] = Expression::Unknown }
148
+ (0..7 ).each { |i| r = "r#{i}".to_sym ; df.backtrace_binding[r] = Expression::Unknown }
149
+ (8..15).each { |i| r = "r#{i}".to_sym ; df.backtrace_binding[r] = Expression[r] }
147
150
  df.backtracked_for = [BacktraceTrace.new(Expression[:pr], :default, Expression[:pr], :x)]
148
151
  df.btfor_callback = lambda { |dasm, btfor, funcaddr, calladdr|
149
152
  if funcaddr != :default
150
153
  btfor
151
154
  elsif di = dasm.decoded[calladdr] and di.opcode.props[:saveip]
152
155
  btfor
153
- else []
156
+ else
157
+ []
154
158
  end
155
159
  }
156
160
  df
157
161
  end
158
162
 
163
+ def backtrace_update_function_binding(dasm, faddr, f, retaddrlist, *wantregs)
164
+ retaddrlist.map! { |retaddr| dasm.decoded[retaddr] ? dasm.decoded[retaddr].block.list.last.address : retaddr } if retaddrlist
165
+ b = f.backtrace_binding
166
+
167
+ bt_val = lambda { |r|
168
+ next if not retaddrlist
169
+ bt = []
170
+ b[r] = Expression::Unknown # break recursive dep
171
+ retaddrlist.each { |retaddr|
172
+ bt |= dasm.backtrace(Expression[r], retaddr,
173
+ :include_start => true, :snapshot_addr => faddr, :origin => retaddr)
174
+ }
175
+ b[r] = ((bt.length == 1) ? bt.first : Expression::Unknown)
176
+ }
177
+ wantregs = GPR::Sym if wantregs.empty?
178
+ wantregs.map { |r| r.to_sym }.each(&bt_val)
179
+ end
180
+
181
+
159
182
  # interprets a condition code (in an opcode name) as an expression
160
183
  def decode_cmp_expr(di, a0, a1)
161
184
  case di.opcode.name
@@ -197,6 +220,7 @@ class Sh4
197
220
  when 'stc.w', 'stc.b', 'mov.w', 'mov.b'
198
221
  lambda { |di, a0, a1| { a1 => Expression[a0, :&, mask[di]] }}
199
222
  when 'movt'; lambda { |di, a0| { a0 => :t_bit }}
223
+ when 'mova'; lambda { |di, a0, a1| { a1 => Expression[a0] }}
200
224
  when 'exts.b', 'exts.w', 'extu.w'
201
225
  lambda { |di, a0, a1| { a1 => Expression[a0, :&, mask[di]] }}
202
226
  when 'cmp/eq', 'cmp/ge', 'cmp/ge', 'cmp/gt', 'cmp/hi', 'cmp/hs'
@@ -212,12 +236,12 @@ class Sh4
212
236
  when 'clrt'; lambda { |di| { :t_bit => 0 }}
213
237
  when 'clrmac'; lambda { |di| { :macl => 0, :mach => 0 }}
214
238
  when 'jmp'; lambda { |di, a0| { :pc => a0 }}
215
- when 'jsr'; lambda { |di, a0| { :pc => Expression[a0], :pr => Expression[di.address+2*2] }}
239
+ when 'jsr', 'bsr', 'bsrf'; lambda { |di, a0| { :pc => Expression[a0], :pr => Expression[di.address, :+, 2*2] }}
216
240
  when 'dt'; lambda { |di, a0|
217
241
  res = Expression[a0, :-, 1]
218
242
  { :a0 => res, :t_bit => Expression[res, :==, 0] }
219
243
  }
220
- when 'add' ; lambda { |di, a0, a1| { a1 => Expression[a0, :+, a1] }}
244
+ when 'add' ; lambda { |di, a0, a1| { a1 => Expression[[a0, :+, a1], :&, 0xffff_ffff] }}
221
245
  when 'addc' ; lambda { |di, a0, a1|
222
246
  res = Expression[[a0, :&, mask[di]], :+, [[a1, :&, mask[di]], :+, :t_bit]]
223
247
  { a1 => Expression[a0, :+, [a1, :+, :t_bit]], :t_bit => Expression[res, :>, mask[di]] }
@@ -252,17 +276,16 @@ class Sh4
252
276
  shift_bit = Expression[a0, :&, 1]
253
277
  { a0 => Expression[a0, :>>, 1], :t_bit => shift_bit }
254
278
  }
255
- when 'sub'; lambda { |di, a0, a1| { a1 => Expression[a0, :-, a1] }}
256
- when 'subc'; lambda { |di, a0, a1| { a1 => Expression[a0, :-, [a1, :-, :t_bit]] }}
279
+ when 'sub'; lambda { |di, a0, a1| { a1 => Expression[[a1, :-, a0], :&, 0xffff_ffff] }}
280
+ when 'subc'; lambda { |di, a0, a1| { a1 => Expression[a1, :-, [a0, :-, :t_bit]] }}
257
281
  when 'and', 'and.b'; lambda { |di, a0, a1| { a1 => Expression[[a0, :&, mask[di]], :|, [[a1, :&, mask[di]]]] }}
258
282
  when 'or', 'or.b'; lambda { |di, a0, a1| { a1 => Expression[[a0, :|, mask[di]], :|, [[a1, :&, mask[di]]]] }}
259
283
  when 'xor', 'xor.b'; lambda { |di, a0, a1| { a1 => Expression[[a0, :|, mask[di]], :^, [[a1, :&, mask[di]]]] }}
260
- when 'add', 'addc', 'addv'; lambda { |di, a0, a1| { a1 => Expression[a0, :+, a1] }}
261
284
  when 'neg' ; lambda { |di, a0, a1| { a1 => Expression[mask[di], :-, a0] }}
262
285
  when 'negc' ; lambda { |di, a0, a1| { a1 => Expression[[[mask[di], :-, a0], :-, :t_bit], :&, mask[di]] }}
263
286
  when 'not'; lambda { |di, a0, a1| { a1 => Expression[a0, :^, mask[di]] }}
264
- when 'nop'; lambda { {} }
265
- when /^b/; lambda { {} } # branches
287
+ when 'nop'; lambda { |*a| {} }
288
+ when /^b/; lambda { |*a| {} } # branches
266
289
  end
267
290
  }
268
291
 
@@ -283,12 +306,15 @@ class Sh4
283
306
  if binding = backtrace_binding[di.opcode.basename]
284
307
  bd = binding[di, *a] || {}
285
308
  di.instruction.args.grep(Memref).each { |m|
286
- if m.post
287
- # TODO preincrement/postdecrement
288
- bd.each { |k, v| bd[k] = v.bind(r => Expression[r, :+, 1]) }
289
- bd[r] ||= Expression[r, :+, 1]
309
+ next unless r = m.base and r.kind_of?(GPR)
310
+ r = r.symbolic
311
+ case m.action
312
+ when :post
313
+ bd[r] ||= Expression[r, :+, di.opcode.props[:memsz]/8]
314
+ when :pre
315
+ bd[r] ||= Expression[r, :-, di.opcode.props[:memsz]/8]
290
316
  end
291
- } if false
317
+ }
292
318
  bd
293
319
  else
294
320
  puts "unhandled instruction to backtrace: #{di}" if $VERBOSE
@@ -310,6 +336,11 @@ class Sh4
310
336
  else val
311
337
  end
312
338
 
339
+ val = case di.instruction.opname
340
+ when 'braf', 'bsrf'; Expression[[di.address, :+, 4], :+, val]
341
+ else val
342
+ end
343
+
313
344
  [Expression[val]]
314
345
  end
315
346
 
@@ -257,6 +257,8 @@ class Sh4 < CPU
257
257
  b = @base
258
258
  b = b.symbolic if b.kind_of? Reg
259
259
 
260
+ b = Expression[b, :-, sz/8] if @action == :pre
261
+
260
262
  if disp
261
263
  o = @disp
262
264
  o = o.symbolic if o.kind_of? Reg
@@ -272,12 +274,16 @@ class Sh4 < CPU
272
274
 
273
275
  def render
274
276
  if @disp
275
- ['@(', @base, ',', @disp, ')']
277
+ #['@(', @base, ',', @disp, ')']
278
+ ['[', @base, '+', @disp, ']']
276
279
  else
277
280
  case @action
278
- when :pre then ['@-', @base]
279
- when :post then ['@', @base, '+']
280
- else ['@', @base]
281
+ when :pre then ['[--', @base, ']']
282
+ when :post then ['[', @base, '++]']
283
+ else ['[', @base, ']']
284
+ #when :pre then ['@-', @base]
285
+ #when :post then ['@', @base, '+']
286
+ #else ['@', @base]
281
287
  end
282
288
  end
283
289
  end
@@ -288,5 +294,8 @@ class Sh4 < CPU
288
294
  init
289
295
  end
290
296
 
297
+ def dbg_register_list
298
+ @dbg_register_list ||= GPR::Sym
299
+ end
291
300
  end
292
301
  end
@@ -3,18 +3,17 @@
3
3
  #
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
- require 'metasm/sh4/main'
6
+ require 'metasm/cpu/sh4/main'
7
7
 
8
8
  module Metasm
9
9
  class Sh4
10
10
  def addop(name, bin, *args)
11
11
  o = Opcode.new name, bin
12
12
 
13
- o.args.concat(args & @fields_mask.keys)
14
- (args & @valid_props).each { |p| o.props[p] = true }
15
-
16
- (args & @fields_mask.keys).each { |f|
17
- o.fields[f] = [@fields_mask[f], @fields_shift[f]]
13
+ args.each { |a|
14
+ o.args << a if @fields_mask[a]
15
+ o.props[a] = true if @valid_props[a]
16
+ o.fields[a] = [@fields_mask[a], @fields_shift[a]] if @fields_mask[a]
18
17
  }
19
18
 
20
19
  @opcode_list << o
@@ -74,7 +73,7 @@ class Sh4
74
73
  # implicit operands
75
74
  [:vbr, :gbr, :sr, :ssr, :spc, :sgr, :dbr, :mach, :macl, :pr, :fpul, :fpscr, :dbr, :pc, :r0].each { |a| @fields_mask[a] = @fields_shift[a] = 0 }
76
75
 
77
- @valid_props = [:setip, :saveip, :stopexec , :delay_slot]
76
+ @valid_props[:delay_slot] = true
78
77
 
79
78
  addop 'add', 0b0011 << 12 | 0b1100, :rm, :rn
80
79
  addop 'add', 0b0111 << 12, :s8, :rn
@@ -275,7 +274,7 @@ class Sh4
275
274
  addop 'mov.w', 0b10000101 << 8, :@disprm, :r0
276
275
 
277
276
  addop 'mova', 0b11000111 << 8, :disppc, :r0 # calculates an effective address using PC-relative with displacement addressing
278
- addop 'movca.l', 0b0000 << 12 | 11000011, :r0, :@rn # stores the long-word in R0 to memory at the effective address specified in Rn.
277
+ addop 'movca.l', 0b0000 << 12 | 11000011, :r0, :@rn # stores the long-word in R0 to memory at the effective address specified in Rn.
279
278
 
280
279
  addop 'movt', 0b0000 << 12 | 0b00101001, :rn # copies the T-bit to Rn
281
280