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