1 // SPDX-License-Identifier: GPL-2.0-or-later 2 #include <linux/objtool_types.h> 3 #include <asm/orc_types.h> 4 5 #include <objtool/check.h> 6 #include <objtool/orc.h> 7 #include <objtool/warn.h> 8 9 int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn) 10 { 11 struct cfi_reg *bp = &cfi->regs[CFI_BP]; 12 13 memset(orc, 0, sizeof(*orc)); 14 15 if (!cfi) { 16 /* 17 * This is usually either unreachable nops/traps (which don't 18 * trigger unreachable instruction warnings), or 19 * STACK_FRAME_NON_STANDARD functions. 20 */ 21 orc->type = ORC_TYPE_UNDEFINED; 22 return 0; 23 } 24 25 switch (cfi->type) { 26 case UNWIND_HINT_TYPE_UNDEFINED: 27 orc->type = ORC_TYPE_UNDEFINED; 28 return 0; 29 case UNWIND_HINT_TYPE_END_OF_STACK: 30 orc->type = ORC_TYPE_END_OF_STACK; 31 return 0; 32 case UNWIND_HINT_TYPE_CALL: 33 orc->type = ORC_TYPE_CALL; 34 break; 35 case UNWIND_HINT_TYPE_REGS: 36 orc->type = ORC_TYPE_REGS; 37 break; 38 case UNWIND_HINT_TYPE_REGS_PARTIAL: 39 orc->type = ORC_TYPE_REGS_PARTIAL; 40 break; 41 default: 42 ERROR_INSN(insn, "unknown unwind hint type %d", cfi->type); 43 return -1; 44 } 45 46 orc->signal = cfi->signal; 47 48 switch (cfi->cfa.base) { 49 case CFI_SP: 50 orc->sp_reg = ORC_REG_SP; 51 break; 52 case CFI_SP_INDIRECT: 53 orc->sp_reg = ORC_REG_SP_INDIRECT; 54 break; 55 case CFI_BP: 56 orc->sp_reg = ORC_REG_BP; 57 break; 58 case CFI_BP_INDIRECT: 59 orc->sp_reg = ORC_REG_BP_INDIRECT; 60 break; 61 case CFI_R10: 62 orc->sp_reg = ORC_REG_R10; 63 break; 64 case CFI_R13: 65 orc->sp_reg = ORC_REG_R13; 66 break; 67 case CFI_DI: 68 orc->sp_reg = ORC_REG_DI; 69 break; 70 case CFI_DX: 71 orc->sp_reg = ORC_REG_DX; 72 break; 73 default: 74 ERROR_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base); 75 return -1; 76 } 77 78 switch (bp->base) { 79 case CFI_UNDEFINED: 80 orc->bp_reg = ORC_REG_UNDEFINED; 81 break; 82 case CFI_CFA: 83 orc->bp_reg = ORC_REG_PREV_SP; 84 break; 85 case CFI_BP: 86 orc->bp_reg = ORC_REG_BP; 87 break; 88 default: 89 ERROR_INSN(insn, "unknown BP base reg %d", bp->base); 90 return -1; 91 } 92 93 orc->sp_offset = cfi->cfa.offset; 94 orc->bp_offset = bp->offset; 95 96 return 0; 97 } 98 99 int write_orc_entry(struct elf *elf, struct section *orc_sec, 100 struct section *ip_sec, unsigned int idx, 101 struct section *insn_sec, unsigned long insn_off, 102 struct orc_entry *o) 103 { 104 struct orc_entry *orc; 105 106 /* populate ORC data */ 107 orc = (struct orc_entry *)orc_sec->data->d_buf + idx; 108 memcpy(orc, o, sizeof(*orc)); 109 orc->sp_offset = bswap_if_needed(elf, orc->sp_offset); 110 orc->bp_offset = bswap_if_needed(elf, orc->bp_offset); 111 112 /* populate reloc for ip */ 113 if (!elf_init_reloc_text_sym(elf, ip_sec, idx * sizeof(int), idx, 114 insn_sec, insn_off)) 115 return -1; 116 117 return 0; 118 } 119 120 static const char *reg_name(unsigned int reg) 121 { 122 switch (reg) { 123 case ORC_REG_PREV_SP: 124 return "prevsp"; 125 case ORC_REG_DX: 126 return "dx"; 127 case ORC_REG_DI: 128 return "di"; 129 case ORC_REG_BP: 130 return "bp"; 131 case ORC_REG_SP: 132 return "sp"; 133 case ORC_REG_R10: 134 return "r10"; 135 case ORC_REG_R13: 136 return "r13"; 137 case ORC_REG_BP_INDIRECT: 138 return "bp(ind)"; 139 case ORC_REG_SP_INDIRECT: 140 return "sp(ind)"; 141 default: 142 return "?"; 143 } 144 } 145 146 static const char *orc_type_name(unsigned int type) 147 { 148 switch (type) { 149 case ORC_TYPE_UNDEFINED: 150 return "(und)"; 151 case ORC_TYPE_END_OF_STACK: 152 return "end"; 153 case ORC_TYPE_CALL: 154 return "call"; 155 case ORC_TYPE_REGS: 156 return "regs"; 157 case ORC_TYPE_REGS_PARTIAL: 158 return "regs (partial)"; 159 default: 160 return "?"; 161 } 162 } 163 164 static void print_reg(unsigned int reg, int offset) 165 { 166 if (reg == ORC_REG_BP_INDIRECT) 167 printf("(bp%+d)", offset); 168 else if (reg == ORC_REG_SP_INDIRECT) 169 printf("(sp)%+d", offset); 170 else if (reg == ORC_REG_UNDEFINED) 171 printf("(und)"); 172 else 173 printf("%s%+d", reg_name(reg), offset); 174 } 175 176 void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i) 177 { 178 printf("type:%s", orc_type_name(orc[i].type)); 179 180 printf(" sp:"); 181 print_reg(orc[i].sp_reg, bswap_if_needed(dummy_elf, orc[i].sp_offset)); 182 183 printf(" bp:"); 184 print_reg(orc[i].bp_reg, bswap_if_needed(dummy_elf, orc[i].bp_offset)); 185 186 printf(" signal:%d\n", orc[i].signal); 187 } 188