mcount.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
  3. *
  4. * This file implements mcount(), which is used to collect profiling data.
  5. * This can also be tweaked for kernel stack overflow detection.
  6. */
  7. #include <linux/linkage.h>
  8. #include <asm/ptrace.h>
  9. #include <asm/thread_info.h>
  10. /*
  11. * This is the main variant and is called by C code. GCC's -pg option
  12. * automatically instruments every C function with a call to this.
  13. */
  14. #ifdef CONFIG_STACK_DEBUG
  15. #define OVSTACKSIZE 4096 /* lets hope this is enough */
  16. .data
  17. .align 8
  18. panicstring:
  19. .asciz "Stack overflow\n"
  20. .align 8
  21. ovstack:
  22. .skip OVSTACKSIZE
  23. #endif
  24. .text
  25. .align 32
  26. .globl _mcount
  27. .type _mcount,#function
  28. .globl mcount
  29. .type mcount,#function
  30. _mcount:
  31. mcount:
  32. #ifdef CONFIG_STACK_DEBUG
  33. /*
  34. * Check whether %sp is dangerously low.
  35. */
  36. ldub [%g6 + TI_FPDEPTH], %g1
  37. srl %g1, 1, %g3
  38. add %g3, 1, %g3
  39. sllx %g3, 8, %g3 ! each fpregs frame is 256b
  40. add %g3, 192, %g3
  41. add %g6, %g3, %g3 ! where does task_struct+frame end?
  42. sub %g3, STACK_BIAS, %g3
  43. cmp %sp, %g3
  44. bg,pt %xcc, 1f
  45. nop
  46. lduh [%g6 + TI_CPU], %g1
  47. sethi %hi(hardirq_stack), %g3
  48. or %g3, %lo(hardirq_stack), %g3
  49. sllx %g1, 3, %g1
  50. ldx [%g3 + %g1], %g7
  51. sub %g7, STACK_BIAS, %g7
  52. cmp %sp, %g7
  53. bleu,pt %xcc, 2f
  54. sethi %hi(THREAD_SIZE), %g3
  55. add %g7, %g3, %g7
  56. cmp %sp, %g7
  57. blu,pn %xcc, 1f
  58. 2: sethi %hi(softirq_stack), %g3
  59. or %g3, %lo(softirq_stack), %g3
  60. ldx [%g3 + %g1], %g7
  61. sub %g7, STACK_BIAS, %g7
  62. cmp %sp, %g7
  63. bleu,pt %xcc, 3f
  64. sethi %hi(THREAD_SIZE), %g3
  65. add %g7, %g3, %g7
  66. cmp %sp, %g7
  67. blu,pn %xcc, 1f
  68. nop
  69. /* If we are already on ovstack, don't hop onto it
  70. * again, we are already trying to output the stack overflow
  71. * message.
  72. */
  73. 3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
  74. or %g7, %lo(ovstack), %g7
  75. add %g7, OVSTACKSIZE, %g3
  76. sub %g3, STACK_BIAS + 192, %g3
  77. sub %g7, STACK_BIAS, %g7
  78. cmp %sp, %g7
  79. blu,pn %xcc, 2f
  80. cmp %sp, %g3
  81. bleu,pn %xcc, 1f
  82. nop
  83. 2: mov %g3, %sp
  84. sethi %hi(panicstring), %g3
  85. call prom_printf
  86. or %g3, %lo(panicstring), %o0
  87. call prom_halt
  88. nop
  89. 1:
  90. #endif
  91. #ifdef CONFIG_FUNCTION_TRACER
  92. #ifdef CONFIG_DYNAMIC_FTRACE
  93. mov %o7, %o0
  94. .globl mcount_call
  95. mcount_call:
  96. call ftrace_stub
  97. mov %o0, %o7
  98. #else
  99. sethi %hi(ftrace_trace_function), %g1
  100. sethi %hi(ftrace_stub), %g2
  101. ldx [%g1 + %lo(ftrace_trace_function)], %g1
  102. or %g2, %lo(ftrace_stub), %g2
  103. cmp %g1, %g2
  104. be,pn %icc, 1f
  105. mov %i7, %o1
  106. jmpl %g1, %g0
  107. mov %o7, %o0
  108. /* not reached */
  109. 1:
  110. #endif
  111. #endif
  112. retl
  113. nop
  114. .size _mcount,.-_mcount
  115. .size mcount,.-mcount
  116. #ifdef CONFIG_FUNCTION_TRACER
  117. .globl ftrace_stub
  118. .type ftrace_stub,#function
  119. ftrace_stub:
  120. retl
  121. nop
  122. .size ftrace_stub,.-ftrace_stub
  123. #ifdef CONFIG_DYNAMIC_FTRACE
  124. .globl ftrace_caller
  125. .type ftrace_caller,#function
  126. ftrace_caller:
  127. mov %i7, %o1
  128. mov %o7, %o0
  129. .globl ftrace_call
  130. ftrace_call:
  131. call ftrace_stub
  132. mov %o0, %o7
  133. retl
  134. nop
  135. .size ftrace_caller,.-ftrace_caller
  136. #endif
  137. #endif