1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com> 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 9 #define unlikely(cond) (cond) 10 #include <asm/insn.h> 11 #include "../../../arch/x86/lib/inat.c" 12 #include "../../../arch/x86/lib/insn.c" 13 14 #define CONFIG_64BIT 1 15 #include <asm/nops.h> 16 17 #include <asm/orc_types.h> 18 #include <objtool/check.h> 19 #include <objtool/elf.h> 20 #include <objtool/arch.h> 21 #include <objtool/warn.h> 22 #include <objtool/endianness.h> 23 #include <objtool/builtin.h> 24 #include <arch/elf.h> 25 26 static int is_x86_64(const struct elf *elf) 27 { 28 switch (elf->ehdr.e_machine) { 29 case EM_X86_64: 30 return 1; 31 case EM_386: 32 return 0; 33 default: 34 WARN("unexpected ELF machine type %d", elf->ehdr.e_machine); 35 return -1; 36 } 37 } 38 39 bool arch_callee_saved_reg(unsigned char reg) 40 { 41 switch (reg) { 42 case CFI_BP: 43 case CFI_BX: 44 case CFI_R12: 45 case CFI_R13: 46 case CFI_R14: 47 case CFI_R15: 48 return true; 49 50 case CFI_AX: 51 case CFI_CX: 52 case CFI_DX: 53 case CFI_SI: 54 case CFI_DI: 55 case CFI_SP: 56 case CFI_R8: 57 case CFI_R9: 58 case CFI_R10: 59 case CFI_R11: 60 case CFI_RA: 61 default: 62 return false; 63 } 64 } 65 66 unsigned long arch_dest_reloc_offset(int addend) 67 { 68 return addend + 4; 69 } 70 71 unsigned long arch_jump_destination(struct instruction *insn) 72 { 73 return insn->offset + insn->len + insn->immediate; 74 } 75 76 bool arch_pc_relative_reloc(struct reloc *reloc) 77 { 78 /* 79 * All relocation types where P (the address of the target) 80 * is included in the computation. 81 */ 82 switch (reloc->type) { 83 case R_X86_64_PC8: 84 case R_X86_64_PC16: 85 case R_X86_64_PC32: 86 case R_X86_64_PC64: 87 88 case R_X86_64_PLT32: 89 case R_X86_64_GOTPC32: 90 case R_X86_64_GOTPCREL: 91 return true; 92 93 default: 94 break; 95 } 96 97 return false; 98 } 99 100 #define ADD_OP(op) \ 101 if (!(op = calloc(1, sizeof(*op)))) \ 102 return -1; \ 103 else for (list_add_tail(&op->list, ops_list); op; op = NULL) 104 105 /* 106 * Helpers to decode ModRM/SIB: 107 * 108 * r/m| AX CX DX BX | SP | BP | SI DI | 109 * | R8 R9 R10 R11 | R12 | R13 | R14 R15 | 110 * Mod+----------------+-----+-----+---------+ 111 * 00 | [r/m] |[SIB]|[IP+]| [r/m] | 112 * 01 | [r/m + d8] |[S+d]| [r/m + d8] | 113 * 10 | [r/m + d32] |[S+D]| [r/m + d32] | 114 * 11 | r/ m | 115 */ 116 117 #define mod_is_mem() (modrm_mod != 3) 118 #define mod_is_reg() (modrm_mod == 3) 119 120 #define is_RIP() ((modrm_rm & 7) == CFI_BP && modrm_mod == 0) 121 #define have_SIB() ((modrm_rm & 7) == CFI_SP && mod_is_mem()) 122 123 #define rm_is(reg) (have_SIB() ? \ 124 sib_base == (reg) && sib_index == CFI_SP : \ 125 modrm_rm == (reg)) 126 127 #define rm_is_mem(reg) (mod_is_mem() && !is_RIP() && rm_is(reg)) 128 #define rm_is_reg(reg) (mod_is_reg() && modrm_rm == (reg)) 129 130 static bool has_notrack_prefix(struct insn *insn) 131 { 132 int i; 133 134 for (i = 0; i < insn->prefixes.nbytes; i++) { 135 if (insn->prefixes.bytes[i] == 0x3e) 136 return true; 137 } 138 139 return false; 140 } 141 142 int arch_decode_instruction(struct objtool_file *file, const struct section *sec, 143 unsigned long offset, unsigned int maxlen, 144 unsigned int *len, enum insn_type *type, 145 unsigned long *immediate, 146 struct list_head *ops_list) 147 { 148 const struct elf *elf = file->elf; 149 struct insn insn; 150 int x86_64, ret; 151 unsigned char op1, op2, op3, prefix, 152 rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, rex_x = 0, 153 modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0, 154 sib = 0, /* sib_scale = 0, */ sib_index = 0, sib_base = 0; 155 struct stack_op *op = NULL; 156 struct symbol *sym; 157 u64 imm; 158 159 x86_64 = is_x86_64(elf); 160 if (x86_64 == -1) 161 return -1; 162 163 ret = insn_decode(&insn, sec->data->d_buf + offset, maxlen, 164 x86_64 ? INSN_MODE_64 : INSN_MODE_32); 165 if (ret < 0) { 166 WARN("can't decode instruction at %s:0x%lx", sec->name, offset); 167 return -1; 168 } 169 170 *len = insn.length; 171 *type = INSN_OTHER; 172 173 if (insn.vex_prefix.nbytes) 174 return 0; 175 176 prefix = insn.prefixes.bytes[0]; 177 178 op1 = insn.opcode.bytes[0]; 179 op2 = insn.opcode.bytes[1]; 180 op3 = insn.opcode.bytes[2]; 181 182 if (insn.rex_prefix.nbytes) { 183 rex = insn.rex_prefix.bytes[0]; 184 rex_w = X86_REX_W(rex) >> 3; 185 rex_r = X86_REX_R(rex) >> 2; 186 rex_x = X86_REX_X(rex) >> 1; 187 rex_b = X86_REX_B(rex); 188 } 189 190 if (insn.modrm.nbytes) { 191 modrm = insn.modrm.bytes[0]; 192 modrm_mod = X86_MODRM_MOD(modrm); 193 modrm_reg = X86_MODRM_REG(modrm) + 8*rex_r; 194 modrm_rm = X86_MODRM_RM(modrm) + 8*rex_b; 195 } 196 197 if (insn.sib.nbytes) { 198 sib = insn.sib.bytes[0]; 199 /* sib_scale = X86_SIB_SCALE(sib); */ 200 sib_index = X86_SIB_INDEX(sib) + 8*rex_x; 201 sib_base = X86_SIB_BASE(sib) + 8*rex_b; 202 } 203 204 switch (op1) { 205 206 case 0x1: 207 case 0x29: 208 if (rex_w && rm_is_reg(CFI_SP)) { 209 210 /* add/sub reg, %rsp */ 211 ADD_OP(op) { 212 op->src.type = OP_SRC_ADD; 213 op->src.reg = modrm_reg; 214 op->dest.type = OP_DEST_REG; 215 op->dest.reg = CFI_SP; 216 } 217 } 218 break; 219 220 case 0x50 ... 0x57: 221 222 /* push reg */ 223 ADD_OP(op) { 224 op->src.type = OP_SRC_REG; 225 op->src.reg = (op1 & 0x7) + 8*rex_b; 226 op->dest.type = OP_DEST_PUSH; 227 } 228 229 break; 230 231 case 0x58 ... 0x5f: 232 233 /* pop reg */ 234 ADD_OP(op) { 235 op->src.type = OP_SRC_POP; 236 op->dest.type = OP_DEST_REG; 237 op->dest.reg = (op1 & 0x7) + 8*rex_b; 238 } 239 240 break; 241 242 case 0x68: 243 case 0x6a: 244 /* push immediate */ 245 ADD_OP(op) { 246 op->src.type = OP_SRC_CONST; 247 op->dest.type = OP_DEST_PUSH; 248 } 249 break; 250 251 case 0x70 ... 0x7f: 252 *type = INSN_JUMP_CONDITIONAL; 253 break; 254 255 case 0x80 ... 0x83: 256 /* 257 * 1000 00sw : mod OP r/m : immediate 258 * 259 * s - sign extend immediate 260 * w - imm8 / imm32 261 * 262 * OP: 000 ADD 100 AND 263 * 001 OR 101 SUB 264 * 010 ADC 110 XOR 265 * 011 SBB 111 CMP 266 */ 267 268 /* 64bit only */ 269 if (!rex_w) 270 break; 271 272 /* %rsp target only */ 273 if (!rm_is_reg(CFI_SP)) 274 break; 275 276 imm = insn.immediate.value; 277 if (op1 & 2) { /* sign extend */ 278 if (op1 & 1) { /* imm32 */ 279 imm <<= 32; 280 imm = (s64)imm >> 32; 281 } else { /* imm8 */ 282 imm <<= 56; 283 imm = (s64)imm >> 56; 284 } 285 } 286 287 switch (modrm_reg & 7) { 288 case 5: 289 imm = -imm; 290 /* fallthrough */ 291 case 0: 292 /* add/sub imm, %rsp */ 293 ADD_OP(op) { 294 op->src.type = OP_SRC_ADD; 295 op->src.reg = CFI_SP; 296 op->src.offset = imm; 297 op->dest.type = OP_DEST_REG; 298 op->dest.reg = CFI_SP; 299 } 300 break; 301 302 case 4: 303 /* and imm, %rsp */ 304 ADD_OP(op) { 305 op->src.type = OP_SRC_AND; 306 op->src.reg = CFI_SP; 307 op->src.offset = insn.immediate.value; 308 op->dest.type = OP_DEST_REG; 309 op->dest.reg = CFI_SP; 310 } 311 break; 312 313 default: 314 /* WARN ? */ 315 break; 316 } 317 318 break; 319 320 case 0x89: 321 if (!rex_w) 322 break; 323 324 if (modrm_reg == CFI_SP) { 325 326 if (mod_is_reg()) { 327 /* mov %rsp, reg */ 328 ADD_OP(op) { 329 op->src.type = OP_SRC_REG; 330 op->src.reg = CFI_SP; 331 op->dest.type = OP_DEST_REG; 332 op->dest.reg = modrm_rm; 333 } 334 break; 335 336 } else { 337 /* skip RIP relative displacement */ 338 if (is_RIP()) 339 break; 340 341 /* skip nontrivial SIB */ 342 if (have_SIB()) { 343 modrm_rm = sib_base; 344 if (sib_index != CFI_SP) 345 break; 346 } 347 348 /* mov %rsp, disp(%reg) */ 349 ADD_OP(op) { 350 op->src.type = OP_SRC_REG; 351 op->src.reg = CFI_SP; 352 op->dest.type = OP_DEST_REG_INDIRECT; 353 op->dest.reg = modrm_rm; 354 op->dest.offset = insn.displacement.value; 355 } 356 break; 357 } 358 359 break; 360 } 361 362 if (rm_is_reg(CFI_SP)) { 363 364 /* mov reg, %rsp */ 365 ADD_OP(op) { 366 op->src.type = OP_SRC_REG; 367 op->src.reg = modrm_reg; 368 op->dest.type = OP_DEST_REG; 369 op->dest.reg = CFI_SP; 370 } 371 break; 372 } 373 374 /* fallthrough */ 375 case 0x88: 376 if (!rex_w) 377 break; 378 379 if (rm_is_mem(CFI_BP)) { 380 381 /* mov reg, disp(%rbp) */ 382 ADD_OP(op) { 383 op->src.type = OP_SRC_REG; 384 op->src.reg = modrm_reg; 385 op->dest.type = OP_DEST_REG_INDIRECT; 386 op->dest.reg = CFI_BP; 387 op->dest.offset = insn.displacement.value; 388 } 389 break; 390 } 391 392 if (rm_is_mem(CFI_SP)) { 393 394 /* mov reg, disp(%rsp) */ 395 ADD_OP(op) { 396 op->src.type = OP_SRC_REG; 397 op->src.reg = modrm_reg; 398 op->dest.type = OP_DEST_REG_INDIRECT; 399 op->dest.reg = CFI_SP; 400 op->dest.offset = insn.displacement.value; 401 } 402 break; 403 } 404 405 break; 406 407 case 0x8b: 408 if (!rex_w) 409 break; 410 411 if (rm_is_mem(CFI_BP)) { 412 413 /* mov disp(%rbp), reg */ 414 ADD_OP(op) { 415 op->src.type = OP_SRC_REG_INDIRECT; 416 op->src.reg = CFI_BP; 417 op->src.offset = insn.displacement.value; 418 op->dest.type = OP_DEST_REG; 419 op->dest.reg = modrm_reg; 420 } 421 break; 422 } 423 424 if (rm_is_mem(CFI_SP)) { 425 426 /* mov disp(%rsp), reg */ 427 ADD_OP(op) { 428 op->src.type = OP_SRC_REG_INDIRECT; 429 op->src.reg = CFI_SP; 430 op->src.offset = insn.displacement.value; 431 op->dest.type = OP_DEST_REG; 432 op->dest.reg = modrm_reg; 433 } 434 break; 435 } 436 437 break; 438 439 case 0x8d: 440 if (mod_is_reg()) { 441 WARN("invalid LEA encoding at %s:0x%lx", sec->name, offset); 442 break; 443 } 444 445 /* skip non 64bit ops */ 446 if (!rex_w) 447 break; 448 449 /* skip RIP relative displacement */ 450 if (is_RIP()) 451 break; 452 453 /* skip nontrivial SIB */ 454 if (have_SIB()) { 455 modrm_rm = sib_base; 456 if (sib_index != CFI_SP) 457 break; 458 } 459 460 /* lea disp(%src), %dst */ 461 ADD_OP(op) { 462 op->src.offset = insn.displacement.value; 463 if (!op->src.offset) { 464 /* lea (%src), %dst */ 465 op->src.type = OP_SRC_REG; 466 } else { 467 /* lea disp(%src), %dst */ 468 op->src.type = OP_SRC_ADD; 469 } 470 op->src.reg = modrm_rm; 471 op->dest.type = OP_DEST_REG; 472 op->dest.reg = modrm_reg; 473 } 474 break; 475 476 case 0x8f: 477 /* pop to mem */ 478 ADD_OP(op) { 479 op->src.type = OP_SRC_POP; 480 op->dest.type = OP_DEST_MEM; 481 } 482 break; 483 484 case 0x90: 485 *type = INSN_NOP; 486 break; 487 488 case 0x9c: 489 /* pushf */ 490 ADD_OP(op) { 491 op->src.type = OP_SRC_CONST; 492 op->dest.type = OP_DEST_PUSHF; 493 } 494 break; 495 496 case 0x9d: 497 /* popf */ 498 ADD_OP(op) { 499 op->src.type = OP_SRC_POPF; 500 op->dest.type = OP_DEST_MEM; 501 } 502 break; 503 504 case 0x0f: 505 506 if (op2 == 0x01) { 507 508 if (modrm == 0xca) 509 *type = INSN_CLAC; 510 else if (modrm == 0xcb) 511 *type = INSN_STAC; 512 513 } else if (op2 >= 0x80 && op2 <= 0x8f) { 514 515 *type = INSN_JUMP_CONDITIONAL; 516 517 } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 || 518 op2 == 0x35) { 519 520 /* sysenter, sysret */ 521 *type = INSN_CONTEXT_SWITCH; 522 523 } else if (op2 == 0x0b || op2 == 0xb9) { 524 525 /* ud2 */ 526 *type = INSN_BUG; 527 528 } else if (op2 == 0x0d || op2 == 0x1f) { 529 530 /* nopl/nopw */ 531 *type = INSN_NOP; 532 533 } else if (op2 == 0x1e) { 534 535 if (prefix == 0xf3 && (modrm == 0xfa || modrm == 0xfb)) 536 *type = INSN_ENDBR; 537 538 539 } else if (op2 == 0x38 && op3 == 0xf8) { 540 if (insn.prefixes.nbytes == 1 && 541 insn.prefixes.bytes[0] == 0xf2) { 542 /* ENQCMD cannot be used in the kernel. */ 543 WARN("ENQCMD instruction at %s:%lx", sec->name, 544 offset); 545 } 546 547 } else if (op2 == 0xa0 || op2 == 0xa8) { 548 549 /* push fs/gs */ 550 ADD_OP(op) { 551 op->src.type = OP_SRC_CONST; 552 op->dest.type = OP_DEST_PUSH; 553 } 554 555 } else if (op2 == 0xa1 || op2 == 0xa9) { 556 557 /* pop fs/gs */ 558 ADD_OP(op) { 559 op->src.type = OP_SRC_POP; 560 op->dest.type = OP_DEST_MEM; 561 } 562 } 563 564 break; 565 566 case 0xc9: 567 /* 568 * leave 569 * 570 * equivalent to: 571 * mov bp, sp 572 * pop bp 573 */ 574 ADD_OP(op) { 575 op->src.type = OP_SRC_REG; 576 op->src.reg = CFI_BP; 577 op->dest.type = OP_DEST_REG; 578 op->dest.reg = CFI_SP; 579 } 580 ADD_OP(op) { 581 op->src.type = OP_SRC_POP; 582 op->dest.type = OP_DEST_REG; 583 op->dest.reg = CFI_BP; 584 } 585 break; 586 587 case 0xcc: 588 /* int3 */ 589 *type = INSN_TRAP; 590 break; 591 592 case 0xe3: 593 /* jecxz/jrcxz */ 594 *type = INSN_JUMP_CONDITIONAL; 595 break; 596 597 case 0xe9: 598 case 0xeb: 599 *type = INSN_JUMP_UNCONDITIONAL; 600 break; 601 602 case 0xc2: 603 case 0xc3: 604 *type = INSN_RETURN; 605 break; 606 607 case 0xc7: /* mov imm, r/m */ 608 if (!opts.noinstr) 609 break; 610 611 if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) { 612 struct reloc *immr, *disp; 613 struct symbol *func; 614 int idx; 615 616 immr = find_reloc_by_dest(elf, (void *)sec, offset+3); 617 disp = find_reloc_by_dest(elf, (void *)sec, offset+7); 618 619 if (!immr || strcmp(immr->sym->name, "pv_ops")) 620 break; 621 622 idx = (immr->addend + 8) / sizeof(void *); 623 624 func = disp->sym; 625 if (disp->sym->type == STT_SECTION) 626 func = find_symbol_by_offset(disp->sym->sec, disp->addend); 627 if (!func) { 628 WARN("no func for pv_ops[]"); 629 return -1; 630 } 631 632 objtool_pv_add(file, idx, func); 633 } 634 635 break; 636 637 case 0xcf: /* iret */ 638 /* 639 * Handle sync_core(), which has an IRET to self. 640 * All other IRET are in STT_NONE entry code. 641 */ 642 sym = find_symbol_containing(sec, offset); 643 if (sym && sym->type == STT_FUNC) { 644 ADD_OP(op) { 645 /* add $40, %rsp */ 646 op->src.type = OP_SRC_ADD; 647 op->src.reg = CFI_SP; 648 op->src.offset = 5*8; 649 op->dest.type = OP_DEST_REG; 650 op->dest.reg = CFI_SP; 651 } 652 break; 653 } 654 655 /* fallthrough */ 656 657 case 0xca: /* retf */ 658 case 0xcb: /* retf */ 659 *type = INSN_CONTEXT_SWITCH; 660 break; 661 662 case 0xe0: /* loopne */ 663 case 0xe1: /* loope */ 664 case 0xe2: /* loop */ 665 *type = INSN_JUMP_CONDITIONAL; 666 break; 667 668 case 0xe8: 669 *type = INSN_CALL; 670 /* 671 * For the impact on the stack, a CALL behaves like 672 * a PUSH of an immediate value (the return address). 673 */ 674 ADD_OP(op) { 675 op->src.type = OP_SRC_CONST; 676 op->dest.type = OP_DEST_PUSH; 677 } 678 break; 679 680 case 0xfc: 681 *type = INSN_CLD; 682 break; 683 684 case 0xfd: 685 *type = INSN_STD; 686 break; 687 688 case 0xff: 689 if (modrm_reg == 2 || modrm_reg == 3) { 690 691 *type = INSN_CALL_DYNAMIC; 692 if (has_notrack_prefix(&insn)) 693 WARN("notrack prefix found at %s:0x%lx", sec->name, offset); 694 695 } else if (modrm_reg == 4) { 696 697 *type = INSN_JUMP_DYNAMIC; 698 if (has_notrack_prefix(&insn)) 699 WARN("notrack prefix found at %s:0x%lx", sec->name, offset); 700 701 } else if (modrm_reg == 5) { 702 703 /* jmpf */ 704 *type = INSN_CONTEXT_SWITCH; 705 706 } else if (modrm_reg == 6) { 707 708 /* push from mem */ 709 ADD_OP(op) { 710 op->src.type = OP_SRC_CONST; 711 op->dest.type = OP_DEST_PUSH; 712 } 713 } 714 715 break; 716 717 default: 718 break; 719 } 720 721 *immediate = insn.immediate.nbytes ? insn.immediate.value : 0; 722 723 return 0; 724 } 725 726 void arch_initial_func_cfi_state(struct cfi_init_state *state) 727 { 728 int i; 729 730 for (i = 0; i < CFI_NUM_REGS; i++) { 731 state->regs[i].base = CFI_UNDEFINED; 732 state->regs[i].offset = 0; 733 } 734 735 /* initial CFA (call frame address) */ 736 state->cfa.base = CFI_SP; 737 state->cfa.offset = 8; 738 739 /* initial RA (return address) */ 740 state->regs[CFI_RA].base = CFI_CFA; 741 state->regs[CFI_RA].offset = -8; 742 } 743 744 const char *arch_nop_insn(int len) 745 { 746 static const char nops[5][5] = { 747 { BYTES_NOP1 }, 748 { BYTES_NOP2 }, 749 { BYTES_NOP3 }, 750 { BYTES_NOP4 }, 751 { BYTES_NOP5 }, 752 }; 753 754 if (len < 1 || len > 5) { 755 WARN("invalid NOP size: %d\n", len); 756 return NULL; 757 } 758 759 return nops[len-1]; 760 } 761 762 #define BYTE_RET 0xC3 763 764 const char *arch_ret_insn(int len) 765 { 766 static const char ret[5][5] = { 767 { BYTE_RET }, 768 { BYTE_RET, 0xcc }, 769 { BYTE_RET, 0xcc, BYTES_NOP1 }, 770 { BYTE_RET, 0xcc, BYTES_NOP2 }, 771 { BYTE_RET, 0xcc, BYTES_NOP3 }, 772 }; 773 774 if (len < 1 || len > 5) { 775 WARN("invalid RET size: %d\n", len); 776 return NULL; 777 } 778 779 return ret[len-1]; 780 } 781 782 int arch_decode_hint_reg(u8 sp_reg, int *base) 783 { 784 switch (sp_reg) { 785 case ORC_REG_UNDEFINED: 786 *base = CFI_UNDEFINED; 787 break; 788 case ORC_REG_SP: 789 *base = CFI_SP; 790 break; 791 case ORC_REG_BP: 792 *base = CFI_BP; 793 break; 794 case ORC_REG_SP_INDIRECT: 795 *base = CFI_SP_INDIRECT; 796 break; 797 case ORC_REG_R10: 798 *base = CFI_R10; 799 break; 800 case ORC_REG_R13: 801 *base = CFI_R13; 802 break; 803 case ORC_REG_DI: 804 *base = CFI_DI; 805 break; 806 case ORC_REG_DX: 807 *base = CFI_DX; 808 break; 809 default: 810 return -1; 811 } 812 813 return 0; 814 } 815 816 bool arch_is_retpoline(struct symbol *sym) 817 { 818 return !strncmp(sym->name, "__x86_indirect_", 15); 819 } 820 821 bool arch_is_rethunk(struct symbol *sym) 822 { 823 return !strcmp(sym->name, "__x86_return_thunk"); 824 } 825