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