~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/lib/backtrace-clang.S

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/lib/backtrace-clang.S (Version linux-6.11-rc3) and /arch/alpha/lib/backtrace-clang.S (Version linux-6.1.104)


  1 /* SPDX-License-Identifier: GPL-2.0-only */       
  2 /*                                                
  3  *  linux/arch/arm/lib/backtrace-clang.S          
  4  *                                                
  5  *  Copyright (C) 2019 Nathan Huckleberry         
  6  *                                                
  7  */                                               
  8 #include <linux/kern_levels.h>                    
  9 #include <linux/linkage.h>                        
 10 #include <asm/assembler.h>                        
 11                 .text                             
 12                                                   
 13 /* fp is 0 or stack frame */                      
 14                                                   
 15 #define frame   r4                                
 16 #define sv_fp   r5                                
 17 #define sv_pc   r6                                
 18 #define mask    r7                                
 19 #define sv_lr   r8                                
 20 #define loglvl  r9                                
 21                                                   
 22 ENTRY(c_backtrace)                                
 23                                                   
 24 #if !defined(CONFIG_FRAME_POINTER) || !defined    
 25                 ret     lr                        
 26 ENDPROC(c_backtrace)                              
 27 #else                                             
 28                                                   
 29                                                   
 30 /*                                                
 31  * Clang does not store pc or sp in function p    
 32  * where the function starts.                     
 33  *                                                
 34  * We can treat the current frame's lr as the     
 35  * frame's lr as the current frame's lr, but w    
 36  * call.  Inserting a false stack frame allows    
 37  * called last in the stacktrace.                 
 38  *                                                
 39  * If the call instruction was a bl we can loo    
 40  * instruction to calculate the saved pc.  We     
 41  * but in cases such as calling function point    
 42  * default to using the lr. This will be some     
 43  * not be the function start.                     
 44  *                                                
 45  * Unfortunately due to the stack frame layout    
 46  * are less frequently saved.                     
 47  *                                                
 48  * Stack frame layout:                            
 49  *              <larger addresses>                
 50  *              saved lr                          
 51  *      frame=> saved fp                          
 52  *              optionally saved caller regist    
 53  *              optionally saved arguments (r0    
 54  *              <top of stack frame>              
 55  *              <smaller addresses>               
 56  *                                                
 57  * Functions start with the following code seq    
 58  * corrected pc =>  stmfd sp!, {..., fp, lr}      
 59  *              add fp, sp, #x                    
 60  *              stmfd sp!, {r0 - r3} (optional    
 61  *                                                
 62  *                                                
 63  *                                                
 64  *                                                
 65  *                                                
 66  *                                                
 67  * The diagram below shows an example stack se    
 68  *                                                
 69  * The frame for c_backtrace has pointers to t    
 70  * why the frame of c_backtrace is used to for    
 71  * dump_stack. This is why we must move back a    
 72  *                                                
 73  * The stored locals for dump_stack are in dum    
 74  * to fully print dump_stack's frame we need b    
 75  * locals) and the frame that was called by du    
 76  *                                                
 77  * To print locals we must know where the func    
 78  * function prologue opcodes we can determine     
 79  * stack frame.                                   
 80  *                                                
 81  * To find the function start of dump_stack we    
 82  * show_stack. It points at the instruction di    
 83  * We can then read the offset from the bl opc    
 84  * takes us.  The address calculated must be t    
 85  *                                                
 86  * c_backtrace frame           dump_stack:        
 87  * {[LR]    }  ============|   ...                
 88  * {[FP]    }  =======|    |   bl c_backtrace     
 89  *                    |    |=> ...                
 90  * {[R4-R10]}         |                           
 91  * {[R0-R3] }         |        show_stack:        
 92  * dump_stack frame   |        ...                
 93  * {[LR]    } =============|   bl dump_stack      
 94  * {[FP]    } <=======|    |=> ...                
 95  * {[R4-R10]}                                     
 96  * {[R0-R3] }                                     
 97  */                                               
 98                                                   
 99                 stmfd   sp!, {r4 - r9, fp, lr}    
