backtrace.S 3.1 KB

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