Lines Matching refs:cfi

12 #include <objtool/cfi.h>
265 static void init_cfi_state(struct cfi_state *cfi)
270 cfi->regs[i].base = CFI_UNDEFINED;
271 cfi->vals[i].base = CFI_UNDEFINED;
273 cfi->cfa.base = CFI_UNDEFINED;
274 cfi->drap_reg = CFI_UNDEFINED;
275 cfi->drap_offset = -1;
282 init_cfi_state(&state->cfi);
295 struct cfi_state *cfi = calloc(1, sizeof(struct cfi_state));
296 if (!cfi) {
301 return cfi;
314 static inline u32 cfi_key(struct cfi_state *cfi)
316 return jhash((void *)cfi + sizeof(cfi->hash),
317 sizeof(*cfi) - sizeof(cfi->hash), 0);
320 static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
322 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
326 if (!cficmp(cfi, obj)) {
333 *obj = *cfi;
339 static void cfi_hash_add(struct cfi_state *cfi)
341 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
343 hlist_add_head(&cfi->hash, head);
1763 orig_alt_group->cfi = calloc(special_alt->orig_len,
1765 if (!orig_alt_group->cfi) {
1885 new_alt_group->cfi = orig_alt_group->cfi;
2225 struct cfi_state cfi = init_cfi;
2276 insn->cfi = &force_undefined_cfi;
2302 insn->cfi = &func_cfi;
2306 if (insn->cfi)
2307 cfi = *(insn->cfi);
2309 if (arch_decode_hint_reg(hint->sp_reg, &cfi.cfa.base)) {
2314 cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset);
2315 cfi.type = hint->type;
2316 cfi.signal = hint->signal;
2318 insn->cfi = cfi_hash_find_or_add(&cfi);
2702 struct cfi_state *cfi = &state->cfi;
2705 if (cfi->cfa.base != initial_func_cfi.cfa.base || cfi->drap)
2708 if (cfi->cfa.offset != initial_func_cfi.cfa.offset)
2711 if (cfi->stack_size != initial_func_cfi.cfa.offset)
2715 if (cfi->regs[i].base != initial_func_cfi.regs[i].base ||
2716 cfi->regs[i].offset != initial_func_cfi.regs[i].offset)
2732 struct cfi_state *cfi = &state->cfi;
2734 if (cfi->cfa.base == CFI_BP &&
2735 check_reg_frame_pos(&cfi->regs[CFI_BP], -cfi->cfa.offset) &&
2736 check_reg_frame_pos(&cfi->regs[CFI_RA], -cfi->cfa.offset + 8))
2739 if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP)
2746 struct cfi_state *cfi,
2749 struct cfi_reg *cfa = &cfi->cfa;
2770 static void save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset)
2773 cfi->regs[reg].base == CFI_UNDEFINED) {
2774 cfi->regs[reg].base = base;
2775 cfi->regs[reg].offset = offset;
2779 static void restore_reg(struct cfi_state *cfi, unsigned char reg)
2781 cfi->regs[reg].base = initial_func_cfi.regs[reg].base;
2782 cfi->regs[reg].offset = initial_func_cfi.regs[reg].offset;
2840 struct cfi_state *cfi, struct stack_op *op)
2842 struct cfi_reg *cfa = &cfi->cfa;
2843 struct cfi_reg *regs = cfi->regs;
2846 if (cfi->force_undefined)
2858 if (cfi->type == UNWIND_HINT_TYPE_REGS ||
2859 cfi->type == UNWIND_HINT_TYPE_REGS_PARTIAL)
2860 return update_cfi_state_regs(insn, cfi, op);
2874 cfi->bp_scratch = false;
2878 op->dest.reg == CFI_BP && cfi->drap) {
2882 regs[CFI_BP].offset = -cfi->stack_size;
2883 cfi->bp_scratch = false;
2898 cfi->vals[op->dest.reg].base = CFI_CFA;
2899 cfi->vals[op->dest.reg].offset = -cfi->stack_size;
2903 (cfa->base == CFI_BP || cfa->base == cfi->drap_reg)) {
2910 cfi->stack_size = -cfi->regs[CFI_BP].offset;
2917 cfi->vals[op->src.reg].base == CFI_CFA) {
2927 cfa->offset = -cfi->vals[op->src.reg].offset;
2928 cfi->stack_size = cfa->offset;
2931 cfi->vals[op->src.reg].base == CFI_SP_INDIRECT &&
2932 cfi->vals[op->src.reg].offset == cfa->offset) {
2969 cfi->vals[op->src.reg].base == CFI_SP_INDIRECT &&
2970 cfi->vals[op->src.reg].offset == cfa->offset) {
2978 cfi->stack_size += 8;
2988 cfi->stack_size -= op->src.offset;
2997 cfi->stack_size = -(op->src.offset + regs[CFI_BP].offset);
3004 cfi->drap_reg = op->dest.reg;
3016 cfi->vals[op->dest.reg].base = CFI_CFA;
3017 cfi->vals[op->dest.reg].offset = \
3018 -cfi->stack_size + op->src.offset;
3023 if (cfi->drap && op->dest.reg == CFI_SP &&
3024 op->src.reg == cfi->drap_reg) {
3028 cfa->offset = cfi->stack_size = -op->src.offset;
3029 cfi->drap_reg = CFI_UNDEFINED;
3030 cfi->drap = false;
3034 if (op->dest.reg == cfi->cfa.base && !(next_insn && next_insn->hint)) {
3043 (cfi->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) ||
3044 (cfi->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) {
3049 if (cfi->drap_reg != CFI_UNDEFINED) {
3051 cfa->base = cfi->drap_reg;
3052 cfa->offset = cfi->stack_size = 0;
3053 cfi->drap = true;
3072 if (!cfi->drap && op->dest.reg == cfa->base) {
3078 if (cfi->drap && cfa->base == CFI_BP_INDIRECT &&
3079 op->dest.reg == cfi->drap_reg &&
3080 cfi->drap_offset == -cfi->stack_size) {
3083 cfa->base = cfi->drap_reg;
3085 cfi->drap_offset = -1;
3087 } else if (cfi->stack_size == -regs[op->dest.reg].offset) {
3090 restore_reg(cfi, op->dest.reg);
3093 cfi->stack_size -= 8;
3100 if (!cfi->drap && op->dest.reg == cfa->base &&
3105 cfa->offset = cfi->stack_size;
3108 if (cfi->drap && op->src.reg == CFI_BP &&
3109 op->src.offset == cfi->drap_offset) {
3112 cfa->base = cfi->drap_reg;
3114 cfi->drap_offset = -1;
3117 if (cfi->drap && op->src.reg == CFI_BP &&
3121 restore_reg(cfi, op->dest.reg);
3128 restore_reg(cfi, op->dest.reg);
3131 op->src.offset == regs[op->dest.reg].offset + cfi->stack_size) {
3134 restore_reg(cfi, op->dest.reg);
3148 cfi->stack_size += 8;
3155 if (cfi->drap) {
3156 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) {
3160 cfa->offset = -cfi->stack_size;
3163 cfi->drap_offset = -cfi->stack_size;
3165 } else if (op->src.reg == CFI_BP && cfa->base == cfi->drap_reg) {
3168 cfi->stack_size = 0;
3173 save_reg(cfi, op->src.reg, CFI_BP, -cfi->stack_size);
3179 save_reg(cfi, op->src.reg, CFI_CFA, -cfi->stack_size);
3185 cfi->bp_scratch = true;
3190 if (cfi->drap) {
3191 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) {
3198 cfi->drap_offset = op->dest.offset;
3202 save_reg(cfi, op->src.reg, CFI_BP, op->dest.offset);
3209 save_reg(cfi, op->src.reg, CFI_CFA,
3210 op->dest.offset - cfi->cfa.offset);
3215 save_reg(cfi, op->src.reg, CFI_CFA,
3216 op->dest.offset - cfi->stack_size);
3221 cfi->vals[op->dest.reg].base = CFI_SP_INDIRECT;
3222 cfi->vals[op->dest.reg].offset = cfa->offset;
3234 cfi->stack_size -= 8;
3265 if (!insn->cfi) {
3270 alt_cfi = insn->alt_group->cfi;
3274 alt_cfi[group_off] = insn->cfi;
3276 if (cficmp(alt_cfi[group_off], insn->cfi)) {
3297 if (update_cfi_state(insn, next_insn, &state->cfi, op))
3329 struct cfi_state *cfi1 = insn->cfi;
3528 if (state->cfi.bp_scratch) {
3607 if (!insn->hint && !insn_cfi_match(insn, &state.cfi))
3655 insn->cfi = save_insn->cfi;
3659 state.cfi = *insn->cfi;
3661 /* XXX track if we actually changed state.cfi */
3663 if (prev_insn && !cficmp(prev_insn->cfi, &state.cfi)) {
3664 insn->cfi = prev_insn->cfi;
3667 insn->cfi = cfi_hash_find_or_add(&state.cfi);
3809 if (state.cfi.cfa.base == CFI_UNDEFINED)
4151 struct cfi_state *cfi;
4180 if (!insn->cfi) {
4188 /* Propagate insn->cfi to the prefix code */
4189 cfi = cfi_hash_find_or_add(insn->cfi);
4191 prev->cfi = cfi;
4253 set_func_state(&state.cfi);
4794 if (opts.cfi) {