immunio 1.2.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -5
  3. data/ext/immunio/Rakefile +14 -6
  4. data/lib/immunio/context.rb +2 -0
  5. data/lib/immunio/plugins/action_view.rb +7 -668
  6. data/lib/immunio/plugins/action_view/action_view.rb +22 -0
  7. data/lib/immunio/plugins/action_view/active_support_hash.rb +29 -0
  8. data/lib/immunio/plugins/action_view/cache_store.rb +24 -0
  9. data/lib/immunio/plugins/action_view/erubi.rb +38 -0
  10. data/lib/immunio/plugins/action_view/erubis.rb +39 -0
  11. data/lib/immunio/plugins/action_view/fragment_caching.rb +29 -0
  12. data/lib/immunio/plugins/action_view/haml.rb +46 -0
  13. data/lib/immunio/plugins/action_view/slim.rb +42 -0
  14. data/lib/immunio/plugins/action_view/template.rb +431 -0
  15. data/lib/immunio/plugins/action_view/template_rendering.rb +45 -0
  16. data/lib/immunio/plugins/http_tracker.rb +2 -0
  17. data/lib/immunio/plugins/io.rb +34 -0
  18. data/lib/immunio/version.rb +1 -1
  19. data/lua-hooks/Makefile +36 -9
  20. data/lua-hooks/ext/luajit/COPYRIGHT +1 -1
  21. data/lua-hooks/ext/luajit/Makefile +22 -15
  22. data/lua-hooks/ext/luajit/README +2 -2
  23. data/lua-hooks/ext/luajit/doc/bluequad-print.css +1 -1
  24. data/lua-hooks/ext/luajit/doc/bluequad.css +1 -1
  25. data/lua-hooks/ext/luajit/doc/changes.html +69 -3
  26. data/lua-hooks/ext/luajit/doc/contact.html +10 -3
  27. data/lua-hooks/ext/luajit/doc/ext_c_api.html +2 -2
  28. data/lua-hooks/ext/luajit/doc/ext_ffi.html +2 -2
  29. data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +2 -2
  30. data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +3 -4
  31. data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +2 -2
  32. data/lua-hooks/ext/luajit/doc/ext_jit.html +3 -3
  33. data/lua-hooks/ext/luajit/doc/ext_profiler.html +2 -2
  34. data/lua-hooks/ext/luajit/doc/extensions.html +47 -20
  35. data/lua-hooks/ext/luajit/doc/faq.html +2 -2
  36. data/lua-hooks/ext/luajit/doc/install.html +74 -45
  37. data/lua-hooks/ext/luajit/doc/luajit.html +5 -5
  38. data/lua-hooks/ext/luajit/doc/running.html +3 -3
  39. data/lua-hooks/ext/luajit/doc/status.html +13 -8
  40. data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +1 -1
  41. data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1 -1
  42. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +1 -1
  43. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1 -1
  44. data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +8 -5
  45. data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +66 -11
  46. data/lua-hooks/ext/luajit/dynasm/dasm_mips64.lua +12 -0
  47. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +1 -1
  48. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1 -1
  49. data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +1 -1
  50. data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +1 -1
  51. data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +1 -1
  52. data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +5 -1
  53. data/lua-hooks/ext/luajit/dynasm/dynasm.lua +2 -2
  54. data/lua-hooks/ext/luajit/etc/luajit.1 +1 -1
  55. data/lua-hooks/ext/luajit/etc/luajit.pc +1 -1
  56. data/lua-hooks/ext/luajit/src/Makefile +15 -11
  57. data/lua-hooks/ext/luajit/src/Makefile.dep +16 -16
  58. data/lua-hooks/ext/luajit/src/host/buildvm.c +2 -2
  59. data/lua-hooks/ext/luajit/src/host/buildvm.h +1 -1
  60. data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +9 -4
  61. data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +2 -2
  62. data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +1 -1
  63. data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +14 -3
  64. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +27 -3
  65. data/lua-hooks/ext/luajit/src/host/genlibbc.lua +1 -1
  66. data/lua-hooks/ext/luajit/src/host/genminilua.lua +6 -5
  67. data/lua-hooks/ext/luajit/src/host/minilua.c +1 -1
  68. data/lua-hooks/ext/luajit/src/jit/bc.lua +1 -1
  69. data/lua-hooks/ext/luajit/src/jit/bcsave.lua +8 -8
  70. data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +2 -2
  71. data/lua-hooks/ext/luajit/src/jit/dis_arm64.lua +1216 -0
  72. data/lua-hooks/ext/luajit/src/jit/dis_arm64be.lua +12 -0
  73. data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +35 -20
  74. data/lua-hooks/ext/luajit/src/jit/dis_mips64.lua +17 -0
  75. data/lua-hooks/ext/luajit/src/jit/dis_mips64el.lua +17 -0
  76. data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +1 -1
  77. data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +2 -2
  78. data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +1 -1
  79. data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +7 -4
  80. data/lua-hooks/ext/luajit/src/jit/dump.lua +17 -12
  81. data/lua-hooks/ext/luajit/src/jit/p.lua +3 -2
  82. data/lua-hooks/ext/luajit/src/jit/v.lua +2 -2
  83. data/lua-hooks/ext/luajit/src/jit/zone.lua +1 -1
  84. data/lua-hooks/ext/luajit/src/lauxlib.h +14 -20
  85. data/lua-hooks/ext/luajit/src/lib_aux.c +38 -27
  86. data/lua-hooks/ext/luajit/src/lib_base.c +12 -5
  87. data/lua-hooks/ext/luajit/src/lib_bit.c +1 -1
  88. data/lua-hooks/ext/luajit/src/lib_debug.c +5 -5
  89. data/lua-hooks/ext/luajit/src/lib_ffi.c +2 -2
  90. data/lua-hooks/ext/luajit/src/lib_init.c +16 -16
  91. data/lua-hooks/ext/luajit/src/lib_io.c +6 -7
  92. data/lua-hooks/ext/luajit/src/lib_jit.c +14 -4
  93. data/lua-hooks/ext/luajit/src/lib_math.c +1 -5
  94. data/lua-hooks/ext/luajit/src/lib_os.c +1 -1
  95. data/lua-hooks/ext/luajit/src/lib_package.c +14 -23
  96. data/lua-hooks/ext/luajit/src/lib_string.c +1 -5
  97. data/lua-hooks/ext/luajit/src/lib_table.c +21 -1
  98. data/lua-hooks/ext/luajit/src/lj.supp +3 -3
  99. data/lua-hooks/ext/luajit/src/lj_alloc.c +174 -83
  100. data/lua-hooks/ext/luajit/src/lj_api.c +97 -18
  101. data/lua-hooks/ext/luajit/src/lj_arch.h +54 -22
  102. data/lua-hooks/ext/luajit/src/lj_asm.c +172 -53
  103. data/lua-hooks/ext/luajit/src/lj_asm.h +1 -1
  104. data/lua-hooks/ext/luajit/src/lj_asm_arm.h +19 -16
  105. data/lua-hooks/ext/luajit/src/lj_asm_arm64.h +2022 -0
  106. data/lua-hooks/ext/luajit/src/lj_asm_mips.h +564 -158
  107. data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +19 -18
  108. data/lua-hooks/ext/luajit/src/lj_asm_x86.h +578 -92
  109. data/lua-hooks/ext/luajit/src/lj_bc.c +1 -1
  110. data/lua-hooks/ext/luajit/src/lj_bc.h +1 -1
  111. data/lua-hooks/ext/luajit/src/lj_bcdump.h +1 -1
  112. data/lua-hooks/ext/luajit/src/lj_bcread.c +1 -1
  113. data/lua-hooks/ext/luajit/src/lj_bcwrite.c +1 -1
  114. data/lua-hooks/ext/luajit/src/lj_buf.c +1 -1
  115. data/lua-hooks/ext/luajit/src/lj_buf.h +1 -1
  116. data/lua-hooks/ext/luajit/src/lj_carith.c +1 -1
  117. data/lua-hooks/ext/luajit/src/lj_carith.h +1 -1
  118. data/lua-hooks/ext/luajit/src/lj_ccall.c +172 -7
  119. data/lua-hooks/ext/luajit/src/lj_ccall.h +21 -5
  120. data/lua-hooks/ext/luajit/src/lj_ccallback.c +71 -17
  121. data/lua-hooks/ext/luajit/src/lj_ccallback.h +1 -1
  122. data/lua-hooks/ext/luajit/src/lj_cconv.c +4 -2
  123. data/lua-hooks/ext/luajit/src/lj_cconv.h +1 -1
  124. data/lua-hooks/ext/luajit/src/lj_cdata.c +7 -5
  125. data/lua-hooks/ext/luajit/src/lj_cdata.h +1 -1
  126. data/lua-hooks/ext/luajit/src/lj_clib.c +5 -5
  127. data/lua-hooks/ext/luajit/src/lj_clib.h +1 -1
  128. data/lua-hooks/ext/luajit/src/lj_cparse.c +11 -6
  129. data/lua-hooks/ext/luajit/src/lj_cparse.h +1 -1
  130. data/lua-hooks/ext/luajit/src/lj_crecord.c +70 -14
  131. data/lua-hooks/ext/luajit/src/lj_crecord.h +1 -1
  132. data/lua-hooks/ext/luajit/src/lj_ctype.c +1 -1
  133. data/lua-hooks/ext/luajit/src/lj_ctype.h +8 -8
  134. data/lua-hooks/ext/luajit/src/lj_debug.c +1 -1
  135. data/lua-hooks/ext/luajit/src/lj_debug.h +1 -1
  136. data/lua-hooks/ext/luajit/src/lj_def.h +6 -9
  137. data/lua-hooks/ext/luajit/src/lj_dispatch.c +3 -3
  138. data/lua-hooks/ext/luajit/src/lj_dispatch.h +2 -1
  139. data/lua-hooks/ext/luajit/src/lj_emit_arm.h +5 -4
  140. data/lua-hooks/ext/luajit/src/lj_emit_arm64.h +419 -0
  141. data/lua-hooks/ext/luajit/src/lj_emit_mips.h +100 -20
  142. data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +4 -4
  143. data/lua-hooks/ext/luajit/src/lj_emit_x86.h +116 -25
  144. data/lua-hooks/ext/luajit/src/lj_err.c +34 -13
  145. data/lua-hooks/ext/luajit/src/lj_err.h +1 -1
  146. data/lua-hooks/ext/luajit/src/lj_errmsg.h +1 -1
  147. data/lua-hooks/ext/luajit/src/lj_ff.h +1 -1
  148. data/lua-hooks/ext/luajit/src/lj_ffrecord.c +58 -49
  149. data/lua-hooks/ext/luajit/src/lj_ffrecord.h +1 -1
  150. data/lua-hooks/ext/luajit/src/lj_frame.h +33 -6
  151. data/lua-hooks/ext/luajit/src/lj_func.c +4 -2
  152. data/lua-hooks/ext/luajit/src/lj_func.h +1 -1
  153. data/lua-hooks/ext/luajit/src/lj_gc.c +16 -7
  154. data/lua-hooks/ext/luajit/src/lj_gc.h +1 -1
  155. data/lua-hooks/ext/luajit/src/lj_gdbjit.c +31 -1
  156. data/lua-hooks/ext/luajit/src/lj_gdbjit.h +1 -1
  157. data/lua-hooks/ext/luajit/src/lj_ir.c +69 -96
  158. data/lua-hooks/ext/luajit/src/lj_ir.h +29 -18
  159. data/lua-hooks/ext/luajit/src/lj_ircall.h +24 -30
  160. data/lua-hooks/ext/luajit/src/lj_iropt.h +9 -9
  161. data/lua-hooks/ext/luajit/src/lj_jit.h +67 -9
  162. data/lua-hooks/ext/luajit/src/lj_lex.c +1 -1
  163. data/lua-hooks/ext/luajit/src/lj_lex.h +1 -1
  164. data/lua-hooks/ext/luajit/src/lj_lib.c +1 -1
  165. data/lua-hooks/ext/luajit/src/lj_lib.h +1 -1
  166. data/lua-hooks/ext/luajit/src/lj_load.c +1 -1
  167. data/lua-hooks/ext/luajit/src/lj_mcode.c +11 -10
  168. data/lua-hooks/ext/luajit/src/lj_mcode.h +1 -1
  169. data/lua-hooks/ext/luajit/src/lj_meta.c +1 -1
  170. data/lua-hooks/ext/luajit/src/lj_meta.h +1 -1
  171. data/lua-hooks/ext/luajit/src/lj_obj.c +1 -1
  172. data/lua-hooks/ext/luajit/src/lj_obj.h +7 -3
  173. data/lua-hooks/ext/luajit/src/lj_opt_dce.c +1 -1
  174. data/lua-hooks/ext/luajit/src/lj_opt_fold.c +84 -17
  175. data/lua-hooks/ext/luajit/src/lj_opt_loop.c +1 -1
  176. data/lua-hooks/ext/luajit/src/lj_opt_mem.c +3 -3
  177. data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +24 -22
  178. data/lua-hooks/ext/luajit/src/lj_opt_sink.c +11 -6
  179. data/lua-hooks/ext/luajit/src/lj_opt_split.c +11 -2
  180. data/lua-hooks/ext/luajit/src/lj_parse.c +9 -7
  181. data/lua-hooks/ext/luajit/src/lj_parse.h +1 -1
  182. data/lua-hooks/ext/luajit/src/lj_profile.c +1 -1
  183. data/lua-hooks/ext/luajit/src/lj_profile.h +1 -1
  184. data/lua-hooks/ext/luajit/src/lj_record.c +201 -117
  185. data/lua-hooks/ext/luajit/src/lj_record.h +1 -1
  186. data/lua-hooks/ext/luajit/src/lj_snap.c +72 -26
  187. data/lua-hooks/ext/luajit/src/lj_snap.h +1 -1
  188. data/lua-hooks/ext/luajit/src/lj_state.c +6 -6
  189. data/lua-hooks/ext/luajit/src/lj_state.h +2 -2
  190. data/lua-hooks/ext/luajit/src/lj_str.c +1 -1
  191. data/lua-hooks/ext/luajit/src/lj_str.h +1 -1
  192. data/lua-hooks/ext/luajit/src/lj_strfmt.c +7 -3
  193. data/lua-hooks/ext/luajit/src/lj_strfmt.h +1 -1
  194. data/lua-hooks/ext/luajit/src/lj_strfmt_num.c +4 -3
  195. data/lua-hooks/ext/luajit/src/lj_strscan.c +1 -1
  196. data/lua-hooks/ext/luajit/src/lj_strscan.h +1 -1
  197. data/lua-hooks/ext/luajit/src/lj_tab.c +1 -2
  198. data/lua-hooks/ext/luajit/src/lj_tab.h +1 -1
  199. data/lua-hooks/ext/luajit/src/lj_target.h +3 -3
  200. data/lua-hooks/ext/luajit/src/lj_target_arm.h +1 -1
  201. data/lua-hooks/ext/luajit/src/lj_target_arm64.h +239 -7
  202. data/lua-hooks/ext/luajit/src/lj_target_mips.h +111 -22
  203. data/lua-hooks/ext/luajit/src/lj_target_ppc.h +1 -1
  204. data/lua-hooks/ext/luajit/src/lj_target_x86.h +21 -4
  205. data/lua-hooks/ext/luajit/src/lj_trace.c +63 -18
  206. data/lua-hooks/ext/luajit/src/lj_trace.h +2 -1
  207. data/lua-hooks/ext/luajit/src/lj_traceerr.h +1 -1
  208. data/lua-hooks/ext/luajit/src/lj_udata.c +1 -1
  209. data/lua-hooks/ext/luajit/src/lj_udata.h +1 -1
  210. data/lua-hooks/ext/luajit/src/lj_vm.h +5 -1
  211. data/lua-hooks/ext/luajit/src/lj_vmevent.c +1 -1
  212. data/lua-hooks/ext/luajit/src/lj_vmevent.h +1 -1
  213. data/lua-hooks/ext/luajit/src/lj_vmmath.c +1 -1
  214. data/lua-hooks/ext/luajit/src/ljamalg.c +1 -1
  215. data/lua-hooks/ext/luajit/src/lua.h +9 -1
  216. data/lua-hooks/ext/luajit/src/luaconf.h +3 -7
  217. data/lua-hooks/ext/luajit/src/luajit.c +69 -54
  218. data/lua-hooks/ext/luajit/src/luajit.h +4 -4
  219. data/lua-hooks/ext/luajit/src/lualib.h +1 -1
  220. data/lua-hooks/ext/luajit/src/msvcbuild.bat +12 -4
  221. data/lua-hooks/ext/luajit/src/vm_arm.dasc +1 -1
  222. data/lua-hooks/ext/luajit/src/vm_arm64.dasc +255 -32
  223. data/lua-hooks/ext/luajit/src/vm_mips.dasc +26 -23
  224. data/lua-hooks/ext/luajit/src/vm_mips64.dasc +5062 -0
  225. data/lua-hooks/ext/luajit/src/vm_ppc.dasc +1 -1
  226. data/lua-hooks/ext/luajit/src/vm_x64.dasc +24 -25
  227. data/lua-hooks/ext/luajit/src/vm_x86.dasc +77 -4
  228. data/lua-hooks/libluahooks.darwin.a +0 -0
  229. data/lua-hooks/libluahooks.linux.a +0 -0
  230. data/lua-hooks/options.mk +1 -1
  231. metadata +37 -77
  232. data/lua-hooks/ext/all.c +0 -69
  233. data/lua-hooks/ext/libinjection/COPYING +0 -37
  234. data/lua-hooks/ext/libinjection/libinjection.h +0 -65
  235. data/lua-hooks/ext/libinjection/libinjection_html5.c +0 -847
  236. data/lua-hooks/ext/libinjection/libinjection_html5.h +0 -54
  237. data/lua-hooks/ext/libinjection/libinjection_sqli.c +0 -2301
  238. data/lua-hooks/ext/libinjection/libinjection_sqli.h +0 -295
  239. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +0 -9349
  240. data/lua-hooks/ext/libinjection/libinjection_xss.c +0 -531
  241. data/lua-hooks/ext/libinjection/libinjection_xss.h +0 -21
  242. data/lua-hooks/ext/libinjection/lualib.c +0 -145
  243. data/lua-hooks/ext/libinjection/module.mk +0 -5
  244. data/lua-hooks/ext/lpeg/HISTORY +0 -96
  245. data/lua-hooks/ext/lpeg/lpcap.c +0 -537
  246. data/lua-hooks/ext/lpeg/lpcap.h +0 -56
  247. data/lua-hooks/ext/lpeg/lpcode.c +0 -1014
  248. data/lua-hooks/ext/lpeg/lpcode.h +0 -40
  249. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  250. data/lua-hooks/ext/lpeg/lpeg.html +0 -1445
  251. data/lua-hooks/ext/lpeg/lpprint.c +0 -244
  252. data/lua-hooks/ext/lpeg/lpprint.h +0 -36
  253. data/lua-hooks/ext/lpeg/lptree.c +0 -1303
  254. data/lua-hooks/ext/lpeg/lptree.h +0 -82
  255. data/lua-hooks/ext/lpeg/lptypes.h +0 -149
  256. data/lua-hooks/ext/lpeg/lpvm.c +0 -364
  257. data/lua-hooks/ext/lpeg/lpvm.h +0 -58
  258. data/lua-hooks/ext/lpeg/makefile +0 -55
  259. data/lua-hooks/ext/lpeg/module.mk +0 -6
  260. data/lua-hooks/ext/lpeg/re.html +0 -498
  261. data/lua-hooks/ext/lua-cmsgpack/.gitignore +0 -13
  262. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +0 -45
  263. data/lua-hooks/ext/lua-cmsgpack/README.md +0 -115
  264. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +0 -970
  265. data/lua-hooks/ext/lua-cmsgpack/module.mk +0 -2
  266. data/lua-hooks/ext/lua-cmsgpack/test.lua +0 -570
  267. data/lua-hooks/ext/lua-snapshot/LICENSE +0 -7
  268. data/lua-hooks/ext/lua-snapshot/Makefile +0 -12
  269. data/lua-hooks/ext/lua-snapshot/README.md +0 -18
  270. data/lua-hooks/ext/lua-snapshot/dump.lua +0 -15
  271. data/lua-hooks/ext/lua-snapshot/module.mk +0 -2
  272. data/lua-hooks/ext/lua-snapshot/snapshot.c +0 -462
  273. data/lua-hooks/ext/luautf8/README.md +0 -152
  274. data/lua-hooks/ext/luautf8/lutf8lib.c +0 -1274
  275. data/lua-hooks/ext/luautf8/module.mk +0 -2
  276. data/lua-hooks/ext/luautf8/unidata.h +0 -3064
  277. data/lua-hooks/ext/module.mk +0 -15
  278. data/lua-hooks/ext/modules.h +0 -17
  279. data/lua-hooks/ext/perf/luacpu.c +0 -114
  280. data/lua-hooks/ext/perf/lualoadavg.c +0 -40
  281. data/lua-hooks/ext/perf/luameminfo.c +0 -38
  282. data/lua-hooks/ext/perf/luaoslib.c +0 -203
  283. data/lua-hooks/ext/perf/module.mk +0 -5
  284. data/lua-hooks/ext/sha1/luasha1.c +0 -74
  285. data/lua-hooks/ext/sha1/module.mk +0 -5
  286. data/lua-hooks/ext/sha1/sha1.c +0 -145
  287. data/lua-hooks/ext/sha2/luasha256.c +0 -77
  288. data/lua-hooks/ext/sha2/module.mk +0 -5
  289. data/lua-hooks/ext/sha2/sha256.c +0 -196
  290. data/lua-hooks/ext/sysutils/lua_utils.c +0 -56
  291. data/lua-hooks/ext/sysutils/module.mk +0 -2
