1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <objtool/check.h> 6 #include <objtool/elf.h> 7 #include <objtool/arch.h> 8 #include <objtool/warn.h> 9 #include <objtool/builtin.h> 10 11 int arch_ftrace_match(const char *name) 12 { 13 return !strcmp(name, "_mcount"); 14 } 15 16 s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *reloc) 17 { 18 return reloc_addend(reloc); 19 } 20 21 bool arch_callee_saved_reg(unsigned char reg) 22 { 23 return false; 24 } 25 26 int arch_decode_hint_reg(u8 sp_reg, int *base) 27 { 28 exit(-1); 29 } 30 31 const char *arch_nop_insn(int len) 32 { 33 exit(-1); 34 } 35 36 const char *arch_ret_insn(int len) 37 { 38 exit(-1); 39 } 40 41 int arch_decode_instruction(struct objtool_file *file, const struct section *sec, 42 unsigned long offset, unsigned int maxlen, 43 struct instruction *insn) 44 { 45 unsigned int opcode; 46 enum insn_type typ; 47 unsigned long imm; 48 u32 ins; 49 50 ins = bswap_if_needed(file->elf, *(u32 *)(sec->data->d_buf + offset)); 51 opcode = ins >> 26; 52 typ = INSN_OTHER; 53 imm = 0; 54 55 switch (opcode) { 56 case 18: /* b[l][a] */ 57 if (ins == 0x48000005) /* bl .+4 */ 58 typ = INSN_OTHER; 59 else if (ins & 1) /* bl[a] */ 60 typ = INSN_CALL; 61 else /* b[a] */ 62 typ = INSN_JUMP_UNCONDITIONAL; 63 64 imm = ins & 0x3fffffc; 65 if (imm & 0x2000000) 66 imm -= 0x4000000; 67 imm |= ins & 2; /* AA flag */ 68 break; 69 } 70 71 if (opcode == 1) 72 insn->len = 8; 73 else 74 insn->len = 4; 75 76 insn->type = typ; 77 insn->immediate = imm; 78 79 return 0; 80 } 81 82 unsigned long arch_jump_destination(struct instruction *insn) 83 { 84 if (insn->immediate & 2) 85 return insn->immediate & ~2; 86 87 return insn->offset + insn->immediate; 88 } 89 90 bool arch_pc_relative_reloc(struct reloc *reloc) 91 { 92 /* 93 * The powerpc build only allows certain relocation types, see 94 * relocs_check.sh, and none of those accepted are PC relative. 95 */ 96 return false; 97 } 98 99 void arch_initial_func_cfi_state(struct cfi_init_state *state) 100 { 101 int i; 102 103 for (i = 0; i < CFI_NUM_REGS; i++) { 104 state->regs[i].base = CFI_UNDEFINED; 105 state->regs[i].offset = 0; 106 } 107 108 /* initial CFA (call frame address) */ 109 state->cfa.base = CFI_SP; 110 state->cfa.offset = 0; 111 112 /* initial LR (return address) */ 113 state->regs[CFI_RA].base = CFI_CFA; 114 state->regs[CFI_RA].offset = 0; 115 } 116 117 unsigned int arch_reloc_size(struct reloc *reloc) 118 { 119 switch (reloc_type(reloc)) { 120 case R_PPC_REL32: 121 case R_PPC_ADDR32: 122 case R_PPC_UADDR32: 123 case R_PPC_PLT32: 124 case R_PPC_PLTREL32: 125 return 4; 126 default: 127 return 8; 128 } 129 } 130