unwind_prologue.c (4733f09d880745953b88c3358b49ad495aecd8e9) | unwind_prologue.c (a51ac5246d2505b58229242959d2bc73d113ca50) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2022 Loongson Technology Corporation Limited 4 */ | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2022 Loongson Technology Corporation Limited 4 */ |
5#include <linux/ftrace.h> |
|
5#include <linux/kallsyms.h> 6 7#include <asm/inst.h> 8#include <asm/ptrace.h> 9#include <asm/unwind.h> 10 11static inline void unwind_state_fixup(struct unwind_state *state) 12{ --- 24 unchanged lines hidden (view full) --- 37{ 38 struct stack_info *info = &state->stack_info; 39 unsigned long addr; 40 41 for (state->sp += sizeof(unsigned long); 42 state->sp < info->end; 43 state->sp += sizeof(unsigned long)) { 44 addr = *(unsigned long *)(state->sp); | 6#include <linux/kallsyms.h> 7 8#include <asm/inst.h> 9#include <asm/ptrace.h> 10#include <asm/unwind.h> 11 12static inline void unwind_state_fixup(struct unwind_state *state) 13{ --- 24 unchanged lines hidden (view full) --- 38{ 39 struct stack_info *info = &state->stack_info; 40 unsigned long addr; 41 42 for (state->sp += sizeof(unsigned long); 43 state->sp < info->end; 44 state->sp += sizeof(unsigned long)) { 45 addr = *(unsigned long *)(state->sp); |
46 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, 47 addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); |
|
45 if (__kernel_text_address(addr)) 46 return true; 47 } 48 49 return false; 50} 51 52static bool unwind_by_prologue(struct unwind_state *state) --- 116 unchanged lines hidden (view full) --- 169 switch (state->type) { 170 case UNWINDER_GUESS: 171 state->first = false; 172 if (unwind_by_guess(state)) 173 return true; 174 break; 175 176 case UNWINDER_PROLOGUE: | 48 if (__kernel_text_address(addr)) 49 return true; 50 } 51 52 return false; 53} 54 55static bool unwind_by_prologue(struct unwind_state *state) --- 116 unchanged lines hidden (view full) --- 172 switch (state->type) { 173 case UNWINDER_GUESS: 174 state->first = false; 175 if (unwind_by_guess(state)) 176 return true; 177 break; 178 179 case UNWINDER_PROLOGUE: |
177 if (unwind_by_prologue(state)) | 180 if (unwind_by_prologue(state)) { 181 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, 182 state->pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); |
178 return true; | 183 return true; |
184 } |
|
179 180 if (info->type == STACK_TYPE_IRQ && 181 info->end == state->sp) { 182 regs = (struct pt_regs *)info->next_sp; 183 pc = regs->csr_era; 184 185 if (user_mode(regs) || !__kernel_text_address(pc)) 186 return false; 187 | 185 186 if (info->type == STACK_TYPE_IRQ && 187 info->end == state->sp) { 188 regs = (struct pt_regs *)info->next_sp; 189 pc = regs->csr_era; 190 191 if (user_mode(regs) || !__kernel_text_address(pc)) 192 return false; 193 |
188 state->pc = pc; 189 state->sp = regs->regs[3]; 190 state->ra = regs->regs[1]; | |
191 state->first = true; | 194 state->first = true; |
195 state->ra = regs->regs[1]; 196 state->sp = regs->regs[3]; 197 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, 198 pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); |
|
192 get_stack_info(state->sp, state->task, info); 193 194 return true; 195 } 196 } 197 198 state->sp = info->next_sp; 199 200 } while (!get_stack_info(state->sp, state->task, info)); 201 202 return false; 203} 204EXPORT_SYMBOL_GPL(unwind_next_frame); | 199 get_stack_info(state->sp, state->task, info); 200 201 return true; 202 } 203 } 204 205 state->sp = info->next_sp; 206 207 } while (!get_stack_info(state->sp, state->task, info)); 208 209 return false; 210} 211EXPORT_SYMBOL_GPL(unwind_next_frame); |