unwind_prologue.c (4f2c0a4acffbec01079c28f839422e64ddeff004) | unwind_prologue.c (4733f09d880745953b88c3358b49ad495aecd8e9) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2022 Loongson Technology Corporation Limited 4 */ 5#include <linux/kallsyms.h> 6 7#include <asm/inst.h> 8#include <asm/ptrace.h> 9#include <asm/unwind.h> 10 | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2022 Loongson Technology Corporation Limited 4 */ 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{ 13#ifdef CONFIG_DYNAMIC_FTRACE 14 static unsigned long ftrace = (unsigned long)ftrace_call + 4; 15 16 if (state->pc == ftrace) 17 state->is_ftrace = true; 18#endif 19} 20 |
|
11unsigned long unwind_get_return_address(struct unwind_state *state) 12{ 13 14 if (unwind_done(state)) 15 return 0; 16 else if (state->type) 17 return state->pc; 18 else if (state->first) --- 17 unchanged lines hidden (view full) --- 36 return true; 37 } 38 39 return false; 40} 41 42static bool unwind_by_prologue(struct unwind_state *state) 43{ | 21unsigned long unwind_get_return_address(struct unwind_state *state) 22{ 23 24 if (unwind_done(state)) 25 return 0; 26 else if (state->type) 27 return state->pc; 28 else if (state->first) --- 17 unchanged lines hidden (view full) --- 46 return true; 47 } 48 49 return false; 50} 51 52static bool unwind_by_prologue(struct unwind_state *state) 53{ |
44 struct stack_info *info = &state->stack_info; 45 union loongarch_instruction *ip, *ip_end; | |
46 long frame_ra = -1; 47 unsigned long frame_size = 0; 48 unsigned long size, offset, pc = state->pc; | 54 long frame_ra = -1; 55 unsigned long frame_size = 0; 56 unsigned long size, offset, pc = state->pc; |
57 struct pt_regs *regs; 58 struct stack_info *info = &state->stack_info; 59 union loongarch_instruction *ip, *ip_end; |
|
49 50 if (state->sp >= info->end || state->sp < info->begin) 51 return false; 52 | 60 61 if (state->sp >= info->end || state->sp < info->begin) 62 return false; 63 |
64 if (state->is_ftrace) { 65 /* 66 * As we meet ftrace_regs_entry, reset first flag like first doing 67 * tracing. Prologue analysis will stop soon because PC is at entry. 68 */ 69 regs = (struct pt_regs *)state->sp; 70 state->first = true; 71 state->is_ftrace = false; 72 state->pc = regs->csr_era; 73 state->ra = regs->regs[1]; 74 state->sp = regs->regs[3]; 75 return true; 76 } 77 |
|
53 if (!kallsyms_lookup_size_offset(pc, &size, &offset)) 54 return false; 55 56 ip = (union loongarch_instruction *)(pc - offset); 57 ip_end = (union loongarch_instruction *)pc; 58 59 while (ip < ip_end) { 60 if (is_stack_alloc_ins(ip)) { --- 29 unchanged lines hidden (view full) --- 90 return false; 91 } 92 93 if (state->first) 94 state->first = false; 95 96 state->pc = *(unsigned long *)(state->sp + frame_ra); 97 state->sp = state->sp + frame_size; | 78 if (!kallsyms_lookup_size_offset(pc, &size, &offset)) 79 return false; 80 81 ip = (union loongarch_instruction *)(pc - offset); 82 ip_end = (union loongarch_instruction *)pc; 83 84 while (ip < ip_end) { 85 if (is_stack_alloc_ins(ip)) { --- 29 unchanged lines hidden (view full) --- 115 return false; 116 } 117 118 if (state->first) 119 state->first = false; 120 121 state->pc = *(unsigned long *)(state->sp + frame_ra); 122 state->sp = state->sp + frame_size; |
98 return !!__kernel_text_address(state->pc); | 123 goto out; |
99 100first: 101 state->first = false; 102 if (state->pc == state->ra) 103 return false; 104 105 state->pc = state->ra; 106 | 124 125first: 126 state->first = false; 127 if (state->pc == state->ra) 128 return false; 129 130 state->pc = state->ra; 131 |
107 return !!__kernel_text_address(state->ra); | 132out: 133 unwind_state_fixup(state); 134 return !!__kernel_text_address(state->pc); |
108} 109 110void unwind_start(struct unwind_state *state, struct task_struct *task, 111 struct pt_regs *regs) 112{ 113 memset(state, 0, sizeof(*state)); 114 115 if (regs && __kernel_text_address(regs->csr_era)) { --- 62 unchanged lines hidden --- | 135} 136 137void unwind_start(struct unwind_state *state, struct task_struct *task, 138 struct pt_regs *regs) 139{ 140 memset(state, 0, sizeof(*state)); 141 142 if (regs && __kernel_text_address(regs->csr_era)) { --- 62 unchanged lines hidden --- |