Lines Matching refs:cfi

12 #include "cfi.h"
249 static void init_cfi_state(struct cfi_state *cfi)
254 cfi->regs[i].base = CFI_UNDEFINED;
255 cfi->vals[i].base = CFI_UNDEFINED;
257 cfi->cfa.base = CFI_UNDEFINED;
258 cfi->drap_reg = CFI_UNDEFINED;
259 cfi->drap_offset = -1;
265 init_cfi_state(&state->cfi);
278 struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
279 if (!cfi) {
284 return cfi;
297 static inline u32 cfi_key(struct cfi_state *cfi)
299 return jhash((void *)cfi + sizeof(cfi->hash),
300 sizeof(*cfi) - sizeof(cfi->hash), 0);
303 static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
305 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
309 if (!cficmp(cfi, obj)) {
316 *obj = *cfi;
322 static void cfi_hash_add(struct cfi_state *cfi)
324 struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
326 hlist_add_head(&cfi->hash, head);
1328 orig_alt_group->cfi = calloc(special_alt->orig_len,
1330 if (!orig_alt_group->cfi) {
1445 new_alt_group->cfi = orig_alt_group->cfi;
1747 struct cfi_state cfi = init_cfi;
1813 insn->cfi = &func_cfi;
1817 if (insn->cfi)
1818 cfi = *(insn->cfi);
1820 if (arch_decode_hint_reg(hint->sp_reg, &cfi.cfa.base)) {
1826 cfi.cfa.offset = hint->sp_offset;
1827 cfi.type = hint->type;
1828 cfi.end = hint->end;
1830 insn->cfi = cfi_hash_find_or_add(&cfi);
2119 struct cfi_state *cfi = &state->cfi;
2122 if (cfi->cfa.base != initial_func_cfi.cfa.base || cfi->drap)
2125 if (cfi->cfa.offset != initial_func_cfi.cfa.offset)
2128 if (cfi->stack_size != initial_func_cfi.cfa.offset)
2132 if (cfi->regs[i].base != initial_func_cfi.regs[i].base ||
2133 cfi->regs[i].offset != initial_func_cfi.regs[i].offset)
2142 struct cfi_state *cfi = &state->cfi;
2144 if (cfi->cfa.base == CFI_BP && cfi->regs[CFI_BP].base == CFI_CFA &&
2145 cfi->regs[CFI_BP].offset == -16)
2148 if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP)
2155 struct cfi_state *cfi,
2158 struct cfi_reg *cfa = &cfi->cfa;
2179 static void save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset)
2182 cfi->regs[reg].base == CFI_UNDEFINED) {
2183 cfi->regs[reg].base = base;
2184 cfi->regs[reg].offset = offset;
2188 static void restore_reg(struct cfi_state *cfi, unsigned char reg)
2190 cfi->regs[reg].base = initial_func_cfi.regs[reg].base;
2191 cfi->regs[reg].offset = initial_func_cfi.regs[reg].offset;
2247 static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi,
2250 struct cfi_reg *cfa = &cfi->cfa;
2251 struct cfi_reg *regs = cfi->regs;
2262 if (cfi->type == UNWIND_HINT_TYPE_REGS ||
2263 cfi->type == UNWIND_HINT_TYPE_REGS_PARTIAL)
2264 return update_cfi_state_regs(insn, cfi, op);
2279 cfi->bp_scratch = false;
2283 op->dest.reg == CFI_BP && cfi->drap) {
2287 regs[CFI_BP].offset = -cfi->stack_size;
2288 cfi->bp_scratch = false;
2303 cfi->vals[op->dest.reg].base = CFI_CFA;
2304 cfi->vals[op->dest.reg].offset = -cfi->stack_size;
2315 cfi->stack_size = -cfi->regs[CFI_BP].offset;
2322 cfi->vals[op->src.reg].base == CFI_CFA) {
2332 cfa->offset = -cfi->vals[op->src.reg].offset;
2333 cfi->stack_size = cfa->offset;
2347 cfi->stack_size -= op->src.offset;
2356 cfi->stack_size = -(op->src.offset + regs[CFI_BP].offset);
2363 cfi->drap_reg = op->dest.reg;
2375 cfi->vals[op->dest.reg].base = CFI_CFA;
2376 cfi->vals[op->dest.reg].offset = \
2377 -cfi->stack_size + op->src.offset;
2382 if (cfi->drap && op->dest.reg == CFI_SP &&
2383 op->src.reg == cfi->drap_reg) {
2387 cfa->offset = cfi->stack_size = -op->src.offset;
2388 cfi->drap_reg = CFI_UNDEFINED;
2389 cfi->drap = false;
2393 if (op->dest.reg == cfi->cfa.base) {
2403 (cfi->drap_reg != CFI_UNDEFINED && cfa->base != CFI_SP) ||
2404 (cfi->drap_reg == CFI_UNDEFINED && cfa->base != CFI_BP)) {
2410 if (cfi->drap_reg != CFI_UNDEFINED) {
2412 cfa->base = cfi->drap_reg;
2413 cfa->offset = cfi->stack_size = 0;
2414 cfi->drap = true;
2426 if (!cfi->drap && op->dest.reg == cfa->base) {
2432 if (cfi->drap && cfa->base == CFI_BP_INDIRECT &&
2433 op->dest.reg == cfi->drap_reg &&
2434 cfi->drap_offset == -cfi->stack_size) {
2437 cfa->base = cfi->drap_reg;
2439 cfi->drap_offset = -1;
2441 } else if (regs[op->dest.reg].offset == -cfi->stack_size) {
2444 restore_reg(cfi, op->dest.reg);
2447 cfi->stack_size -= 8;
2454 if (cfi->drap && op->src.reg == CFI_BP &&
2455 op->src.offset == cfi->drap_offset) {
2458 cfa->base = cfi->drap_reg;
2460 cfi->drap_offset = -1;
2463 if (cfi->drap && op->src.reg == CFI_BP &&
2467 restore_reg(cfi, op->dest.reg);
2474 restore_reg(cfi, op->dest.reg);
2489 cfi->stack_size += 8;
2496 if (cfi->drap) {
2497 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) {
2501 cfa->offset = -cfi->stack_size;
2504 cfi->drap_offset = -cfi->stack_size;
2506 } else if (op->src.reg == CFI_BP && cfa->base == cfi->drap_reg) {
2509 cfi->stack_size = 0;
2514 save_reg(cfi, op->src.reg, CFI_BP, -cfi->stack_size);
2520 save_reg(cfi, op->src.reg, CFI_CFA, -cfi->stack_size);
2526 cfi->bp_scratch = true;
2531 if (cfi->drap) {
2532 if (op->src.reg == cfa->base && op->src.reg == cfi->drap_reg) {
2539 cfi->drap_offset = op->dest.offset;
2543 save_reg(cfi, op->src.reg, CFI_BP, op->dest.offset);
2550 save_reg(cfi, op->src.reg, CFI_CFA,
2551 op->dest.offset - cfi->cfa.offset);
2557 if ((!cfi->drap && cfa->base != CFI_BP) ||
2558 (cfi->drap && cfa->base != cfi->drap_reg)) {
2566 cfi->stack_size = -cfi->regs[CFI_BP].offset - 8;
2567 restore_reg(cfi, CFI_BP);
2569 if (!cfi->drap) {
2584 cfi->stack_size -= 8;
2616 if (!insn->cfi) {
2621 alt_cfi = insn->alt_group->cfi;
2625 alt_cfi[group_off] = insn->cfi;
2627 if (cficmp(alt_cfi[group_off], insn->cfi)) {
2643 if (update_cfi_state(insn, &state->cfi, op))
2673 struct cfi_state *cfi1 = insn->cfi;
2830 if (state->cfi.bp_scratch) {
2889 if (!insn->hint && !insn_cfi_match(insn, &state.cfi))
2927 insn->cfi = save_insn->cfi;
2931 state.cfi = *insn->cfi;
2933 /* XXX track if we actually changed state.cfi */
2935 if (prev_insn && !cficmp(prev_insn->cfi, &state.cfi)) {
2936 insn->cfi = prev_insn->cfi;
2939 insn->cfi = cfi_hash_find_or_add(&state.cfi);
3097 if (state.cfi.cfa.base == CFI_UNDEFINED)
3441 set_func_state(&state.cfi);