@@ -1606,7 +1606,7 @@ luaC_barriert(L,t,key);
1606
1606
  return gval(mp);
1607
1607
  }
1608
1608
  static const TValue*luaH_getnum(Table*t,int key){
1609
- if(cast(unsigned int,key-1)<cast(unsigned int,t->sizearray))
1609
+ if(cast(unsigned int,key)-1<cast(unsigned int,t->sizearray))
1610
1610
  return&t->array[key-1];
1611
1611
  else{
1612
1612
  lua_Number nk=cast_num(key);
@@ -1,7 +1,7 @@
1
1
  ----------------------------------------------------------------------------
2
2
  -- LuaJIT bytecode listing module.
3
3
  --
4
- -- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
4
+ -- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
5
5
  -- Released under the MIT license. See Copyright Notice in luajit.h
6
6
  ----------------------------------------------------------------------------
7
7
  --
@@ -1,7 +1,7 @@
1
1
  ----------------------------------------------------------------------------
2
2
  -- LuaJIT module to save/list bytecode.
3
3
  --
4
- -- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
4
+ -- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
5
5
  -- Released under the MIT license. See Copyright Notice in luajit.h
6
6
  ----------------------------------------------------------------------------
7
7
  --
@@ -63,8 +63,8 @@ local map_type = {
63
63
  }
64
64
 
65
65
  local map_arch = {
66
- x86 = true, x64 = true, arm = true, arm64 = true, ppc = true,
67
- mips = true, mipsel = true,
66
+ x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true,
67
+ ppc = true, mips = true, mipsel = true,
68
68
  }
69
69
 
70
70
  local map_os = {
@@ -125,12 +125,12 @@ extern "C"
125
125
  #ifdef _WIN32
126
126
  __declspec(dllexport)
127
127
  #endif
128
- const char %s%s[] = {
128
+ const unsigned char %s%s[] = {
129
129
  ]], LJBC_PREFIX, ctx.modname))
130
130
  else
131
131
  fp:write(string.format([[
132
132
  #define %s%s_SIZE %d
133
- static const char %s%s[] = {
133
+ static const unsigned char %s%s[] = {
134
134
  ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
135
135
  end
136
136
  local t, n, m = {}, 0, 0
@@ -200,7 +200,7 @@ typedef struct {
200
200
  ]]
201
201
  local symname = LJBC_PREFIX..ctx.modname
202
202
  local is64, isbe = false, false
203
- if ctx.arch == "x64" or ctx.arch == "arm64" then
203
+ if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then
204
204
  is64 = true
205
205
  elseif ctx.arch == "ppc" or ctx.arch == "mips" then
206
206
  isbe = true
@@ -237,9 +237,9 @@ typedef struct {
237
237
  hdr.eendian = isbe and 2 or 1
238
238
  hdr.eversion = 1
239
239
  hdr.type = f16(1)
240
- hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
240
+ hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
241
241
  if ctx.arch == "mips" or ctx.arch == "mipsel" then
242
- hdr.flags = 0x50001006
242
+ hdr.flags = f32(0x50001006)
243
243
  end
244
244
  hdr.version = f32(1)
245
245
  hdr.shofs = fofs(ffi.offsetof(o, "sect"))
@@ -1,7 +1,7 @@
1
1
  ----------------------------------------------------------------------------
2
2
  -- LuaJIT ARM disassembler module.
3
3
  --
4
- -- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
4
+ -- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
5
5
  -- Released under the MIT license. See Copyright Notice in luajit.h
6
6
  ----------------------------------------------------------------------------
7
7
  -- This is a helper module used by the LuaJIT machine code dumper module.
@@ -12,7 +12,7 @@
12
12
 
13
13
  local type = type
14
14
  local sub, byte, format = string.sub, string.byte, string.format
15
- local match, gmatch, gsub = string.match, string.gmatch, string.gsub
15
+ local match, gmatch = string.match, string.gmatch
16
16
  local concat = table.concat
17
17
  local bit = require("bit")
18
18
  local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
@@ -0,0 +1,1216 @@
1
+ ----------------------------------------------------------------------------
2
+ -- LuaJIT ARM64 disassembler module.
3
+ --
4
+ -- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
5
+ -- Released under the MIT license. See Copyright Notice in luajit.h
6
+ --
7
+ -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
8
+ -- Sponsored by Cisco Systems, Inc.
9
+ ----------------------------------------------------------------------------
10
+ -- This is a helper module used by the LuaJIT machine code dumper module.
11
+ --
12
+ -- It disassembles most user-mode AArch64 instructions.
13
+ -- NYI: Advanced SIMD and VFP instructions.
14
+ ------------------------------------------------------------------------------
15
+
16
+ local type = type
17
+ local sub, byte, format = string.sub, string.byte, string.format
18
+ local match, gmatch, gsub = string.match, string.gmatch, string.gsub
19
+ local concat = table.concat
20
+ local bit = require("bit")
21
+ local band, bor, bxor, tohex = bit.band, bit.bor, bit.bxor, bit.tohex
22
+ local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
23
+ local ror = bit.ror
24
+
25
+ ------------------------------------------------------------------------------
26
+ -- Opcode maps
27
+ ------------------------------------------------------------------------------
28
+
29
+ local map_adr = { -- PC-relative addressing.
30
+ shift = 31, mask = 1,
31
+ [0] = "adrDBx", "adrpDBx"
32
+ }
33
+
34
+ local map_addsubi = { -- Add/subtract immediate.
35
+ shift = 29, mask = 3,
36
+ [0] = "add|movDNIg", "adds|cmnD0NIg", "subDNIg", "subs|cmpD0NIg",
37
+ }
38
+
39
+ local map_logi = { -- Logical immediate.
40
+ shift = 31, mask = 1,
41
+ [0] = {
42
+ shift = 22, mask = 1,
43
+ [0] = {
44
+ shift = 29, mask = 3,
45
+ [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig"
46
+ },
47
+ false -- unallocated
48
+ },
49
+ {
50
+ shift = 29, mask = 3,
51
+ [0] = "andDNig", "orr|movDN0ig", "eorDNig", "ands|tstD0Nig"
52
+ }
53
+ }
54
+
55
+ local map_movwi = { -- Move wide immediate.
56
+ shift = 31, mask = 1,
57
+ [0] = {
58
+ shift = 22, mask = 1,
59
+ [0] = {
60
+ shift = 29, mask = 3,
61
+ [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg"
62
+ }, false -- unallocated
63
+ },
64
+ {
65
+ shift = 29, mask = 3,
66
+ [0] = "movnDWRg", false, "movz|movDYRg", "movkDWRg"
67
+ },
68
+ }
69
+
70
+ local map_bitf = { -- Bitfield.
71
+ shift = 31, mask = 1,
72
+ [0] = {
73
+ shift = 22, mask = 1,
74
+ [0] = {
75
+ shift = 29, mask = 3,
76
+ [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12w",
77
+ "bfm|bfi|bfxilDN13w",
78
+ "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12w"
79
+ }
80
+ },
81
+ {
82
+ shift = 22, mask = 1,
83
+ {
84
+ shift = 29, mask = 3,
85
+ [0] = "sbfm|sbfiz|sbfx|asr|sxtw|sxth|sxtbDN12x",
86
+ "bfm|bfi|bfxilDN13x",
87
+ "ubfm|ubfiz|ubfx|lsr|lsl|uxth|uxtbDN12x"
88
+ }
89
+ }
90
+ }
91
+
92
+ local map_datai = { -- Data processing - immediate.
93
+ shift = 23, mask = 7,
94
+ [0] = map_adr, map_adr, map_addsubi, false,
95
+ map_logi, map_movwi, map_bitf,
96
+ {
97
+ shift = 15, mask = 0x1c0c1,
98
+ [0] = "extr|rorDNM4w", [0x10080] = "extr|rorDNM4x",
99
+ [0x10081] = "extr|rorDNM4x"
100
+ }
101
+ }
102
+
103
+ local map_logsr = { -- Logical, shifted register.
104
+ shift = 31, mask = 1,
105
+ [0] = {
106
+ shift = 15, mask = 1,
107
+ [0] = {
108
+ shift = 29, mask = 3,
109
+ [0] = {
110
+ shift = 21, mask = 7,
111
+ [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg",
112
+ "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg"
113
+ },
114
+ {
115
+ shift = 21, mask = 7,
116
+ [0] ="orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg",
117
+ "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg"
118
+ },
119
+ {
120
+ shift = 21, mask = 7,
121
+ [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg",
122
+ "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg"
123
+ },
124
+ {
125
+ shift = 21, mask = 7,
126
+ [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg",
127
+ "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg"
128
+ }
129
+ },
130
+ false -- unallocated
131
+ },
132
+ {
133
+ shift = 29, mask = 3,
134
+ [0] = {
135
+ shift = 21, mask = 7,
136
+ [0] = "andDNMSg", "bicDNMSg", "andDNMSg", "bicDNMSg",
137
+ "andDNMSg", "bicDNMSg", "andDNMg", "bicDNMg"
138
+ },
139
+ {
140
+ shift = 21, mask = 7,
141
+ [0] = "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0MSg", "orn|mvnDN0MSg",
142
+ "orr|movDN0MSg", "orn|mvnDN0MSg", "orr|movDN0Mg", "orn|mvnDN0Mg"
143
+ },
144
+ {
145
+ shift = 21, mask = 7,
146
+ [0] = "eorDNMSg", "eonDNMSg", "eorDNMSg", "eonDNMSg",
147
+ "eorDNMSg", "eonDNMSg", "eorDNMg", "eonDNMg"
148
+ },
149
+ {
150
+ shift = 21, mask = 7,
151
+ [0] = "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMSg", "bicsDNMSg",
152
+ "ands|tstD0NMSg", "bicsDNMSg", "ands|tstD0NMg", "bicsDNMg"
153
+ }
154
+ }
155
+ }
156
+
157
+ local map_assh = {
158
+ shift = 31, mask = 1,
159
+ [0] = {
160
+ shift = 15, mask = 1,
161
+ [0] = {
162
+ shift = 29, mask = 3,
163
+ [0] = {
164
+ shift = 22, mask = 3,
165
+ [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg"
166
+ },
167
+ {
168
+ shift = 22, mask = 3,
169
+ [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg",
170
+ "adds|cmnD0NMSg", "adds|cmnD0NMg"
171
+ },
172
+ {
173
+ shift = 22, mask = 3,
174
+ [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg"
175
+ },
176
+ {
177
+ shift = 22, mask = 3,
178
+ [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg",
179
+ "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg"
180
+ },
181
+ },
182
+ false -- unallocated
183
+ },
184
+ {
185
+ shift = 29, mask = 3,
186
+ [0] = {
187
+ shift = 22, mask = 3,
188
+ [0] = "addDNMSg", "addDNMSg", "addDNMSg", "addDNMg"
189
+ },
190
+ {
191
+ shift = 22, mask = 3,
192
+ [0] = "adds|cmnD0NMSg", "adds|cmnD0NMSg", "adds|cmnD0NMSg",
193
+ "adds|cmnD0NMg"
194
+ },
195
+ {
196
+ shift = 22, mask = 3,
197
+ [0] = "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0MSg", "sub|negDN0Mg"
198
+ },
199
+ {
200
+ shift = 22, mask = 3,
201
+ [0] = "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0MzSg",
202
+ "subs|cmp|negsD0N0MzSg", "subs|cmp|negsD0N0Mzg"
203
+ }
204
+ }
205
+ }
206
+
207
+ local map_addsubsh = { -- Add/subtract, shifted register.
208
+ shift = 22, mask = 3,
209
+ [0] = map_assh, map_assh, map_assh
210
+ }
211
+
212
+ local map_addsubex = { -- Add/subtract, extended register.
213
+ shift = 22, mask = 3,
214
+ [0] = {
215
+ shift = 29, mask = 3,
216
+ [0] = "addDNMXg", "adds|cmnD0NMXg", "subDNMXg", "subs|cmpD0NMzXg",
217
+ }
218
+ }
219
+
220
+ local map_addsubc = { -- Add/subtract, with carry.
221
+ shift = 10, mask = 63,
222
+ [0] = {
223
+ shift = 29, mask = 3,
224
+ [0] = "adcDNMg", "adcsDNMg", "sbc|ngcDN0Mg", "sbcs|ngcsDN0Mg",
225
+ }
226
+ }
227
+
228
+ local map_ccomp = {
229
+ shift = 4, mask = 1,
230
+ [0] = {
231
+ shift = 10, mask = 3,
232
+ [0] = { -- Conditional compare register.
233
+ shift = 29, mask = 3,
234
+ "ccmnNMVCg", false, "ccmpNMVCg",
235
+ },
236
+ [2] = { -- Conditional compare immediate.
237
+ shift = 29, mask = 3,
238
+ "ccmnN5VCg", false, "ccmpN5VCg",
239
+ }
240
+ }
241
+ }
242
+
243
+ local map_csel = { -- Conditional select.
244
+ shift = 11, mask = 1,
245
+ [0] = {
246
+ shift = 10, mask = 1,
247
+ [0] = {
248
+ shift = 29, mask = 3,
249
+ [0] = "cselDNMzCg", false, "csinv|cinv|csetmDNMcg", false,
250
+ },
251
+ {
252
+ shift = 29, mask = 3,
253
+ [0] = "csinc|cinc|csetDNMcg", false, "csneg|cnegDNMcg", false,
254
+ }
255
+ }
256
+ }
257
+
258
+ local map_data1s = { -- Data processing, 1 source.
259
+ shift = 29, mask = 1,
260
+ [0] = {
261
+ shift = 31, mask = 1,
262
+ [0] = {
263
+ shift = 10, mask = 0x7ff,
264
+ [0] = "rbitDNg", "rev16DNg", "revDNw", false, "clzDNg", "clsDNg"
265
+ },
266
+ {
267
+ shift = 10, mask = 0x7ff,
268
+ [0] = "rbitDNg", "rev16DNg", "rev32DNx", "revDNx", "clzDNg", "clsDNg"
269
+ }
270
+ }
271
+ }
272
+
273
+ local map_data2s = { -- Data processing, 2 sources.
274
+ shift = 29, mask = 1,
275
+ [0] = {
276
+ shift = 10, mask = 63,
277
+ false, "udivDNMg", "sdivDNMg", false, false, false, false, "lslDNMg",
278
+ "lsrDNMg", "asrDNMg", "rorDNMg"
279
+ }
280
+ }
281
+
282
+ local map_data3s = { -- Data processing, 3 sources.
283
+ shift = 29, mask = 7,
284
+ [0] = {
285
+ shift = 21, mask = 7,
286
+ [0] = {
287
+ shift = 15, mask = 1,
288
+ [0] = "madd|mulDNMA0g", "msub|mnegDNMA0g"
289
+ }
290
+ }, false, false, false,
291
+ {
292
+ shift = 15, mask = 1,
293
+ [0] = {
294
+ shift = 21, mask = 7,
295
+ [0] = "madd|mulDNMA0g", "smaddl|smullDxNMwA0x", "smulhDNMx", false,
296
+ false, "umaddl|umullDxNMwA0x", "umulhDNMx"
297
+ },
298
+ {
299
+ shift = 21, mask = 7,
300
+ [0] = "msub|mnegDNMA0g", "smsubl|smneglDxNMwA0x", false, false,
301
+ false, "umsubl|umneglDxNMwA0x"
302
+ }
303
+ }
304
+ }
305
+
306
+ local map_datar = { -- Data processing, register.
307
+ shift = 28, mask = 1,
308
+ [0] = {
309
+ shift = 24, mask = 1,
310
+ [0] = map_logsr,
311
+ {
312
+ shift = 21, mask = 1,
313
+ [0] = map_addsubsh, map_addsubex
314
+ }
315
+ },
316
+ {
317
+ shift = 21, mask = 15,
318
+ [0] = map_addsubc, false, map_ccomp, false, map_csel, false,
319
+ {
320
+ shift = 30, mask = 1,
321
+ [0] = map_data2s, map_data1s
322
+ },
323
+ false, map_data3s, map_data3s, map_data3s, map_data3s, map_data3s,
324
+ map_data3s, map_data3s, map_data3s
325
+ }
326
+ }
327
+
328
+ local map_lrl = { -- Load register, literal.
329
+ shift = 26, mask = 1,
330
+ [0] = {
331
+ shift = 30, mask = 3,
332
+ [0] = "ldrDwB", "ldrDxB", "ldrswDxB"
333
+ },
334
+ {
335
+ shift = 30, mask = 3,
336
+ [0] = "ldrDsB", "ldrDdB"
337
+ }
338
+ }
339
+
340
+ local map_lsriind = { -- Load/store register, immediate pre/post-indexed.
341
+ shift = 30, mask = 3,
342
+ [0] = {
343
+ shift = 26, mask = 1,
344
+ [0] = {
345
+ shift = 22, mask = 3,
346
+ [0] = "strbDwzL", "ldrbDwzL", "ldrsbDxzL", "ldrsbDwzL"
347
+ }
348
+ },
349
+ {
350
+ shift = 26, mask = 1,
351
+ [0] = {
352
+ shift = 22, mask = 3,
353
+ [0] = "strhDwzL", "ldrhDwzL", "ldrshDxzL", "ldrshDwzL"
354
+ }
355
+ },
356
+ {
357
+ shift = 26, mask = 1,
358
+ [0] = {
359
+ shift = 22, mask = 3,
360
+ [0] = "strDwzL", "ldrDwzL", "ldrswDxzL"
361
+ },
362
+ {
363
+ shift = 22, mask = 3,
364
+ [0] = "strDszL", "ldrDszL"
365
+ }
366
+ },
367
+ {
368
+ shift = 26, mask = 1,
369
+ [0] = {
370
+ shift = 22, mask = 3,
371
+ [0] = "strDxzL", "ldrDxzL"
372
+ },
373
+ {
374
+ shift = 22, mask = 3,
375
+ [0] = "strDdzL", "ldrDdzL"
376
+ }
377
+ }
378
+ }
379
+
380
+ local map_lsriro = {
381
+ shift = 21, mask = 1,
382
+ [0] = { -- Load/store register immediate.
383
+ shift = 10, mask = 3,
384
+ [0] = { -- Unscaled immediate.
385
+ shift = 26, mask = 1,
386
+ [0] = {
387
+ shift = 30, mask = 3,
388
+ [0] = {
389
+ shift = 22, mask = 3,
390
+ [0] = "sturbDwK", "ldurbDwK"
391
+ },
392
+ {
393
+ shift = 22, mask = 3,
394
+ [0] = "sturhDwK", "ldurhDwK"
395
+ },
396
+ {
397
+ shift = 22, mask = 3,
398
+ [0] = "sturDwK", "ldurDwK"
399
+ },
400
+ {
401
+ shift = 22, mask = 3,
402
+ [0] = "sturDxK", "ldurDxK"
403
+ }
404
+ }
405
+ }, map_lsriind, false, map_lsriind
406
+ },
407
+ { -- Load/store register, register offset.
408
+ shift = 10, mask = 3,
409
+ [2] = {
410
+ shift = 26, mask = 1,
411
+ [0] = {
412
+ shift = 30, mask = 3,
413
+ [0] = {
414
+ shift = 22, mask = 3,
415
+ [0] = "strbDwO", "ldrbDwO", "ldrsbDxO", "ldrsbDwO"
416
+ },
417
+ {
418
+ shift = 22, mask = 3,
419
+ [0] = "strhDwO", "ldrhDwO", "ldrshDxO", "ldrshDwO"
420
+ },
421
+ {
422
+ shift = 22, mask = 3,
423
+ [0] = "strDwO", "ldrDwO", "ldrswDxO"
424
+ },
425
+ {
426
+ shift = 22, mask = 3,
427
+ [0] = "strDxO", "ldrDxO"
428
+ }
429
+ },
430
+ {
431
+ shift = 30, mask = 3,
432
+ [2] = {
433
+ shift = 22, mask = 3,
434
+ [0] = "strDsO", "ldrDsO"
435
+ },
436
+ [3] = {
437
+ shift = 22, mask = 3,
438
+ [0] = "strDdO", "ldrDdO"
439
+ }
440
+ }
441
+ }
442
+ }
443
+ }
444
+
445
+ local map_lsp = { -- Load/store register pair, offset.
446
+ shift = 22, mask = 1,
447
+ [0] = {
448
+ shift = 30, mask = 3,
449
+ [0] = {
450
+ shift = 26, mask = 1,
451
+ [0] = "stpDzAzwP", "stpDzAzsP",
452
+ },
453
+ {
454
+ shift = 26, mask = 1,
455
+ "stpDzAzdP"
456
+ },
457
+ {
458
+ shift = 26, mask = 1,
459
+ [0] = "stpDzAzxP"
460
+ }
461
+ },
462
+ {
463
+ shift = 30, mask = 3,
464
+ [0] = {
465
+ shift = 26, mask = 1,
466
+ [0] = "ldpDzAzwP", "ldpDzAzsP",
467
+ },
468
+ {
469
+ shift = 26, mask = 1,
470
+ [0] = "ldpswDAxP", "ldpDzAzdP"
471
+ },
472
+ {
473
+ shift = 26, mask = 1,
474
+ [0] = "ldpDzAzxP"
475
+ }
476
+ }
477
+ }
478
+
479
+ local map_ls = { -- Loads and stores.
480
+ shift = 24, mask = 0x31,
481
+ [0x10] = map_lrl, [0x30] = map_lsriro,
482
+ [0x20] = {
483
+ shift = 23, mask = 3,
484
+ map_lsp, map_lsp, map_lsp
485
+ },
486
+ [0x21] = {
487
+ shift = 23, mask = 3,
488
+ map_lsp, map_lsp, map_lsp
489
+ },
490
+ [0x31] = {
491
+ shift = 26, mask = 1,
492
+ [0] = {
493
+ shift = 30, mask = 3,
494
+ [0] = {
495
+ shift = 22, mask = 3,
496
+ [0] = "strbDwzU", "ldrbDwzU"
497
+ },
498
+ {
499
+ shift = 22, mask = 3,
500
+ [0] = "strhDwzU", "ldrhDwzU"
501
+ },
502
+ {
503
+ shift = 22, mask = 3,
504
+ [0] = "strDwzU", "ldrDwzU"
505
+ },
506
+ {
507
+ shift = 22, mask = 3,
508
+ [0] = "strDxzU", "ldrDxzU"
509
+ }
510
+ },
511
+ {
512
+ shift = 30, mask = 3,
513
+ [2] = {
514
+ shift = 22, mask = 3,
515
+ [0] = "strDszU", "ldrDszU"
516
+ },
517
+ [3] = {
518
+ shift = 22, mask = 3,
519
+ [0] = "strDdzU", "ldrDdzU"
520
+ }
521
+ }
522
+ },
523
+ }
524
+
525
+ local map_datafp = { -- Data processing, SIMD and FP.
526
+ shift = 28, mask = 7,
527
+ { -- 001
528
+ shift = 24, mask = 1,
529
+ [0] = {
530
+ shift = 21, mask = 1,
531
+ {
532
+ shift = 10, mask = 3,
533
+ [0] = {
534
+ shift = 12, mask = 1,
535
+ [0] = {
536
+ shift = 13, mask = 1,
537
+ [0] = {
538
+ shift = 14, mask = 1,
539
+ [0] = {
540
+ shift = 15, mask = 1,
541
+ [0] = { -- FP/int conversion.
542
+ shift = 31, mask = 1,
543
+ [0] = {
544
+ shift = 16, mask = 0xff,
545
+ [0x20] = "fcvtnsDwNs", [0x21] = "fcvtnuDwNs",
546
+ [0x22] = "scvtfDsNw", [0x23] = "ucvtfDsNw",
547
+ [0x24] = "fcvtasDwNs", [0x25] = "fcvtauDwNs",
548
+ [0x26] = "fmovDwNs", [0x27] = "fmovDsNw",
549
+ [0x28] = "fcvtpsDwNs", [0x29] = "fcvtpuDwNs",
550
+ [0x30] = "fcvtmsDwNs", [0x31] = "fcvtmuDwNs",
551
+ [0x38] = "fcvtzsDwNs", [0x39] = "fcvtzuDwNs",
552
+ [0x60] = "fcvtnsDwNd", [0x61] = "fcvtnuDwNd",
553
+ [0x62] = "scvtfDdNw", [0x63] = "ucvtfDdNw",
554
+ [0x64] = "fcvtasDwNd", [0x65] = "fcvtauDwNd",
555
+ [0x68] = "fcvtpsDwNd", [0x69] = "fcvtpuDwNd",
556
+ [0x70] = "fcvtmsDwNd", [0x71] = "fcvtmuDwNd",
557
+ [0x78] = "fcvtzsDwNd", [0x79] = "fcvtzuDwNd"
558
+ },
559
+ {
560
+ shift = 16, mask = 0xff,
561
+ [0x20] = "fcvtnsDxNs", [0x21] = "fcvtnuDxNs",
562
+ [0x22] = "scvtfDsNx", [0x23] = "ucvtfDsNx",
563
+ [0x24] = "fcvtasDxNs", [0x25] = "fcvtauDxNs",
564
+ [0x28] = "fcvtpsDxNs", [0x29] = "fcvtpuDxNs",
565
+ [0x30] = "fcvtmsDxNs", [0x31] = "fcvtmuDxNs",
566
+ [0x38] = "fcvtzsDxNs", [0x39] = "fcvtzuDxNs",
567
+ [0x60] = "fcvtnsDxNd", [0x61] = "fcvtnuDxNd",
568
+ [0x62] = "scvtfDdNx", [0x63] = "ucvtfDdNx",
569
+ [0x64] = "fcvtasDxNd", [0x65] = "fcvtauDxNd",
570
+ [0x66] = "fmovDxNd", [0x67] = "fmovDdNx",
571
+ [0x68] = "fcvtpsDxNd", [0x69] = "fcvtpuDxNd",
572
+ [0x70] = "fcvtmsDxNd", [0x71] = "fcvtmuDxNd",
573
+ [0x78] = "fcvtzsDxNd", [0x79] = "fcvtzuDxNd"
574
+ }
575
+ }
576
+ },
577
+ { -- FP data-processing, 1 source.
578
+ shift = 31, mask = 1,
579
+ [0] = {
580
+ shift = 22, mask = 3,
581
+ [0] = {
582
+ shift = 15, mask = 63,
583
+ [0] = "fmovDNf", "fabsDNf", "fnegDNf",
584
+ "fsqrtDNf", false, "fcvtDdNs", false, false,
585
+ "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf",
586
+ "frintaDNf", false, "frintxDNf", "frintiDNf",
587
+ },
588
+ {
589
+ shift = 15, mask = 63,
590
+ [0] = "fmovDNf", "fabsDNf", "fnegDNf",
591
+ "fsqrtDNf", "fcvtDsNd", false, false, false,
592
+ "frintnDNf", "frintpDNf", "frintmDNf", "frintzDNf",
593
+ "frintaDNf", false, "frintxDNf", "frintiDNf",
594
+ }
595
+ }
596
+ }
597
+ },
598
+ { -- FP compare.
599
+ shift = 31, mask = 1,
600
+ [0] = {
601
+ shift = 14, mask = 3,
602
+ [0] = {
603
+ shift = 23, mask = 1,
604
+ [0] = {
605
+ shift = 0, mask = 31,
606
+ [0] = "fcmpNMf", [8] = "fcmpNZf",
607
+ [16] = "fcmpeNMf", [24] = "fcmpeNZf",
608
+ }
609
+ }
610
+ }
611
+ }
612
+ },
613
+ { -- FP immediate.
614
+ shift = 31, mask = 1,
615
+ [0] = {
616
+ shift = 5, mask = 31,
617
+ [0] = {
618
+ shift = 23, mask = 1,
619
+ [0] = "fmovDFf"
620
+ }
621
+ }
622
+ }
623
+ },
624
+ { -- FP conditional compare.
625
+ shift = 31, mask = 1,
626
+ [0] = {
627
+ shift = 23, mask = 1,
628
+ [0] = {
629
+ shift = 4, mask = 1,
630
+ [0] = "fccmpNMVCf", "fccmpeNMVCf"
631
+ }
632
+ }
633
+ },
634
+ { -- FP data-processing, 2 sources.
635
+ shift = 31, mask = 1,
636
+ [0] = {
637
+ shift = 23, mask = 1,
638
+ [0] = {
639
+ shift = 12, mask = 15,
640
+ [0] = "fmulDNMf", "fdivDNMf", "faddDNMf", "fsubDNMf",
641
+ "fmaxDNMf", "fminDNMf", "fmaxnmDNMf", "fminnmDNMf",
642
+ "fnmulDNMf"
643
+ }
644
+ }
645
+ },
646
+ { -- FP conditional select.
647
+ shift = 31, mask = 1,
648
+ [0] = {
649
+ shift = 23, mask = 1,
650
+ [0] = "fcselDNMCf"
651
+ }
652
+ }
653
+ }
654
+ },
655
+ { -- FP data-processing, 3 sources.
656
+ shift = 31, mask = 1,
657
+ [0] = {
658
+ shift = 15, mask = 1,
659
+ [0] = {
660
+ shift = 21, mask = 5,
661
+ [0] = "fmaddDNMAf", "fnmaddDNMAf"
662
+ },
663
+ {
664
+ shift = 21, mask = 5,
665
+ [0] = "fmsubDNMAf", "fnmsubDNMAf"
666
+ }
667
+ }
668
+ }
669
+ }
670
+ }
671
+
672
+ local map_br = { -- Branches, exception generating and system instructions.
673
+ shift = 29, mask = 7,
674
+ [0] = "bB",
675
+ { -- Compare & branch, immediate.
676
+ shift = 24, mask = 3,
677
+ [0] = "cbzDBg", "cbnzDBg", "tbzDTBw", "tbnzDTBw"
678
+ },
679
+ { -- Conditional branch, immediate.
680
+ shift = 24, mask = 3,
681
+ [0] = {
682
+ shift = 4, mask = 1,
683
+ [0] = {
684
+ shift = 0, mask = 15,
685
+ [0] = "beqB", "bneB", "bhsB", "bloB", "bmiB", "bplB", "bvsB", "bvcB",
686
+ "bhiB", "blsB", "bgeB", "bltB", "bgtB", "bleB", "balB"
687
+ }
688
+ }
689
+ }, false, "blB",
690
+ { -- Compare & branch, immediate.
691
+ shift = 24, mask = 3,
692
+ [0] = "cbzDBg", "cbnzDBg", "tbzDTBx", "tbnzDTBx"
693
+ },
694
+ {
695
+ shift = 24, mask = 3,
696
+ [0] = { -- Exception generation.
697
+ shift = 0, mask = 0xe0001f,
698
+ [0x200000] = "brkW"
699
+ },
700
+ { -- System instructions.
701
+ shift = 0, mask = 0x3fffff,
702
+ [0x03201f] = "nop"
703
+ },
704
+ { -- Unconditional branch, register.
705
+ shift = 0, mask = 0xfffc1f,
706
+ [0x1f0000] = "brNx", [0x3f0000] = "blrNx",
707
+ [0x5f0000] = "retNx"
708
+ },
709
+ }
710
+ }
711
+
712
+ local map_init = {
713
+ shift = 25, mask = 15,
714
+ [0] = false, false, false, false, map_ls, map_datar, map_ls, map_datafp,
715
+ map_datai, map_datai, map_br, map_br, map_ls, map_datar, map_ls, map_datafp
716
+ }
717
+
718
+ ------------------------------------------------------------------------------
719
+
720
+ local map_regs = { x = {}, w = {}, d = {}, s = {} }
721
+
722
+ for i=0,30 do
723
+ map_regs.x[i] = "x"..i
724
+ map_regs.w[i] = "w"..i
725
+ map_regs.d[i] = "d"..i
726
+ map_regs.s[i] = "s"..i
727
+ end
728
+ map_regs.x[31] = "sp"
729
+ map_regs.w[31] = "wsp"
730
+ map_regs.d[31] = "d31"
731
+ map_regs.s[31] = "s31"
732
+
733
+ local map_cond = {
734
+ [0] = "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
735
+ "hi", "ls", "ge", "lt", "gt", "le", "al",
736
+ }
737
+
738
+ local map_shift = { [0] = "lsl", "lsr", "asr", }
739
+
740
+ local map_extend = {
741
+ [0] = "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx",
742
+ }
743
+
744
+ ------------------------------------------------------------------------------
745
+
746
+ -- Output a nicely formatted line with an opcode and operands.
747
+ local function putop(ctx, text, operands)
748
+ local pos = ctx.pos
749
+ local extra = ""
750
+ if ctx.rel then
751
+ local sym = ctx.symtab[ctx.rel]
752
+ if sym then
753
+ extra = "\t->"..sym
754
+ end
755
+ end
756
+ if ctx.hexdump > 0 then
757
+ ctx.out(format("%08x %s %-5s %s%s\n",
758
+ ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
759
+ else
760
+ ctx.out(format("%08x %-5s %s%s\n",
761
+ ctx.addr+pos, text, concat(operands, ", "), extra))
762
+ end
763
+ ctx.pos = pos + 4
764
+ end
765
+
766
+ -- Fallback for unknown opcodes.
767
+ local function unknown(ctx)
768
+ return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
769
+ end
770
+
771
+ local function match_reg(p, pat, regnum)
772
+ return map_regs[match(pat, p.."%w-([xwds])")][regnum]
773
+ end
774
+
775
+ local function fmt_hex32(x)
776
+ if x < 0 then
777
+ return tohex(x)
778
+ else
779
+ return format("%x", x)
780
+ end
781
+ end
782
+
783
+ local imm13_rep = { 0x55555555, 0x11111111, 0x01010101, 0x00010001, 0x00000001 }
784
+
785
+ local function decode_imm13(op)
786
+ local imms = band(rshift(op, 10), 63)
787
+ local immr = band(rshift(op, 16), 63)
788
+ if band(op, 0x00400000) == 0 then
789
+ local len = 5
790
+ if imms >= 56 then
791
+ if imms >= 60 then len = 1 else len = 2 end
792
+ elseif imms >= 48 then len = 3 elseif imms >= 32 then len = 4 end
793
+ local l = lshift(1, len)-1
794
+ local s = band(imms, l)
795
+ local r = band(immr, l)
796
+ local imm = ror(rshift(-1, 31-s), r)
797
+ if len ~= 5 then imm = band(imm, lshift(1, l)-1) + rshift(imm, 31-l) end
798
+ imm = imm * imm13_rep[len]
799
+ local ix = fmt_hex32(imm)
800
+ if rshift(op, 31) ~= 0 then
801
+ return ix..tohex(imm)
802
+ else
803
+ return ix
804
+ end
805
+ else
806
+ local lo, hi = -1, 0
807
+ if imms < 32 then lo = rshift(-1, 31-imms) else hi = rshift(-1, 63-imms) end
808
+ if immr ~= 0 then
809
+ lo, hi = ror(lo, immr), ror(hi, immr)
810
+ local x = immr == 32 and 0 or band(bxor(lo, hi), lshift(-1, 32-immr))
811
+ lo, hi = bxor(lo, x), bxor(hi, x)
812
+ if immr >= 32 then lo, hi = hi, lo end
813
+ end
814
+ if hi ~= 0 then
815
+ return fmt_hex32(hi)..tohex(lo)
816
+ else
817
+ return fmt_hex32(lo)
818
+ end
819
+ end
820
+ end
821
+
822
+ local function parse_immpc(op, name)
823
+ if name == "b" or name == "bl" then
824
+ return arshift(lshift(op, 6), 4)
825
+ elseif name == "adr" or name == "adrp" then
826
+ local immlo = band(rshift(op, 29), 3)
827
+ local immhi = lshift(arshift(lshift(op, 8), 13), 2)
828
+ return bor(immhi, immlo)
829
+ elseif name == "tbz" or name == "tbnz" then
830
+ return lshift(arshift(lshift(op, 13), 18), 2)
831
+ else
832
+ return lshift(arshift(lshift(op, 8), 13), 2)
833
+ end
834
+ end
835
+
836
+ local function parse_fpimm8(op)
837
+ local sign = band(op, 0x100000) == 0 and 1 or -1
838
+ local exp = bxor(rshift(arshift(lshift(op, 12), 5), 24), 0x80) - 131
839
+ local frac = 16+band(rshift(op, 13), 15)
840
+ return sign * frac * 2^exp
841
+ end
842
+
843
+ local function prefer_bfx(sf, uns, imms, immr)
844
+ if imms < immr or imms == 31 or imms == 63 then
845
+ return false
846
+ end
847
+ if immr == 0 then
848
+ if sf == 0 and (imms == 7 or imms == 15) then
849
+ return false
850
+ end
851
+ if sf ~= 0 and uns == 0 and (imms == 7 or imms == 15 or imms == 31) then
852
+ return false
853
+ end
854
+ end
855
+ return true
856
+ end
857
+
858
+ -- Disassemble a single instruction.
859
+ local function disass_ins(ctx)
860
+ local pos = ctx.pos
861
+ local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
862
+ local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
863
+ local operands = {}
864
+ local suffix = ""
865
+ local last, name, pat
866
+ local map_reg
867
+ ctx.op = op
868
+ ctx.rel = nil
869
+ last = nil
870
+ local opat
871
+ opat = map_init[band(rshift(op, 25), 15)]
872
+ while type(opat) ~= "string" do
873
+ if not opat then return unknown(ctx) end
874
+ opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
875
+ end
876
+ name, pat = match(opat, "^([a-z0-9]*)(.*)")
877
+ local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
878
+ if altname then pat = pat2 end
879
+ if sub(pat, 1, 1) == "." then
880
+ local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
881
+ suffix = suffix..s2
882
+ pat = p2
883
+ end
884
+
885
+ local rt = match(pat, "[gf]")
886
+ if rt then
887
+ if rt == "g" then
888
+ map_reg = band(op, 0x80000000) ~= 0 and map_regs.x or map_regs.w
889
+ else
890
+ map_reg = band(op, 0x400000) ~= 0 and map_regs.d or map_regs.s
891
+ end
892
+ end
893
+
894
+ local second0, immr
895
+
896
+ for p in gmatch(pat, ".") do
897
+ local x = nil
898
+ if p == "D" then
899
+ local regnum = band(op, 31)
900
+ x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
901
+ elseif p == "N" then
902
+ local regnum = band(rshift(op, 5), 31)
903
+ x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
904
+ elseif p == "M" then
905
+ local regnum = band(rshift(op, 16), 31)
906
+ x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
907
+ elseif p == "A" then
908
+ local regnum = band(rshift(op, 10), 31)
909
+ x = rt and map_reg[regnum] or match_reg(p, pat, regnum)
910
+ elseif p == "B" then
911
+ local addr = ctx.addr + pos + parse_immpc(op, name)
912
+ ctx.rel = addr
913
+ x = "0x"..tohex(addr)
914
+ elseif p == "T" then
915
+ x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31))
916
+ elseif p == "V" then
917
+ x = band(op, 15)
918
+ elseif p == "C" then
919
+ x = map_cond[band(rshift(op, 12), 15)]
920
+ elseif p == "c" then
921
+ local rn = band(rshift(op, 5), 31)
922
+ local rm = band(rshift(op, 16), 31)
923
+ local cond = band(rshift(op, 12), 15)
924
+ local invc = bxor(cond, 1)
925
+ x = map_cond[cond]
926
+ if altname and cond ~= 14 and cond ~= 15 then
927
+ local a1, a2 = match(altname, "([^|]*)|(.*)")
928
+ if rn == rm then
929
+ local n = #operands
930
+ operands[n] = nil
931
+ x = map_cond[invc]
932
+ if rn ~= 31 then
933
+ if a1 then name = a1 else name = altname end
934
+ else
935
+ operands[n-1] = nil
936
+ name = a2
937
+ end
938
+ end
939
+ end
940
+ elseif p == "W" then
941
+ x = band(rshift(op, 5), 0xffff)
942
+ elseif p == "Y" then
943
+ x = band(rshift(op, 5), 0xffff)
944
+ local hw = band(rshift(op, 21), 3)
945
+ if altname and (hw == 0 or x ~= 0) then
946
+ name = altname
947
+ end
948
+ elseif p == "L" then
949
+ local rn = map_regs.x[band(rshift(op, 5), 31)]
950
+ local imm9 = arshift(lshift(op, 11), 23)
951
+ if band(op, 0x800) ~= 0 then
952
+ x = "["..rn..", #"..imm9.."]!"
953
+ else
954
+ x = "["..rn.."], #"..imm9
955
+ end
956
+ elseif p == "U" then
957
+ local rn = map_regs.x[band(rshift(op, 5), 31)]
958
+ local sz = band(rshift(op, 30), 3)
959
+ local imm12 = lshift(arshift(lshift(op, 10), 20), sz)
960
+ if imm12 ~= 0 then
961
+ x = "["..rn..", #"..imm12.."]"
962
+ else
963
+ x = "["..rn.."]"
964
+ end
965
+ elseif p == "K" then
966
+ local rn = map_regs.x[band(rshift(op, 5), 31)]
967
+ local imm9 = arshift(lshift(op, 11), 23)
968
+ if imm9 ~= 0 then
969
+ x = "["..rn..", #"..imm9.."]"
970
+ else
971
+ x = "["..rn.."]"
972
+ end
973
+ elseif p == "O" then
974
+ local rn, rm = map_regs.x[band(rshift(op, 5), 31)]
975
+ local m = band(rshift(op, 13), 1)
976
+ if m == 0 then
977
+ rm = map_regs.w[band(rshift(op, 16), 31)]
978
+ else
979
+ rm = map_regs.x[band(rshift(op, 16), 31)]
980
+ end
981
+ x = "["..rn..", "..rm
982
+ local opt = band(rshift(op, 13), 7)
983
+ local s = band(rshift(op, 12), 1)
984
+ local sz = band(rshift(op, 30), 3)
985
+ -- extension to be applied
986
+ if opt == 3 then
987
+ if s == 0 then x = x.."]"
988
+ else x = x..", lsl #"..sz.."]" end
989
+ elseif opt == 2 or opt == 6 or opt == 7 then
990
+ if s == 0 then x = x..", "..map_extend[opt].."]"
991
+ else x = x..", "..map_extend[opt].." #"..sz.."]" end
992
+ else
993
+ x = x.."]"
994
+ end
995
+ elseif p == "P" then
996
+ local opcv, sh = rshift(op, 26), 2
997
+ if opcv >= 0x2a then sh = 4 elseif opcv >= 0x1b then sh = 3 end
998
+ local imm7 = lshift(arshift(lshift(op, 10), 25), sh)
999
+ local rn = map_regs.x[band(rshift(op, 5), 31)]
1000
+ local ind = band(rshift(op, 23), 3)
1001
+ if ind == 1 then
1002
+ x = "["..rn.."], #"..imm7
1003
+ elseif ind == 2 then
1004
+ if imm7 == 0 then
1005
+ x = "["..rn.."]"
1006
+ else
1007
+ x = "["..rn..", #"..imm7.."]"
1008
+ end
1009
+ elseif ind == 3 then
1010
+ x = "["..rn..", #"..imm7.."]!"
1011
+ end
1012
+ elseif p == "I" then
1013
+ local shf = band(rshift(op, 22), 3)
1014
+ local imm12 = band(rshift(op, 10), 0x0fff)
1015
+ local rn, rd = band(rshift(op, 5), 31), band(op, 31)
1016
+ if altname == "mov" and shf == 0 and imm12 == 0 and (rn == 31 or rd == 31) then
1017
+ name = altname
1018
+ x = nil
1019
+ elseif shf == 0 then
1020
+ x = imm12
1021
+ elseif shf == 1 then
1022
+ x = imm12..", lsl #12"
1023
+ end
1024
+ elseif p == "i" then
1025
+ x = "#0x"..decode_imm13(op)
1026
+ elseif p == "1" then
1027
+ immr = band(rshift(op, 16), 63)
1028
+ x = immr
1029
+ elseif p == "2" then
1030
+ x = band(rshift(op, 10), 63)
1031
+ if altname then
1032
+ local a1, a2, a3, a4, a5, a6 =
1033
+ match(altname, "([^|]*)|([^|]*)|([^|]*)|([^|]*)|([^|]*)|(.*)")
1034
+ local sf = band(rshift(op, 26), 32)
1035
+ local uns = band(rshift(op, 30), 1)
1036
+ if prefer_bfx(sf, uns, x, immr) then
1037
+ name = a2
1038
+ x = x - immr + 1
1039
+ elseif immr == 0 and x == 7 then
1040
+ local n = #operands
1041
+ operands[n] = nil
1042
+ if sf ~= 0 then
1043
+ operands[n-1] = gsub(operands[n-1], "x", "w")
1044
+ end
1045
+ last = operands[n-1]
1046
+ name = a6
1047
+ x = nil
1048
+ elseif immr == 0 and x == 15 then
1049
+ local n = #operands
1050
+ operands[n] = nil
1051
+ if sf ~= 0 then
1052
+ operands[n-1] = gsub(operands[n-1], "x", "w")
1053
+ end
1054
+ last = operands[n-1]
1055
+ name = a5
1056
+ x = nil
1057
+ elseif x == 31 or x == 63 then
1058
+ if x == 31 and immr == 0 and name == "sbfm" then
1059
+ name = a4
1060
+ local n = #operands
1061
+ operands[n] = nil
1062
+ if sf ~= 0 then
1063
+ operands[n-1] = gsub(operands[n-1], "x", "w")
1064
+ end
1065
+ last = operands[n-1]
1066
+ else
1067
+ name = a3
1068
+ end
1069
+ x = nil
1070
+ elseif band(x, 31) ~= 31 and immr == x+1 and name == "ubfm" then
1071
+ name = a4
1072
+ last = "#"..(sf+32 - immr)
1073
+ operands[#operands] = last
1074
+ x = nil
1075
+ elseif x < immr then
1076
+ name = a1
1077
+ last = "#"..(sf+32 - immr)
1078
+ operands[#operands] = last
1079
+ x = x + 1
1080
+ end
1081
+ end
1082
+ elseif p == "3" then
1083
+ x = band(rshift(op, 10), 63)
1084
+ if altname then
1085
+ local a1, a2 = match(altname, "([^|]*)|(.*)")
1086
+ if x < immr then
1087
+ name = a1
1088
+ local sf = band(rshift(op, 26), 32)
1089
+ last = "#"..(sf+32 - immr)
1090
+ operands[#operands] = last
1091
+ x = x + 1
1092
+ elseif x >= immr then
1093
+ name = a2
1094
+ x = x - immr + 1
1095
+ end
1096
+ end
1097
+ elseif p == "4" then
1098
+ x = band(rshift(op, 10), 63)
1099
+ local rn = band(rshift(op, 5), 31)
1100
+ local rm = band(rshift(op, 16), 31)
1101
+ if altname and rn == rm then
1102
+ local n = #operands
1103
+ operands[n] = nil
1104
+ last = operands[n-1]
1105
+ name = altname
1106
+ end
1107
+ elseif p == "5" then
1108
+ x = band(rshift(op, 16), 31)
1109
+ elseif p == "S" then
1110
+ x = band(rshift(op, 10), 63)
1111
+ if x == 0 then x = nil
1112
+ else x = map_shift[band(rshift(op, 22), 3)].." #"..x end
1113
+ elseif p == "X" then
1114
+ local opt = band(rshift(op, 13), 7)
1115
+ -- Width specifier <R>.
1116
+ if opt ~= 3 and opt ~= 7 then
1117
+ last = map_regs.w[band(rshift(op, 16), 31)]
1118
+ operands[#operands] = last
1119
+ end
1120
+ x = band(rshift(op, 10), 7)
1121
+ -- Extension.
1122
+ if opt == 2 + band(rshift(op, 31), 1) and
1123
+ band(rshift(op, second0 and 5 or 0), 31) == 31 then
1124
+ if x == 0 then x = nil
1125
+ else x = "lsl #"..x end
1126
+ else
1127
+ if x == 0 then x = map_extend[band(rshift(op, 13), 7)]
1128
+ else x = map_extend[band(rshift(op, 13), 7)].." #"..x end
1129
+ end
1130
+ elseif p == "R" then
1131
+ x = band(rshift(op,21), 3)
1132
+ if x == 0 then x = nil
1133
+ else x = "lsl #"..x*16 end
1134
+ elseif p == "z" then
1135
+ local n = #operands
1136
+ if operands[n] == "sp" then operands[n] = "xzr"
1137
+ elseif operands[n] == "wsp" then operands[n] = "wzr"
1138
+ end
1139
+ elseif p == "Z" then
1140
+ x = 0
1141
+ elseif p == "F" then
1142
+ x = parse_fpimm8(op)
1143
+ elseif p == "g" or p == "f" or p == "x" or p == "w" or
1144
+ p == "d" or p == "s" then
1145
+ -- These are handled in D/N/M/A.
1146
+ elseif p == "0" then
1147
+ if last == "sp" or last == "wsp" then
1148
+ local n = #operands
1149
+ operands[n] = nil
1150
+ last = operands[n-1]
1151
+ if altname then
1152
+ local a1, a2 = match(altname, "([^|]*)|(.*)")
1153
+ if not a1 then
1154
+ name = altname
1155
+ elseif second0 then
1156
+ name, altname = a2, a1
1157
+ else
1158
+ name, altname = a1, a2
1159
+ end
1160
+ end
1161
+ end
1162
+ second0 = true
1163
+ else
1164
+ assert(false)
1165
+ end
1166
+ if x then
1167
+ last = x
1168
+ if type(x) == "number" then x = "#"..x end
1169
+ operands[#operands+1] = x
1170
+ end
1171
+ end
1172
+
1173
+ return putop(ctx, name..suffix, operands)
1174
+ end
1175
+
1176
+ ------------------------------------------------------------------------------
1177
+
1178
+ -- Disassemble a block of code.
1179
+ local function disass_block(ctx, ofs, len)
1180
+ if not ofs then ofs = 0 end
1181
+ local stop = len and ofs+len or #ctx.code
1182
+ ctx.pos = ofs
1183
+ ctx.rel = nil
1184
+ while ctx.pos < stop do disass_ins(ctx) end
1185
+ end
1186
+
1187
+ -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
1188
+ local function create(code, addr, out)
1189
+ local ctx = {}
1190
+ ctx.code = code
1191
+ ctx.addr = addr or 0
1192
+ ctx.out = out or io.write
1193
+ ctx.symtab = {}
1194
+ ctx.disass = disass_block
1195
+ ctx.hexdump = 8
1196
+ return ctx
1197
+ end
1198
+
1199
+ -- Simple API: disassemble code (a string) at address and output via out.
1200
+ local function disass(code, addr, out)
1201
+ create(code, addr, out):disass()
1202
+ end
1203
+
1204
+ -- Return register name for RID.
1205
+ local function regname(r)
1206
+ if r < 32 then return map_regs.x[r] end
1207
+ return map_regs.d[r-32]
1208
+ end
1209
+
1210
+ -- Public module functions.
1211
+ return {
1212
+ create = create,
1213
+ disass = disass,
1214
+ regname = regname
1215
+ }
1216
+