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.

shell_cmds.h 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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_SHELL_CMDS_H
  14. #define ASMSH_SHELL_CMDS_H
  15. #include "config.h"
  16. #include <errno.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include "logger.h"
  21. #define ASMSH_CMD_MAXLEN 31
  22. #define ASMSH_CMD_MAXARG 15
  23. typedef struct asmsh_cmd_s asmsh_cmd_t;
  24. typedef struct asmsh_cmd_args_s asmsh_cmd_args_t;
  25. #include "shell.h"
  26. /** @return <0 on recoverable error 0 on ok, 1+status on exit */
  27. typedef int (asmsh_cmd_f)(asmsh_t*, asmsh_cmd_args_t*);
  28. /** Represent a single command */
  29. struct asmsh_cmd_s
  30. {
  31. /** The command (with the leading '.') */
  32. const char *str;
  33. /** The command function pointer */
  34. asmsh_cmd_f *cmd;
  35. /**If non-zero indicate the minimum of chars to
  36. * match. ".quit" while have 2 to match starting
  37. * from ".q"
  38. */
  39. unsigned char sm;
  40. /* Help information */
  41. /** Small command name (like .h(elp) )*/
  42. const char *sms;
  43. /** Command usage */
  44. const char *usage;
  45. /** Command description */
  46. const char *desc;
  47. };
  48. /** A command arguments with command name & NULL terminated array of args */
  49. struct asmsh_cmd_args_s
  50. {
  51. char cmd[ASMSH_CMD_MAXLEN+1];
  52. int argc;
  53. char *args[ASMSH_CMD_MAXARG+1];
  54. };
  55. /**@param const char* the text to match
  56. * @param int the len of the text to match
  57. * @return a ptr or NULL
  58. */
  59. const asmsh_cmd_t *asmsh_cmd_match(const char *cmd, int stop);
  60. /** @return NULL on error or ptr on new cmd args */
  61. asmsh_cmd_args_t *asmsh_cmd_parse(const char *cmd);
  62. void asmsh_cmd_args_free(asmsh_cmd_args_t *args);
  63. const char *asmsh_cmd_help(asmsh_t *sh);
  64. /*
  65. * Commands declaration
  66. *
  67. * A command can return 0 if no errors, -X for a recoverable error
  68. * 1 for exit with status 0, 1+S for exit with status S
  69. */
  70. // Quit the shell
  71. static int _quit(asmsh_t *sh, asmsh_cmd_args_t *args)
  72. {
  73. asmsh_cleanup(sh);
  74. return 1;
  75. }
  76. // Print an instruction bytecode
  77. int asmsh_cmd_bcode(asmsh_t *sh, char *buf, int bufsz, int argc, char **args);
  78. static int _bcode(asmsh_t *sh, asmsh_cmd_args_t *args)
  79. {
  80. char str[256];
  81. int ret;
  82. ret = asmsh_cmd_bcode(sh, str, 256, args->argc, args->args);
  83. if(ret)
  84. {
  85. return ret;
  86. }
  87. printf("%s\n", str);
  88. return 0;
  89. }
  90. // Print the registers
  91. static int _print_regs(asmsh_t *sh, asmsh_cmd_args_t *args)
  92. {
  93. asmsh_env_t *env = sh->env;
  94. asmsh_env_update_regs(env);
  95. struct user_regs_struct *r = &env->regs;
  96. #define FLG(b, l) ( (r->eflags & (1<<b))?l:'-' )
  97. printf("rax: %016llx rbx: %016llx rcx: %016llx rdx: %016llx\n\
  98. rbp: %016llx rsi: %016llx rdi: %016llx rsp: %016llx\n\
  99. r8: %016llx r9: %016llx r10: %016llx r11: %016llx\n\
  100. r12: %016llx r13: %016llx r14: %016llx r15: %016llx\n\
  101. rip: %016llx flg: %016llx\n\
  102. cs: %04llx ds: %04llx es: %04llx fs:%04llx gs: %04llx ss:%04llx\n\
  103. flags: %c%c%c%c|%c%c%c\n\
  104. ODSZ|APC\n\
  105. ", r->rax, r->rbx, r->rcx, r->rdx,\
  106. r->rbp, r->rsi, r->rdi, r->rsp,\
  107. r->r8, r->r9, r->r10, r->r11,\
  108. r->r12, r->r13, r->r14, r->r15,\
  109. r->rip, r->eflags,\
  110. r->cs, r->ds, r->es, r->fs, r->gs, r->ss,
  111. FLG(11,'O'), FLG(10, 'D'), FLG(7, 'S'), FLG(6, 'Z'),
  112. FLG(4, 'A'), FLG(2, 'P'), FLG(0, 'C'));
  113. #undef FLG
  114. return 0;
  115. }
  116. // Reset the shell (restart the child etc)
  117. static int _reset(asmsh_t *sh, asmsh_cmd_args_t *args)
  118. {
  119. char *childpath = strdup(sh->child_path);
  120. asmsh_cleanup(sh);
  121. asmsh_init(sh, childpath);
  122. free(childpath);
  123. return 0;
  124. }
  125. // Display CPU flag resister values
  126. static int _flags(asmsh_t *sh, asmsh_cmd_args_t *args)
  127. {
  128. printf("Flags :\n");
  129. #define printFLG(name, b) printf(" (%2d)%16s : %d\n", b, name,\
  130. (sh->env->regs.eflags & (1<<b))?1:0);
  131. printFLG("Overflow", 11);
  132. printFLG("Direction", 10);
  133. printFLG("Sign", 7);
  134. printFLG("Zero", 6);
  135. printFLG("Auxiliary carry", 4);
  136. printFLG("Parity", 2);
  137. printFLG("Carry", 0);
  138. #undef printFLG
  139. #define EFLG(b,n) ((sh->env->regs.eflags & (1<<b))?n:'-')
  140. printf("%c%c%c%c %c%c%c\n",
  141. EFLG(11,'O'), EFLG(10, 'D'), EFLG(7,'S'), EFLG(6,'Z'),
  142. EFLG(4,'A'), EFLG(2, 'P'), EFLG(0, 'C'));
  143. return 0;
  144. }
  145. // Declared because referenced in command list but not implemented
  146. // because the _help function needs a reference to the command list
  147. static int _help(asmsh_t *sh, asmsh_cmd_args_t *args);
  148. /*
  149. * The list of shell commands
  150. */
  151. static const asmsh_cmd_t asmsh_CMDS[] = {
  152. {".bytecode", _bcode, 2,
  153. ".b(ytecode)", "",
  154. "display last instruction bytecode"},
  155. {".flags", _flags, 2,
  156. ".f(lags)", "",
  157. "display CPU flags"},
  158. {".help", _help, 2,
  159. ".h(elp)","[cmd]",
  160. "display this help or the help of specified command"},
  161. {".quit", _quit, 2,
  162. ".q(uit)","",
  163. "quit asmsh"},
  164. {".regs", _print_regs, 1,
  165. ".(regs)", "",
  166. "display registers value"},
  167. {".reset", _reset, 0,
  168. ".reset", "",
  169. "reset the shell"},
  170. {NULL, NULL, 0},
  171. };
  172. // Print help (command list + help)
  173. static int _help(asmsh_t *sh, asmsh_cmd_args_t *args)
  174. {
  175. char buf[4096], abuf[64];
  176. int ret;
  177. ret = snprintf(buf, 4096, "Available commands :\n");
  178. for(const asmsh_cmd_t *cmd = asmsh_CMDS; cmd->str; cmd++)
  179. {
  180. snprintf(abuf, 64, "%s %s", cmd->sms, cmd->usage);
  181. ret += snprintf(buf+ret, 4096-ret, " %-18s : %s\n",
  182. abuf, cmd->desc);
  183. }
  184. dprintf(2, buf);
  185. return 0;
  186. }
  187. #endif