LoongArch: Get frame info in unwind_start() when regs is not available
At unwind_start(), it is better to get its frame info here rather than get them outside, even we don't have 'regs'. In this way we can simply use unwind_{start, next_frame, done} outside. Signed-off-by: Jinyang He <hejinyang@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
parent
e2f2739227
commit
429a9671f2
|
@ -191,20 +191,14 @@ out:
|
|||
|
||||
unsigned long __get_wchan(struct task_struct *task)
|
||||
{
|
||||
unsigned long pc;
|
||||
unsigned long pc = 0;
|
||||
struct unwind_state state;
|
||||
|
||||
if (!try_get_task_stack(task))
|
||||
return 0;
|
||||
|
||||
unwind_start(&state, task, NULL);
|
||||
state.sp = thread_saved_fp(task);
|
||||
get_stack_info(state.sp, state.task, &state.stack_info);
|
||||
state.pc = thread_saved_ra(task);
|
||||
#ifdef CONFIG_UNWINDER_PROLOGUE
|
||||
state.type = UNWINDER_PROLOGUE;
|
||||
#endif
|
||||
for (; !unwind_done(&state); unwind_next_frame(&state)) {
|
||||
for (unwind_start(&state, task, NULL);
|
||||
!unwind_done(&state); unwind_next_frame(&state)) {
|
||||
pc = unwind_get_return_address(&state);
|
||||
if (!pc)
|
||||
break;
|
||||
|
|
|
@ -26,6 +26,12 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
|
|||
if (regs) {
|
||||
state->sp = regs->regs[3];
|
||||
state->pc = regs->csr_era;
|
||||
} else if (task && task != current) {
|
||||
state->sp = thread_saved_fp(task);
|
||||
state->pc = thread_saved_ra(task);
|
||||
} else {
|
||||
state->sp = (unsigned long)__builtin_frame_address(0);
|
||||
state->pc = (unsigned long)__builtin_return_address(0);
|
||||
}
|
||||
|
||||
state->task = task;
|
||||
|
|
|
@ -146,12 +146,22 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->type = UNWINDER_PROLOGUE;
|
||||
|
||||
if (regs && __kernel_text_address(regs->csr_era)) {
|
||||
state->pc = regs->csr_era;
|
||||
if (regs) {
|
||||
state->sp = regs->regs[3];
|
||||
state->pc = regs->csr_era;
|
||||
state->ra = regs->regs[1];
|
||||
state->type = UNWINDER_PROLOGUE;
|
||||
if (!__kernel_text_address(state->pc))
|
||||
state->type = UNWINDER_GUESS;
|
||||
} else if (task && task != current) {
|
||||
state->sp = thread_saved_fp(task);
|
||||
state->pc = thread_saved_ra(task);
|
||||
state->ra = 0;
|
||||
} else {
|
||||
state->sp = (unsigned long)__builtin_frame_address(0);
|
||||
state->pc = (unsigned long)__builtin_return_address(0);
|
||||
state->ra = 0;
|
||||
}
|
||||
|
||||
state->task = task;
|
||||
|
|
Loading…
Reference in New Issue