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

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

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  *  linux/arch/arm/lib/backtrace.S
  4  *
  5  *  Copyright (C) 1995, 1996 Russell King
  6  *
  7  * 27/03/03 Ian Molton Clean up CONFIG_CPU
  8  */
  9 #include <linux/kern_levels.h>
 10 #include <linux/linkage.h>
 11 #include <asm/assembler.h>
 12                 .text
 13 
 14 @ fp is 0 or stack frame
 15 
 16 #define frame   r4
 17 #define sv_fp   r5
 18 #define sv_pc   r6
 19 #define mask    r7
 20 #define offset  r8
 21 #define loglvl  r9
 22 
 23 ENTRY(c_backtrace)
 24 
 25 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
 26                 ret     lr
 27 ENDPROC(c_backtrace)
 28 #else
 29                 stmfd   sp!, {r4 - r9, lr}      @ Save an extra register so we have a location...
 30                 movs    frame, r0               @ if frame pointer is zero
 31                 beq     no_frame                @ we have no stack frames
 32                 mov     loglvl, r2
 33 
 34                 tst     r1, #0x10               @ 26 or 32-bit mode?
 35  ARM(           moveq   mask, #0xfc000003       )
 36  THUMB(         moveq   mask, #0xfc000000       )
 37  THUMB(         orreq   mask, #0x03             )
 38                 movne   mask, #0                @ mask for 32-bit
 39 
 40 1:              stmfd   sp!, {pc}               @ calculate offset of PC stored
 41                 ldr     r0, [sp], #4            @ by stmfd for this CPU
 42                 adr     r1, 1b
 43                 sub     offset, r0, r1
 44 
 45 /*
 46  * Stack frame layout:
 47  *             optionally saved caller registers (r4 - r10)
 48  *             saved fp
 49  *             saved sp
 50  *             saved lr
 51  *    frame => saved pc
 52  *             optionally saved arguments (r0 - r3)
 53  * saved sp => <next word>
 54  *
 55  * Functions start with the following code sequence:
 56  *                  mov   ip, sp
 57  *                  stmfd sp!, {r0 - r3} (optional)
 58  * corrected pc =>  stmfd sp!, {..., fp, ip, lr, pc}
 59  */
 60 for_each_frame: tst     frame, mask             @ Check for address exceptions
 61                 bne     no_frame
 62 
 63 1001:           ldr     sv_pc, [frame, #0]      @ get saved pc
 64 1002:           ldr     sv_fp, [frame, #-12]    @ get saved fp
 65 
 66                 sub     sv_pc, sv_pc, offset    @ Correct PC for prefetching
 67                 bic     sv_pc, sv_pc, mask      @ mask PC/LR for the mode
 68 
 69 1003:           ldr     r2, [sv_pc, #-4]        @ if stmfd sp!, {args} exists,
 70                 ldr     r3, .Ldsi+4             @ adjust saved 'pc' back one
 71                 teq     r3, r2, lsr #11         @ instruction
 72                 subne   r0, sv_pc, #4           @ allow for mov
 73                 subeq   r0, sv_pc, #8           @ allow for mov + stmia
 74 
 75                 ldr     r1, [frame, #-4]        @ get saved lr
 76                 mov     r2, frame
 77                 bic     r1, r1, mask            @ mask PC/LR for the mode
 78                 mov     r3, loglvl
 79                 bl      dump_backtrace_entry
 80 
 81                 ldr     r1, [sv_pc, #-4]        @ if stmfd sp!, {args} exists,
 82                 ldr     r3, .Ldsi+4
 83                 teq     r3, r1, lsr #11
 84                 ldreq   r0, [frame, #-8]        @ get sp
 85                 subeq   r0, r0, #4              @ point at the last arg
 86                 mov     r2, loglvl
 87                 bleq    dump_backtrace_stm      @ dump saved registers
 88 
 89 1004:           ldr     r1, [sv_pc, #0]         @ if stmfd sp!, {..., fp, ip, lr, pc}
 90                 ldr     r3, .Ldsi               @ instruction exists,
 91                 teq     r3, r1, lsr #11
 92                 subeq   r0, frame, #16
 93                 mov     r2, loglvl
 94                 bleq    dump_backtrace_stm      @ dump saved registers
 95 
 96                 teq     sv_fp, #0               @ zero saved fp means
 97                 beq     no_frame                @ no further frames
 98 
 99                 cmp     sv_fp, frame            @ next frame must be
100                 mov     frame, sv_fp            @ above the current frame
101 #ifdef CONFIG_IRQSTACKS
102                 @
103                 @ Kernel stacks may be discontiguous in memory. If the next
104                 @ frame is below the previous frame, accept it as long as it
105                 @ lives in kernel memory.
106                 @
107                 cmpls   sv_fp, #PAGE_OFFSET
108 #endif
109                 bhi     for_each_frame
110 
111 1006:           adr     r0, .Lbad
112                 mov     r1, loglvl
113                 mov     r2, frame
114                 bl      _printk
115 no_frame:       ldmfd   sp!, {r4 - r9, pc}
116 ENDPROC(c_backtrace)
117                 
118                 .pushsection __ex_table,"a"
119                 .align  3
120                 .long   1001b, 1006b
121                 .long   1002b, 1006b
122                 .long   1003b, 1006b
123                 .long   1004b, 1006b
124                 .popsection
125 
126 .Lbad:          .asciz  "%sBacktrace aborted due to bad frame pointer <%p>\n"
127                 .align
128 .Ldsi:          .word   0xe92dd800 >> 11        @ stmfd sp!, {... fp, ip, lr, pc}
129                 .word   0xe92d0000 >> 11        @ stmfd sp!, {}
130 
131 #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