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 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. struct asmsh_cmd_s
  29. {
  30. const char *str;
  31. asmsh_cmd_f *cmd;
  32. /**If non-zero indicate the minimum of chars to
  33. * match. ".quit" while have 2 to match starting
  34. * from ".q"
  35. */
  36. unsigned char sm;
  37. const char *sms;
  38. const char *usage;
  39. const char *desc;
  40. };
  41. struct asmsh_cmd_args_s
  42. {
  43. char cmd[ASMSH_CMD_MAXLEN+1];
  44. char *args[ASMSH_CMD_MAXARG+1];
  45. };
  46. static int _quit(asmsh_t *sh, asmsh_cmd_args_t *args)
  47. {
  48. asmsh_cleanup(sh);
  49. return 1;
  50. }
  51. static int _print_regs(asmsh_t *sh, asmsh_cmd_args_t *args)
  52. {
  53. asmsh_env_t *env = sh->env;
  54. asmsh_env_update_regs(env);
  55. struct user_regs_struct *r = &env->regs;
  56. #define FLG(b, l) ( (r->eflags & (1<<b))?l:'-' )
  57. printf("rax: %016lx rbx: %016lx rcx: %016lx rdx: %016lx\n\
  58. rbp: %016lx rsi: %016lx rdi: %016lx rsp: %016lx\n\
  59. r8: %016lx r9: %016lx r10: %016lx r11: %016lx\n\
  60. r12: %016lx r13: %016lx r14: %016lx r15: %016lx\n\
  61. rip: %016lx flg: %016lx\n\
  62. cs: %04x ds: %04x es: %04x fs:%04x gs: %04x ss:%04x\n\
  63. flags: %c%c%c%c|%c%c%c\n\
  64. ODSZ|APC\n\
  65. ", r->rax, r->rbx, r->rcx, r->rdx,\
  66. r->rbp, r->rsi, r->rdi, r->rsp,\
  67. r->r8, r->r9, r->r10, r->r11,\
  68. r->r12, r->r13, r->r14, r->r15,\
  69. r->rip, r->eflags,\
  70. r->cs, r->ds, r->es, r->fs, r->gs, r->ss,
  71. FLG(11,'O'), FLG(10, 'D'), FLG(7, 'S'), FLG(6, 'Z'),
  72. FLG(4, 'A'), FLG(2, 'P'), FLG(0, 'C'));
  73. #undef FLG
  74. return 0;
  75. }
  76. static int _reset(asmsh_t *sh, asmsh_cmd_args_t *args)
  77. {
  78. char *childpath = strdup(sh->child_path);
  79. asmsh_cleanup(sh);
  80. asmsh_init(sh, childpath);
  81. free(childpath);
  82. }
  83. static int _flags(asmsh_t *sh, asmsh_cmd_args_t *args)
  84. {
  85. printf("Flags :\n");
  86. #define printFLG(name, b) printf(" (%2d)%16s : %d\n", b, name,\
  87. (sh->env->regs.eflags & (1<<b))?1:0);
  88. printFLG("Overflow", 11);
  89. printFLG("Direction", 10);
  90. printFLG("Sign", 7);
  91. printFLG("Zero", 6);
  92. printFLG("Auxiliary carry", 4);
  93. printFLG("Parity", 2);
  94. printFLG("Carry", 0);
  95. #undef printFLG
  96. #define EFLG(b,n) ((sh->env->regs.eflags & (1<<b))?n:'-')
  97. printf("%c%c%c%c %c%c%c\n",
  98. EFLG(11,'O'), EFLG(10, 'D'), EFLG(7,'S'), EFLG(6,'Z'),
  99. EFLG(4,'A'), EFLG(2, 'P'), EFLG(0, 'C'));
  100. return 0;
  101. }
  102. static int _help(asmsh_t *sh, asmsh_cmd_args_t *args);
  103. static const asmsh_cmd_t asmsh_CMDS[] = {
  104. {".flags", _flags, 2,
  105. ".f(lags)", "",
  106. "display CPU flags"},
  107. {".help", _help, 2,
  108. ".h(elp)","[cmd]",
  109. "display this help or the help of specified command"},
  110. {".quit", _quit, 2,
  111. ".q(uit)","",
  112. "quit asmsh"},
  113. {".regs", _print_regs, 1,
  114. ".(regs)", "",
  115. "display registers value"},
  116. {".reset", _reset, 0,
  117. ".reset", "",
  118. "reset the shell"},
  119. {NULL, NULL, 0},
  120. };
  121. static int _help(asmsh_t *sh, asmsh_cmd_args_t *args)
  122. {
  123. char buf[4096], abuf[64];
  124. int ret, pret;
  125. ret = snprintf(buf, 4096, "Available commands :\n");
  126. pret = ret;
  127. for(const asmsh_cmd_t *cmd = asmsh_CMDS; cmd->str; cmd++)
  128. {
  129. snprintf(abuf, 64, "%s %s", cmd->sms, cmd->usage);
  130. ret += snprintf(buf+ret, 4096-ret, " %-18s : %s\n",
  131. abuf, cmd->desc);
  132. }
  133. dprintf(2, buf);
  134. return 0;
  135. }
  136. /**@param const char* the text to match
  137. * @param int the len of the text to match
  138. * @return a ptr or NULL
  139. */
  140. const asmsh_cmd_t *asmsh_cmd_match(const char *cmd, int stop);
  141. /** @return NULL on error or ptr on new cmd args */
  142. asmsh_cmd_args_t *asmsh_cmd_parse(const char *cmd);
  143. static void asmsh_cmd_args_free(asmsh_cmd_args_t *args)
  144. {
  145. if(!args) { return; }
  146. for(char **a=args->args; *a; a++)
  147. {
  148. free(*a);
  149. }
  150. free(args);
  151. }
  152. const char *asmsh_cmd_help(asmsh_t *sh);
  153. #endif