1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2010-03-22 Bernard first version 9 */ 10 #include <finsh.h> 11 12 #include "finsh_vm.h" 13 #include "finsh_ops.h" 14 #include "finsh_var.h" 15 16 /* stack */ 17 union finsh_value finsh_vm_stack[FINSH_STACK_MAX]; 18 /* text segment */ 19 uint8_t text_segment[FINSH_TEXT_MAX]; 20 21 union finsh_value* finsh_sp; /* stack pointer */ 22 uint8_t* finsh_pc; /* PC */ 23 24 /* syscall list, for dynamic system call register */ 25 struct finsh_syscall_item* global_syscall_list = NULL; 26 27 // #define FINSH_VM_DISASSEMBLE 28 void finsh_vm_run() 29 { 30 uint8_t op; 31 32 /* if you want to disassemble the byte code, please define FINSH_VM_DISASSEMBLE */ 33 #ifdef FINSH_VM_DISASSEMBLE 34 void finsh_disassemble(); 35 finsh_disassemble(); 36 #endif 37 38 /* set sp(stack pointer) to the beginning of stack */ 39 finsh_sp = &finsh_vm_stack[0]; 40 41 /* set pc to the beginning of text segment */ 42 finsh_pc = &text_segment[0]; 43 44 while ((finsh_pc - &text_segment[0] >= 0) && 45 (finsh_pc - &text_segment[0] < FINSH_TEXT_MAX)) 46 { 47 /* get op */ 48 op = *finsh_pc++; 49 50 /* call op function */ 51 op_table[op](); 52 } 53 } 54 55 #ifdef RT_USING_HEAP 56 void finsh_syscall_append(const char* name, syscall_func func) 57 { 58 /* create the syscall */ 59 struct finsh_syscall_item* item; 60 61 item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item)); 62 if (item != RT_NULL) 63 { 64 item->next = NULL; 65 item->syscall.name = rt_strdup(name); 66 item->syscall.func = func; 67 68 if (global_syscall_list == NULL) 69 { 70 global_syscall_list = item; 71 } 72 else 73 { 74 item->next = global_syscall_list; 75 global_syscall_list = item; 76 } 77 } 78 } 79 #endif 80 81 #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) 82 struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call) 83 { 84 unsigned int *ptr; 85 ptr = (unsigned int*) (call + 1); 86 while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end)) 87 ptr ++; 88 89 return (struct finsh_syscall*)ptr; 90 } 91 92 struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call) 93 { 94 unsigned int *ptr; 95 ptr = (unsigned int*) (call + 1); 96 while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end)) 97 ptr ++; 98 99 return (struct finsh_sysvar*)ptr; 100 } 101 #endif 102 103 struct finsh_syscall* finsh_syscall_lookup(const char* name) 104 { 105 struct finsh_syscall* index; 106 struct finsh_syscall_item* item; 107 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 114 /* find on syscall list */ 115 item = global_syscall_list; 116 while (item != NULL) 117 { 118 if (strncmp(item->syscall.name, name, strlen(name)) == 0) 119 { 120 return &(item->syscall); 121 } 122 123 item = item->next; 124 } 125 126 return NULL; 127 } 128 129 #ifdef FINSH_VM_DISASSEMBLE 130 void finsh_disassemble() 131 { 132 uint8_t *pc, op; 133 134 pc = &text_segment[0]; 135 while (*pc != 0) 136 { 137 op = *pc; 138 switch (op) 139 { 140 case FINSH_OP_ADD_BYTE: 141 pc ++; 142 rt_kprintf("addb\n"); 143 break; 144 145 case FINSH_OP_SUB_BYTE: 146 pc ++; 147 rt_kprintf("subb\n"); 148 break; 149 150 case FINSH_OP_DIV_BYTE: 151 pc ++; 152 rt_kprintf("divb\n"); 153 break; 154 155 case FINSH_OP_MOD_BYTE: 156 pc ++; 157 rt_kprintf("modb\n"); 158 break; 159 160 case FINSH_OP_MUL_BYTE: 161 pc ++; 162 rt_kprintf("mulb\n"); 163 break; 164 165 case FINSH_OP_AND_BYTE: 166 pc ++; 167 rt_kprintf("andb\n"); 168 break; 169 170 case FINSH_OP_OR_BYTE: 171 pc ++; 172 rt_kprintf("orb\n"); 173 break; 174 175 case FINSH_OP_XOR_BYTE: 176 pc ++; 177 rt_kprintf("xorb\n"); 178 break; 179 180 case FINSH_OP_BITWISE_BYTE: 181 pc ++; 182 rt_kprintf("bwb\n"); 183 break; 184 185 case FINSH_OP_SHL_BYTE: 186 pc ++; 187 rt_kprintf("shlb\n"); 188 break; 189 190 case FINSH_OP_SHR_BYTE: 191 pc ++; 192 rt_kprintf("shrb\n"); 193 break; 194 195 case FINSH_OP_LD_BYTE: 196 pc ++; 197 rt_kprintf("ldb %d\n", *pc++); 198 break; 199 200 case FINSH_OP_LD_VALUE_BYTE: 201 pc ++; 202 rt_kprintf("ldb [0x%x]\n", FINSH_GET32(pc)); 203 pc += 4; 204 break; 205 206 case FINSH_OP_ST_BYTE: 207 pc ++; 208 rt_kprintf("stb\n"); 209 break; 210 211 case FINSH_OP_ADD_WORD: 212 pc ++; 213 rt_kprintf("addw\n"); 214 break; 215 216 case FINSH_OP_SUB_WORD: 217 pc ++; 218 rt_kprintf("subw\n"); 219 break; 220 221 case FINSH_OP_DIV_WORD: 222 pc ++; 223 rt_kprintf("divw\n"); 224 break; 225 226 case FINSH_OP_MOD_WORD: 227 pc ++; 228 rt_kprintf("modw\n"); 229 break; 230 231 case FINSH_OP_MUL_WORD: 232 pc ++; 233 rt_kprintf("mulw\n"); 234 break; 235 236 case FINSH_OP_AND_WORD: 237 pc ++; 238 rt_kprintf("andw\n"); 239 break; 240 241 case FINSH_OP_OR_WORD: 242 pc ++; 243 rt_kprintf("orw\n"); 244 break; 245 246 case FINSH_OP_XOR_WORD: 247 pc ++; 248 rt_kprintf("xorw\n"); 249 break; 250 251 case FINSH_OP_BITWISE_WORD: 252 pc ++; 253 rt_kprintf("bww\n"); 254 break; 255 256 case FINSH_OP_SHL_WORD: 257 pc ++; 258 rt_kprintf("shlw\n"); 259 break; 260 261 case FINSH_OP_SHR_WORD: 262 pc ++; 263 rt_kprintf("shrw\n"); 264 break; 265 266 case FINSH_OP_LD_WORD: 267 pc ++; 268 rt_kprintf("ldw %d\n", FINSH_GET16(pc)); 269 pc += 2; 270 break; 271 272 case FINSH_OP_LD_VALUE_WORD: 273 pc ++; 274 rt_kprintf("ldw [0x%x]\n", FINSH_GET32(pc)); 275 pc += 4; 276 break; 277 278 case FINSH_OP_ST_WORD: 279 pc ++; 280 rt_kprintf("stw\n"); 281 break; 282 283 case FINSH_OP_ADD_DWORD: 284 pc ++; 285 rt_kprintf("addd\n"); 286 break; 287 288 case FINSH_OP_SUB_DWORD: 289 pc ++; 290 rt_kprintf("subd\n"); 291 break; 292 293 case FINSH_OP_DIV_DWORD: 294 pc ++; 295 rt_kprintf("divd\n"); 296 break; 297 298 case FINSH_OP_MOD_DWORD: 299 pc ++; 300 rt_kprintf("modd\n"); 301 break; 302 303 case FINSH_OP_MUL_DWORD: 304 pc ++; 305 rt_kprintf("muld\n"); 306 break; 307 308 case FINSH_OP_AND_DWORD: 309 pc ++; 310 rt_kprintf("andd\n"); 311 break; 312 313 case FINSH_OP_OR_DWORD: 314 pc ++; 315 rt_kprintf("ord\n"); 316 break; 317 318 case FINSH_OP_XOR_DWORD: 319 pc ++; 320 rt_kprintf("xord\n"); 321 break; 322 323 case FINSH_OP_BITWISE_DWORD: 324 pc ++; 325 rt_kprintf("bwd\n"); 326 break; 327 328 case FINSH_OP_SHL_DWORD: 329 pc ++; 330 rt_kprintf("shld\n"); 331 break; 332 333 case FINSH_OP_SHR_DWORD: 334 pc ++; 335 rt_kprintf("shrd\n"); 336 break; 337 338 case FINSH_OP_LD_DWORD: 339 pc ++; 340 rt_kprintf("ldd 0x%x\n", FINSH_GET32(pc)); 341 pc += 4; 342 break; 343 344 case FINSH_OP_LD_VALUE_DWORD: 345 pc ++; 346 rt_kprintf("ldd [0x%x]\n", FINSH_GET32(pc)); 347 pc += 4; 348 break; 349 350 case FINSH_OP_ST_DWORD: 351 pc ++; 352 rt_kprintf("std\n"); 353 break; 354 355 case FINSH_OP_POP: 356 rt_kprintf("pop\n"); 357 pc ++; 358 break; 359 360 case FINSH_OP_SYSCALL: 361 pc ++; 362 rt_kprintf("syscall %d\n", *pc++); 363 break; 364 365 case FINSH_OP_LD_VALUE_BYTE_STACK: 366 pc ++; 367 rt_kprintf("ldb [sp]\n"); 368 break; 369 370 case FINSH_OP_LD_VALUE_WORD_STACK: 371 pc ++; 372 rt_kprintf("ldw [sp]\n"); 373 break; 374 375 case FINSH_OP_LD_VALUE_DWORD_STACK: 376 pc ++; 377 rt_kprintf("ldd [sp]\n"); 378 break; 379 380 default: 381 return; 382 } 383 } 384 } 385 #endif 386