@@ -19,32 +19,14 @@ static inline void unwind_state_fixup(struct unwind_state *state)
1919#endif
2020}
2121
22- unsigned long unwind_get_return_address (struct unwind_state * state )
23- {
24- if (unwind_done (state ))
25- return 0 ;
26-
27- return state -> pc ;
28- }
29- EXPORT_SYMBOL_GPL (unwind_get_return_address );
30-
31- static bool unwind_by_guess (struct unwind_state * state )
32- {
33- struct stack_info * info = & state -> stack_info ;
34- unsigned long addr ;
35-
36- for (state -> sp += sizeof (unsigned long );
37- state -> sp < info -> end ;
38- state -> sp += sizeof (unsigned long )) {
39- addr = * (unsigned long * )(state -> sp );
40- state -> pc = unwind_graph_addr (state , addr , state -> sp + 8 );
41- if (__kernel_text_address (state -> pc ))
42- return true;
43- }
44-
45- return false;
46- }
47-
22+ /*
23+ * LoongArch function prologue is like follows,
24+ * [instructions not use stack var]
25+ * addi.d sp, sp, -imm
26+ * st.d xx, sp, offset <- save callee saved regs and
27+ * st.d yy, sp, offset save ra if function is nest.
28+ * [others instructions]
29+ */
4830static bool unwind_by_prologue (struct unwind_state * state )
4931{
5032 long frame_ra = -1 ;
@@ -91,6 +73,10 @@ static bool unwind_by_prologue(struct unwind_state *state)
9173 ip ++ ;
9274 }
9375
76+ /*
77+ * Can't find stack alloc action, PC may be in a leaf function. Only the
78+ * first being true is reasonable, otherwise indicate analysis is broken.
79+ */
9480 if (!frame_size ) {
9581 if (state -> first )
9682 goto first ;
@@ -108,6 +94,7 @@ static bool unwind_by_prologue(struct unwind_state *state)
10894 ip ++ ;
10995 }
11096
97+ /* Can't find save $ra action, PC may be in a leaf function, too. */
11198 if (frame_ra < 0 ) {
11299 if (state -> first ) {
113100 state -> sp = state -> sp + frame_size ;
@@ -116,96 +103,48 @@ static bool unwind_by_prologue(struct unwind_state *state)
116103 return false;
117104 }
118105
119- if (state -> first )
120- state -> first = false;
121-
122106 state -> pc = * (unsigned long * )(state -> sp + frame_ra );
123107 state -> sp = state -> sp + frame_size ;
124108 goto out ;
125109
126110first :
127- state -> first = false;
128- if (state -> pc == state -> ra )
129- return false;
130-
131111 state -> pc = state -> ra ;
132112
133113out :
114+ state -> first = false;
134115 unwind_state_fixup (state );
135116 return !!__kernel_text_address (state -> pc );
136117}
137118
138- void unwind_start (struct unwind_state * state , struct task_struct * task ,
139- struct pt_regs * regs )
140- {
141- memset (state , 0 , sizeof (* state ));
142- state -> type = UNWINDER_PROLOGUE ;
143-
144- if (regs ) {
145- state -> sp = regs -> regs [3 ];
146- state -> pc = regs -> csr_era ;
147- state -> ra = regs -> regs [1 ];
148- if (!__kernel_text_address (state -> pc ))
149- state -> type = UNWINDER_GUESS ;
150- } else if (task && task != current ) {
151- state -> sp = thread_saved_fp (task );
152- state -> pc = thread_saved_ra (task );
153- state -> ra = 0 ;
154- } else {
155- state -> sp = (unsigned long )__builtin_frame_address (0 );
156- state -> pc = (unsigned long )__builtin_return_address (0 );
157- state -> ra = 0 ;
158- }
159-
160- state -> task = task ;
161- state -> first = true;
162- state -> pc = unwind_graph_addr (state , state -> pc , state -> sp );
163- get_stack_info (state -> sp , state -> task , & state -> stack_info );
164-
165- if (!unwind_done (state ) && !__kernel_text_address (state -> pc ))
166- unwind_next_frame (state );
167- }
168- EXPORT_SYMBOL_GPL (unwind_start );
169-
170- bool unwind_next_frame (struct unwind_state * state )
119+ static bool next_frame (struct unwind_state * state )
171120{
172- struct stack_info * info = & state -> stack_info ;
173- struct pt_regs * regs ;
174121 unsigned long pc ;
122+ struct pt_regs * regs ;
123+ struct stack_info * info = & state -> stack_info ;
175124
176125 if (unwind_done (state ))
177126 return false;
178127
179128 do {
180- switch (state -> type ) {
181- case UNWINDER_GUESS :
182- state -> first = false;
183- if (unwind_by_guess (state ))
184- return true;
185- break ;
186-
187- case UNWINDER_PROLOGUE :
188- if (unwind_by_prologue (state )) {
189- state -> pc = unwind_graph_addr (state , state -> pc , state -> sp );
190- return true;
191- }
129+ if (unwind_by_prologue (state )) {
130+ state -> pc = unwind_graph_addr (state , state -> pc , state -> sp );
131+ return true;
132+ }
192133
193- if (info -> type == STACK_TYPE_IRQ &&
194- info -> end == state -> sp ) {
195- regs = (struct pt_regs * )info -> next_sp ;
196- pc = regs -> csr_era ;
134+ if (info -> type == STACK_TYPE_IRQ && info -> end == state -> sp ) {
135+ regs = (struct pt_regs * )info -> next_sp ;
136+ pc = regs -> csr_era ;
197137
198- if (user_mode (regs ) || !__kernel_text_address (pc ))
199- return false;
138+ if (user_mode (regs ) || !__kernel_text_address (pc ))
139+ return false;
200140
201- state -> first = true;
202- state -> ra = regs -> regs [ 1 ] ;
203- state -> sp = regs -> regs [3 ];
204- state -> pc = pc ;
205- get_stack_info (state -> sp , state -> task , info );
141+ state -> first = true;
142+ state -> pc = pc ;
143+ state -> ra = regs -> regs [1 ];
144+ state -> sp = regs -> regs [ 3 ] ;
145+ get_stack_info (state -> sp , state -> task , info );
206146
207- return true;
208- }
147+ return true;
209148 }
210149
211150 state -> sp = info -> next_sp ;
@@ -214,4 +153,36 @@ bool unwind_next_frame(struct unwind_state *state)
214153
215154 return false;
216155}
156+
157+ unsigned long unwind_get_return_address (struct unwind_state * state )
158+ {
159+ return __unwind_get_return_address (state );
160+ }
161+ EXPORT_SYMBOL_GPL (unwind_get_return_address );
162+
163+ void unwind_start (struct unwind_state * state , struct task_struct * task ,
164+ struct pt_regs * regs )
165+ {
166+ __unwind_start (state , task , regs );
167+ state -> type = UNWINDER_PROLOGUE ;
168+ state -> first = true;
169+
170+ /*
171+ * The current PC is not kernel text address, we cannot find its
172+ * relative symbol. Thus, prologue analysis will be broken. Luckily,
173+ * we can use the default_next_frame().
174+ */
175+ if (!__kernel_text_address (state -> pc )) {
176+ state -> type = UNWINDER_GUESS ;
177+ if (!unwind_done (state ))
178+ unwind_next_frame (state );
179+ }
180+ }
181+ EXPORT_SYMBOL_GPL (unwind_start );
182+
183+ bool unwind_next_frame (struct unwind_state * state )
184+ {
185+ return state -> type == UNWINDER_PROLOGUE ?
186+ next_frame (state ) : default_next_frame (state );
187+ }
217188EXPORT_SYMBOL_GPL (unwind_next_frame );
0 commit comments