A shell that runs x86_64 assembly
c
x86-64
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

shell_cmds.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. #include "shell_cmds.h"
  14. const asmsh_cmd_t *asmsh_cmd_match(const char *text, int tlen)
  15. {
  16. for(const asmsh_cmd_t *cmd=asmsh_CMDS; cmd->str; cmd++)
  17. {
  18. const int clen = strlen(cmd->str);
  19. if(cmd->sm && tlen >= cmd->sm && tlen < clen)
  20. {
  21. if(!strncmp(cmd->str, text, tlen))
  22. {
  23. return cmd;
  24. }
  25. continue;
  26. }
  27. else if(tlen != clen) { continue; }
  28. else
  29. {
  30. int cmp = strncmp(text, cmd->str, tlen);
  31. if(cmp < 0)
  32. {
  33. break;
  34. }
  35. else if(!cmp)
  36. {
  37. return cmd;
  38. }
  39. }
  40. }
  41. return NULL;
  42. }
  43. asmsh_cmd_args_t *asmsh_cmd_parse(const char *cmd)
  44. {
  45. asmsh_cmd_args_t *ret;
  46. int cmdlen, err, argno;
  47. const char *ptr, *arg;
  48. if(!cmd || !*cmd || *cmd != '.') { return NULL; }
  49. if(!(ret = malloc(sizeof(*ret))))
  50. {
  51. asmsh_log_fatal("Unable to allocate command");
  52. return NULL;
  53. }
  54. bzero(ret, sizeof(*ret));
  55. cmdlen=0;
  56. for(ptr=cmd; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ptr++)
  57. {
  58. cmdlen++;
  59. }
  60. if(cmdlen > ASMSH_CMD_MAXLEN)
  61. {
  62. asmsh_log_error("Invalid command"); //TODO printf command
  63. err=EINVAL;
  64. goto err;
  65. }
  66. strncpy(ret->cmd, cmd, cmdlen);
  67. ret->cmd[cmdlen] = '\0';
  68. // lstrip white chars
  69. for(ptr; *ptr && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n'); ptr++);
  70. if(!*ptr)
  71. {
  72. // end of command
  73. ret->args[0] = NULL;
  74. return ret;
  75. }
  76. arg = ptr;
  77. argno=0;
  78. do
  79. {
  80. int arglen = 0;
  81. for(ptr; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ptr++)
  82. {
  83. arglen++;
  84. }
  85. ret->args[argno] = strndup(arg, arglen);
  86. if(!ret->args[argno])
  87. {
  88. asmsh_log_error("strndup args failed");
  89. err=errno;
  90. goto err;
  91. }
  92. argno++;
  93. if(argno >= ASMSH_CMD_MAXARG)
  94. {
  95. //too many arguments
  96. asmsh_log_error("too many arguments");
  97. err=EINVAL;
  98. goto err;
  99. }
  100. // lstrip white chars
  101. for(ptr; *ptr && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n'); ptr++);
  102. arg=ptr;
  103. }while(*ptr);
  104. ret->argc = argno;
  105. ret->args[argno] = NULL;
  106. return ret;
  107. err:
  108. for(char **p=ret->args; *p; p++) { free(*p); }
  109. errno = err;
  110. free(ret);
  111. return NULL;
  112. }
  113. int asmsh_cmd_bcode(asmsh_t *sh, char *argbuf, int bufsz, int argc, char **args)
  114. {
  115. asmsh_bytecode_t bcode;
  116. char _buf[256], *buf;
  117. const char *instr;
  118. int ret;
  119. if(!argbuf)
  120. {
  121. buf=_buf;
  122. bufsz=256;
  123. }
  124. else
  125. {
  126. buf=argbuf;
  127. }
  128. if(argc == 0)
  129. {
  130. if(sh->last_instr == NULL)
  131. {
  132. asmsh_log_error("No instruction compiled yet");
  133. return -1;
  134. }
  135. bcode = sh->last_bcode;
  136. instr = sh->last_instr;
  137. }
  138. else
  139. {
  140. char **arg;
  141. char code[256];
  142. int sz = 0;
  143. for(arg=args;*arg;arg++)
  144. {
  145. sz+=snprintf(code+sz, 255-sz, "%s", *arg);
  146. if(*(arg+1))
  147. {
  148. code[sz] = ' ';
  149. sz++;
  150. }
  151. }
  152. code[sz]='\0';
  153. dprintf(2, "INSTR='%s'\n", code);
  154. if(asmsh_asmc_compile(sh->cctx, code, &bcode) < 0)
  155. {
  156. return -1;
  157. }
  158. instr = code;
  159. }
  160. ret = snprintf(buf, bufsz, "%s = (%02db) ",
  161. instr, bcode.size);
  162. for(int i=0; i<sizeof(bcode.bytes); i++)
  163. {
  164. char repr[3] = "..";
  165. if(i<bcode.size)
  166. {
  167. snprintf(repr, 3, "%02x", bcode.bytes[i]);
  168. }
  169. repr[2]='\0';
  170. ret += snprintf(buf+ret, bufsz-ret, "%s%s%s",
  171. i&&(i%4==0)?" ":"",i==8?" ":"",
  172. repr);
  173. }
  174. buf[ret] = '\0';
  175. return 0;
  176. }