Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | /* * MIPS specific _mcount support * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive for * more details. * * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China * Copyright (C) 2010 DSLab, Lanzhou University, China * Author: Wu Zhangjin <wuzhangjin@gmail.com> */ #include <asm/export.h> #include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/ftrace.h> .text .set noreorder .set noat .macro MCOUNT_SAVE_REGS PTR_SUBU sp, PT_SIZE PTR_S ra, PT_R31(sp) PTR_S AT, PT_R1(sp) PTR_S a0, PT_R4(sp) PTR_S a1, PT_R5(sp) PTR_S a2, PT_R6(sp) PTR_S a3, PT_R7(sp) #ifdef CONFIG_64BIT PTR_S a4, PT_R8(sp) PTR_S a5, PT_R9(sp) PTR_S a6, PT_R10(sp) PTR_S a7, PT_R11(sp) #endif .endm .macro MCOUNT_RESTORE_REGS PTR_L ra, PT_R31(sp) PTR_L AT, PT_R1(sp) PTR_L a0, PT_R4(sp) PTR_L a1, PT_R5(sp) PTR_L a2, PT_R6(sp) PTR_L a3, PT_R7(sp) #ifdef CONFIG_64BIT PTR_L a4, PT_R8(sp) PTR_L a5, PT_R9(sp) PTR_L a6, PT_R10(sp) PTR_L a7, PT_R11(sp) #endif PTR_ADDIU sp, PT_SIZE .endm .macro RETURN_BACK jr ra move ra, AT .endm /* * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass * the location of the parent's return address. */ #define MCOUNT_RA_ADDRESS_REG $12 #ifdef CONFIG_DYNAMIC_FTRACE NESTED(ftrace_caller, PT_SIZE, ra) .globl _mcount _mcount: EXPORT_SYMBOL(_mcount) b ftrace_stub #ifdef CONFIG_32BIT addiu sp,sp,8 #else nop #endif /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ MCOUNT_SAVE_REGS #ifdef KBUILD_MCOUNT_RA_ADDRESS PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp) #endif PTR_SUBU a0, ra, 8 /* arg1: self address */ PTR_LA t1, _stext sltu t2, a0, t1 /* t2 = (a0 < _stext) */ PTR_LA t1, _etext sltu t3, t1, a0 /* t3 = (a0 > _etext) */ or t1, t2, t3 beqz t1, ftrace_call nop #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */ #else PTR_SUBU a0, a0, 12 #endif .globl ftrace_call ftrace_call: nop /* a placeholder for the call to a real tracing function */ move a1, AT /* arg2: parent's return address */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_call ftrace_graph_call: nop nop #endif MCOUNT_RESTORE_REGS .globl ftrace_stub ftrace_stub: RETURN_BACK END(ftrace_caller) #else /* ! CONFIG_DYNAMIC_FTRACE */ NESTED(_mcount, PT_SIZE, ra) EXPORT_SYMBOL(_mcount) PTR_LA t1, ftrace_stub PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ beq t1, t2, fgraph_trace nop MCOUNT_SAVE_REGS move a0, ra /* arg1: self return address */ jalr t2 /* (1) call *ftrace_trace_function */ move a1, AT /* arg2: parent's return address */ MCOUNT_RESTORE_REGS fgraph_trace: #ifdef CONFIG_FUNCTION_GRAPH_TRACER PTR_LA t1, ftrace_stub PTR_L t3, ftrace_graph_return bne t1, t3, ftrace_graph_caller nop PTR_LA t1, ftrace_graph_entry_stub PTR_L t3, ftrace_graph_entry bne t1, t3, ftrace_graph_caller nop #endif #ifdef CONFIG_32BIT addiu sp, sp, 8 #endif .globl ftrace_stub ftrace_stub: RETURN_BACK END(_mcount) #endif /* ! CONFIG_DYNAMIC_FTRACE */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER NESTED(ftrace_graph_caller, PT_SIZE, ra) #ifndef CONFIG_DYNAMIC_FTRACE MCOUNT_SAVE_REGS #endif /* arg1: Get the location of the parent's return address */ #ifdef KBUILD_MCOUNT_RA_ADDRESS #ifdef CONFIG_DYNAMIC_FTRACE PTR_L a0, PT_R12(sp) #else move a0, MCOUNT_RA_ADDRESS_REG #endif bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */ nop #endif PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */ 1: /* arg2: Get self return address */ #ifdef CONFIG_DYNAMIC_FTRACE PTR_L a1, PT_R31(sp) #else move a1, ra #endif /* arg3: Get frame pointer of current stack */ #ifdef CONFIG_64BIT PTR_LA a2, PT_SIZE(sp) #else PTR_LA a2, (PT_SIZE+8)(sp) #endif jal prepare_ftrace_return nop MCOUNT_RESTORE_REGS #ifndef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_32BIT addiu sp, sp, 8 #endif #endif RETURN_BACK END(ftrace_graph_caller) .align 2 .globl return_to_handler return_to_handler: PTR_SUBU sp, PT_SIZE PTR_S v0, PT_R2(sp) jal ftrace_return_to_handler PTR_S v1, PT_R3(sp) /* restore the real parent address: v0 -> ra */ move ra, v0 PTR_L v0, PT_R2(sp) PTR_L v1, PT_R3(sp) jr ra PTR_ADDIU sp, PT_SIZE #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ .set at .set reorder |