Lines Matching refs:cfi

328 static void init_cfi_state(struct cfi_state *cfi)  in init_cfi_state()  argument
333 cfi->regs[i].base = CFI_UNDEFINED; in init_cfi_state()
334 cfi->vals[i].base = CFI_UNDEFINED; in init_cfi_state()
336 cfi->cfa.base = CFI_UNDEFINED; in init_cfi_state()
337 cfi->drap_reg = CFI_UNDEFINED; in init_cfi_state()
338 cfi->drap_offset = -1; in init_cfi_state()
345 init_cfi_state(&state->cfi); in init_insn_state()
353 struct cfi_state *cfi = calloc(1, sizeof(struct cfi_state)); in cfi_alloc() local
354 if (!cfi) { in cfi_alloc()
359 return cfi; in cfi_alloc()
372 static inline u32 cfi_key(struct cfi_state *cfi) in cfi_key() argument
374 return jhash((void *)cfi + sizeof(cfi->hash), in cfi_key()
375 sizeof(*cfi) - sizeof(cfi->hash), 0); in cfi_key()
378 static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi) in cfi_hash_find_or_add() argument
380 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)]; in cfi_hash_find_or_add()
384 if (!cficmp(cfi, obj)) { in cfi_hash_find_or_add()
391 *obj = *cfi; in cfi_hash_find_or_add()
397 static void cfi_hash_add(struct cfi_state *cfi) in cfi_hash_add() argument
399 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)]; in cfi_hash_add()
401 hlist_add_head(&cfi->hash, head); in cfi_hash_add()
1727 orig_alt_group->cfi = calloc(special_alt->orig_len, in handle_group_alt()
1729 if (!orig_alt_group->cfi) { in handle_group_alt()
1849 new_alt_group->cfi = orig_alt_group->cfi; in handle_group_alt()
2195 struct cfi_state cfi = init_cfi; in read_unwind_hints() local
2246 insn->cfi = &force_undefined_cfi; in read_unwind_hints()
2273 insn->cfi = &func_cfi; in read_unwind_hints()
2277 if (insn->cfi) in read_unwind_hints()
2278 cfi = *(insn->cfi); in read_unwind_hints()
2280 if (arch_decode_hint_reg(hint->sp_reg, &cfi.cfa.base)) { in read_unwind_hints()
2285 cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset); in read_unwind_hints()
2286 cfi.type = hint->type; in read_unwind_hints()
2287 cfi.signal = hint->signal; in read_unwind_hints()
2289 insn->cfi = cfi_hash_find_or_add(&cfi); in read_unwind_hints()
2623 struct cfi_state *cfi = &state->cfi; in has_modified_stack_frame() local
2626 if (cfi->cfa.base != initial_func_cfi.cfa.base || cfi->drap) in has_modified_stack_frame()
2629 if (cfi->cfa.offset != initial_func_cfi.cfa.offset) in has_modified_stack_frame()
2632 if (cfi->stack_size != initial_func_cfi.cfa.offset) in has_modified_stack_frame()
2636 if (cfi->regs[i].base != initial_func_cfi.regs[i].base || in has_modified_stack_frame()
2637 cfi->regs[i].offset != initial_func_cfi.regs[i].offset) in has_modified_stack_frame()
2653 struct cfi_state *cfi = &state->cfi; in has_valid_stack_frame() local
2655 if (cfi->cfa.base == CFI_BP && in has_valid_stack_frame()
2656 check_reg_frame_pos(&cfi->regs[CFI_BP], -cfi->cfa.offset) && in has_valid_stack_frame()
2657 check_reg_frame_pos(&cfi->regs[CFI_RA], -cfi->cfa.offset + 8)) in has_valid_stack_frame()
2660 if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP) in has_valid_stack_frame()
2667 struct cfi_state *cfi, in update_cfi_state_regs() argument
2670 struct cfi_reg *cfa = &cfi->cfa; in update_cfi_state_regs()
2691 static void save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset) in save_reg() argument
2694 cfi->regs[reg].base == CFI_UNDEFINED) { in save_reg()
2695 cfi->regs[reg].base = base; in save_reg()
2696 cfi->regs[reg].offset = offset; in save_reg()
2700 static void restore_reg(struct cfi_state *cfi, unsigned char reg) in restore_reg() argument
2702 cfi->regs[reg].base = initial_func_cfi.regs[reg].base; in restore_reg()
2703 cfi->regs[reg].offset = initial_func_cfi.regs[reg].offset; in restore_reg()
2761 struct cfi_state *cfi, struct stack_op *op) in update_cfi_state() argument
2763 struct cfi_reg *cfa = &cfi->cfa; in update_cfi_state()
2764 struct cfi_reg *regs = cfi->regs; in update_cfi_state()
2767 if (cfi->force_undefined) in update_cfi_state()
2779 if (cfi->type == UNWIND_HINT_TYPE_REGS || in update_cfi_state()
2780 cfi->type == UNWIND_HINT_TYPE_REGS_PARTIAL) in update_cfi_state()
2781 return update_cfi_state_regs(insn, cfi, op); in update_cfi_state()
2795 cfi->bp_scratch = false; in update_cfi_state()
2799 op->dest.reg == CFI_BP && cfi->drap) { in update_cfi_state()
2803 regs[CFI_BP].offset = -cfi->stack_size; in update_cfi_state()
2804 cfi->bp_scratch = false; in update_cfi_state()
2819 cfi->vals[op->dest.reg].base = CFI_CFA; in update_cfi_state()
2820 cfi->vals[op->dest.reg].offset = -cfi->stack_size; in update_cfi_state()
2824 (cfa->base == CFI_BP || cfa->base == cfi->drap_reg)) { in update_cfi_state()
2831 cfi->stack_size = -cfi->regs[CFI_BP].offset; in update_cfi_state()
2838 cfi->vals[op->src.reg].base == CFI_CFA) { in update_cfi_state()
2848 cfa->offset = -cfi->vals[op->src.reg].offset; in update_cfi_state()
2849 cfi->stack_size = cfa->offset; in update_cfi_state()
2852 cfi->vals[op->src.reg].base == CFI_SP_INDIRECT && in update_cfi_state()
2853 cfi->vals[op->src.reg].offset == cfa->offset) { in update_cfi_state()
2890 cfi->vals[op->src.reg].base == CFI_SP_INDIRECT && in update_cfi_state()
2891 cfi->vals[op->src.reg].offset == cfa->offset) { in update_cfi_state()
2899 cfi->stack_size += 8; in update_cfi_state()
2909 cfi->stack_size -= op->src.offset; in update_cfi_state()
2934 cfi->stack_size = -(op->src.offset + regs[CFI_BP].offset); in update_cfi_state()
2942 cfi->drap_reg = op->dest.reg; in update_cfi_state()
2954 cfi->vals[op->dest.reg].base = CFI_CFA; in update_cfi_state()
2955 cfi->vals[op->dest.reg].offset = \ in update_cfi_state()
2956 -cfi->stack_size + op->src.offset; in update_cfi_state()
2961 if (cfi->drap && op->dest.reg == CFI_SP && in update_cfi_state()
2962 op->src.reg == cfi->drap_reg) { in update_cfi_state()
2966 cfa->offset = cfi->stack_size = -op->src.offset; in update_cfi_state()
2967 cfi->drap_reg = CFI_UNDEFINED; in update_cfi_state()
2968 cfi->drap = false; in update_cfi_state()
2972 if (op->dest.reg == cfi->cfa.base && !(next_insn && next_insn->hint)) { in update_cfi_state()
2981 (cfi->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) || in update_cfi_state()
2982 (cfi->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) { in update_cfi_state()
2987 if (cfi->drap_reg != CFI_UNDEFINED) { in update_cfi_state()
2989 cfa->base = cfi->drap_reg; in update_cfi_state()
2990 cfa->offset = cfi->stack_size = 0; in update_cfi_state()
2991 cfi->drap = true; in update_cfi_state()
3010 if (!cfi->drap && op->dest.reg == cfa->base) { in update_cfi_state()
3016 if (cfi->drap && cfa->base == CFI_BP_INDIRECT && in update_cfi_state()
3017 op->dest.reg == cfi->drap_reg && in update_cfi_state()
3018 cfi->drap_offset == -cfi->stack_size) { in update_cfi_state()
3021 cfa->base = cfi->drap_reg; in update_cfi_state()
3023 cfi->drap_offset = -1; in update_cfi_state()
3025 } else if (cfi->stack_size == -regs[op->dest.reg].offset) { in update_cfi_state()
3028 restore_reg(cfi, op->dest.reg); in update_cfi_state()
3031 cfi->stack_size -= 8; in update_cfi_state()
3038 if (!cfi->drap && op->dest.reg == cfa->base && in update_cfi_state()
3043 cfa->offset = cfi->stack_size; in update_cfi_state()
3046 if (cfi->drap && op->src.reg == CFI_BP && in update_cfi_state()
3047 op->src.offset == cfi->drap_offset) { in update_cfi_state()
3050 cfa->base = cfi->drap_reg; in update_cfi_state()
3052 cfi->drap_offset = -1; in update_cfi_state()
3055 if (cfi->drap && op->src.reg == CFI_BP && in update_cfi_state()
3059 restore_reg(cfi, op->dest.reg); in update_cfi_state()
3066 restore_reg(cfi, op->dest.reg); in update_cfi_state()
3069 op->src.offset == regs[op->dest.reg].offset + cfi->stack_size) { in update_cfi_state()
3072 restore_reg(cfi, op->dest.reg); in update_cfi_state()
3086 cfi->stack_size += 8; in update_cfi_state()
3093 if (cfi->drap) { in update_cfi_state()
3094 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) { in update_cfi_state()
3098 cfa->offset = -cfi->stack_size; in update_cfi_state()
3101 cfi->drap_offset = -cfi->stack_size; in update_cfi_state()
3103 } else if (op->src.reg == CFI_BP && cfa->base == cfi->drap_reg) { in update_cfi_state()
3106 cfi->stack_size = 0; in update_cfi_state()
3111 save_reg(cfi, op->src.reg, CFI_BP, -cfi->stack_size); in update_cfi_state()
3117 save_reg(cfi, op->src.reg, CFI_CFA, -cfi->stack_size); in update_cfi_state()
3123 cfi->bp_scratch = true; in update_cfi_state()
3128 if (cfi->drap) { in update_cfi_state()
3129 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) { in update_cfi_state()
3136 cfi->drap_offset = op->dest.offset; in update_cfi_state()
3140 save_reg(cfi, op->src.reg, CFI_BP, op->dest.offset); in update_cfi_state()
3147 save_reg(cfi, op->src.reg, CFI_CFA, in update_cfi_state()
3148 op->dest.offset - cfi->cfa.offset); in update_cfi_state()
3153 save_reg(cfi, op->src.reg, CFI_CFA, in update_cfi_state()
3154 op->dest.offset - cfi->stack_size); in update_cfi_state()
3159 cfi->vals[op->dest.reg].base = CFI_SP_INDIRECT; in update_cfi_state()
3160 cfi->vals[op->dest.reg].offset = cfa->offset; in update_cfi_state()
3172 cfi->stack_size -= 8; in update_cfi_state()
3203 if (!insn->cfi) { in propagate_alt_cfi()
3208 alt_cfi = insn->alt_group->cfi; in propagate_alt_cfi()
3212 alt_cfi[group_off] = insn->cfi; in propagate_alt_cfi()
3214 if (cficmp(alt_cfi[group_off], insn->cfi)) { in propagate_alt_cfi()
3235 ret = update_cfi_state(insn, next_insn, &state->cfi, op); in handle_insn_ops()
3268 struct cfi_state *cfi1 = insn->cfi; in insn_cfi_match()
3472 if (state->cfi.bp_scratch) { in validate_return()
3582 if (!insn->hint && !insn_cfi_match(insn, &state.cfi)) in validate_branch()
3630 insn->cfi = save_insn->cfi; in validate_branch()
3634 state.cfi = *insn->cfi; in validate_branch()
3638 if (prev_insn && !cficmp(prev_insn->cfi, &state.cfi)) { in validate_branch()
3639 insn->cfi = prev_insn->cfi; in validate_branch()
3642 insn->cfi = cfi_hash_find_or_add(&state.cfi); in validate_branch()
3791 if (state.cfi.cfa.base == CFI_UNDEFINED) in validate_branch()
4133 struct cfi_state *cfi; in add_prefix_symbol() local
4162 if (!insn->cfi) { in add_prefix_symbol()
4171 cfi = cfi_hash_find_or_add(insn->cfi); in add_prefix_symbol()
4173 prev->cfi = cfi; in add_prefix_symbol()
4236 set_func_state(&state.cfi); in validate_section()
4744 if (opts.cfi) { in check()