1 /* Capstone Disassembly Engine */ 2 /* By Spike, xwings 2019 */ 3 4 #include <string.h> 5 #include <stddef.h> // offsetof macro 6 // alternatively #include "../../utils.h" like everyone else 7 8 #include "WASMDisassembler.h" 9 #include "WASMMapping.h" 10 #include "../../cs_priv.h" 11 12 static const short opcodes[256] = { 13 WASM_INS_UNREACHABLE, 14 WASM_INS_NOP, 15 WASM_INS_BLOCK, 16 WASM_INS_LOOP, 17 WASM_INS_IF, 18 WASM_INS_ELSE, 19 -1, 20 -1, 21 -1, 22 -1, 23 -1, 24 WASM_INS_END, 25 WASM_INS_BR, 26 WASM_INS_BR_IF, 27 WASM_INS_BR_TABLE, 28 WASM_INS_RETURN, 29 WASM_INS_CALL, 30 WASM_INS_CALL_INDIRECT, 31 -1, 32 -1, 33 -1, 34 -1, 35 -1, 36 -1, 37 -1, 38 -1, 39 WASM_INS_DROP, 40 WASM_INS_SELECT, 41 -1, 42 -1, 43 -1, 44 -1, 45 WASM_INS_GET_LOCAL, 46 WASM_INS_SET_LOCAL, 47 WASM_INS_TEE_LOCAL, 48 WASM_INS_GET_GLOBAL, 49 WASM_INS_SET_GLOBAL, 50 -1, 51 -1, 52 -1, 53 WASM_INS_I32_LOAD, 54 WASM_INS_I64_LOAD, 55 WASM_INS_F32_LOAD, 56 WASM_INS_F64_LOAD, 57 WASM_INS_I32_LOAD8_S, 58 WASM_INS_I32_LOAD8_U, 59 WASM_INS_I32_LOAD16_S, 60 WASM_INS_I32_LOAD16_U, 61 WASM_INS_I64_LOAD8_S, 62 WASM_INS_I64_LOAD8_U, 63 WASM_INS_I64_LOAD16_S, 64 WASM_INS_I64_LOAD16_U, 65 WASM_INS_I64_LOAD32_S, 66 WASM_INS_I64_LOAD32_U, 67 WASM_INS_I32_STORE, 68 WASM_INS_I64_STORE, 69 WASM_INS_F32_STORE, 70 WASM_INS_F64_STORE, 71 WASM_INS_I32_STORE8, 72 WASM_INS_I32_STORE16, 73 WASM_INS_I64_STORE8, 74 WASM_INS_I64_STORE16, 75 WASM_INS_I64_STORE32, 76 WASM_INS_CURRENT_MEMORY, 77 WASM_INS_GROW_MEMORY, 78 WASM_INS_I32_CONST, 79 WASM_INS_I64_CONST, 80 WASM_INS_F32_CONST, 81 WASM_INS_F64_CONST, 82 WASM_INS_I32_EQZ, 83 WASM_INS_I32_EQ, 84 WASM_INS_I32_NE, 85 WASM_INS_I32_LT_S, 86 WASM_INS_I32_LT_U, 87 WASM_INS_I32_GT_S, 88 WASM_INS_I32_GT_U, 89 WASM_INS_I32_LE_S, 90 WASM_INS_I32_LE_U, 91 WASM_INS_I32_GE_S, 92 WASM_INS_I32_GE_U, 93 WASM_INS_I64_EQZ, 94 WASM_INS_I64_EQ, 95 WASM_INS_I64_NE, 96 WASM_INS_I64_LT_S, 97 WASM_INS_I64_LT_U, 98 WASN_INS_I64_GT_S, 99 WASM_INS_I64_GT_U, 100 WASM_INS_I64_LE_S, 101 WASM_INS_I64_LE_U, 102 WASM_INS_I64_GE_S, 103 WASM_INS_I64_GE_U, 104 WASM_INS_F32_EQ, 105 WASM_INS_F32_NE, 106 WASM_INS_F32_LT, 107 WASM_INS_F32_GT, 108 WASM_INS_F32_LE, 109 WASM_INS_F32_GE, 110 WASM_INS_F64_EQ, 111 WASM_INS_F64_NE, 112 WASM_INS_F64_LT, 113 WASM_INS_F64_GT, 114 WASM_INS_F64_LE, 115 WASM_INS_F64_GE, 116 WASM_INS_I32_CLZ, 117 WASM_INS_I32_CTZ, 118 WASM_INS_I32_POPCNT, 119 WASM_INS_I32_ADD, 120 WASM_INS_I32_SUB, 121 WASM_INS_I32_MUL, 122 WASM_INS_I32_DIV_S, 123 WASM_INS_I32_DIV_U, 124 WASM_INS_I32_REM_S, 125 WASM_INS_I32_REM_U, 126 WASM_INS_I32_AND, 127 WASM_INS_I32_OR, 128 WASM_INS_I32_XOR, 129 WASM_INS_I32_SHL, 130 WASM_INS_I32_SHR_S, 131 WASM_INS_I32_SHR_U, 132 WASM_INS_I32_ROTL, 133 WASM_INS_I32_ROTR, 134 WASM_INS_I64_CLZ, 135 WASM_INS_I64_CTZ, 136 WASM_INS_I64_POPCNT, 137 WASM_INS_I64_ADD, 138 WASM_INS_I64_SUB, 139 WASM_INS_I64_MUL, 140 WASM_INS_I64_DIV_S, 141 WASM_INS_I64_DIV_U, 142 WASM_INS_I64_REM_S, 143 WASM_INS_I64_REM_U, 144 WASM_INS_I64_AND, 145 WASM_INS_I64_OR, 146 WASM_INS_I64_XOR, 147 WASM_INS_I64_SHL, 148 WASM_INS_I64_SHR_S, 149 WASM_INS_I64_SHR_U, 150 WASM_INS_I64_ROTL, 151 WASM_INS_I64_ROTR, 152 WASM_INS_F32_ABS, 153 WASM_INS_F32_NEG, 154 WASM_INS_F32_CEIL, 155 WASM_INS_F32_FLOOR, 156 WASM_INS_F32_TRUNC, 157 WASM_INS_F32_NEAREST, 158 WASM_INS_F32_SQRT, 159 WASM_INS_F32_ADD, 160 WASM_INS_F32_SUB, 161 WASM_INS_F32_MUL, 162 WASM_INS_F32_DIV, 163 WASM_INS_F32_MIN, 164 WASM_INS_F32_MAX, 165 WASM_INS_F32_COPYSIGN, 166 WASM_INS_F64_ABS, 167 WASM_INS_F64_NEG, 168 WASM_INS_F64_CEIL, 169 WASM_INS_F64_FLOOR, 170 WASM_INS_F64_TRUNC, 171 WASM_INS_F64_NEAREST, 172 WASM_INS_F64_SQRT, 173 WASM_INS_F64_ADD, 174 WASM_INS_F64_SUB, 175 WASM_INS_F64_MUL, 176 WASM_INS_F64_DIV, 177 WASM_INS_F64_MIN, 178 WASM_INS_F64_MAX, 179 WASM_INS_F64_COPYSIGN, 180 WASM_INS_I32_WARP_I64, 181 WASP_INS_I32_TRUNC_S_F32, 182 WASM_INS_I32_TRUNC_U_F32, 183 WASM_INS_I32_TRUNC_S_F64, 184 WASM_INS_I32_TRUNC_U_F64, 185 WASM_INS_I64_EXTEND_S_I32, 186 WASM_INS_I64_EXTEND_U_I32, 187 WASM_INS_I64_TRUNC_S_F32, 188 WASM_INS_I64_TRUNC_U_F32, 189 WASM_INS_I64_TRUNC_S_F64, 190 WASM_INS_I64_TRUNC_U_F64, 191 WASM_INS_F32_CONVERT_S_I32, 192 WASM_INS_F32_CONVERT_U_I32, 193 WASM_INS_F32_CONVERT_S_I64, 194 WASM_INS_F32_CONVERT_U_I64, 195 WASM_INS_F32_DEMOTE_F64, 196 WASM_INS_F64_CONVERT_S_I32, 197 WASM_INS_F64_CONVERT_U_I32, 198 WASM_INS_F64_CONVERT_S_I64, 199 WASM_INS_F64_CONVERT_U_I64, 200 WASM_INS_F64_PROMOTE_F32, 201 WASM_INS_I32_REINTERPRET_F32, 202 WASM_INS_I64_REINTERPRET_F64, 203 WASM_INS_F32_REINTERPRET_I32, 204 WASM_INS_F64_REINTERPRET_I64, 205 -1, 206 -1, 207 -1, 208 -1, 209 -1, 210 -1, 211 -1, 212 -1, 213 -1, 214 -1, 215 -1, 216 -1, 217 -1, 218 -1, 219 -1, 220 -1, 221 -1, 222 -1, 223 -1, 224 -1, 225 -1, 226 -1, 227 -1, 228 -1, 229 -1, 230 -1, 231 -1, 232 -1, 233 -1, 234 -1, 235 -1, 236 -1, 237 -1, 238 -1, 239 -1, 240 -1, 241 -1, 242 -1, 243 -1, 244 -1, 245 -1, 246 -1, 247 -1, 248 -1, 249 -1, 250 -1, 251 -1, 252 -1, 253 -1, 254 -1, 255 -1, 256 -1, 257 -1, 258 -1, 259 -1, 260 -1, 261 -1, 262 -1, 263 -1, 264 -1, 265 -1, 266 -1, 267 -1, 268 -1, 269 }; 270 271 // input | code: code pointer start from varuint32 272 // | code_len: real code len count from varint 273 // | leng: return value, means length of varint. -1 means error 274 // return | varint 275 static uint32_t get_varuint32(const uint8_t *code, size_t code_len, size_t *leng) 276 { 277 uint32_t data = 0; 278 int i; 279 280 for(i = 0;; i++) { 281 if (code_len < i + 1) { 282 *leng = -1; 283 return 0; 284 } 285 286 287 if (i > 4 || (i == 4 && (code[i] & 0x7f) > 0x0f)) { 288 *leng = -1; 289 return 0; 290 } 291 292 data = data + (((uint32_t) code[i] & 0x7f) << (i * 7)); 293 if (code[i] >> 7 == 0) { 294 break; 295 } 296 } 297 298 *leng = i + 1; 299 300 return data; 301 } 302 303 // input | code : code pointer start from varuint64 304 // | code_len : real code len count from varint 305 // | leng: return value, means length of varint. -1 means error 306 // return | varint 307 static uint64_t get_varuint64(const uint8_t *code, size_t code_len, size_t *leng) 308 { 309 uint64_t data; 310 int i; 311 312 data = 0; 313 for(i = 0;; i++){ 314 if (code_len < i + 1) { 315 *leng = -1; 316 return 0; 317 } 318 319 if (i > 9 || (i == 9 && (code[i] & 0x7f) > 0x01)) { 320 *leng = -1; 321 return 0; 322 } 323 324 data = data + (((uint64_t) code[i] & 0x7f) << (i * 7)); 325 if (code[i] >> 7 == 0) { 326 break; 327 } 328 } 329 330 *leng = i + 1; 331 332 return data; 333 } 334 335 // input | code : code pointer start from uint32 336 // | dest : the pointer where we store the uint32 337 // return | None 338 static void get_uint32(const uint8_t *code, uint32_t *dest) 339 { 340 memcpy(dest, code, 4); 341 } 342 343 // input | code : code pointer start from uint32 344 // | dest : the pointer where we store the uint64 345 // return | None 346 static void get_uint64(const uint8_t *code, uint64_t *dest) 347 { 348 memcpy(dest, code, 8); 349 } 350 351 // input | code : code pointer start from varint7 352 // | code_len : start from the code pointer to the end, how long is it 353 // | leng : length of the param , -1 means error 354 // return | data of varint7 355 static int8_t get_varint7(const uint8_t *code, size_t code_len, size_t *leng) 356 { 357 int8_t data; 358 359 if (code_len < 1) { 360 *leng = -1; 361 return -1; 362 } 363 364 *leng = 1; 365 366 if (code[0] == 0x40) { 367 return -1; 368 } 369 370 data = code[0] & 0x7f; 371 372 return data; 373 } 374 375 // input | code : code pointer start from varuint32 376 // | code_len : start from the code pointer to the end, how long is it 377 // | param_size : pointer of the param size 378 // | MI : Mcinst handler in this round of disasm 379 // return | true/false if the function successfully finished 380 static bool read_varuint32(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 381 { 382 size_t len = 0; 383 uint32_t data; 384 385 data = get_varuint32(code, code_len, &len); 386 if (len == -1) { 387 return false; 388 } 389 390 if (MI->flat_insn->detail) { 391 MI->flat_insn->detail->wasm.op_count = 1; 392 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_VARUINT32; 393 MI->flat_insn->detail->wasm.operands[0].size= len; 394 MI->flat_insn->detail->wasm.operands[0].varuint32= data; 395 } 396 397 MI->wasm_data.size = len; 398 MI->wasm_data.type = WASM_OP_VARUINT32; 399 MI->wasm_data.uint32 = data; 400 *param_size = len; 401 402 return true; 403 } 404 405 // input | code : code pointer start from varuint64 406 // | code_len : start from the code pointer to the end, how long is it 407 // | param_size : pointer of the param size 408 // | MI : Mcinst handler in this round of disasm 409 // return | true/false if the function successfully finished 410 static bool read_varuint64(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 411 { 412 size_t len = 0; 413 uint64_t data; 414 415 data = get_varuint64(code, code_len, &len); 416 if (len == -1) { 417 return false; 418 } 419 420 if (MI->flat_insn->detail) { 421 MI->flat_insn->detail->wasm.op_count = 1; 422 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_VARUINT64; 423 MI->flat_insn->detail->wasm.operands[0].size = len; 424 MI->flat_insn->detail->wasm.operands[0].varuint64 = data; 425 } 426 427 MI->wasm_data.size = len; 428 MI->wasm_data.type = WASM_OP_VARUINT64; 429 MI->wasm_data.uint64 = data; 430 *param_size = len; 431 432 return true; 433 } 434 435 // input | code : code pointer start from memoryimmediate 436 // | code_len : start from the code pointer to the end, how long is it 437 // | param_size : pointer of the param size (sum of two params) 438 // | MI : Mcinst handler in this round of disasm 439 // return | true/false if the function successfully finished 440 static bool read_memoryimmediate(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 441 { 442 size_t tmp, len = 0; 443 uint32_t data[2]; 444 445 if (MI->flat_insn->detail) { 446 MI->flat_insn->detail->wasm.op_count = 2; 447 } 448 449 data[0] = get_varuint32(code, code_len, &tmp); 450 if (tmp == -1) { 451 return false; 452 } 453 454 if (MI->flat_insn->detail) { 455 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_VARUINT32; 456 MI->flat_insn->detail->wasm.operands[0].size = tmp; 457 MI->flat_insn->detail->wasm.operands[0].varuint32 = data[0]; 458 } 459 460 len = tmp; 461 data[1] = get_varuint32(&code[len], code_len - len, &tmp); 462 if (len == -1) { 463 return false; 464 } 465 466 if (MI->flat_insn->detail) { 467 MI->flat_insn->detail->wasm.operands[1].type = WASM_OP_VARUINT32; 468 MI->flat_insn->detail->wasm.operands[1].size = tmp; 469 MI->flat_insn->detail->wasm.operands[1].varuint32 = data[1]; 470 } 471 472 len += tmp; 473 MI->wasm_data.size = len; 474 MI->wasm_data.type = WASM_OP_IMM; 475 MI->wasm_data.immediate[0] = data[0]; 476 MI->wasm_data.immediate[1] = data[1]; 477 *param_size = len; 478 479 return true; 480 } 481 482 // input | code : code pointer start from uint32 483 // | code_len : start from the code pointer to the end, how long is it 484 // | param_size : pointer of the param size 485 // | MI : Mcinst handler in this round of disasm 486 // return | true/false if the function successfully finished 487 static bool read_uint32(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 488 { 489 if (code_len < 4) { 490 return false; 491 } 492 493 get_uint32(code, &(MI->wasm_data.uint32)); 494 495 if (MI->flat_insn->detail) { 496 MI->flat_insn->detail->wasm.op_count = 1; 497 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_UINT32; 498 MI->flat_insn->detail->wasm.operands[0].size = 4; 499 get_uint32(code, &(MI->flat_insn->detail->wasm.operands[0].uint32)); 500 } 501 502 MI->wasm_data.size = 4; 503 MI->wasm_data.type = WASM_OP_UINT32; 504 *param_size = 4; 505 506 return true; 507 } 508 509 // input | code : code pointer start from uint64 510 // | code_len : start from the code pointer to the end, how long is it 511 // | param_size : pointer of the param size 512 // | MI : Mcinst handler in this round of disasm 513 // return | true/false if the function successfully finished 514 static bool read_uint64(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 515 { 516 if (code_len < 8) { 517 return false; 518 } 519 520 get_uint64(code, &(MI->wasm_data.uint64)); 521 522 if (MI->flat_insn->detail) { 523 MI->flat_insn->detail->wasm.op_count = 1; 524 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_UINT64; 525 MI->flat_insn->detail->wasm.operands[0].size = 8; 526 get_uint64(code, &(MI->flat_insn->detail->wasm.operands[0].uint64)); 527 } 528 529 MI->wasm_data.size = 8; 530 MI->wasm_data.type = WASM_OP_UINT64; 531 *param_size = 8; 532 533 return true; 534 } 535 536 // input | code : code pointer start from brtable 537 // | code_len : start from the code pointer to the end, how long is it 538 // | param_size : pointer of the param size (sum of all param) 539 // | MI : Mcinst handler in this round of disasm 540 // return | true/false if the function successfully finished 541 static bool read_brtable(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 542 { 543 uint32_t length, default_target; 544 int tmp_len = 0, i; 545 size_t var_len; 546 547 // read length 548 length = get_varuint32(code, code_len, &var_len); 549 if (var_len == -1) { 550 return false; 551 } 552 553 tmp_len += var_len; 554 MI->wasm_data.brtable.length = length; 555 if (length >= UINT32_MAX - tmp_len) { 556 // integer overflow check 557 return false; 558 } 559 if (code_len < tmp_len + length) { 560 // safety check that we have minimum enough data to read 561 return false; 562 } 563 // base address + 1 byte opcode + tmp_len for number of cases = start of targets 564 MI->wasm_data.brtable.address = MI->address + 1 + tmp_len; 565 566 if (MI->flat_insn->detail) { 567 MI->flat_insn->detail->wasm.op_count = 1; 568 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_BRTABLE; 569 MI->flat_insn->detail->wasm.operands[0].brtable.length = MI->wasm_data.brtable.length; 570 MI->flat_insn->detail->wasm.operands[0].brtable.address = MI->wasm_data.brtable.address; 571 } 572 573 // read data 574 for(i = 0; i < length; i++){ 575 if (code_len < tmp_len) { 576 return false; 577 } 578 579 get_varuint32(code + tmp_len, code_len - tmp_len, &var_len); 580 if (var_len == -1) { 581 return false; 582 } 583 584 tmp_len += var_len; 585 } 586 587 // read default target 588 default_target = get_varuint32(code + tmp_len, code_len - tmp_len, &var_len); 589 if (var_len == -1) { 590 return false; 591 } 592 593 MI->wasm_data.brtable.default_target = default_target; 594 MI->wasm_data.type = WASM_OP_BRTABLE; 595 *param_size = tmp_len + var_len; 596 597 if (MI->flat_insn->detail) { 598 MI->flat_insn->detail->wasm.operands[0].size = *param_size; 599 MI->flat_insn->detail->wasm.operands[0].brtable.default_target = MI->wasm_data.brtable.default_target; 600 } 601 602 return true; 603 } 604 605 // input | code : code pointer start from varint7 606 // | code_len : start from the code pointer to the end, how long is it 607 // | param_size : pointer of the param size 608 // | MI : Mcinst handler in this round of disasm 609 // return | true/false if the function successfully finished 610 static bool read_varint7(const uint8_t *code, size_t code_len, uint16_t *param_size, MCInst *MI) 611 { 612 size_t len = 0; 613 614 MI->wasm_data.type = WASM_OP_INT7; 615 MI->wasm_data.int7 = get_varint7(code, code_len, &len); 616 if (len == -1) { 617 return false; 618 } 619 620 if (MI->flat_insn->detail) { 621 MI->flat_insn->detail->wasm.op_count = 1; 622 MI->flat_insn->detail->wasm.operands[0].type = WASM_OP_INT7; 623 MI->flat_insn->detail->wasm.operands[0].size = 1; 624 MI->flat_insn->detail->wasm.operands[0].int7 = MI->wasm_data.int7; 625 } 626 627 *param_size = len; 628 629 return true; 630 } 631 632 bool WASM_getInstruction(csh ud, const uint8_t *code, size_t code_len, 633 MCInst *MI, uint16_t *size, uint64_t address, void *inst_info) 634 { 635 unsigned char opcode; 636 uint16_t param_size; 637 638 if (code_len == 0) 639 return false; 640 641 opcode = code[0]; 642 if (opcodes[opcode] == -1) { 643 // invalid opcode 644 return false; 645 } 646 647 // valid opcode 648 MI->address = address; 649 MI->OpcodePub = MI->Opcode = opcode; 650 651 if (MI->flat_insn->detail) { 652 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, wasm)+sizeof(cs_wasm)); 653 WASM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode); 654 } 655 656 // setup groups 657 switch(opcode) { 658 default: 659 return false; 660 661 case WASM_INS_I32_CONST: 662 if (code_len == 1 || !read_varuint32(&code[1], code_len - 1, ¶m_size, MI)) { 663 return false; 664 } 665 666 if (MI->flat_insn->detail) { 667 MI->flat_insn->detail->wasm.op_count = 1; 668 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_NUMBERIC; 669 MI->flat_insn->detail->groups_count++; 670 } 671 672 *size = param_size + 1; 673 674 break; 675 676 case WASM_INS_I64_CONST: 677 if (code_len == 1 || !read_varuint64(&code[1], code_len - 1, ¶m_size, MI)) { 678 return false; 679 } 680 681 if (MI->flat_insn->detail) { 682 MI->flat_insn->detail->wasm.op_count = 1; 683 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_NUMBERIC; 684 MI->flat_insn->detail->groups_count++; 685 } 686 687 *size = param_size + 1; 688 689 break; 690 691 case WASM_INS_F32_CONST: 692 if (code_len == 1 || !read_uint32(&code[1], code_len - 1, ¶m_size, MI)) { 693 return false; 694 } 695 696 if (MI->flat_insn->detail) { 697 MI->flat_insn->detail->wasm.op_count = 1; 698 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_NUMBERIC; 699 MI->flat_insn->detail->groups_count++; 700 } 701 702 *size = param_size + 1; 703 704 break; 705 706 case WASM_INS_F64_CONST: 707 if (code_len == 1 || !read_uint64(&code[1], code_len - 1, ¶m_size, MI)) { 708 return false; 709 } 710 711 if (MI->flat_insn->detail) { 712 MI->flat_insn->detail->wasm.op_count = 1; 713 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_NUMBERIC; 714 MI->flat_insn->detail->groups_count++; 715 } 716 717 *size = param_size + 1; 718 719 break; 720 721 case WASM_INS_I32_EQZ: 722 case WASM_INS_I32_EQ: 723 case WASM_INS_I32_NE: 724 case WASM_INS_I32_LT_S: 725 case WASM_INS_I32_LT_U: 726 case WASM_INS_I32_GT_S: 727 case WASM_INS_I32_GT_U: 728 case WASM_INS_I32_LE_S: 729 case WASM_INS_I32_LE_U: 730 case WASM_INS_I32_GE_S: 731 case WASM_INS_I32_GE_U: 732 case WASM_INS_I64_EQZ: 733 case WASM_INS_I64_EQ: 734 case WASM_INS_I64_NE: 735 case WASM_INS_I64_LT_S: 736 case WASM_INS_I64_LT_U: 737 case WASN_INS_I64_GT_S: 738 case WASM_INS_I64_GT_U: 739 case WASM_INS_I64_LE_S: 740 case WASM_INS_I64_LE_U: 741 case WASM_INS_I64_GE_S: 742 case WASM_INS_I64_GE_U: 743 case WASM_INS_F32_EQ: 744 case WASM_INS_F32_NE: 745 case WASM_INS_F32_LT: 746 case WASM_INS_F32_GT: 747 case WASM_INS_F32_LE: 748 case WASM_INS_F32_GE: 749 case WASM_INS_F64_EQ: 750 case WASM_INS_F64_NE: 751 case WASM_INS_F64_LT: 752 case WASM_INS_F64_GT: 753 case WASM_INS_F64_LE: 754 case WASM_INS_F64_GE: 755 case WASM_INS_I32_CLZ: 756 case WASM_INS_I32_CTZ: 757 case WASM_INS_I32_POPCNT: 758 case WASM_INS_I32_ADD: 759 case WASM_INS_I32_SUB: 760 case WASM_INS_I32_MUL: 761 case WASM_INS_I32_DIV_S: 762 case WASM_INS_I32_DIV_U: 763 case WASM_INS_I32_REM_S: 764 case WASM_INS_I32_REM_U: 765 case WASM_INS_I32_AND: 766 case WASM_INS_I32_OR: 767 case WASM_INS_I32_XOR: 768 case WASM_INS_I32_SHL: 769 case WASM_INS_I32_SHR_S: 770 case WASM_INS_I32_SHR_U: 771 case WASM_INS_I32_ROTL: 772 case WASM_INS_I32_ROTR: 773 case WASM_INS_I64_CLZ: 774 case WASM_INS_I64_CTZ: 775 case WASM_INS_I64_POPCNT: 776 case WASM_INS_I64_ADD: 777 case WASM_INS_I64_SUB: 778 case WASM_INS_I64_MUL: 779 case WASM_INS_I64_DIV_S: 780 case WASM_INS_I64_DIV_U: 781 case WASM_INS_I64_REM_S: 782 case WASM_INS_I64_REM_U: 783 case WASM_INS_I64_AND: 784 case WASM_INS_I64_OR: 785 case WASM_INS_I64_XOR: 786 case WASM_INS_I64_SHL: 787 case WASM_INS_I64_SHR_S: 788 case WASM_INS_I64_SHR_U: 789 case WASM_INS_I64_ROTL: 790 case WASM_INS_I64_ROTR: 791 case WASM_INS_F32_ABS: 792 case WASM_INS_F32_NEG: 793 case WASM_INS_F32_CEIL: 794 case WASM_INS_F32_FLOOR: 795 case WASM_INS_F32_TRUNC: 796 case WASM_INS_F32_NEAREST: 797 case WASM_INS_F32_SQRT: 798 case WASM_INS_F32_ADD: 799 case WASM_INS_F32_SUB: 800 case WASM_INS_F32_MUL: 801 case WASM_INS_F32_DIV: 802 case WASM_INS_F32_MIN: 803 case WASM_INS_F32_MAX: 804 case WASM_INS_F32_COPYSIGN: 805 case WASM_INS_F64_ABS: 806 case WASM_INS_F64_NEG: 807 case WASM_INS_F64_CEIL: 808 case WASM_INS_F64_FLOOR: 809 case WASM_INS_F64_TRUNC: 810 case WASM_INS_F64_NEAREST: 811 case WASM_INS_F64_SQRT: 812 case WASM_INS_F64_ADD: 813 case WASM_INS_F64_SUB: 814 case WASM_INS_F64_MUL: 815 case WASM_INS_F64_DIV: 816 case WASM_INS_F64_MIN: 817 case WASM_INS_F64_MAX: 818 case WASM_INS_F64_COPYSIGN: 819 case WASM_INS_I32_WARP_I64: 820 case WASP_INS_I32_TRUNC_S_F32: 821 case WASM_INS_I32_TRUNC_U_F32: 822 case WASM_INS_I32_TRUNC_S_F64: 823 case WASM_INS_I32_TRUNC_U_F64: 824 case WASM_INS_I64_EXTEND_S_I32: 825 case WASM_INS_I64_EXTEND_U_I32: 826 case WASM_INS_I64_TRUNC_S_F32: 827 case WASM_INS_I64_TRUNC_U_F32: 828 case WASM_INS_I64_TRUNC_S_F64: 829 case WASM_INS_I64_TRUNC_U_F64: 830 case WASM_INS_F32_CONVERT_S_I32: 831 case WASM_INS_F32_CONVERT_U_I32: 832 case WASM_INS_F32_CONVERT_S_I64: 833 case WASM_INS_F32_CONVERT_U_I64: 834 case WASM_INS_F32_DEMOTE_F64: 835 case WASM_INS_F64_CONVERT_S_I32: 836 case WASM_INS_F64_CONVERT_U_I32: 837 case WASM_INS_F64_CONVERT_S_I64: 838 case WASM_INS_F64_CONVERT_U_I64: 839 case WASM_INS_F64_PROMOTE_F32: 840 case WASM_INS_I32_REINTERPRET_F32: 841 case WASM_INS_I64_REINTERPRET_F64: 842 case WASM_INS_F32_REINTERPRET_I32: 843 case WASM_INS_F64_REINTERPRET_I64: 844 MI->wasm_data.type = WASM_OP_NONE; 845 846 if (MI->flat_insn->detail) { 847 MI->flat_insn->detail->wasm.op_count = 0; 848 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_NUMBERIC; 849 MI->flat_insn->detail->groups_count++; 850 } 851 852 *size = 1; 853 854 break; 855 856 case WASM_INS_DROP: 857 case WASM_INS_SELECT: 858 MI->wasm_data.type = WASM_OP_NONE; 859 860 if (MI->flat_insn->detail) { 861 MI->flat_insn->detail->wasm.op_count = 0; 862 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_PARAMETRIC; 863 MI->flat_insn->detail->groups_count++; 864 } 865 866 *size = 1; 867 868 break; 869 870 case WASM_INS_GET_LOCAL: 871 case WASM_INS_SET_LOCAL: 872 case WASM_INS_TEE_LOCAL: 873 case WASM_INS_GET_GLOBAL: 874 case WASM_INS_SET_GLOBAL: 875 if (code_len == 1 || !read_varuint32(&code[1], code_len - 1, ¶m_size, MI)) { 876 return false; 877 } 878 879 if (MI->flat_insn->detail) { 880 MI->flat_insn->detail->wasm.op_count = 1; 881 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_VARIABLE; 882 MI->flat_insn->detail->groups_count++; 883 } 884 885 *size = param_size + 1; 886 887 break; 888 889 case WASM_INS_I32_LOAD: 890 case WASM_INS_I64_LOAD: 891 case WASM_INS_F32_LOAD: 892 case WASM_INS_F64_LOAD: 893 case WASM_INS_I32_LOAD8_S: 894 case WASM_INS_I32_LOAD8_U: 895 case WASM_INS_I32_LOAD16_S: 896 case WASM_INS_I32_LOAD16_U: 897 case WASM_INS_I64_LOAD8_S: 898 case WASM_INS_I64_LOAD8_U: 899 case WASM_INS_I64_LOAD16_S: 900 case WASM_INS_I64_LOAD16_U: 901 case WASM_INS_I64_LOAD32_S: 902 case WASM_INS_I64_LOAD32_U: 903 case WASM_INS_I32_STORE: 904 case WASM_INS_I64_STORE: 905 case WASM_INS_F32_STORE: 906 case WASM_INS_F64_STORE: 907 case WASM_INS_I32_STORE8: 908 case WASM_INS_I32_STORE16: 909 case WASM_INS_I64_STORE8: 910 case WASM_INS_I64_STORE16: 911 case WASM_INS_I64_STORE32: 912 if (code_len == 1 || !read_memoryimmediate(&code[1], code_len - 1, ¶m_size, MI)) { 913 return false; 914 } 915 916 if (MI->flat_insn->detail) { 917 MI->flat_insn->detail->wasm.op_count = 2; 918 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_MEMORY; 919 MI->flat_insn->detail->groups_count++; 920 } 921 922 *size = param_size + 1; 923 924 break; 925 926 case WASM_INS_CURRENT_MEMORY: 927 case WASM_INS_GROW_MEMORY: 928 MI->wasm_data.type = WASM_OP_NONE; 929 930 if (MI->flat_insn->detail) { 931 MI->flat_insn->detail->wasm.op_count = 0; 932 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_MEMORY; 933 MI->flat_insn->detail->groups_count++; 934 } 935 936 *size = 1; 937 938 break; 939 940 case WASM_INS_UNREACHABLE: 941 case WASM_INS_NOP: 942 case WASM_INS_ELSE: 943 case WASM_INS_END: 944 case WASM_INS_RETURN: 945 MI->wasm_data.type = WASM_OP_NONE; 946 947 if (MI->flat_insn->detail) { 948 MI->flat_insn->detail->wasm.op_count = 0; 949 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_CONTROL; 950 MI->flat_insn->detail->groups_count++; 951 } 952 953 *size = 1; 954 955 break; 956 957 case WASM_INS_BLOCK: 958 case WASM_INS_LOOP: 959 case WASM_INS_IF: 960 if (code_len == 1 || !read_varint7(&code[1], code_len - 1, ¶m_size, MI)) { 961 return false; 962 } 963 964 if (MI->flat_insn->detail) { 965 MI->flat_insn->detail->wasm.op_count = 1; 966 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_CONTROL; 967 MI->flat_insn->detail->groups_count++; 968 } 969 970 *size = param_size + 1; 971 972 break; 973 974 case WASM_INS_BR: 975 case WASM_INS_BR_IF: 976 case WASM_INS_CALL: 977 case WASM_INS_CALL_INDIRECT: 978 if (code_len == 1 || !read_varuint32(&code[1], code_len - 1, ¶m_size, MI)) { 979 return false; 980 } 981 982 if (MI->flat_insn->detail) { 983 MI->flat_insn->detail->wasm.op_count = 1; 984 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_CONTROL; 985 MI->flat_insn->detail->groups_count++; 986 } 987 988 *size = param_size + 1; 989 990 break; 991 992 case WASM_INS_BR_TABLE: 993 if (code_len == 1 || !read_brtable(&code[1], code_len - 1, ¶m_size, MI)) { 994 return false; 995 } 996 997 if (MI->flat_insn->detail) { 998 MI->flat_insn->detail->wasm.op_count = 1; 999 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = WASM_GRP_CONTROL; 1000 MI->flat_insn->detail->groups_count++; 1001 } 1002 1003 *size = param_size + 1; 1004 1005 break; 1006 } 1007 1008 return true; 1009 } 1010