100                                                   
101                 movs    frame, r0                 
102                 beq     no_frame                  
103                 mov     loglvl, r2                
104                 tst     r1, #0x10                 
105                 moveq   mask, #0xfc000003         
106                 movne   mask, #0                  
107                                                   
108 /*                                                
109  * Switches the current frame to be the frame     
110  */                                               
111                 add     frame, sp, #24            
112 for_each_frame: tst     frame, mask               
113                 bne     no_frame                  
114                                                   
115 /*                                                
116  * sv_fp is the stack frame with the locals fo    
117  * function.                                      
118  *                                                
119  * sv_pc is the saved lr frame the frame above    
120  * address within the current considered funct    
121  * start. This value gets updated to be the fu    
122  * possible.                                      
123  */                                               
124 1001:           ldr     sv_pc, [frame, #4]        
125 1002:           ldr     sv_fp, [frame, #0]        
126                                                   
127                 teq     sv_fp, mask               
128                 beq     no_frame                  
129                                                   
130 /*                                                
131  * sv_lr is the lr from the function that call    
132  * a pointer to a code address in the current     
133  * the instruction used to call the current fu    
134  *                                                
135  * This sv_lr can be used to calculate the fun    
136  * called using a bl instruction. If the funct    
137  * is overwritten with the function start.        
138  *                                                
139  * If the current function was called using a     
140  * recover the function start and instead cont    
141  * value within the current function. If this     
142  * registers for the current function, but the    
143  * properly.                                      
144  */                                               
145 1003:           ldr     sv_lr, [sv_fp, #4]        
146                                                   
147 1004:           ldr     r0, [sv_lr, #-4]          
148                 ldr     r3, .Lopcode+4            
149                 and     r2, r3, r0                
150                 teq     r2, r3                    
151                 bne     finished_setup            
152                 and     r0, #0xffffff             
153                 lsl     r0, r0, #8                
154                 asr     r0, r0, #8                
155                 ldr     sv_pc, [sv_fp, #4]        
156                 add     sv_pc, sv_pc, #-4         
157                 add     sv_pc, sv_pc, #8          
158                 add     sv_pc, sv_pc, r0, lsl     
159                                                   
160 finished_setup:                                   
161                                                   
162                 bic     sv_pc, sv_pc, mask        
163                                                   
164 /*                                                
165  * Print the function (sv_pc) and where it was    
166  */                                               
167                 mov     r0, sv_pc                 
168                                                   
169                 mov     r1, sv_lr                 
170                 mov     r2, frame                 
171                 bic     r1, r1, mask              
172                 mov     r3, loglvl                
173                 bl      dump_backtrace_entry      
174                                                   
175 /*                                                
176  * Test if the function start is a stmfd instr    
177  * registers were stored in the function prolo    
178  *                                                
179  * If we could not recover the sv_pc because w    
180  * pointer the comparison will fail and no reg    
181  * continue as if there had been no registers     
182  */                                               
183 1005:           ldr     r1, [sv_pc, #0]           
184                 ldr     r3, .Lopcode              
185                 teq     r3, r1, lsr #11           
186                 ldr     r0, [frame]               
187                                                   
188                 subeq   r0, r0, #4                
189                 mov     r2, loglvl                
190                 bleq    dump_backtrace_stm        
191                                                   
192 /*                                                
193  * If we are out of frames or if the next fram    
194  */                                               
195                 teq     sv_fp, #0                 
196                 beq     no_frame                  
197                                                   
198                 cmp     sv_fp, frame              
199                 mov     frame, sv_fp              
200 #ifdef CONFIG_IRQSTACKS                           
201                 @                                 
202                 @ Kernel stacks may be discont    
203                 @ frame is below the previous     
204                 @ lives in kernel memory.         
205                 @                                 
206                 cmpls   sv_fp, #PAGE_OFFSET       
207 #endif                                            
208                 bhi     for_each_frame            
209                                                   
210 1006:           adr     r0, .Lbad                 
211                 mov     r1, loglvl                
212                 mov     r2, frame                 
213                 bl      _printk                   
214 no_frame:       ldmfd   sp!, {r4 - r9, fp, pc}    
215 ENDPROC(c_backtrace)                              
216                 .pushsection __ex_table,"a"       
217                 .align  3                         
218                 .long   1001b, 1006b              
219                 .long   1002b, 1006b              
220                 .long   1003b, 1006b              
221                 .long   1004b, finished_setup     
222                 .long   1005b, 1006b              
223                 .popsection                       
224                                                   
225 .Lbad:          .asciz  "%sBacktrace aborted d    
226                 .align                            
227 .Lopcode:       .word   0xe92d4800 >> 11          
228                 .word   0x0b000000                
229                                                   
230 #endif                                            
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php