0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #ifdef __KERNEL__
0010 #include <linux/string.h>
0011 #else
0012 #include <string.h>
0013 #endif
0014 #include "../include/asm/inat.h" /* __ignore_sync_check__ */
0015 #include "../include/asm/insn.h" /* __ignore_sync_check__ */
0016 #include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
0017
0018 #include <linux/errno.h>
0019 #include <linux/kconfig.h>
0020
0021 #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
0022
0023 #define leXX_to_cpu(t, r) \
0024 ({ \
0025 __typeof__(t) v; \
0026 switch (sizeof(t)) { \
0027 case 4: v = le32_to_cpu(r); break; \
0028 case 2: v = le16_to_cpu(r); break; \
0029 case 1: v = r; break; \
0030 default: \
0031 BUILD_BUG(); break; \
0032 } \
0033 v; \
0034 })
0035
0036
0037 #define validate_next(t, insn, n) \
0038 ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
0039
0040 #define __get_next(t, insn) \
0041 ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
0042
0043 #define __peek_nbyte_next(t, insn, n) \
0044 ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
0045
0046 #define get_next(t, insn) \
0047 ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
0048
0049 #define peek_nbyte_next(t, insn, n) \
0050 ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); })
0051
0052 #define peek_next(t, insn) peek_nbyte_next(t, insn, 0)
0053
0054
0055
0056
0057
0058
0059
0060
0061 void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
0062 {
0063
0064
0065
0066
0067 if (buf_len > MAX_INSN_SIZE)
0068 buf_len = MAX_INSN_SIZE;
0069
0070 memset(insn, 0, sizeof(*insn));
0071 insn->kaddr = kaddr;
0072 insn->end_kaddr = kaddr + buf_len;
0073 insn->next_byte = kaddr;
0074 insn->x86_64 = x86_64 ? 1 : 0;
0075 insn->opnd_bytes = 4;
0076 if (x86_64)
0077 insn->addr_bytes = 8;
0078 else
0079 insn->addr_bytes = 4;
0080 }
0081
0082 static const insn_byte_t xen_prefix[] = { __XEN_EMULATE_PREFIX };
0083 static const insn_byte_t kvm_prefix[] = { __KVM_EMULATE_PREFIX };
0084
0085 static int __insn_get_emulate_prefix(struct insn *insn,
0086 const insn_byte_t *prefix, size_t len)
0087 {
0088 size_t i;
0089
0090 for (i = 0; i < len; i++) {
0091 if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i])
0092 goto err_out;
0093 }
0094
0095 insn->emulate_prefix_size = len;
0096 insn->next_byte += len;
0097
0098 return 1;
0099
0100 err_out:
0101 return 0;
0102 }
0103
0104 static void insn_get_emulate_prefix(struct insn *insn)
0105 {
0106 if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
0107 return;
0108
0109 __insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 int insn_get_prefixes(struct insn *insn)
0125 {
0126 struct insn_field *prefixes = &insn->prefixes;
0127 insn_attr_t attr;
0128 insn_byte_t b, lb;
0129 int i, nb;
0130
0131 if (prefixes->got)
0132 return 0;
0133
0134 insn_get_emulate_prefix(insn);
0135
0136 nb = 0;
0137 lb = 0;
0138 b = peek_next(insn_byte_t, insn);
0139 attr = inat_get_opcode_attribute(b);
0140 while (inat_is_legacy_prefix(attr)) {
0141
0142 for (i = 0; i < nb; i++)
0143 if (prefixes->bytes[i] == b)
0144 goto found;
0145 if (nb == 4)
0146
0147 break;
0148 prefixes->bytes[nb++] = b;
0149 if (inat_is_address_size_prefix(attr)) {
0150
0151 if (insn->x86_64)
0152 insn->addr_bytes ^= 12;
0153 else
0154 insn->addr_bytes ^= 6;
0155 } else if (inat_is_operand_size_prefix(attr)) {
0156
0157 insn->opnd_bytes ^= 6;
0158 }
0159 found:
0160 prefixes->nbytes++;
0161 insn->next_byte++;
0162 lb = b;
0163 b = peek_next(insn_byte_t, insn);
0164 attr = inat_get_opcode_attribute(b);
0165 }
0166
0167 if (lb && lb != insn->prefixes.bytes[3]) {
0168 if (unlikely(insn->prefixes.bytes[3])) {
0169
0170 b = insn->prefixes.bytes[3];
0171 for (i = 0; i < nb; i++)
0172 if (prefixes->bytes[i] == lb)
0173 insn_set_byte(prefixes, i, b);
0174 }
0175 insn_set_byte(&insn->prefixes, 3, lb);
0176 }
0177
0178
0179 if (insn->x86_64) {
0180 b = peek_next(insn_byte_t, insn);
0181 attr = inat_get_opcode_attribute(b);
0182 if (inat_is_rex_prefix(attr)) {
0183 insn_field_set(&insn->rex_prefix, b, 1);
0184 insn->next_byte++;
0185 if (X86_REX_W(b))
0186
0187 insn->opnd_bytes = 8;
0188 }
0189 }
0190 insn->rex_prefix.got = 1;
0191
0192
0193 b = peek_next(insn_byte_t, insn);
0194 attr = inat_get_opcode_attribute(b);
0195 if (inat_is_vex_prefix(attr)) {
0196 insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
0197 if (!insn->x86_64) {
0198
0199
0200
0201
0202
0203 if (X86_MODRM_MOD(b2) != 3)
0204 goto vex_end;
0205 }
0206 insn_set_byte(&insn->vex_prefix, 0, b);
0207 insn_set_byte(&insn->vex_prefix, 1, b2);
0208 if (inat_is_evex_prefix(attr)) {
0209 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
0210 insn_set_byte(&insn->vex_prefix, 2, b2);
0211 b2 = peek_nbyte_next(insn_byte_t, insn, 3);
0212 insn_set_byte(&insn->vex_prefix, 3, b2);
0213 insn->vex_prefix.nbytes = 4;
0214 insn->next_byte += 4;
0215 if (insn->x86_64 && X86_VEX_W(b2))
0216
0217 insn->opnd_bytes = 8;
0218 } else if (inat_is_vex3_prefix(attr)) {
0219 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
0220 insn_set_byte(&insn->vex_prefix, 2, b2);
0221 insn->vex_prefix.nbytes = 3;
0222 insn->next_byte += 3;
0223 if (insn->x86_64 && X86_VEX_W(b2))
0224
0225 insn->opnd_bytes = 8;
0226 } else {
0227
0228
0229
0230
0231
0232 insn_set_byte(&insn->vex_prefix, 2, b2 & 0x7f);
0233 insn->vex_prefix.nbytes = 2;
0234 insn->next_byte += 2;
0235 }
0236 }
0237 vex_end:
0238 insn->vex_prefix.got = 1;
0239
0240 prefixes->got = 1;
0241
0242 return 0;
0243
0244 err_out:
0245 return -ENODATA;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 int insn_get_opcode(struct insn *insn)
0263 {
0264 struct insn_field *opcode = &insn->opcode;
0265 int pfx_id, ret;
0266 insn_byte_t op;
0267
0268 if (opcode->got)
0269 return 0;
0270
0271 if (!insn->prefixes.got) {
0272 ret = insn_get_prefixes(insn);
0273 if (ret)
0274 return ret;
0275 }
0276
0277
0278 op = get_next(insn_byte_t, insn);
0279 insn_set_byte(opcode, 0, op);
0280 opcode->nbytes = 1;
0281
0282
0283 if (insn_is_avx(insn)) {
0284 insn_byte_t m, p;
0285 m = insn_vex_m_bits(insn);
0286 p = insn_vex_p_bits(insn);
0287 insn->attr = inat_get_avx_attribute(op, m, p);
0288 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
0289 (!inat_accept_vex(insn->attr) &&
0290 !inat_is_group(insn->attr))) {
0291
0292 insn->attr = 0;
0293 return -EINVAL;
0294 }
0295
0296 goto end;
0297 }
0298
0299 insn->attr = inat_get_opcode_attribute(op);
0300 while (inat_is_escape(insn->attr)) {
0301
0302 op = get_next(insn_byte_t, insn);
0303 opcode->bytes[opcode->nbytes++] = op;
0304 pfx_id = insn_last_prefix_id(insn);
0305 insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
0306 }
0307
0308 if (inat_must_vex(insn->attr)) {
0309
0310 insn->attr = 0;
0311 return -EINVAL;
0312 }
0313 end:
0314 opcode->got = 1;
0315 return 0;
0316
0317 err_out:
0318 return -ENODATA;
0319 }
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 int insn_get_modrm(struct insn *insn)
0334 {
0335 struct insn_field *modrm = &insn->modrm;
0336 insn_byte_t pfx_id, mod;
0337 int ret;
0338
0339 if (modrm->got)
0340 return 0;
0341
0342 if (!insn->opcode.got) {
0343 ret = insn_get_opcode(insn);
0344 if (ret)
0345 return ret;
0346 }
0347
0348 if (inat_has_modrm(insn->attr)) {
0349 mod = get_next(insn_byte_t, insn);
0350 insn_field_set(modrm, mod, 1);
0351 if (inat_is_group(insn->attr)) {
0352 pfx_id = insn_last_prefix_id(insn);
0353 insn->attr = inat_get_group_attribute(mod, pfx_id,
0354 insn->attr);
0355 if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) {
0356
0357 insn->attr = 0;
0358 return -EINVAL;
0359 }
0360 }
0361 }
0362
0363 if (insn->x86_64 && inat_is_force64(insn->attr))
0364 insn->opnd_bytes = 8;
0365
0366 modrm->got = 1;
0367 return 0;
0368
0369 err_out:
0370 return -ENODATA;
0371 }
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 int insn_rip_relative(struct insn *insn)
0382 {
0383 struct insn_field *modrm = &insn->modrm;
0384 int ret;
0385
0386 if (!insn->x86_64)
0387 return 0;
0388
0389 if (!modrm->got) {
0390 ret = insn_get_modrm(insn);
0391 if (ret)
0392 return 0;
0393 }
0394
0395
0396
0397
0398 return (modrm->nbytes && (modrm->bytes[0] & 0xc7) == 0x5);
0399 }
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 int insn_get_sib(struct insn *insn)
0413 {
0414 insn_byte_t modrm;
0415 int ret;
0416
0417 if (insn->sib.got)
0418 return 0;
0419
0420 if (!insn->modrm.got) {
0421 ret = insn_get_modrm(insn);
0422 if (ret)
0423 return ret;
0424 }
0425
0426 if (insn->modrm.nbytes) {
0427 modrm = insn->modrm.bytes[0];
0428 if (insn->addr_bytes != 2 &&
0429 X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
0430 insn_field_set(&insn->sib,
0431 get_next(insn_byte_t, insn), 1);
0432 }
0433 }
0434 insn->sib.got = 1;
0435
0436 return 0;
0437
0438 err_out:
0439 return -ENODATA;
0440 }
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 int insn_get_displacement(struct insn *insn)
0456 {
0457 insn_byte_t mod, rm, base;
0458 int ret;
0459
0460 if (insn->displacement.got)
0461 return 0;
0462
0463 if (!insn->sib.got) {
0464 ret = insn_get_sib(insn);
0465 if (ret)
0466 return ret;
0467 }
0468
0469 if (insn->modrm.nbytes) {
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 mod = X86_MODRM_MOD(insn->modrm.value);
0488 rm = X86_MODRM_RM(insn->modrm.value);
0489 base = X86_SIB_BASE(insn->sib.value);
0490 if (mod == 3)
0491 goto out;
0492 if (mod == 1) {
0493 insn_field_set(&insn->displacement,
0494 get_next(signed char, insn), 1);
0495 } else if (insn->addr_bytes == 2) {
0496 if ((mod == 0 && rm == 6) || mod == 2) {
0497 insn_field_set(&insn->displacement,
0498 get_next(short, insn), 2);
0499 }
0500 } else {
0501 if ((mod == 0 && rm == 5) || mod == 2 ||
0502 (mod == 0 && base == 5)) {
0503 insn_field_set(&insn->displacement,
0504 get_next(int, insn), 4);
0505 }
0506 }
0507 }
0508 out:
0509 insn->displacement.got = 1;
0510 return 0;
0511
0512 err_out:
0513 return -ENODATA;
0514 }
0515
0516
0517 static int __get_moffset(struct insn *insn)
0518 {
0519 switch (insn->addr_bytes) {
0520 case 2:
0521 insn_field_set(&insn->moffset1, get_next(short, insn), 2);
0522 break;
0523 case 4:
0524 insn_field_set(&insn->moffset1, get_next(int, insn), 4);
0525 break;
0526 case 8:
0527 insn_field_set(&insn->moffset1, get_next(int, insn), 4);
0528 insn_field_set(&insn->moffset2, get_next(int, insn), 4);
0529 break;
0530 default:
0531 goto err_out;
0532 }
0533 insn->moffset1.got = insn->moffset2.got = 1;
0534
0535 return 1;
0536
0537 err_out:
0538 return 0;
0539 }
0540
0541
0542 static int __get_immv32(struct insn *insn)
0543 {
0544 switch (insn->opnd_bytes) {
0545 case 2:
0546 insn_field_set(&insn->immediate, get_next(short, insn), 2);
0547 break;
0548 case 4:
0549 case 8:
0550 insn_field_set(&insn->immediate, get_next(int, insn), 4);
0551 break;
0552 default:
0553 goto err_out;
0554 }
0555
0556 return 1;
0557
0558 err_out:
0559 return 0;
0560 }
0561
0562
0563 static int __get_immv(struct insn *insn)
0564 {
0565 switch (insn->opnd_bytes) {
0566 case 2:
0567 insn_field_set(&insn->immediate1, get_next(short, insn), 2);
0568 break;
0569 case 4:
0570 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
0571 insn->immediate1.nbytes = 4;
0572 break;
0573 case 8:
0574 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
0575 insn_field_set(&insn->immediate2, get_next(int, insn), 4);
0576 break;
0577 default:
0578 goto err_out;
0579 }
0580 insn->immediate1.got = insn->immediate2.got = 1;
0581
0582 return 1;
0583 err_out:
0584 return 0;
0585 }
0586
0587
0588 static int __get_immptr(struct insn *insn)
0589 {
0590 switch (insn->opnd_bytes) {
0591 case 2:
0592 insn_field_set(&insn->immediate1, get_next(short, insn), 2);
0593 break;
0594 case 4:
0595 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
0596 break;
0597 case 8:
0598
0599 return 0;
0600 default:
0601 goto err_out;
0602 }
0603 insn_field_set(&insn->immediate2, get_next(unsigned short, insn), 2);
0604 insn->immediate1.got = insn->immediate2.got = 1;
0605
0606 return 1;
0607 err_out:
0608 return 0;
0609 }
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 int insn_get_immediate(struct insn *insn)
0625 {
0626 int ret;
0627
0628 if (insn->immediate.got)
0629 return 0;
0630
0631 if (!insn->displacement.got) {
0632 ret = insn_get_displacement(insn);
0633 if (ret)
0634 return ret;
0635 }
0636
0637 if (inat_has_moffset(insn->attr)) {
0638 if (!__get_moffset(insn))
0639 goto err_out;
0640 goto done;
0641 }
0642
0643 if (!inat_has_immediate(insn->attr))
0644
0645 goto done;
0646
0647 switch (inat_immediate_size(insn->attr)) {
0648 case INAT_IMM_BYTE:
0649 insn_field_set(&insn->immediate, get_next(signed char, insn), 1);
0650 break;
0651 case INAT_IMM_WORD:
0652 insn_field_set(&insn->immediate, get_next(short, insn), 2);
0653 break;
0654 case INAT_IMM_DWORD:
0655 insn_field_set(&insn->immediate, get_next(int, insn), 4);
0656 break;
0657 case INAT_IMM_QWORD:
0658 insn_field_set(&insn->immediate1, get_next(int, insn), 4);
0659 insn_field_set(&insn->immediate2, get_next(int, insn), 4);
0660 break;
0661 case INAT_IMM_PTR:
0662 if (!__get_immptr(insn))
0663 goto err_out;
0664 break;
0665 case INAT_IMM_VWORD32:
0666 if (!__get_immv32(insn))
0667 goto err_out;
0668 break;
0669 case INAT_IMM_VWORD:
0670 if (!__get_immv(insn))
0671 goto err_out;
0672 break;
0673 default:
0674
0675 goto err_out;
0676 }
0677 if (inat_has_second_immediate(insn->attr)) {
0678 insn_field_set(&insn->immediate2, get_next(signed char, insn), 1);
0679 }
0680 done:
0681 insn->immediate.got = 1;
0682 return 0;
0683
0684 err_out:
0685 return -ENODATA;
0686 }
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699 int insn_get_length(struct insn *insn)
0700 {
0701 int ret;
0702
0703 if (insn->length)
0704 return 0;
0705
0706 if (!insn->immediate.got) {
0707 ret = insn_get_immediate(insn);
0708 if (ret)
0709 return ret;
0710 }
0711
0712 insn->length = (unsigned char)((unsigned long)insn->next_byte
0713 - (unsigned long)insn->kaddr);
0714
0715 return 0;
0716 }
0717
0718
0719 static inline int insn_complete(struct insn *insn)
0720 {
0721 return insn->opcode.got && insn->modrm.got && insn->sib.got &&
0722 insn->displacement.got && insn->immediate.got;
0723 }
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m)
0737 {
0738 int ret;
0739
0740 #define INSN_MODE_KERN (enum insn_mode)-1
0741
0742 if (m == INSN_MODE_KERN)
0743 insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
0744 else
0745 insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);
0746
0747 ret = insn_get_length(insn);
0748 if (ret)
0749 return ret;
0750
0751 if (insn_complete(insn))
0752 return 0;
0753
0754 return -EINVAL;
0755 }