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