| .. | .. |
|---|
| 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 |
|---|