----- Original Message ----- > ARM kernels built with the Thumb-2 instruction need R7 instead of FP for > unwinding stacks using the DWARF unwinder. > > On a Thumb-2 kernel: > > Before: > crash> bt 1 > PID: 1 TASK: ee7e0000 CPU: 1 COMMAND: "systemd-shutdow" > > After: > crash> bt 1 > PID: 1 TASK: ee7e0000 CPU: 1 COMMAND: "systemd-shutdow" > #0 [<805587a1>] (__schedule) from [<80558d2b>] > #1 [<80558d2b>] (schedule) from [<8055c8bb>] > #2 [<8055c8bb>] (schedule_hrtimeout_range_clock) from [<8055c937>] > #3 [<8055c937>] (schedule_hrtimeout_range) from [<8012cbdf>] > #4 [<8012cbdf>] (sys_rt_sigtimedwait) from [<80107259>] Queued for crash-7.2.6: https://github.com/crash-utility/crash/commit/8e21aa3fa5c255396e9dce49786eae595f0371c1 Thanks, Dave > > Change-Id: Iec0c3a3ab089441d0ebf0002343790d65fe6ca78 > --- > arm.c | 15 +++++++++++---- > defs.h | 1 + > symbols.c | 2 ++ > unwind_arm.c | 14 ++++++++++---- > 4 files changed, 24 insertions(+), 8 deletions(-) > > diff --git a/arm.c b/arm.c > index 9652361..b05b0b3 100644 > --- a/arm.c > +++ b/arm.c > @@ -301,6 +301,8 @@ arm_init(int when) > * thread_info.cpu_context. > */ > STRUCT_SIZE_INIT(cpu_context_save, "cpu_context_save"); > + MEMBER_OFFSET_INIT(cpu_context_save_r7, > + "cpu_context_save", "r7"); > MEMBER_OFFSET_INIT(cpu_context_save_fp, > "cpu_context_save", "fp"); > MEMBER_OFFSET_INIT(cpu_context_save_sp, > @@ -1313,13 +1315,18 @@ arm_get_frame(struct bt_info *bt, ulong *pcp, ulong > *spp) > cpu_context = tt->thread_info + OFFSET(thread_info_cpu_context); > > #define GET_REG(ptr, cp, off) ((*ptr) = (*((ulong *)((cp) + OFFSET(off))))) > - /* > - * Unwinding code needs FP value also so we pass it with bt. > - */ > - GET_REG(&bt->frameptr, cpu_context, cpu_context_save_fp); > GET_REG(spp, cpu_context, cpu_context_save_sp); > GET_REG(pcp, cpu_context, cpu_context_save_pc); > > + /* > + * Unwinding code needs FP (R7 for Thumb code) value also so we pass it > + * with bt. > + */ > + if (*pcp & 1) > + GET_REG(&bt->frameptr, cpu_context, cpu_context_save_r7); > + else > + GET_REG(&bt->frameptr, cpu_context, cpu_context_save_fp); > + > return TRUE; > } > > diff --git a/defs.h b/defs.h > index 5841b1f..b4f6372 100644 > --- a/defs.h > +++ b/defs.h > @@ -2066,6 +2066,7 @@ struct offset_table { /* stash of > commonly-used offsets */ > long xa_node_shift; > long hd_struct_dkstats; > long disk_stats_in_flight; > + long cpu_context_save_r7; > }; > > struct size_table { /* stash of commonly-used sizes */ > diff --git a/symbols.c b/symbols.c > index e73e735..31a4d7b 100644 > --- a/symbols.c > +++ b/symbols.c > @@ -10047,6 +10047,8 @@ dump_offset_table(char *spec, ulong makestruct) > fprintf(fp, " s390_stack_frame_r14: %ld\n", > OFFSET(s390_stack_frame_r14)); > > + fprintf(fp, " cpu_context_save_r7: %ld\n", > + OFFSET(cpu_context_save_r7)); > fprintf(fp, " cpu_context_save_fp: %ld\n", > OFFSET(cpu_context_save_fp)); > fprintf(fp, " cpu_context_save_sp: %ld\n", > diff --git a/unwind_arm.c b/unwind_arm.c > index 8667d3c..1a8f51e 100644 > --- a/unwind_arm.c > +++ b/unwind_arm.c > @@ -87,6 +87,7 @@ struct stackframe { > }; > > enum regs { > + R7 = 7, > FP = 11, > SP = 13, > LR = 14, > @@ -615,6 +616,7 @@ unwind_frame(struct stackframe *frame, ulong stacktop) > struct unwind_ctrl_block ctrl; > struct unwind_idx *idx; > ulong low, high; > + int fpindex = FP; > > low = frame->sp; > high = stacktop; > @@ -622,6 +624,10 @@ unwind_frame(struct stackframe *frame, ulong stacktop) > if (!is_kernel_text(frame->pc)) > return FALSE; > > + /* Thumb needs R7 instead of FP */ > + if (frame->pc & 1) > + fpindex = R7; > + > tbl = search_table(frame->pc); > if (!tbl) { > error(WARNING, "UNWIND: cannot find unwind table for %lx\n", > @@ -630,13 +636,13 @@ unwind_frame(struct stackframe *frame, ulong stacktop) > } > idx = search_index(tbl, frame->pc); > > - ctrl.vrs[FP] = frame->fp; > + ctrl.vrs[fpindex] = frame->fp; > ctrl.vrs[SP] = frame->sp; > ctrl.vrs[LR] = frame->lr; > ctrl.vrs[PC] = 0; > > if (CRASHDEBUG(5)) { > - fprintf(fp, "UNWIND: >frame: FP=%lx\n", ctrl.vrs[FP]); > + fprintf(fp, "UNWIND: >frame: FP=%lx\n", ctrl.vrs[fpindex]); > fprintf(fp, "UNWIND: >frame: SP=%lx\n", ctrl.vrs[SP]); > fprintf(fp, "UNWIND: >frame: LR=%lx\n", ctrl.vrs[LR]); > fprintf(fp, "UNWIND: >frame: PC=%lx\n", ctrl.vrs[PC]); > @@ -706,13 +712,13 @@ unwind_frame(struct stackframe *frame, ulong stacktop) > if (frame->pc == ctrl.vrs[PC]) > return FALSE; > > - frame->fp = ctrl.vrs[FP]; > + frame->fp = ctrl.vrs[fpindex]; > frame->sp = ctrl.vrs[SP]; > frame->lr = ctrl.vrs[LR]; > frame->pc = ctrl.vrs[PC]; > > if (CRASHDEBUG(5)) { > - fprintf(fp, "UNWIND: <frame: FP=%lx\n", ctrl.vrs[FP]); > + fprintf(fp, "UNWIND: <frame: FP=%lx\n", ctrl.vrs[fpindex]); > fprintf(fp, "UNWIND: <frame: SP=%lx\n", ctrl.vrs[SP]); > fprintf(fp, "UNWIND: <frame: LR=%lx\n", ctrl.vrs[LR]); > fprintf(fp, "UNWIND: <frame: PC=%lx\n", ctrl.vrs[PC]); > -- > 2.20.0 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility