backtrace.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * linux/arch/arm/lib/backtrace.S
  3. *
  4. * Copyright (C) 1995, 1996 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * 27/03/03 Ian Molton Clean up CONFIG_CPU
  11. *
  12. */
  13. #include <linux/linkage.h>
  14. #include <asm/assembler.h>
  15. .text
  16. @ fp is 0 or stack frame
  17. #define frame r4
  18. #define next r5
  19. #define save r6
  20. #define mask r7
  21. #define offset r8
  22. ENTRY(__backtrace)
  23. mov r1, #0x10
  24. mov r0, fp
  25. ENTRY(c_backtrace)
  26. #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
  27. mov pc, lr
  28. #else
  29. stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
  30. tst r1, #0x10 @ 26 or 32-bit?
  31. moveq mask, #0xfc000003
  32. movne mask, #0
  33. tst mask, r0
  34. movne r0, #0
  35. movs frame, r0
  36. 1: moveq r0, #-2
  37. ldmeqfd sp!, {r4 - r8, pc}
  38. 2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction
  39. ldr r0, [sp], #4
  40. adr r1, 2b - 4
  41. sub offset, r0, r1
  42. 3: tst frame, mask @ Check for address exceptions...
  43. bne 1b
  44. 1001: ldr next, [frame, #-12] @ get fp
  45. 1002: ldr r2, [frame, #-4] @ get lr
  46. 1003: ldr r3, [frame, #0] @ get pc
  47. sub save, r3, offset @ Correct PC for prefetching
  48. bic save, save, mask
  49. 1004: ldr r1, [save, #0] @ get instruction at function
  50. mov r1, r1, lsr #10
  51. ldr r3, .Ldsi+4
  52. teq r1, r3
  53. subeq save, save, #4
  54. mov r0, save
  55. bic r1, r2, mask
  56. bl dump_backtrace_entry
  57. ldr r0, [frame, #-8] @ get sp
  58. sub r0, r0, #4
  59. 1005: ldr r1, [save, #4] @ get instruction at function+4
  60. mov r3, r1, lsr #10
  61. ldr r2, .Ldsi+4
  62. teq r3, r2 @ Check for stmia sp!, {args}
  63. addeq save, save, #4 @ next instruction
  64. bleq .Ldumpstm
  65. sub r0, frame, #16
  66. 1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
  67. mov r3, r1, lsr #10
  68. ldr r2, .Ldsi
  69. teq r3, r2
  70. bleq .Ldumpstm
  71. /*
  72. * A zero next framepointer means we're done.
  73. */
  74. teq next, #0
  75. ldmeqfd sp!, {r4 - r8, pc}
  76. /*
  77. * The next framepointer must be above the
  78. * current framepointer.
  79. */
  80. cmp next, frame
  81. mov frame, next
  82. bhi 3b
  83. b 1007f
  84. /*
  85. * Fixup for LDMDB. Note that this must not be in the fixup section.
  86. */
  87. 1007: ldr r0, =.Lbad
  88. mov r1, frame
  89. bl printk
  90. ldmfd sp!, {r4 - r8, pc}
  91. .ltorg
  92. .section __ex_table,"a"
  93. .align 3
  94. .long 1001b, 1007b
  95. .long 1002b, 1007b
  96. .long 1003b, 1007b
  97. .long 1004b, 1007b
  98. .long 1005b, 1007b
  99. .long 1006b, 1007b
  100. .previous
  101. #define instr r4
  102. #define reg r5
  103. #define stack r6
  104. .Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr}
  105. mov stack, r0
  106. mov instr, r1
  107. mov reg, #9
  108. mov r7, #0
  109. 1: mov r3, #1
  110. tst instr, r3, lsl reg
  111. beq 2f
  112. add r7, r7, #1
  113. teq r7, #4
  114. moveq r7, #0
  115. moveq r3, #'\n'
  116. movne r3, #' '
  117. ldr r2, [stack], #-4
  118. mov r1, reg
  119. adr r0, .Lfp
  120. bl printk
  121. 2: subs reg, reg, #1
  122. bpl 1b
  123. teq r7, #0
  124. adrne r0, .Lcr
  125. blne printk
  126. mov r0, stack
  127. ldmfd sp!, {instr, reg, stack, r7, r8, pc}
  128. .Lfp: .asciz " r%d = %08X%c"
  129. .Lcr: .asciz "\n"
  130. .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
  131. .align
  132. .Ldsi: .word 0x00e92dd8 >> 2
  133. .word 0x00e92d00 >> 2
  134. #endif