mirror of https://github.com/crash-utility/crash
32-bit ARM kernels built with the Thumb-2 instruction set utilize
the R7 register instead of FP for unwinding stacks using the DWARF unwinder. On those kernels, without the patch, the "bt" command only shows the task header. (vincent.whitchurch@axis.com)
This commit is contained in:
parent
5aa3c1da3e
commit
8e21aa3fa5
15
arm.c
15
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;
|
||||
}
|
||||
|
||||
|
|
1
defs.h
1
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 */
|
||||
|
|
|
@ -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",
|
||||
|
|
14
unwind_arm.c
14
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]);
|
||||
|
|
Loading…
Reference in New Issue