1
0

finsh_vm.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * Virtual machine of finsh shell.
  3. *
  4. * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
  5. *
  6. * This file is part of RT-Thread (http://www.rt-thread.org)
  7. * Maintainer: bernard.xiong <bernard.xiong at gmail.com>
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along
  22. * with this program; if not, write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24. *
  25. * Change Logs:
  26. * Date Author Notes
  27. * 2010-03-22 Bernard first version
  28. */
  29. #include <finsh.h>
  30. #include "finsh_vm.h"
  31. #include "finsh_ops.h"
  32. #include "finsh_var.h"
  33. /* stack */
  34. union finsh_value finsh_vm_stack[FINSH_STACK_MAX];
  35. /* text segment */
  36. u_char text_segment[FINSH_TEXT_MAX];
  37. union finsh_value* finsh_sp; /* stack pointer */
  38. u_char* finsh_pc; /* PC */
  39. /* syscall list, for dynamic system call register */
  40. struct finsh_syscall_item* global_syscall_list = NULL;
  41. // #define FINSH_VM_DISASSEMBLE
  42. void finsh_vm_run()
  43. {
  44. u_char op;
  45. /* if you want to disassemble the byte code, please define FINSH_VM_DISASSEMBLE */
  46. #ifdef FINSH_VM_DISASSEMBLE
  47. void finsh_disassemble();
  48. finsh_disassemble();
  49. #endif
  50. /* set sp(stack pointer) to the beginning of stack */
  51. finsh_sp = &finsh_vm_stack[0];
  52. /* set pc to the beginning of text segment */
  53. finsh_pc = &text_segment[0];
  54. while ((finsh_pc - &text_segment[0] >= 0) &&
  55. (finsh_pc - &text_segment[0] < FINSH_TEXT_MAX))
  56. {
  57. /* get op */
  58. op = *finsh_pc++;
  59. /* call op function */
  60. op_table[op]();
  61. }
  62. }
  63. #ifdef RT_USING_HEAP
  64. void finsh_syscall_append(const char* name, syscall_func func)
  65. {
  66. /* create the syscall */
  67. struct finsh_syscall_item* item;
  68. item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item));
  69. if (item != RT_NULL)
  70. {
  71. item->next = NULL;
  72. item->syscall.name = rt_strdup(name);
  73. item->syscall.func = func;
  74. if (global_syscall_list == NULL)
  75. {
  76. global_syscall_list = item;
  77. }
  78. else
  79. {
  80. item->next = global_syscall_list;
  81. global_syscall_list = item;
  82. }
  83. }
  84. }
  85. #endif
  86. #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
  87. struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
  88. {
  89. unsigned int *ptr;
  90. ptr = (unsigned int*) (call + 1);
  91. while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
  92. ptr ++;
  93. return (struct finsh_syscall*)ptr;
  94. }
  95. struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
  96. {
  97. unsigned int *ptr;
  98. ptr = (unsigned int*) (call + 1);
  99. while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
  100. ptr ++;
  101. return (struct finsh_sysvar*)ptr;
  102. }
  103. #endif
  104. struct finsh_syscall* finsh_syscall_lookup(const char* name)
  105. {
  106. struct finsh_syscall* index;
  107. struct finsh_syscall_item* item;
  108. for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
  109. {
  110. if (strcmp(index->name, name) == 0)
  111. return index;
  112. }
  113. /* find on syscall list */
  114. item = global_syscall_list;
  115. while (item != NULL)
  116. {
  117. if (strncmp(item->syscall.name, name, strlen(name)) == 0)
  118. {
  119. return &(item->syscall);
  120. }
  121. item = item->next;
  122. }
  123. return NULL;
  124. }
  125. #ifdef FINSH_VM_DISASSEMBLE
  126. void finsh_disassemble()
  127. {
  128. u_char *pc, op;
  129. pc = &text_segment[0];
  130. while (*pc != 0)
  131. {
  132. op = *pc;
  133. switch (op)
  134. {
  135. case FINSH_OP_ADD_BYTE:
  136. pc ++;
  137. rt_kprintf("addb\n");
  138. break;
  139. case FINSH_OP_SUB_BYTE:
  140. pc ++;
  141. rt_kprintf("subb\n");
  142. break;
  143. case FINSH_OP_DIV_BYTE:
  144. pc ++;
  145. rt_kprintf("divb\n");
  146. break;
  147. case FINSH_OP_MOD_BYTE:
  148. pc ++;
  149. rt_kprintf("modb\n");
  150. break;
  151. case FINSH_OP_MUL_BYTE:
  152. pc ++;
  153. rt_kprintf("mulb\n");
  154. break;
  155. case FINSH_OP_AND_BYTE:
  156. pc ++;
  157. rt_kprintf("andb\n");
  158. break;
  159. case FINSH_OP_OR_BYTE:
  160. pc ++;
  161. rt_kprintf("orb\n");
  162. break;
  163. case FINSH_OP_XOR_BYTE:
  164. pc ++;
  165. rt_kprintf("xorb\n");
  166. break;
  167. case FINSH_OP_BITWISE_BYTE:
  168. pc ++;
  169. rt_kprintf("bwb\n");
  170. break;
  171. case FINSH_OP_SHL_BYTE:
  172. pc ++;
  173. rt_kprintf("shlb\n");
  174. break;
  175. case FINSH_OP_SHR_BYTE:
  176. pc ++;
  177. rt_kprintf("shrb\n");
  178. break;
  179. case FINSH_OP_LD_BYTE:
  180. pc ++;
  181. rt_kprintf("ldb %d\n", *pc++);
  182. break;
  183. case FINSH_OP_LD_VALUE_BYTE:
  184. pc ++;
  185. rt_kprintf("ldb [0x%x]\n", FINSH_GET32(pc));
  186. pc += 4;
  187. break;
  188. case FINSH_OP_ST_BYTE:
  189. pc ++;
  190. rt_kprintf("stb\n");
  191. break;
  192. case FINSH_OP_ADD_WORD:
  193. pc ++;
  194. rt_kprintf("addw\n");
  195. break;
  196. case FINSH_OP_SUB_WORD:
  197. pc ++;
  198. rt_kprintf("subw\n");
  199. break;
  200. case FINSH_OP_DIV_WORD:
  201. pc ++;
  202. rt_kprintf("divw\n");
  203. break;
  204. case FINSH_OP_MOD_WORD:
  205. pc ++;
  206. rt_kprintf("modw\n");
  207. break;
  208. case FINSH_OP_MUL_WORD:
  209. pc ++;
  210. rt_kprintf("mulw\n");
  211. break;
  212. case FINSH_OP_AND_WORD:
  213. pc ++;
  214. rt_kprintf("andw\n");
  215. break;
  216. case FINSH_OP_OR_WORD:
  217. pc ++;
  218. rt_kprintf("orw\n");
  219. break;
  220. case FINSH_OP_XOR_WORD:
  221. pc ++;
  222. rt_kprintf("xorw\n");
  223. break;
  224. case FINSH_OP_BITWISE_WORD:
  225. pc ++;
  226. rt_kprintf("bww\n");
  227. break;
  228. case FINSH_OP_SHL_WORD:
  229. pc ++;
  230. rt_kprintf("shlw\n");
  231. break;
  232. case FINSH_OP_SHR_WORD:
  233. pc ++;
  234. rt_kprintf("shrw\n");
  235. break;
  236. case FINSH_OP_LD_WORD:
  237. pc ++;
  238. rt_kprintf("ldw %d\n", FINSH_GET16(pc));
  239. pc += 2;
  240. break;
  241. case FINSH_OP_LD_VALUE_WORD:
  242. pc ++;
  243. rt_kprintf("ldw [0x%x]\n", FINSH_GET32(pc));
  244. pc += 4;
  245. break;
  246. case FINSH_OP_ST_WORD:
  247. pc ++;
  248. rt_kprintf("stw\n");
  249. break;
  250. case FINSH_OP_ADD_DWORD:
  251. pc ++;
  252. rt_kprintf("addd\n");
  253. break;
  254. case FINSH_OP_SUB_DWORD:
  255. pc ++;
  256. rt_kprintf("subd\n");
  257. break;
  258. case FINSH_OP_DIV_DWORD:
  259. pc ++;
  260. rt_kprintf("divd\n");
  261. break;
  262. case FINSH_OP_MOD_DWORD:
  263. pc ++;
  264. rt_kprintf("modd\n");
  265. break;
  266. case FINSH_OP_MUL_DWORD:
  267. pc ++;
  268. rt_kprintf("muld\n");
  269. break;
  270. case FINSH_OP_AND_DWORD:
  271. pc ++;
  272. rt_kprintf("andd\n");
  273. break;
  274. case FINSH_OP_OR_DWORD:
  275. pc ++;
  276. rt_kprintf("ord\n");
  277. break;
  278. case FINSH_OP_XOR_DWORD:
  279. pc ++;
  280. rt_kprintf("xord\n");
  281. break;
  282. case FINSH_OP_BITWISE_DWORD:
  283. pc ++;
  284. rt_kprintf("bwd\n");
  285. break;
  286. case FINSH_OP_SHL_DWORD:
  287. pc ++;
  288. rt_kprintf("shld\n");
  289. break;
  290. case FINSH_OP_SHR_DWORD:
  291. pc ++;
  292. rt_kprintf("shrd\n");
  293. break;
  294. case FINSH_OP_LD_DWORD:
  295. pc ++;
  296. rt_kprintf("ldd 0x%x\n", FINSH_GET32(pc));
  297. pc += 4;
  298. break;
  299. case FINSH_OP_LD_VALUE_DWORD:
  300. pc ++;
  301. rt_kprintf("ldd [0x%x]\n", FINSH_GET32(pc));
  302. pc += 4;
  303. break;
  304. case FINSH_OP_ST_DWORD:
  305. pc ++;
  306. rt_kprintf("std\n");
  307. break;
  308. case FINSH_OP_POP:
  309. rt_kprintf("pop\n");
  310. pc ++;
  311. break;
  312. case FINSH_OP_SYSCALL:
  313. pc ++;
  314. rt_kprintf("syscall %d\n", *pc++);
  315. break;
  316. case FINSH_OP_LD_VALUE_BYTE_STACK:
  317. pc ++;
  318. rt_kprintf("ldb [sp]\n");
  319. break;
  320. case FINSH_OP_LD_VALUE_WORD_STACK:
  321. pc ++;
  322. rt_kprintf("ldw [sp]\n");
  323. break;
  324. case FINSH_OP_LD_VALUE_DWORD_STACK:
  325. pc ++;
  326. rt_kprintf("ldd [sp]\n");
  327. break;
  328. default:
  329. return;
  330. }
  331. }
  332. }
  333. #endif