immunio 1.2.1 → 2.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 (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
+