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