A shell that runs x86_64 assembly
c
x86-64
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

completion.h 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* Copyright Yann Weber <asmsh@yannweb.net>
  2. This file is part of asmsh.
  3. asmsh is free software: you can redistribute it and/or modify it under the
  4. terms of the GNU General Public License as published by the Free Software
  5. Foundation, either version 3 of the License, or any later version.
  6. asmsh is distributed in the hope that it will be useful, but WITHOUT ANY
  7. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  9. details.
  10. You should have received a copy of the GNU General Public License along
  11. with asmsh. If not, see <https://www.gnu.org/licenses/>.
  12. */
  13. #ifndef ASMSH_COMPLETION_H
  14. #define ASMSH_COMPLETION_H
  15. #include "config.h"
  16. #include <errno.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #if HAVE_LIBREADLINE == 1
  21. #include <readline/readline.h>
  22. #include <readline/history.h>
  23. #endif
  24. #include "shell_cmds.h"
  25. #define ASHCOMP_NOARG 0x00
  26. #define ASHCOMP_REG8 0x01
  27. #define ASHCOMP_REG16 0x02
  28. #define ASHCOMP_REG32 0x04
  29. #define ASHCOMP_REG64 0x08
  30. #define ASHCOMP_REGALL 0x0F
  31. #define ASHCOMP_SEGREG 0x10
  32. #define ASHCOMP_IMM 0x20
  33. #define ASHCOMP_ADDR 0x40
  34. #define ASHCOMP_XMM 0x100
  35. #define ASHCOMP_XMM2 0x200
  36. #define ASHCOMP_YMM 0x400
  37. #define ASHCOMP_XALL 0x700
  38. typedef struct asmsh_completion_s asmsh_completion_t;
  39. typedef struct asmsh_compinstr_s asmsh_compinstr_t;
  40. typedef unsigned int flag_t;
  41. struct asmsh_compinstr_s
  42. {
  43. const char *mnemo;
  44. flag_t arg1;
  45. flag_t arg2;
  46. };
  47. struct asmsh_completion_s
  48. {
  49. flag_t regs;
  50. };
  51. char **asmsh_completion(const char *buf, const char *text, int start, int end);
  52. #if HAVE_LIBREADLINE == 1
  53. char *asmsh_rl_completion_gen(const char *text, int state);
  54. char **asmsh_rl_completion(const char *text, int start, int end);
  55. #endif
  56. /** Return all possible instructions given a start */
  57. char **asmsh_compl_instr(const char *start);
  58. /** Return possible commands given a start */
  59. char **asmsh_compl_cmds(const char *start);
  60. char **asmsh_compl_arg(const char *buf, const char *text, int start);
  61. static const char * const M_conds[] = {"o","no","b","c","nae","ae","nb","nc","e","z","ne","nz","be","na","a","nbe","s","ns","p","pe","np","po","l","nge","ge","nl","le","ng","g","nle", NULL};
  62. static const char M_sizes[] = "bwdq";
  63. /* Upper case letters are flags pointing to
  64. * more complex completion (like conditions)
  65. * C -> CMOVcc cc conditions
  66. * S -> a size descriptor or nothing
  67. */
  68. static const asmsh_compinstr_t x86_64_instr[] = {
  69. {"aaa", 0, 0},
  70. {"aad", ASHCOMP_IMM, 0},
  71. {"aam", ASHCOMP_IMM, 0},
  72. {"aas", 0, 0},
  73. {"adc", 0xff, 0xff},
  74. {"add", 0xff, 0xff},
  75. {"and", 0xff, 0xff},
  76. {"andn", 0xff, 0xff},
  77. {"bextr", 0xff, 0xff},
  78. {"blcfill", 0xff, 0xff},
  79. {"blci", 0xff, 0xff},
  80. {"blcic", 0xff, 0xff},
  81. {"blcmsk", 0xff, 0xff},
  82. {"blcs", 0xff, 0xff},
  83. {"blsfill", 0xff, 0xff},
  84. {"blsi", 0xff, 0xff},
  85. {"blsic", 0xff, 0xff},
  86. {"blsmsk", 0xff, 0xff},
  87. {"blsr", 0xff, 0xff},
  88. {"bound", 0x6|0x40, 0x6|0x40},
  89. {"bsf", 0xff, 0xff},
  90. {"bsr", 0xff, 0xff},
  91. {"bswap", ASHCOMP_REG32 | ASHCOMP_REG64, 0},
  92. {"bt", 0xff, 0},
  93. {"btc", 0xff, 0},
  94. {"btr", 0xff, 0},
  95. {"bts", 0xff, 0},
  96. {"call", 0xff, 0},
  97. {"cbw", 0, 0},
  98. {"cdq", 0, 0},
  99. {"cdqe", 0, 0},
  100. {"clc", 0, 0},
  101. {"cld", 0, 0},
  102. {"clflush", 0, 0},
  103. {"cli", 0, 0},
  104. {"cmc", 0, 0},
  105. {"cmovC", 0xff, 0xff},
  106. {"cmp", 0xff, 0xff},
  107. {"cmpsS", 0, 0},
  108. {"cmpxchg", 0xff, 0xff},
  109. {"cmpxchg16b", 0xff, 0xff},
  110. {"cmpxchg8b", 0xff, 0xff},
  111. {"cpuid", 0, 0},
  112. {"cqo", 0, 0},
  113. {"crc32", 0xff, 0xff},
  114. {"cwd", 0, 0},
  115. {"daa", 0, 0},
  116. {"das", 0, 0},
  117. {"dec", 0xff, 0},
  118. {"div", 0xff, 0},
  119. {"enter", 0xff, 0xff},
  120. {"idiv", 0xff, 0},
  121. {"imul", 0xff, 0},
  122. {"in", ASHCOMP_IMM, 0},
  123. {"inc", 0xff, 0},
  124. {"ins", 0, 0},
  125. {"insd", 0, 0},
  126. {"insw", 0, 0},
  127. {"int", ASHCOMP_IMM, 0},
  128. {"into", 0, 0},
  129. {"iret", 0, 0},
  130. {"iretd", 0, 0},
  131. {"jC", 0xff, 0},
  132. {"jmp", 0xff, 0},
  133. {"lahf", 0, 0},
  134. {"lds", ASHCOMP_REGALL, ASHCOMP_ADDR},
  135. {"lea", ASHCOMP_REGALL, ASHCOMP_ADDR},
  136. {"leave", 0xff, 0xff},
  137. {"lfence", 0, 0},
  138. {"lfs", ASHCOMP_REGALL, ASHCOMP_ADDR},
  139. {"lgs", ASHCOMP_REGALL, ASHCOMP_ADDR},
  140. {"lodsS", 0, 0},
  141. {"loopC", 0xff, 0},
  142. {"lss", ASHCOMP_REGALL, ASHCOMP_ADDR},
  143. {"lzcnt", 0xff, 0xff},
  144. {"mfence", 0, 0},
  145. {"movS", 0xff, 0xff},
  146. {"movbe", 0xff, 0xff},
  147. {"movd", 0xff, 0xff},
  148. {"movmskpd", ASHCOMP_REGALL, ASHCOMP_XALL},
  149. {"movmsksps", ASHCOMP_REGALL, ASHCOMP_XALL},
  150. {"movnti", 0xff, 0xff},
  151. {"movsS", 0, 0},
  152. {"movsx", 0xff, 0xff},
  153. {"movzx", 0xff, 0xff},
  154. {"mul", 0xff, 0},
  155. {"neg", 0xff, 0},
  156. {"nop", 0, 0},
  157. {"not", 0xff, 0xff},
  158. {"or", 0xff, 0xff},
  159. {"out", ASHCOMP_IMM, 0},
  160. {"outs", 0, 0},
  161. {"outsb", 0, 0},
  162. {"outsd", 0, 0},
  163. {"outsw", 0, 0},
  164. {"pop", ASHCOMP_REGALL, 0},
  165. {"popS", ASHCOMP_IMM, 0},
  166. {"popa", 0xff, 0},
  167. {"popad", 0xff, 0},
  168. {"popcnt", 0xff, 0xff},
  169. {"popfd", 0, 0},
  170. {"popfq", 0, 0},
  171. {"prefetch", ASHCOMP_ADDR, 0},
  172. {"prefetch0", ASHCOMP_ADDR, 0},
  173. {"prefetch1", ASHCOMP_ADDR, 0},
  174. {"prefetch2", ASHCOMP_ADDR, 0},
  175. {"prefetchw", ASHCOMP_ADDR, 0},
  176. {"push", ASHCOMP_REGALL, 0},
  177. {"pushS", ASHCOMP_IMM, 0},
  178. {"pusha", 0xff, 0},
  179. {"pushad", 0xff, 0},
  180. {"pushf", 0, 0},
  181. {"pushfd", 0, 0},
  182. {"pushfq", 0, 0},
  183. {"rcl", 0xff, 0},
  184. {"rcr", 0xff, 0},
  185. {"ret", 0xff, 0},
  186. {"rol", 0xff, 0},
  187. {"ror", 0xff, 0},
  188. {"sahf", 0, 0},
  189. {"sal", 0xff, 0},
  190. {"sar", 0xff, 0},
  191. {"sbb", 0xff, 0xff},
  192. {"scasS", 0, 0},
  193. {"setC", 0xff, 0},
  194. {"sfence", 0, 0},
  195. {"shl", 0xff, 0},
  196. {"shld", 0xff, 0},
  197. {"shr", 0xff, 0},
  198. {"shrd", 0xff, 0},
  199. {"stc", 0, 0},
  200. {"std", 0, 0},
  201. {"sti", 0, 0},
  202. {"stosS", 0, 0},
  203. {"sub", 0xff, 0},
  204. {"syscall", 0, 0},
  205. {"sysenter", 0, 0},
  206. {"sysexit", 0, 0},
  207. {"t1mskc", 0xff, 0xff},
  208. {"test", 0xff, 0xff},
  209. {"tzcnt", 0xff, 0xff},
  210. {"tzmsk", 0xff, 0xff},
  211. {"vmovmksps", ASHCOMP_REGALL, ASHCOMP_XALL},
  212. {"vmovmskpd", ASHCOMP_REGALL, ASHCOMP_XALL},
  213. {"xadd", 0xff, 0xff},
  214. {"xchg", 0xff, 0xff},
  215. {"xlat", 0, 0},
  216. {"xor", 0xff, 0xff},
  217. {NULL,0,0}
  218. };
  219. static const char * const asmsh_sym_regs64[] = {
  220. "%rax", "%rbx", "%rcx", "%rdx", "%rbp", "%rsi", "%rdi", "%rsp",
  221. "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
  222. NULL
  223. };
  224. static const char * const asmsh_sym_regs32[] = {
  225. "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
  226. NULL
  227. };
  228. static const char * const asmsh_sym_regs16[] = {
  229. "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
  230. NULL
  231. };
  232. static const char * const asmsh_sym_regs8[] = {
  233. "%ah", "%al", "%bh", "%bl", "%ch", "%cl", "%dh", "%dl",
  234. NULL
  235. };
  236. static const char * const asmsh_sym_regsseg[] = {
  237. "%cs", "%ds", "%es", "%fs", "%gs", "%ss",
  238. NULL
  239. };
  240. static const char * const asmsh_sym_imm[] = {
  241. "$", "$0x", "$0o",
  242. NULL
  243. };
  244. static const char * const asmsh_sym_xmm[] = {
  245. "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7",
  246. NULL
  247. };
  248. static const char * const asmsh_sym_xmm2[] = {
  249. "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15",
  250. NULL
  251. };
  252. static const char * const asmsh_sym_ymm[] = {
  253. "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7",
  254. NULL
  255. };
  256. typedef struct {
  257. const int flag;
  258. const char * const * const regs;
  259. } asmsh_symtable_elt_t;
  260. static const asmsh_symtable_elt_t asmsh_symtable[] = {
  261. { ASHCOMP_REG8, asmsh_sym_regs8},
  262. { ASHCOMP_REG16, asmsh_sym_regs16},
  263. { ASHCOMP_REG32, asmsh_sym_regs32},
  264. { ASHCOMP_REG64, asmsh_sym_regs64},
  265. { ASHCOMP_SEGREG, asmsh_sym_regsseg},
  266. { ASHCOMP_IMM, asmsh_sym_imm},
  267. { ASHCOMP_XMM, asmsh_sym_xmm},
  268. { ASHCOMP_XMM2, asmsh_sym_xmm2},
  269. { ASHCOMP_YMM, asmsh_sym_ymm},
  270. { 0, NULL },
  271. };
  272. #endif