.. | .. |
---|
10 | 10 | #include <asm/ftrace.h> |
---|
11 | 11 | #include <asm/nospec-branch.h> |
---|
12 | 12 | #include <asm/frame.h> |
---|
| 13 | +#include <asm/asm-offsets.h> |
---|
13 | 14 | |
---|
14 | | -#ifdef CC_USING_FENTRY |
---|
15 | | -# define function_hook __fentry__ |
---|
16 | | -EXPORT_SYMBOL(__fentry__) |
---|
17 | | -#else |
---|
18 | | -# define function_hook mcount |
---|
19 | | -EXPORT_SYMBOL(mcount) |
---|
20 | | -#endif |
---|
21 | | - |
---|
22 | | -#ifdef CONFIG_DYNAMIC_FTRACE |
---|
23 | | - |
---|
24 | | -/* mcount uses a frame pointer even if CONFIG_FRAME_POINTER is not set */ |
---|
25 | | -#if !defined(CC_USING_FENTRY) || defined(CONFIG_FRAME_POINTER) |
---|
26 | | -# define USING_FRAME_POINTER |
---|
27 | | -#endif |
---|
28 | | - |
---|
29 | | -#ifdef USING_FRAME_POINTER |
---|
| 15 | +#ifdef CONFIG_FRAME_POINTER |
---|
30 | 16 | # define MCOUNT_FRAME 1 /* using frame = true */ |
---|
31 | 17 | #else |
---|
32 | 18 | # define MCOUNT_FRAME 0 /* using frame = false */ |
---|
33 | 19 | #endif |
---|
34 | 20 | |
---|
35 | | -ENTRY(function_hook) |
---|
36 | | - ret |
---|
37 | | -END(function_hook) |
---|
| 21 | +SYM_FUNC_START(__fentry__) |
---|
| 22 | + RET |
---|
| 23 | +SYM_FUNC_END(__fentry__) |
---|
| 24 | +EXPORT_SYMBOL(__fentry__) |
---|
38 | 25 | |
---|
39 | | -ENTRY(ftrace_caller) |
---|
| 26 | +SYM_CODE_START(ftrace_caller) |
---|
40 | 27 | |
---|
41 | | -#ifdef USING_FRAME_POINTER |
---|
42 | | -# ifdef CC_USING_FENTRY |
---|
| 28 | +#ifdef CONFIG_FRAME_POINTER |
---|
43 | 29 | /* |
---|
44 | 30 | * Frame pointers are of ip followed by bp. |
---|
45 | 31 | * Since fentry is an immediate jump, we are left with |
---|
.. | .. |
---|
50 | 36 | pushl %ebp |
---|
51 | 37 | movl %esp, %ebp |
---|
52 | 38 | pushl 2*4(%esp) /* function ip */ |
---|
53 | | -# endif |
---|
| 39 | + |
---|
54 | 40 | /* For mcount, the function ip is directly above */ |
---|
55 | 41 | pushl %ebp |
---|
56 | 42 | movl %esp, %ebp |
---|
.. | .. |
---|
60 | 46 | pushl %edx |
---|
61 | 47 | pushl $0 /* Pass NULL as regs pointer */ |
---|
62 | 48 | |
---|
63 | | -#ifdef USING_FRAME_POINTER |
---|
| 49 | +#ifdef CONFIG_FRAME_POINTER |
---|
64 | 50 | /* Load parent ebp into edx */ |
---|
65 | 51 | movl 4*4(%esp), %edx |
---|
66 | 52 | #else |
---|
.. | .. |
---|
83 | 69 | popl %edx |
---|
84 | 70 | popl %ecx |
---|
85 | 71 | popl %eax |
---|
86 | | -#ifdef USING_FRAME_POINTER |
---|
| 72 | +#ifdef CONFIG_FRAME_POINTER |
---|
87 | 73 | popl %ebp |
---|
88 | | -# ifdef CC_USING_FENTRY |
---|
89 | 74 | addl $4,%esp /* skip function ip */ |
---|
90 | 75 | popl %ebp /* this is the orig bp */ |
---|
91 | 76 | addl $4, %esp /* skip parent ip */ |
---|
92 | | -# endif |
---|
93 | 77 | #endif |
---|
94 | 78 | .Lftrace_ret: |
---|
95 | 79 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
---|
.. | .. |
---|
99 | 83 | #endif |
---|
100 | 84 | |
---|
101 | 85 | /* This is weak to keep gas from relaxing the jumps */ |
---|
102 | | -WEAK(ftrace_stub) |
---|
103 | | - ret |
---|
104 | | -END(ftrace_caller) |
---|
| 86 | +SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK) |
---|
| 87 | + RET |
---|
| 88 | +SYM_CODE_END(ftrace_caller) |
---|
105 | 89 | |
---|
106 | | -ENTRY(ftrace_regs_caller) |
---|
| 90 | +SYM_CODE_START(ftrace_regs_caller) |
---|
107 | 91 | /* |
---|
108 | | - * i386 does not save SS and ESP when coming from kernel. |
---|
109 | | - * Instead, to get sp, ®s->sp is used (see ptrace.h). |
---|
110 | | - * Unfortunately, that means eflags must be at the same location |
---|
111 | | - * as the current return ip is. We move the return ip into the |
---|
112 | | - * regs->ip location, and move flags into the return ip location. |
---|
| 92 | + * We're here from an mcount/fentry CALL, and the stack frame looks like: |
---|
| 93 | + * |
---|
| 94 | + * <previous context> |
---|
| 95 | + * RET-IP |
---|
| 96 | + * |
---|
| 97 | + * The purpose of this function is to call out in an emulated INT3 |
---|
| 98 | + * environment with a stack frame like: |
---|
| 99 | + * |
---|
| 100 | + * <previous context> |
---|
| 101 | + * gap / RET-IP |
---|
| 102 | + * gap |
---|
| 103 | + * gap |
---|
| 104 | + * gap |
---|
| 105 | + * pt_regs |
---|
| 106 | + * |
---|
| 107 | + * We do _NOT_ restore: ss, flags, cs, gs, fs, es, ds |
---|
113 | 108 | */ |
---|
114 | | - pushl $__KERNEL_CS |
---|
115 | | - pushl 4(%esp) /* Save the return ip */ |
---|
116 | | - pushl $0 /* Load 0 into orig_ax */ |
---|
| 109 | + subl $3*4, %esp # RET-IP + 3 gaps |
---|
| 110 | + pushl %ss # ss |
---|
| 111 | + pushl %esp # points at ss |
---|
| 112 | + addl $5*4, (%esp) # make it point at <previous context> |
---|
| 113 | + pushfl # flags |
---|
| 114 | + pushl $__KERNEL_CS # cs |
---|
| 115 | + pushl 7*4(%esp) # ip <- RET-IP |
---|
| 116 | + pushl $0 # orig_eax |
---|
| 117 | + |
---|
117 | 118 | pushl %gs |
---|
118 | 119 | pushl %fs |
---|
119 | 120 | pushl %es |
---|
120 | 121 | pushl %ds |
---|
| 122 | + |
---|
121 | 123 | pushl %eax |
---|
122 | | - |
---|
123 | | - /* Get flags and place them into the return ip slot */ |
---|
124 | | - pushf |
---|
125 | | - popl %eax |
---|
126 | | - movl %eax, 8*4(%esp) |
---|
127 | | - |
---|
128 | 124 | pushl %ebp |
---|
129 | 125 | pushl %edi |
---|
130 | 126 | pushl %esi |
---|
.. | .. |
---|
134 | 130 | |
---|
135 | 131 | ENCODE_FRAME_POINTER |
---|
136 | 132 | |
---|
137 | | - movl 12*4(%esp), %eax /* Load ip (1st parameter) */ |
---|
138 | | - subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ |
---|
139 | | -#ifdef CC_USING_FENTRY |
---|
140 | | - movl 15*4(%esp), %edx /* Load parent ip (2nd parameter) */ |
---|
141 | | -#else |
---|
142 | | - movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ |
---|
143 | | -#endif |
---|
144 | | - movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ |
---|
145 | | - pushl %esp /* Save pt_regs as 4th parameter */ |
---|
| 133 | + movl PT_EIP(%esp), %eax # 1st argument: IP |
---|
| 134 | + subl $MCOUNT_INSN_SIZE, %eax |
---|
| 135 | + movl 21*4(%esp), %edx # 2nd argument: parent ip |
---|
| 136 | + movl function_trace_op, %ecx # 3rd argument: ftrace_pos |
---|
| 137 | + pushl %esp # 4th argument: pt_regs |
---|
146 | 138 | |
---|
147 | | -GLOBAL(ftrace_regs_call) |
---|
| 139 | +SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) |
---|
148 | 140 | call ftrace_stub |
---|
149 | 141 | |
---|
150 | | - addl $4, %esp /* Skip pt_regs */ |
---|
| 142 | + addl $4, %esp # skip 4th argument |
---|
151 | 143 | |
---|
152 | | - /* restore flags */ |
---|
153 | | - push 14*4(%esp) |
---|
154 | | - popf |
---|
| 144 | + /* place IP below the new SP */ |
---|
| 145 | + movl PT_OLDESP(%esp), %eax |
---|
| 146 | + movl PT_EIP(%esp), %ecx |
---|
| 147 | + movl %ecx, -4(%eax) |
---|
155 | 148 | |
---|
156 | | - /* Move return ip back to its original location */ |
---|
157 | | - movl 12*4(%esp), %eax |
---|
158 | | - movl %eax, 14*4(%esp) |
---|
| 149 | + /* place EAX below that */ |
---|
| 150 | + movl PT_EAX(%esp), %ecx |
---|
| 151 | + movl %ecx, -8(%eax) |
---|
159 | 152 | |
---|
160 | 153 | popl %ebx |
---|
161 | 154 | popl %ecx |
---|
.. | .. |
---|
163 | 156 | popl %esi |
---|
164 | 157 | popl %edi |
---|
165 | 158 | popl %ebp |
---|
166 | | - popl %eax |
---|
167 | | - popl %ds |
---|
168 | | - popl %es |
---|
169 | | - popl %fs |
---|
170 | | - popl %gs |
---|
171 | 159 | |
---|
172 | | - /* use lea to not affect flags */ |
---|
173 | | - lea 3*4(%esp), %esp /* Skip orig_ax, ip and cs */ |
---|
| 160 | + lea -8(%eax), %esp |
---|
| 161 | + popl %eax |
---|
174 | 162 | |
---|
175 | 163 | jmp .Lftrace_ret |
---|
176 | | -#else /* ! CONFIG_DYNAMIC_FTRACE */ |
---|
177 | | - |
---|
178 | | -ENTRY(function_hook) |
---|
179 | | - cmpl $__PAGE_OFFSET, %esp |
---|
180 | | - jb ftrace_stub /* Paging not enabled yet? */ |
---|
181 | | - |
---|
182 | | - cmpl $ftrace_stub, ftrace_trace_function |
---|
183 | | - jnz .Ltrace |
---|
184 | | -#ifdef CONFIG_FUNCTION_GRAPH_TRACER |
---|
185 | | - cmpl $ftrace_stub, ftrace_graph_return |
---|
186 | | - jnz ftrace_graph_caller |
---|
187 | | - |
---|
188 | | - cmpl $ftrace_graph_entry_stub, ftrace_graph_entry |
---|
189 | | - jnz ftrace_graph_caller |
---|
190 | | -#endif |
---|
191 | | -.globl ftrace_stub |
---|
192 | | -ftrace_stub: |
---|
193 | | - ret |
---|
194 | | - |
---|
195 | | - /* taken from glibc */ |
---|
196 | | -.Ltrace: |
---|
197 | | - pushl %eax |
---|
198 | | - pushl %ecx |
---|
199 | | - pushl %edx |
---|
200 | | - movl 0xc(%esp), %eax |
---|
201 | | - movl 0x4(%ebp), %edx |
---|
202 | | - subl $MCOUNT_INSN_SIZE, %eax |
---|
203 | | - |
---|
204 | | - movl ftrace_trace_function, %ecx |
---|
205 | | - CALL_NOSPEC %ecx |
---|
206 | | - |
---|
207 | | - popl %edx |
---|
208 | | - popl %ecx |
---|
209 | | - popl %eax |
---|
210 | | - jmp ftrace_stub |
---|
211 | | -END(function_hook) |
---|
212 | | -#endif /* CONFIG_DYNAMIC_FTRACE */ |
---|
| 164 | +SYM_CODE_END(ftrace_regs_caller) |
---|
213 | 165 | |
---|
214 | 166 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
---|
215 | | -ENTRY(ftrace_graph_caller) |
---|
| 167 | +SYM_CODE_START(ftrace_graph_caller) |
---|
216 | 168 | pushl %eax |
---|
217 | 169 | pushl %ecx |
---|
218 | 170 | pushl %edx |
---|
219 | 171 | movl 3*4(%esp), %eax |
---|
220 | 172 | /* Even with frame pointers, fentry doesn't have one here */ |
---|
221 | | -#ifdef CC_USING_FENTRY |
---|
222 | 173 | lea 4*4(%esp), %edx |
---|
223 | 174 | movl $0, %ecx |
---|
224 | | -#else |
---|
225 | | - lea 0x4(%ebp), %edx |
---|
226 | | - movl (%ebp), %ecx |
---|
227 | | -#endif |
---|
228 | 175 | subl $MCOUNT_INSN_SIZE, %eax |
---|
229 | 176 | call prepare_ftrace_return |
---|
230 | 177 | popl %edx |
---|
231 | 178 | popl %ecx |
---|
232 | 179 | popl %eax |
---|
233 | | - ret |
---|
234 | | -END(ftrace_graph_caller) |
---|
| 180 | + RET |
---|
| 181 | +SYM_CODE_END(ftrace_graph_caller) |
---|
235 | 182 | |
---|
236 | 183 | .globl return_to_handler |
---|
237 | 184 | return_to_handler: |
---|
238 | 185 | pushl %eax |
---|
239 | 186 | pushl %edx |
---|
240 | | -#ifdef CC_USING_FENTRY |
---|
241 | 187 | movl $0, %eax |
---|
242 | | -#else |
---|
243 | | - movl %ebp, %eax |
---|
244 | | -#endif |
---|
245 | 188 | call ftrace_return_to_handler |
---|
246 | 189 | movl %eax, %ecx |
---|
247 | 190 | popl %edx |
---|
248 | 191 | popl %eax |
---|
249 | | - JMP_NOSPEC %ecx |
---|
| 192 | + JMP_NOSPEC ecx |
---|
250 | 193 | #endif |
---|