![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * linux/arch/arm/lib/backtrace-clang.S 0004 * 0005 * Copyright (C) 2019 Nathan Huckleberry 0006 * 0007 */ 0008 #include <linux/kern_levels.h> 0009 #include <linux/linkage.h> 0010 #include <asm/assembler.h> 0011 .text 0012 0013 /* fp is 0 or stack frame */ 0014 0015 #define frame r4 0016 #define sv_fp r5 0017 #define sv_pc r6 0018 #define mask r7 0019 #define sv_lr r8 0020 #define loglvl r9 0021 0022 ENTRY(c_backtrace) 0023 0024 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK) 0025 ret lr 0026 ENDPROC(c_backtrace) 0027 #else 0028 0029 0030 /* 0031 * Clang does not store pc or sp in function prologues so we don't know exactly 0032 * where the function starts. 0033 * 0034 * We can treat the current frame's lr as the saved pc and the preceding 0035 * frame's lr as the current frame's lr, but we can't trace the most recent 0036 * call. Inserting a false stack frame allows us to reference the function 0037 * called last in the stacktrace. 0038 * 0039 * If the call instruction was a bl we can look at the callers branch 0040 * instruction to calculate the saved pc. We can recover the pc in most cases, 0041 * but in cases such as calling function pointers we cannot. In this case, 0042 * default to using the lr. This will be some address in the function, but will 0043 * not be the function start. 0044 * 0045 * Unfortunately due to the stack frame layout we can't dump r0 - r3, but these 0046 * are less frequently saved. 0047 * 0048 * Stack frame layout: 0049 * <larger addresses> 0050 * saved lr 0051 * frame=> saved fp 0052 * optionally saved caller registers (r4 - r10) 0053 * optionally saved arguments (r0 - r3) 0054 * <top of stack frame> 0055 * <smaller addresses> 0056 * 0057 * Functions start with the following code sequence: 0058 * corrected pc => stmfd sp!, {..., fp, lr} 0059 * add fp, sp, #x 0060 * stmfd sp!, {r0 - r3} (optional) 0061 * 0062 * 0063 * 0064 * 0065 * 0066 * 0067 * The diagram below shows an example stack setup for dump_stack. 0068 * 0069 * The frame for c_backtrace has pointers to the code of dump_stack. This is 0070 * why the frame of c_backtrace is used to for the pc calculation of 0071 * dump_stack. This is why we must move back a frame to print dump_stack. 0072 * 0073 * The stored locals for dump_stack are in dump_stack's frame. This means that 0074 * to fully print dump_stack's frame we need both the frame for dump_stack (for 0075 * locals) and the frame that was called by dump_stack (for pc). 0076 * 0077 * To print locals we must know where the function start is. If we read the 0078 * function prologue opcodes we can determine which variables are stored in the 0079 * stack frame. 0080 * 0081 * To find the function start of dump_stack we can look at the stored LR of 0082 * show_stack. It points at the instruction directly after the bl dump_stack. 0083 * We can then read the offset from the bl opcode to determine where the branch 0084 * takes us. The address calculated must be the start of dump_stack. 0085 * 0086 * c_backtrace frame dump_stack: 0087 * {[LR] } ============| ... 0088 * {[FP] } =======| | bl c_backtrace 0089 * | |=> ... 0090 * {[R4-R10]} | 0091 * {[R0-R3] } | show_stack: 0092 * dump_stack frame | ... 0093 * {[LR] } =============| bl dump_stack 0094 * {[FP] } <=======| |=> ... 0095 * {[R4-R10]} 0096 * {[R0-R3] } 0097 */ 0098 0099 stmfd sp!, {r4 - r9, fp, lr} @ Save an extra register 0100 @ to ensure 8 byte alignment 0101 movs frame, r0 @ if frame pointer is zero 0102 beq no_frame @ we have no stack frames 0103 mov loglvl, r2 0104 tst r1, #0x10 @ 26 or 32-bit mode? 0105 moveq mask, #0xfc000003 0106 movne mask, #0 @ mask for 32-bit 0107 0108 /* 0109 * Switches the current frame to be the frame for dump_stack. 0110 */ 0111 add frame, sp, #24 @ switch to false frame 0112 for_each_frame: tst frame, mask @ Check for address exceptions 0113 bne no_frame 0114 0115 /* 0116 * sv_fp is the stack frame with the locals for the current considered 0117 * function. 0118 * 0119 * sv_pc is the saved lr frame the frame above. This is a pointer to a code 0120 * address within the current considered function, but it is not the function 0121 * start. This value gets updated to be the function start later if it is 0122 * possible. 0123 */ 0124 1001: ldr sv_pc, [frame, #4] @ get saved 'pc' 0125 1002: ldr sv_fp, [frame, #0] @ get saved fp 0126 0127 teq sv_fp, mask @ make sure next frame exists 0128 beq no_frame 0129 0130 /* 0131 * sv_lr is the lr from the function that called the current function. This is 0132 * a pointer to a code address in the current function's caller. sv_lr-4 is 0133 * the instruction used to call the current function. 0134 * 0135 * This sv_lr can be used to calculate the function start if the function was 0136 * called using a bl instruction. If the function start can be recovered sv_pc 0137 * is overwritten with the function start. 0138 * 0139 * If the current function was called using a function pointer we cannot 0140 * recover the function start and instead continue with sv_pc as an arbitrary 0141 * value within the current function. If this is the case we cannot print 0142 * registers for the current function, but the stacktrace is still printed 0143 * properly. 0144 */ 0145 1003: ldr sv_lr, [sv_fp, #4] @ get saved lr from next frame 0146 0147 1004: ldr r0, [sv_lr, #-4] @ get call instruction 0148 ldr r3, .Lopcode+4 0149 and r2, r3, r0 @ is this a bl call 0150 teq r2, r3 0151 bne finished_setup @ give up if it's not 0152 and r0, #0xffffff @ get call offset 24-bit int 0153 lsl r0, r0, #8 @ sign extend offset 0154 asr r0, r0, #8 0155 ldr sv_pc, [sv_fp, #4] @ get lr address 0156 add sv_pc, sv_pc, #-4 @ get call instruction address 0157 add sv_pc, sv_pc, #8 @ take care of prefetch 0158 add sv_pc, sv_pc, r0, lsl #2@ find function start 0159 0160 finished_setup: 0161 0162 bic sv_pc, sv_pc, mask @ mask PC/LR for the mode 0163 0164 /* 0165 * Print the function (sv_pc) and where it was called from (sv_lr). 0166 */ 0167 mov r0, sv_pc 0168 0169 mov r1, sv_lr 0170 mov r2, frame 0171 bic r1, r1, mask @ mask PC/LR for the mode 0172 mov r3, loglvl 0173 bl dump_backtrace_entry 0174 0175 /* 0176 * Test if the function start is a stmfd instruction to determine which 0177 * registers were stored in the function prologue. 0178 * 0179 * If we could not recover the sv_pc because we were called through a function 0180 * pointer the comparison will fail and no registers will print. Unwinding will 0181 * continue as if there had been no registers stored in this frame. 0182 */ 0183 1005: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, lr} 0184 ldr r3, .Lopcode @ instruction exists, 0185 teq r3, r1, lsr #11 0186 ldr r0, [frame] @ locals are stored in 0187 @ the preceding frame 0188 subeq r0, r0, #4 0189 mov r2, loglvl 0190 bleq dump_backtrace_stm @ dump saved registers 0191 0192 /* 0193 * If we are out of frames or if the next frame is invalid. 0194 */ 0195 teq sv_fp, #0 @ zero saved fp means 0196 beq no_frame @ no further frames 0197 0198 cmp sv_fp, frame @ next frame must be 0199 mov frame, sv_fp @ above the current frame 0200 #ifdef CONFIG_IRQSTACKS 0201 @ 0202 @ Kernel stacks may be discontiguous in memory. If the next 0203 @ frame is below the previous frame, accept it as long as it 0204 @ lives in kernel memory. 0205 @ 0206 cmpls sv_fp, #PAGE_OFFSET 0207 #endif 0208 bhi for_each_frame 0209 0210 1006: adr r0, .Lbad 0211 mov r1, loglvl 0212 mov r2, frame 0213 bl _printk 0214 no_frame: ldmfd sp!, {r4 - r9, fp, pc} 0215 ENDPROC(c_backtrace) 0216 .pushsection __ex_table,"a" 0217 .align 3 0218 .long 1001b, 1006b 0219 .long 1002b, 1006b 0220 .long 1003b, 1006b 0221 .long 1004b, finished_setup 0222 .long 1005b, 1006b 0223 .popsection 0224 0225 .Lbad: .asciz "%sBacktrace aborted due to bad frame pointer <%p>\n" 0226 .align 0227 .Lopcode: .word 0xe92d4800 >> 11 @ stmfd sp!, {... fp, lr} 0228 .word 0x0b000000 @ bl if these bits are set 0229 0230 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |