Co-developed-by: Alexey Makhalov <alexey.makhalov@xxxxxxxxxxxx> Co-developed-by: Tao Liu <ltao@xxxxxxxxxx> Signed-off-by: Tao Liu <ltao@xxxxxxxxxx> --- arm64.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/arm64.c b/arm64.c index 8291301..53cbf48 100644 --- a/arm64.c +++ b/arm64.c @@ -226,6 +226,12 @@ arm64_get_current_task_reg(int regno, const char *name, tc = CURRENT_CONTEXT(); if (!tc) return FALSE; + + if (sid && sid <= extra_stacks_idx) { + ur_bitmap = extra_stacks_regs[extra_stacks_idx - 1]; + goto get_sub; + } + BZERO(&bt_setup, sizeof(struct bt_info)); clone_bt_info(&bt_setup, &bt_info, tc); fill_stackbuf(&bt_info); @@ -241,25 +247,29 @@ arm64_get_current_task_reg(int regno, const char *name, goto get_all; } +get_sub: switch (regno) { case X0_REGNUM ... X30_REGNUM: if (!NUM_IN_BITMAP(ur_bitmap->bitmap, REG_SEQ(arm64_pt_regs, regs[0]) + regno - X0_REGNUM)) { - FREEBUF(ur_bitmap); + if (!sid) + FREEBUF(ur_bitmap); return FALSE; } break; case SP_REGNUM: if (!NUM_IN_BITMAP(ur_bitmap->bitmap, REG_SEQ(arm64_pt_regs, sp))) { - FREEBUF(ur_bitmap); + if (!sid) + FREEBUF(ur_bitmap); return FALSE; } break; case PC_REGNUM: if (!NUM_IN_BITMAP(ur_bitmap->bitmap, REG_SEQ(arm64_pt_regs, pc))) { - FREEBUF(ur_bitmap); + if (!sid) + FREEBUF(ur_bitmap); return FALSE; } break; @@ -287,7 +297,7 @@ get_all: break; } - if (bt_info.need_free) { + if (!sid && bt_info.need_free) { FREEBUF(ur_bitmap); bt_info.need_free = FALSE; } @@ -3680,6 +3690,7 @@ arm64_back_trace_cmd(struct bt_info *bt) int level; ulong exception_frame; FILE *ofp; + extra_stacks_idx = 0; if (bt->flags & BT_OPT_BACK_TRACE) { if (machdep->flags & UNW_4_14) { @@ -3733,6 +3744,29 @@ arm64_back_trace_cmd(struct bt_info *bt) stackframe.fp = bt->frameptr; } + if (is_task_active(bt->task)) { + if (!extra_stacks_regs[extra_stacks_idx]) { + extra_stacks_regs[extra_stacks_idx] = (struct user_regs_bitmap_struct *) + malloc(sizeof(struct user_regs_bitmap_struct)); + } + memset(extra_stacks_regs[extra_stacks_idx], 0, + sizeof(struct user_regs_bitmap_struct)); + if (bt->task != tt->panic_task && stackframe.sp) { + readmem(stackframe.sp - 8, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.pc, + sizeof(ulong), "extra_stacks_regs.pc", RETURN_ON_ERROR); + readmem(stackframe.sp - 16, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.sp, + sizeof(ulong), "extra_stacks_regs.sp", RETURN_ON_ERROR); + } else { + extra_stacks_regs[extra_stacks_idx]->ur.pc = stackframe.pc; + extra_stacks_regs[extra_stacks_idx]->ur.sp = stackframe.sp; + } + SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, + REG_SEQ(arm64_pt_regs, pc)); + SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, + REG_SEQ(arm64_pt_regs, sp)); + gdb_add_substack (extra_stacks_idx++); + } + if (bt->flags & BT_TEXT_SYMBOLS) { arm64_print_text_symbols(bt, &stackframe, ofp); if (BT_REFERENCE_FOUND(bt)) { @@ -3854,6 +3888,29 @@ arm64_back_trace_cmd_v2(struct bt_info *bt) stackframe.fp = bt->frameptr; } + if (is_task_active(bt->task)) { + if (!extra_stacks_regs[extra_stacks_idx]) { + extra_stacks_regs[extra_stacks_idx] = (struct user_regs_bitmap_struct *) + malloc(sizeof(struct user_regs_bitmap_struct)); + } + memset(extra_stacks_regs[extra_stacks_idx], 0, + sizeof(struct user_regs_bitmap_struct)); + if (bt->task != tt->panic_task && stackframe.sp) { + readmem(stackframe.sp - 8, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.pc, + sizeof(ulong), "extra_stacks_regs.pc", RETURN_ON_ERROR); + readmem(stackframe.sp - 16, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.sp, + sizeof(ulong), "extra_stacks_regs.sp", RETURN_ON_ERROR); + } else { + extra_stacks_regs[extra_stacks_idx]->ur.pc = stackframe.pc; + extra_stacks_regs[extra_stacks_idx]->ur.sp = stackframe.sp; + } + SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, + REG_SEQ(arm64_pt_regs, pc)); + SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, + REG_SEQ(arm64_pt_regs, sp)); + gdb_add_substack (extra_stacks_idx++); + } + if (bt->flags & BT_TEXT_SYMBOLS) { arm64_print_text_symbols(bt, &stackframe, ofp); if (BT_REFERENCE_FOUND(bt)) { @@ -4468,6 +4525,20 @@ arm64_print_exception_frame(struct bt_info *bt, ulong pt_regs, int mode, FILE *o fprintf(ofp, "ORIG_X0: %016lx SYSCALLNO: %lx", (ulong)regs->orig_x0, (ulong)regs->syscallno); fprintf(ofp, " PSTATE: %08lx\n", (ulong)regs->pstate); + } else if (!bt->machdep || + regs->pc != ((struct user_regs_bitmap_struct *)bt->machdep)->ur.pc) { + if (!extra_stacks_regs[extra_stacks_idx]) { + extra_stacks_regs[extra_stacks_idx] = + (struct user_regs_bitmap_struct *) + malloc(sizeof(struct user_regs_bitmap_struct)); + } + memset(extra_stacks_regs[extra_stacks_idx], 0, + sizeof(struct user_regs_bitmap_struct)); + memcpy(&extra_stacks_regs[extra_stacks_idx]->ur, regs, + sizeof(struct arm64_pt_regs)); + for (int i = 0; i < sizeof(struct arm64_pt_regs)/sizeof(long); i++) + SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, i); + gdb_add_substack (extra_stacks_idx++); } } -- 2.47.0 -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki