181 lines
6.2 KiB
Diff
181 lines
6.2 KiB
Diff
From 08271e45e4ea6263fc2957d1e876becd6cfc1a0d Mon Sep 17 00:00:00 2001
|
|
From: Tao Liu <ltao@redhat.com>
|
|
Date: Wed, 25 Jun 2025 16:02:02 +1200
|
|
Subject: [PATCH 6/9] arm64: Add gdb multi-stack unwind support
|
|
|
|
Co-developed-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
|
|
Co-developed-by: Tao Liu <ltao@redhat.com>
|
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
|
---
|
|
arm64.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 92 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/arm64.c b/arm64.c
|
|
index 8291301..354d17a 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,35 @@ 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));
|
|
+ if (!bt->machdep ||
|
|
+ (extra_stacks_regs[extra_stacks_idx]->ur.sp !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.sp &&
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.pc !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.pc)) {
|
|
+ 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 +3894,35 @@ 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));
|
|
+ if (!bt->machdep ||
|
|
+ (extra_stacks_regs[extra_stacks_idx]->ur.sp !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.sp &&
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.pc !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.pc)) {
|
|
+ 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 +4537,25 @@ 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->flags & BT_EFRAME_SEARCH)) {
|
|
+ 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);
|
|
+ if (!bt->machdep ||
|
|
+ (extra_stacks_regs[extra_stacks_idx]->ur.sp !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.sp &&
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.pc !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.pc)) {
|
|
+ gdb_add_substack (extra_stacks_idx++);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
--
|
|
2.47.0
|
|
|