backtrace-clang.S 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. /* fp is 0 or stack frame */
  13. #define frame r4
  14. #define sv_fp r5
  15. #define sv_pc r6
  16. #define mask r7
  17. #define sv_lr r8
  18. #define loglvl r9
  19. ENTRY(c_backtrace)
  20. #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
  21. ret lr
  22. ENDPROC(c_backtrace)
  23. #else
  24. /*
  25. * Clang does not store pc or sp in function prologues so we don't know exactly
  26. * where the function starts.
  27. *
  28. * We can treat the current frame's lr as the saved pc and the preceding
  29. * frame's lr as the current frame's lr, but we can't trace the most recent
  30. * call. Inserting a false stack frame allows us to reference the function
  31. * called last in the stacktrace.
  32. *
  33. * If the call instruction was a bl we can look at the callers branch
  34. * instruction to calculate the saved pc. We can recover the pc in most cases,
  35. * but in cases such as calling function pointers we cannot. In this case,
  36. * default to using the lr. This will be some address in the function, but will
  37. * not be the function start.
  38. *
  39. * Unfortunately due to the stack frame layout we can't dump r0 - r3, but these
  40. * are less frequently saved.
  41. *
  42. * Stack frame layout:
  43. * <larger addresses>
  44. * saved lr
  45. * frame=> saved fp
  46. * optionally saved caller registers (r4 - r10)
  47. * optionally saved arguments (r0 - r3)
  48. * <top of stack frame>
  49. * <smaller addresses>
  50. *
  51. * Functions start with the following code sequence:
  52. * corrected pc => stmfd sp!, {..., fp, lr}
  53. * add fp, sp, #x
  54. * stmfd sp!, {r0 - r3} (optional)
  55. *
  56. *
  57. *
  58. *
  59. *
  60. *
  61. * The diagram below shows an example stack setup for dump_stack.
  62. *
  63. * The frame for c_backtrace has pointers to the code of dump_stack. This is
  64. * why the frame of c_backtrace is used to for the pc calculation of
  65. * dump_stack. This is why we must move back a frame to print dump_stack.
  66. *
  67. * The stored locals for dump_stack are in dump_stack's frame. This means that
  68. * to fully print dump_stack's frame we need both the frame for dump_stack (for
  69. * locals) and the frame that was called by dump_stack (for pc).
  70. *
  71. * To print locals we must know where the function start is. If we read the
  72. * function prologue opcodes we can determine which variables are stored in the
  73. * stack frame.
  74. *
  75. * To find the function start of dump_stack we can look at the stored LR of
  76. * show_stack. It points at the instruction directly after the bl dump_stack.
  77. * We can then read the offset from the bl opcode to determine where the branch
  78. * takes us. The address calculated must be the start of dump_stack.
  79. *
  80. * c_backtrace frame dump_stack:
  81. * {[LR] } ============| ...
  82. * {[FP] } =======| | bl c_backtrace
  83. * | |=> ...
  84. * {[R4-R10]} |
  85. * {[R0-R3] } | show_stack:
  86. * dump_stack frame | ...
  87. * {[LR] } =============| bl dump_stack
  88. * {[FP] } <=======| |=> ...
  89. * {[R4-R10]}
  90. * {[R0-R3] }
  91. */
  92. stmfd sp!, {r4 - r9, fp, lr} @ Save an extra register
  93. @ to ensure 8 byte alignment
  94. movs frame, r0 @ if frame pointer is zero
  95. beq no_frame @ we have no stack frames
  96. mov loglvl, r2
  97. tst r1, #0x10 @ 26 or 32-bit mode?
  98. moveq mask, #0xfc000003
  99. movne mask, #0 @ mask for 32-bit
  100. /*
  101. * Switches the current frame to be the frame for dump_stack.
  102. */
  103. add frame, sp, #24 @ switch to false frame
  104. for_each_frame: tst frame, mask @ Check for address exceptions
  105. bne no_frame
  106. /*
  107. * sv_fp is the stack frame with the locals for the current considered
  108. * function.
  109. *
  110. * sv_pc is the saved lr frame the frame above. This is a pointer to a code
  111. * address within the current considered function, but it is not the function
  112. * start. This value gets updated to be the function start later if it is
  113. * possible.
  114. */
  115. 1001: ldr sv_pc, [frame, #4] @ get saved 'pc'
  116. 1002: ldr sv_fp, [frame, #0] @ get saved fp
  117. teq sv_fp, mask @ make sure next frame exists
  118. beq no_frame
  119. /*
  120. * sv_lr is the lr from the function that called the current function. This is
  121. * a pointer to a code address in the current function's caller. sv_lr-4 is
  122. * the instruction used to call the current function.
  123. *
  124. * This sv_lr can be used to calculate the function start if the function was
  125. * called using a bl instruction. If the function start can be recovered sv_pc
  126. * is overwritten with the function start.
  127. *
  128. * If the current function was called using a function pointer we cannot
  129. * recover the function start and instead continue with sv_pc as an arbitrary
  130. * value within the current function. If this is the case we cannot print
  131. * registers for the current function, but the stacktrace is still printed
  132. * properly.
  133. */
  134. 1003: ldr sv_lr, [sv_fp, #4] @ get saved lr from next frame
  135. 1004: ldr r0, [sv_lr, #-4] @ get call instruction
  136. ldr r3, .Lopcode+4
  137. and r2, r3, r0 @ is this a bl call
  138. teq r2, r3
  139. bne finished_setup @ give up if it's not
  140. and r0, #0xffffff @ get call offset 24-bit int
  141. lsl r0, r0, #8 @ sign extend offset
  142. asr r0, r0, #8
  143. ldr sv_pc, [sv_fp, #4] @ get lr address
  144. add sv_pc, sv_pc, #-4 @ get call instruction address
  145. add sv_pc, sv_pc, #8 @ take care of prefetch
  146. add sv_pc, sv_pc, r0, lsl #2@ find function start
  147. finished_setup:
  148. bic sv_pc, sv_pc, mask @ mask PC/LR for the mode
  149. /*
  150. * Print the function (sv_pc) and where it was called from (sv_lr).
  151. */
  152. mov r0, sv_pc
  153. mov r1, sv_lr
  154. mov r2, frame
  155. bic r1, r1, mask @ mask PC/LR for the mode
  156. mov r3, loglvl
  157. bl dump_backtrace_entry
  158. /*
  159. * Test if the function start is a stmfd instruction to determine which
  160. * registers were stored in the function prologue.
  161. *
  162. * If we could not recover the sv_pc because we were called through a function
  163. * pointer the comparison will fail and no registers will print. Unwinding will
  164. * continue as if there had been no registers stored in this frame.
  165. */
  166. 1005: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, lr}
  167. ldr r3, .Lopcode @ instruction exists,
  168. teq r3, r1, lsr #11
  169. ldr r0, [frame] @ locals are stored in
  170. @ the preceding frame
  171. subeq r0, r0, #4
  172. mov r2, loglvl
  173. bleq dump_backtrace_stm @ dump saved registers
  174. /*
  175. * If we are out of frames or if the next frame is invalid.
  176. */
  177. teq sv_fp, #0 @ zero saved fp means
  178. beq no_frame @ no further frames
  179. cmp sv_fp, frame @ next frame must be
  180. mov frame, sv_fp @ above the current frame
  181. #ifdef CONFIG_IRQSTACKS
  182. @
  183. @ Kernel stacks may be discontiguous in memory. If the next
  184. @ frame is below the previous frame, accept it as long as it
  185. @ lives in kernel memory.
  186. @
  187. cmpls sv_fp, #PAGE_OFFSET
  188. #endif
  189. bhi for_each_frame
  190. 1006: adr r0, .Lbad
  191. mov r1, loglvl
  192. mov r2, frame
  193. bl _printk
  194. no_frame: ldmfd sp!, {r4 - r9, fp, pc}
  195. ENDPROC(c_backtrace)
  196. .pushsection __ex_table,"a"
  197. .align 3
  198. .long 1001b, 1006b
  199. .long 1002b, 1006b
  200. .long 1003b, 1006b
  201. .long 1004b, finished_setup
  202. .long 1005b, 1006b
  203. .popsection
  204. .Lbad: .asciz "%sBacktrace aborted due to bad frame pointer <%p>\n"
  205. .align
  206. .Lopcode: .word 0xe92d4800 >> 11 @ stmfd sp!, {... fp, lr}
  207. .word 0x0b000000 @ bl if these bits are set
  208. #endif