Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
0004  */
0005 
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 
0009 #define unlikely(cond) (cond)
0010 #include <asm/insn.h>
0011 #include "../../../arch/x86/lib/inat.c"
0012 #include "../../../arch/x86/lib/insn.c"
0013 
0014 #define CONFIG_64BIT 1
0015 #include <asm/nops.h>
0016 
0017 #include <asm/orc_types.h>
0018 #include <objtool/check.h>
0019 #include <objtool/elf.h>
0020 #include <objtool/arch.h>
0021 #include <objtool/warn.h>
0022 #include <objtool/endianness.h>
0023 #include <objtool/builtin.h>
0024 #include <arch/elf.h>
0025 
0026 static int is_x86_64(const struct elf *elf)
0027 {
0028     switch (elf->ehdr.e_machine) {
0029     case EM_X86_64:
0030         return 1;
0031     case EM_386:
0032         return 0;
0033     default:
0034         WARN("unexpected ELF machine type %d", elf->ehdr.e_machine);
0035         return -1;
0036     }
0037 }
0038 
0039 bool arch_callee_saved_reg(unsigned char reg)
0040 {
0041     switch (reg) {
0042     case CFI_BP:
0043     case CFI_BX:
0044     case CFI_R12:
0045     case CFI_R13:
0046     case CFI_R14:
0047     case CFI_R15:
0048         return true;
0049 
0050     case CFI_AX:
0051     case CFI_CX:
0052     case CFI_DX:
0053     case CFI_SI:
0054     case CFI_DI:
0055     case CFI_SP:
0056     case CFI_R8:
0057     case CFI_R9:
0058     case CFI_R10:
0059     case CFI_R11:
0060     case CFI_RA:
0061     default:
0062         return false;
0063     }
0064 }
0065 
0066 unsigned long arch_dest_reloc_offset(int addend)
0067 {
0068     return addend + 4;
0069 }
0070 
0071 unsigned long arch_jump_destination(struct instruction *insn)
0072 {
0073     return insn->offset + insn->len + insn->immediate;
0074 }
0075 
0076 #define ADD_OP(op) \
0077     if (!(op = calloc(1, sizeof(*op)))) \
0078         return -1; \
0079     else for (list_add_tail(&op->list, ops_list); op; op = NULL)
0080 
0081 /*
0082  * Helpers to decode ModRM/SIB:
0083  *
0084  * r/m| AX  CX  DX  BX |  SP |  BP |  SI  DI |
0085  *    | R8  R9 R10 R11 | R12 | R13 | R14 R15 |
0086  * Mod+----------------+-----+-----+---------+
0087  * 00 |    [r/m]       |[SIB]|[IP+]|  [r/m]  |
0088  * 01 |  [r/m + d8]    |[S+d]|   [r/m + d8]  |
0089  * 10 |  [r/m + d32]   |[S+D]|   [r/m + d32] |
0090  * 11 |                   r/ m               |
0091  */
0092 
0093 #define mod_is_mem()    (modrm_mod != 3)
0094 #define mod_is_reg()    (modrm_mod == 3)
0095 
0096 #define is_RIP()   ((modrm_rm & 7) == CFI_BP && modrm_mod == 0)
0097 #define have_SIB() ((modrm_rm & 7) == CFI_SP && mod_is_mem())
0098 
0099 #define rm_is(reg) (have_SIB() ? \
0100             sib_base == (reg) && sib_index == CFI_SP : \
0101             modrm_rm == (reg))
0102 
0103 #define rm_is_mem(reg)  (mod_is_mem() && !is_RIP() && rm_is(reg))
0104 #define rm_is_reg(reg)  (mod_is_reg() && modrm_rm == (reg))
0105 
0106 static bool has_notrack_prefix(struct insn *insn)
0107 {
0108     int i;
0109 
0110     for (i = 0; i < insn->prefixes.nbytes; i++) {
0111         if (insn->prefixes.bytes[i] == 0x3e)
0112             return true;
0113     }
0114 
0115     return false;
0116 }
0117 
0118 int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
0119                 unsigned long offset, unsigned int maxlen,
0120                 unsigned int *len, enum insn_type *type,
0121                 unsigned long *immediate,
0122                 struct list_head *ops_list)
0123 {
0124     const struct elf *elf = file->elf;
0125     struct insn insn;
0126     int x86_64, ret;
0127     unsigned char op1, op2, op3, prefix,
0128               rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, rex_x = 0,
0129               modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0,
0130               sib = 0, /* sib_scale = 0, */ sib_index = 0, sib_base = 0;
0131     struct stack_op *op = NULL;
0132     struct symbol *sym;
0133     u64 imm;
0134 
0135     x86_64 = is_x86_64(elf);
0136     if (x86_64 == -1)
0137         return -1;
0138 
0139     ret = insn_decode(&insn, sec->data->d_buf + offset, maxlen,
0140               x86_64 ? INSN_MODE_64 : INSN_MODE_32);
0141     if (ret < 0) {
0142         WARN("can't decode instruction at %s:0x%lx", sec->name, offset);
0143         return -1;
0144     }
0145 
0146     *len = insn.length;
0147     *type = INSN_OTHER;
0148 
0149     if (insn.vex_prefix.nbytes)
0150         return 0;
0151 
0152     prefix = insn.prefixes.bytes[0];
0153 
0154     op1 = insn.opcode.bytes[0];
0155     op2 = insn.opcode.bytes[1];
0156     op3 = insn.opcode.bytes[2];
0157 
0158     if (insn.rex_prefix.nbytes) {
0159         rex = insn.rex_prefix.bytes[0];
0160         rex_w = X86_REX_W(rex) >> 3;
0161         rex_r = X86_REX_R(rex) >> 2;
0162         rex_x = X86_REX_X(rex) >> 1;
0163         rex_b = X86_REX_B(rex);
0164     }
0165 
0166     if (insn.modrm.nbytes) {
0167         modrm = insn.modrm.bytes[0];
0168         modrm_mod = X86_MODRM_MOD(modrm);
0169         modrm_reg = X86_MODRM_REG(modrm) + 8*rex_r;
0170         modrm_rm  = X86_MODRM_RM(modrm)  + 8*rex_b;
0171     }
0172 
0173     if (insn.sib.nbytes) {
0174         sib = insn.sib.bytes[0];
0175         /* sib_scale = X86_SIB_SCALE(sib); */
0176         sib_index = X86_SIB_INDEX(sib) + 8*rex_x;
0177         sib_base  = X86_SIB_BASE(sib)  + 8*rex_b;
0178     }
0179 
0180     switch (op1) {
0181 
0182     case 0x1:
0183     case 0x29:
0184         if (rex_w && rm_is_reg(CFI_SP)) {
0185 
0186             /* add/sub reg, %rsp */
0187             ADD_OP(op) {
0188                 op->src.type = OP_SRC_ADD;
0189                 op->src.reg = modrm_reg;
0190                 op->dest.type = OP_DEST_REG;
0191                 op->dest.reg = CFI_SP;
0192             }
0193         }
0194         break;
0195 
0196     case 0x50 ... 0x57:
0197 
0198         /* push reg */
0199         ADD_OP(op) {
0200             op->src.type = OP_SRC_REG;
0201             op->src.reg = (op1 & 0x7) + 8*rex_b;
0202             op->dest.type = OP_DEST_PUSH;
0203         }
0204 
0205         break;
0206 
0207     case 0x58 ... 0x5f:
0208 
0209         /* pop reg */
0210         ADD_OP(op) {
0211             op->src.type = OP_SRC_POP;
0212             op->dest.type = OP_DEST_REG;
0213             op->dest.reg = (op1 & 0x7) + 8*rex_b;
0214         }
0215 
0216         break;
0217 
0218     case 0x68:
0219     case 0x6a:
0220         /* push immediate */
0221         ADD_OP(op) {
0222             op->src.type = OP_SRC_CONST;
0223             op->dest.type = OP_DEST_PUSH;
0224         }
0225         break;
0226 
0227     case 0x70 ... 0x7f:
0228         *type = INSN_JUMP_CONDITIONAL;
0229         break;
0230 
0231     case 0x80 ... 0x83:
0232         /*
0233          * 1000 00sw : mod OP r/m : immediate
0234          *
0235          * s - sign extend immediate
0236          * w - imm8 / imm32
0237          *
0238          * OP: 000 ADD    100 AND
0239          *     001 OR     101 SUB
0240          *     010 ADC    110 XOR
0241          *     011 SBB    111 CMP
0242          */
0243 
0244         /* 64bit only */
0245         if (!rex_w)
0246             break;
0247 
0248         /* %rsp target only */
0249         if (!rm_is_reg(CFI_SP))
0250             break;
0251 
0252         imm = insn.immediate.value;
0253         if (op1 & 2) { /* sign extend */
0254             if (op1 & 1) { /* imm32 */
0255                 imm <<= 32;
0256                 imm = (s64)imm >> 32;
0257             } else { /* imm8 */
0258                 imm <<= 56;
0259                 imm = (s64)imm >> 56;
0260             }
0261         }
0262 
0263         switch (modrm_reg & 7) {
0264         case 5:
0265             imm = -imm;
0266             /* fallthrough */
0267         case 0:
0268             /* add/sub imm, %rsp */
0269             ADD_OP(op) {
0270                 op->src.type = OP_SRC_ADD;
0271                 op->src.reg = CFI_SP;
0272                 op->src.offset = imm;
0273                 op->dest.type = OP_DEST_REG;
0274                 op->dest.reg = CFI_SP;
0275             }
0276             break;
0277 
0278         case 4:
0279             /* and imm, %rsp */
0280             ADD_OP(op) {
0281                 op->src.type = OP_SRC_AND;
0282                 op->src.reg = CFI_SP;
0283                 op->src.offset = insn.immediate.value;
0284                 op->dest.type = OP_DEST_REG;
0285                 op->dest.reg = CFI_SP;
0286             }
0287             break;
0288 
0289         default:
0290             /* WARN ? */
0291             break;
0292         }
0293 
0294         break;
0295 
0296     case 0x89:
0297         if (!rex_w)
0298             break;
0299 
0300         if (modrm_reg == CFI_SP) {
0301 
0302             if (mod_is_reg()) {
0303                 /* mov %rsp, reg */
0304                 ADD_OP(op) {
0305                     op->src.type = OP_SRC_REG;
0306                     op->src.reg = CFI_SP;
0307                     op->dest.type = OP_DEST_REG;
0308                     op->dest.reg = modrm_rm;
0309                 }
0310                 break;
0311 
0312             } else {
0313                 /* skip RIP relative displacement */
0314                 if (is_RIP())
0315                     break;
0316 
0317                 /* skip nontrivial SIB */
0318                 if (have_SIB()) {
0319                     modrm_rm = sib_base;
0320                     if (sib_index != CFI_SP)
0321                         break;
0322                 }
0323 
0324                 /* mov %rsp, disp(%reg) */
0325                 ADD_OP(op) {
0326                     op->src.type = OP_SRC_REG;
0327                     op->src.reg = CFI_SP;
0328                     op->dest.type = OP_DEST_REG_INDIRECT;
0329                     op->dest.reg = modrm_rm;
0330                     op->dest.offset = insn.displacement.value;
0331                 }
0332                 break;
0333             }
0334 
0335             break;
0336         }
0337 
0338         if (rm_is_reg(CFI_SP)) {
0339 
0340             /* mov reg, %rsp */
0341             ADD_OP(op) {
0342                 op->src.type = OP_SRC_REG;
0343                 op->src.reg = modrm_reg;
0344                 op->dest.type = OP_DEST_REG;
0345                 op->dest.reg = CFI_SP;
0346             }
0347             break;
0348         }
0349 
0350         /* fallthrough */
0351     case 0x88:
0352         if (!rex_w)
0353             break;
0354 
0355         if (rm_is_mem(CFI_BP)) {
0356 
0357             /* mov reg, disp(%rbp) */
0358             ADD_OP(op) {
0359                 op->src.type = OP_SRC_REG;
0360                 op->src.reg = modrm_reg;
0361                 op->dest.type = OP_DEST_REG_INDIRECT;
0362                 op->dest.reg = CFI_BP;
0363                 op->dest.offset = insn.displacement.value;
0364             }
0365             break;
0366         }
0367 
0368         if (rm_is_mem(CFI_SP)) {
0369 
0370             /* mov reg, disp(%rsp) */
0371             ADD_OP(op) {
0372                 op->src.type = OP_SRC_REG;
0373                 op->src.reg = modrm_reg;
0374                 op->dest.type = OP_DEST_REG_INDIRECT;
0375                 op->dest.reg = CFI_SP;
0376                 op->dest.offset = insn.displacement.value;
0377             }
0378             break;
0379         }
0380 
0381         break;
0382 
0383     case 0x8b:
0384         if (!rex_w)
0385             break;
0386 
0387         if (rm_is_mem(CFI_BP)) {
0388 
0389             /* mov disp(%rbp), reg */
0390             ADD_OP(op) {
0391                 op->src.type = OP_SRC_REG_INDIRECT;
0392                 op->src.reg = CFI_BP;
0393                 op->src.offset = insn.displacement.value;
0394                 op->dest.type = OP_DEST_REG;
0395                 op->dest.reg = modrm_reg;
0396             }
0397             break;
0398         }
0399 
0400         if (rm_is_mem(CFI_SP)) {
0401 
0402             /* mov disp(%rsp), reg */
0403             ADD_OP(op) {
0404                 op->src.type = OP_SRC_REG_INDIRECT;
0405                 op->src.reg = CFI_SP;
0406                 op->src.offset = insn.displacement.value;
0407                 op->dest.type = OP_DEST_REG;
0408                 op->dest.reg = modrm_reg;
0409             }
0410             break;
0411         }
0412 
0413         break;
0414 
0415     case 0x8d:
0416         if (mod_is_reg()) {
0417             WARN("invalid LEA encoding at %s:0x%lx", sec->name, offset);
0418             break;
0419         }
0420 
0421         /* skip non 64bit ops */
0422         if (!rex_w)
0423             break;
0424 
0425         /* skip RIP relative displacement */
0426         if (is_RIP())
0427             break;
0428 
0429         /* skip nontrivial SIB */
0430         if (have_SIB()) {
0431             modrm_rm = sib_base;
0432             if (sib_index != CFI_SP)
0433                 break;
0434         }
0435 
0436         /* lea disp(%src), %dst */
0437         ADD_OP(op) {
0438             op->src.offset = insn.displacement.value;
0439             if (!op->src.offset) {
0440                 /* lea (%src), %dst */
0441                 op->src.type = OP_SRC_REG;
0442             } else {
0443                 /* lea disp(%src), %dst */
0444                 op->src.type = OP_SRC_ADD;
0445             }
0446             op->src.reg = modrm_rm;
0447             op->dest.type = OP_DEST_REG;
0448             op->dest.reg = modrm_reg;
0449         }
0450         break;
0451 
0452     case 0x8f:
0453         /* pop to mem */
0454         ADD_OP(op) {
0455             op->src.type = OP_SRC_POP;
0456             op->dest.type = OP_DEST_MEM;
0457         }
0458         break;
0459 
0460     case 0x90:
0461         *type = INSN_NOP;
0462         break;
0463 
0464     case 0x9c:
0465         /* pushf */
0466         ADD_OP(op) {
0467             op->src.type = OP_SRC_CONST;
0468             op->dest.type = OP_DEST_PUSHF;
0469         }
0470         break;
0471 
0472     case 0x9d:
0473         /* popf */
0474         ADD_OP(op) {
0475             op->src.type = OP_SRC_POPF;
0476             op->dest.type = OP_DEST_MEM;
0477         }
0478         break;
0479 
0480     case 0x0f:
0481 
0482         if (op2 == 0x01) {
0483 
0484             if (modrm == 0xca)
0485                 *type = INSN_CLAC;
0486             else if (modrm == 0xcb)
0487                 *type = INSN_STAC;
0488 
0489         } else if (op2 >= 0x80 && op2 <= 0x8f) {
0490 
0491             *type = INSN_JUMP_CONDITIONAL;
0492 
0493         } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
0494                op2 == 0x35) {
0495 
0496             /* sysenter, sysret */
0497             *type = INSN_CONTEXT_SWITCH;
0498 
0499         } else if (op2 == 0x0b || op2 == 0xb9) {
0500 
0501             /* ud2 */
0502             *type = INSN_BUG;
0503 
0504         } else if (op2 == 0x0d || op2 == 0x1f) {
0505 
0506             /* nopl/nopw */
0507             *type = INSN_NOP;
0508 
0509         } else if (op2 == 0x1e) {
0510 
0511             if (prefix == 0xf3 && (modrm == 0xfa || modrm == 0xfb))
0512                 *type = INSN_ENDBR;
0513 
0514 
0515         } else if (op2 == 0x38 && op3 == 0xf8) {
0516             if (insn.prefixes.nbytes == 1 &&
0517                 insn.prefixes.bytes[0] == 0xf2) {
0518                 /* ENQCMD cannot be used in the kernel. */
0519                 WARN("ENQCMD instruction at %s:%lx", sec->name,
0520                      offset);
0521             }
0522 
0523         } else if (op2 == 0xa0 || op2 == 0xa8) {
0524 
0525             /* push fs/gs */
0526             ADD_OP(op) {
0527                 op->src.type = OP_SRC_CONST;
0528                 op->dest.type = OP_DEST_PUSH;
0529             }
0530 
0531         } else if (op2 == 0xa1 || op2 == 0xa9) {
0532 
0533             /* pop fs/gs */
0534             ADD_OP(op) {
0535                 op->src.type = OP_SRC_POP;
0536                 op->dest.type = OP_DEST_MEM;
0537             }
0538         }
0539 
0540         break;
0541 
0542     case 0xc9:
0543         /*
0544          * leave
0545          *
0546          * equivalent to:
0547          * mov bp, sp
0548          * pop bp
0549          */
0550         ADD_OP(op) {
0551             op->src.type = OP_SRC_REG;
0552             op->src.reg = CFI_BP;
0553             op->dest.type = OP_DEST_REG;
0554             op->dest.reg = CFI_SP;
0555         }
0556         ADD_OP(op) {
0557             op->src.type = OP_SRC_POP;
0558             op->dest.type = OP_DEST_REG;
0559             op->dest.reg = CFI_BP;
0560         }
0561         break;
0562 
0563     case 0xcc:
0564         /* int3 */
0565         *type = INSN_TRAP;
0566         break;
0567 
0568     case 0xe3:
0569         /* jecxz/jrcxz */
0570         *type = INSN_JUMP_CONDITIONAL;
0571         break;
0572 
0573     case 0xe9:
0574     case 0xeb:
0575         *type = INSN_JUMP_UNCONDITIONAL;
0576         break;
0577 
0578     case 0xc2:
0579     case 0xc3:
0580         *type = INSN_RETURN;
0581         break;
0582 
0583     case 0xc7: /* mov imm, r/m */
0584         if (!opts.noinstr)
0585             break;
0586 
0587         if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) {
0588             struct reloc *immr, *disp;
0589             struct symbol *func;
0590             int idx;
0591 
0592             immr = find_reloc_by_dest(elf, (void *)sec, offset+3);
0593             disp = find_reloc_by_dest(elf, (void *)sec, offset+7);
0594 
0595             if (!immr || strcmp(immr->sym->name, "pv_ops"))
0596                 break;
0597 
0598             idx = (immr->addend + 8) / sizeof(void *);
0599 
0600             func = disp->sym;
0601             if (disp->sym->type == STT_SECTION)
0602                 func = find_symbol_by_offset(disp->sym->sec, disp->addend);
0603             if (!func) {
0604                 WARN("no func for pv_ops[]");
0605                 return -1;
0606             }
0607 
0608             objtool_pv_add(file, idx, func);
0609         }
0610 
0611         break;
0612 
0613     case 0xcf: /* iret */
0614         /*
0615          * Handle sync_core(), which has an IRET to self.
0616          * All other IRET are in STT_NONE entry code.
0617          */
0618         sym = find_symbol_containing(sec, offset);
0619         if (sym && sym->type == STT_FUNC) {
0620             ADD_OP(op) {
0621                 /* add $40, %rsp */
0622                 op->src.type = OP_SRC_ADD;
0623                 op->src.reg = CFI_SP;
0624                 op->src.offset = 5*8;
0625                 op->dest.type = OP_DEST_REG;
0626                 op->dest.reg = CFI_SP;
0627             }
0628             break;
0629         }
0630 
0631         /* fallthrough */
0632 
0633     case 0xca: /* retf */
0634     case 0xcb: /* retf */
0635         *type = INSN_CONTEXT_SWITCH;
0636         break;
0637 
0638     case 0xe8:
0639         *type = INSN_CALL;
0640         /*
0641          * For the impact on the stack, a CALL behaves like
0642          * a PUSH of an immediate value (the return address).
0643          */
0644         ADD_OP(op) {
0645             op->src.type = OP_SRC_CONST;
0646             op->dest.type = OP_DEST_PUSH;
0647         }
0648         break;
0649 
0650     case 0xfc:
0651         *type = INSN_CLD;
0652         break;
0653 
0654     case 0xfd:
0655         *type = INSN_STD;
0656         break;
0657 
0658     case 0xff:
0659         if (modrm_reg == 2 || modrm_reg == 3) {
0660 
0661             *type = INSN_CALL_DYNAMIC;
0662             if (has_notrack_prefix(&insn))
0663                 WARN("notrack prefix found at %s:0x%lx", sec->name, offset);
0664 
0665         } else if (modrm_reg == 4) {
0666 
0667             *type = INSN_JUMP_DYNAMIC;
0668             if (has_notrack_prefix(&insn))
0669                 WARN("notrack prefix found at %s:0x%lx", sec->name, offset);
0670 
0671         } else if (modrm_reg == 5) {
0672 
0673             /* jmpf */
0674             *type = INSN_CONTEXT_SWITCH;
0675 
0676         } else if (modrm_reg == 6) {
0677 
0678             /* push from mem */
0679             ADD_OP(op) {
0680                 op->src.type = OP_SRC_CONST;
0681                 op->dest.type = OP_DEST_PUSH;
0682             }
0683         }
0684 
0685         break;
0686 
0687     default:
0688         break;
0689     }
0690 
0691     *immediate = insn.immediate.nbytes ? insn.immediate.value : 0;
0692 
0693     return 0;
0694 }
0695 
0696 void arch_initial_func_cfi_state(struct cfi_init_state *state)
0697 {
0698     int i;
0699 
0700     for (i = 0; i < CFI_NUM_REGS; i++) {
0701         state->regs[i].base = CFI_UNDEFINED;
0702         state->regs[i].offset = 0;
0703     }
0704 
0705     /* initial CFA (call frame address) */
0706     state->cfa.base = CFI_SP;
0707     state->cfa.offset = 8;
0708 
0709     /* initial RA (return address) */
0710     state->regs[CFI_RA].base = CFI_CFA;
0711     state->regs[CFI_RA].offset = -8;
0712 }
0713 
0714 const char *arch_nop_insn(int len)
0715 {
0716     static const char nops[5][5] = {
0717         { BYTES_NOP1 },
0718         { BYTES_NOP2 },
0719         { BYTES_NOP3 },
0720         { BYTES_NOP4 },
0721         { BYTES_NOP5 },
0722     };
0723 
0724     if (len < 1 || len > 5) {
0725         WARN("invalid NOP size: %d\n", len);
0726         return NULL;
0727     }
0728 
0729     return nops[len-1];
0730 }
0731 
0732 #define BYTE_RET    0xC3
0733 
0734 const char *arch_ret_insn(int len)
0735 {
0736     static const char ret[5][5] = {
0737         { BYTE_RET },
0738         { BYTE_RET, 0xcc },
0739         { BYTE_RET, 0xcc, BYTES_NOP1 },
0740         { BYTE_RET, 0xcc, BYTES_NOP2 },
0741         { BYTE_RET, 0xcc, BYTES_NOP3 },
0742     };
0743 
0744     if (len < 1 || len > 5) {
0745         WARN("invalid RET size: %d\n", len);
0746         return NULL;
0747     }
0748 
0749     return ret[len-1];
0750 }
0751 
0752 int arch_decode_hint_reg(u8 sp_reg, int *base)
0753 {
0754     switch (sp_reg) {
0755     case ORC_REG_UNDEFINED:
0756         *base = CFI_UNDEFINED;
0757         break;
0758     case ORC_REG_SP:
0759         *base = CFI_SP;
0760         break;
0761     case ORC_REG_BP:
0762         *base = CFI_BP;
0763         break;
0764     case ORC_REG_SP_INDIRECT:
0765         *base = CFI_SP_INDIRECT;
0766         break;
0767     case ORC_REG_R10:
0768         *base = CFI_R10;
0769         break;
0770     case ORC_REG_R13:
0771         *base = CFI_R13;
0772         break;
0773     case ORC_REG_DI:
0774         *base = CFI_DI;
0775         break;
0776     case ORC_REG_DX:
0777         *base = CFI_DX;
0778         break;
0779     default:
0780         return -1;
0781     }
0782 
0783     return 0;
0784 }
0785 
0786 bool arch_is_retpoline(struct symbol *sym)
0787 {
0788     return !strncmp(sym->name, "__x86_indirect_", 15);
0789 }
0790 
0791 bool arch_is_rethunk(struct symbol *sym)
0792 {
0793     return !strcmp(sym->name, "__x86_return_thunk");
0794 }