hc
2023-02-13 e440ec23c5a540cdd3f7464e8779219be6fd3d95
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