HIDDEN void tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) { struct cursor *c = (struct cursor *) dwarf_to_cursor (d); unw_tdep_frame_t *f = &c->frame_info; Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" " ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] " "sp [where=%d val=%ld @0x%lx]\n", d->ip, d->cfa, f->frame_type, rs->reg.where[DWARF_CFA_REG_COLUMN], rs->reg.val[DWARF_CFA_REG_COLUMN], rs->reg.val[DWARF_CFA_OFF_COLUMN], DWARF_GET_LOC(d->loc[rs->ret_addr_column]), rs->reg.where[FP], rs->reg.val[FP], DWARF_GET_LOC(d->loc[FP]), rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]), rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP])); /* A standard frame is defined as: - CFA is register-relative offset off FP or SP; - Return address is saved in LR; - FP is unsaved or saved at CFA+offset, offset != -1; - LR is unsaved or saved at CFA+offset, offset != -1; - SP is unsaved or saved at CFA+offset, offset != -1. */ if (f->frame_type == UNW_AARCH64_FRAME_OTHER && (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG) && (rs->reg.val[DWARF_CFA_REG_COLUMN] == FP || rs->reg.val[DWARF_CFA_REG_COLUMN] == SP) && labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29) && rs->ret_addr_column == LR && (rs->reg.where[FP] == DWARF_WHERE_UNDEF || rs->reg.where[FP] == DWARF_WHERE_SAME || (rs->reg.where[FP] == DWARF_WHERE_CFAREL && labs(rs->reg.val[FP]) < (1 << 29) && rs->reg.val[FP]+1 != 0)) && (rs->reg.where[LR] == DWARF_WHERE_UNDEF || rs->reg.where[LR] == DWARF_WHERE_SAME || (rs->reg.where[LR] == DWARF_WHERE_CFAREL && labs(rs->reg.val[LR]) < (1 << 29) && rs->reg.val[LR]+1 != 0)) && (rs->reg.where[SP] == DWARF_WHERE_UNDEF || rs->reg.where[SP] == DWARF_WHERE_SAME || (rs->reg.where[SP] == DWARF_WHERE_CFAREL && labs(rs->reg.val[SP]) < (1 << 29) && rs->reg.val[SP]+1 != 0))) { /* Save information for a standard frame. */ f->frame_type = UNW_AARCH64_FRAME_STANDARD; f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP); f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN]; if (rs->reg.where[FP] == DWARF_WHERE_CFAREL) f->fp_cfa_offset = rs->reg.val[FP]; if (rs->reg.where[LR] == DWARF_WHERE_CFAREL) f->lr_cfa_offset = rs->reg.val[LR]; if (rs->reg.where[SP] == DWARF_WHERE_CFAREL) f->sp_cfa_offset = rs->reg.val[SP]; Debug (4, " standard frame\n"); } else Debug (4, " unusual frame\n"); }
HIDDEN void tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) { struct cursor *c = (struct cursor *) dwarf_to_cursor (d); unw_tdep_frame_t *f = &c->frame_info; Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld" " ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n", d->ip, d->cfa, f->frame_type, rs->reg[DWARF_CFA_REG_COLUMN].where, rs->reg[DWARF_CFA_REG_COLUMN].val, rs->reg[DWARF_CFA_OFF_COLUMN].val, DWARF_GET_LOC(d->loc[d->ret_addr_column]), rs->reg[RBP].where, rs->reg[RBP].val, DWARF_GET_LOC(d->loc[RBP]), rs->reg[RSP].where, rs->reg[RSP].val, DWARF_GET_LOC(d->loc[RSP])); /* A standard frame is defined as: - CFA is register-relative offset off RBP or RSP; - Return address is saved at CFA-8; - RBP is unsaved or saved at CFA+offset, offset != -1; - RSP is unsaved or saved at CFA+offset, offset != -1. */ if (f->frame_type == UNW_X86_64_FRAME_OTHER && (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) && (rs->reg[DWARF_CFA_REG_COLUMN].val == RBP || rs->reg[DWARF_CFA_REG_COLUMN].val == RSP) && labs((long) rs->reg[DWARF_CFA_OFF_COLUMN].val) < (1 << 29) && DWARF_GET_LOC(d->loc[d->ret_addr_column]) == d->cfa-8 && (rs->reg[RBP].where == DWARF_WHERE_UNDEF || rs->reg[RBP].where == DWARF_WHERE_SAME || (rs->reg[RBP].where == DWARF_WHERE_CFAREL && labs((long) rs->reg[RBP].val) < (1 << 14) && rs->reg[RBP].val+1 != 0)) && (rs->reg[RSP].where == DWARF_WHERE_UNDEF || rs->reg[RSP].where == DWARF_WHERE_SAME || (rs->reg[RSP].where == DWARF_WHERE_CFAREL && labs((long) rs->reg[RSP].val) < (1 << 14) && rs->reg[RSP].val+1 != 0))) { /* Save information for a standard frame. */ f->frame_type = UNW_X86_64_FRAME_STANDARD; f->cfa_reg_rsp = (rs->reg[DWARF_CFA_REG_COLUMN].val == RSP); f->cfa_reg_offset = rs->reg[DWARF_CFA_OFF_COLUMN].val; if (rs->reg[RBP].where == DWARF_WHERE_CFAREL) f->rbp_cfa_offset = rs->reg[RBP].val; if (rs->reg[RSP].where == DWARF_WHERE_CFAREL) f->rsp_cfa_offset = rs->reg[RSP].val; Debug (4, " standard frame\n"); } /* Signal frame was detected via augmentation in tdep_fetch_frame() */ else if (f->frame_type == UNW_X86_64_FRAME_SIGRETURN) { /* Later we are going to fish out {RBP,RSP,RIP} from sigcontext via their ucontext_t offsets. Confirm DWARF info agrees with the offsets we expect. */ #ifndef NDEBUG const unw_word_t uc = c->sigcontext_addr; assert (DWARF_GET_LOC(d->loc[RIP]) - uc == UC_MCONTEXT_GREGS_RIP); assert (DWARF_GET_LOC(d->loc[RBP]) - uc == UC_MCONTEXT_GREGS_RBP); assert (DWARF_GET_LOC(d->loc[RSP]) - uc == UC_MCONTEXT_GREGS_RSP); #endif Debug (4, " sigreturn frame\n"); } /* PLT and guessed RBP-walked frames are handled in unw_step(). */ else Debug (4, " unusual frame\n"); }