diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-07-10 20:29:03 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-07-10 21:08:01 -0400 |
commit | 327933f5d6cdf083284d3c06e0370d1de464aef4 (patch) | |
tree | 38046aa3e6b605bf4e16c5d7ac3968f5fa656e8f /arch/sh/lib | |
parent | b99610fb9cdf390965c62c22322596d961591160 (diff) |
sh: Function graph tracer support
Add both dynamic and static function graph tracer support for sh.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/lib')
-rw-r--r-- | arch/sh/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/sh/lib/mcount.S | 117 |
2 files changed, 117 insertions, 1 deletions
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index aaea580b65bb..19328d90a2d1 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile | |||
@@ -25,6 +25,7 @@ memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o | |||
25 | 25 | ||
26 | lib-$(CONFIG_MMU) += copy_page.o clear_page.o | 26 | lib-$(CONFIG_MMU) += copy_page.o clear_page.o |
27 | lib-$(CONFIG_FUNCTION_TRACER) += mcount.o | 27 | lib-$(CONFIG_FUNCTION_TRACER) += mcount.o |
28 | lib-$(CONFIG_FUNCTION_GRAPH_TRACER) += mcount.o | ||
28 | lib-y += $(memcpy-y) $(udivsi3-y) | 29 | lib-y += $(memcpy-y) $(udivsi3-y) |
29 | 30 | ||
30 | EXTRA_CFLAGS += -Werror | 31 | EXTRA_CFLAGS += -Werror |
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 8596483f7b41..bd3ec648becc 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S | |||
@@ -111,14 +111,62 @@ mcount_call: | |||
111 | jsr @r6 | 111 | jsr @r6 |
112 | nop | 112 | nop |
113 | 113 | ||
114 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
115 | mov.l .Lftrace_graph_return, r6 | ||
116 | mov.l .Lftrace_stub, r7 | ||
117 | cmp/eq r6, r7 | ||
118 | bt 1f | ||
119 | |||
120 | mov.l .Lftrace_graph_caller, r0 | ||
121 | jmp @r0 | ||
122 | nop | ||
123 | |||
124 | 1: | ||
125 | mov.l .Lftrace_graph_entry, r6 | ||
126 | mov.l .Lftrace_graph_entry_stub, r7 | ||
127 | cmp/eq r6, r7 | ||
128 | bt skip_trace | ||
129 | |||
130 | mov.l .Lftrace_graph_caller, r0 | ||
131 | jmp @r0 | ||
132 | nop | ||
133 | |||
134 | .align 2 | ||
135 | .Lftrace_graph_return: | ||
136 | .long ftrace_graph_return | ||
137 | .Lftrace_graph_entry: | ||
138 | .long ftrace_graph_entry | ||
139 | .Lftrace_graph_entry_stub: | ||
140 | .long ftrace_graph_entry_stub | ||
141 | .Lftrace_graph_caller: | ||
142 | .long ftrace_graph_caller | ||
143 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
144 | |||
145 | .globl skip_trace | ||
114 | skip_trace: | 146 | skip_trace: |
115 | MCOUNT_LEAVE() | 147 | MCOUNT_LEAVE() |
116 | 148 | ||
117 | .align 2 | 149 | .align 2 |
118 | .Lftrace_trace_function: | 150 | .Lftrace_trace_function: |
119 | .long ftrace_trace_function | 151 | .long ftrace_trace_function |
120 | 152 | ||
121 | #ifdef CONFIG_DYNAMIC_FTRACE | 153 | #ifdef CONFIG_DYNAMIC_FTRACE |
154 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
155 | /* | ||
156 | * NOTE: Do not move either ftrace_graph_call or ftrace_caller | ||
157 | * as this will affect the calculation of GRAPH_INSN_OFFSET. | ||
158 | */ | ||
159 | .globl ftrace_graph_call | ||
160 | ftrace_graph_call: | ||
161 | mov.l .Lskip_trace, r0 | ||
162 | jmp @r0 | ||
163 | nop | ||
164 | |||
165 | .align 2 | ||
166 | .Lskip_trace: | ||
167 | .long skip_trace | ||
168 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
169 | |||
122 | .globl ftrace_caller | 170 | .globl ftrace_caller |
123 | ftrace_caller: | 171 | ftrace_caller: |
124 | mov.l .Lfunction_trace_stop, r0 | 172 | mov.l .Lfunction_trace_stop, r0 |
@@ -136,7 +184,12 @@ ftrace_call: | |||
136 | jsr @r6 | 184 | jsr @r6 |
137 | nop | 185 | nop |
138 | 186 | ||
187 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
188 | bra ftrace_graph_call | ||
189 | nop | ||
190 | #else | ||
139 | MCOUNT_LEAVE() | 191 | MCOUNT_LEAVE() |
192 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
140 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 193 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
141 | 194 | ||
142 | /* | 195 | /* |
@@ -188,3 +241,65 @@ stack_panic: | |||
188 | .Lpanic_str: | 241 | .Lpanic_str: |
189 | .string "Stack error" | 242 | .string "Stack error" |
190 | #endif /* CONFIG_STACK_DEBUG */ | 243 | #endif /* CONFIG_STACK_DEBUG */ |
244 | |||
245 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
246 | .globl ftrace_graph_caller | ||
247 | ftrace_graph_caller: | ||
248 | mov.l 2f, r0 | ||
249 | mov.l @r0, r0 | ||
250 | tst r0, r0 | ||
251 | bt 1f | ||
252 | |||
253 | mov.l 3f, r1 | ||
254 | jmp @r1 | ||
255 | nop | ||
256 | 1: | ||
257 | /* | ||
258 | * MCOUNT_ENTER() pushed 5 registers onto the stack, so | ||
259 | * the stack address containing our return address is | ||
260 | * r15 + 20. | ||
261 | */ | ||
262 | mov #20, r0 | ||
263 | add r15, r0 | ||
264 | mov r0, r4 | ||
265 | |||
266 | mov.l .Lprepare_ftrace_return, r0 | ||
267 | jsr @r0 | ||
268 | nop | ||
269 | |||
270 | MCOUNT_LEAVE() | ||
271 | |||
272 | .align 2 | ||
273 | 2: .long function_trace_stop | ||
274 | 3: .long skip_trace | ||
275 | .Lprepare_ftrace_return: | ||
276 | .long prepare_ftrace_return | ||
277 | |||
278 | .globl return_to_handler | ||
279 | return_to_handler: | ||
280 | /* | ||
281 | * Save the return values. | ||
282 | */ | ||
283 | mov.l r0, @-r15 | ||
284 | mov.l r1, @-r15 | ||
285 | |||
286 | mov #0, r4 | ||
287 | |||
288 | mov.l .Lftrace_return_to_handler, r0 | ||
289 | jsr @r0 | ||
290 | nop | ||
291 | |||
292 | /* | ||
293 | * The return value from ftrace_return_handler has the real | ||
294 | * address that we should return to. | ||
295 | */ | ||
296 | lds r0, pr | ||
297 | mov.l @r15+, r1 | ||
298 | rts | ||
299 | mov.l @r15+, r0 | ||
300 | |||
301 | |||
302 | .align 2 | ||
303 | .Lftrace_return_to_handler: | ||
304 | .long ftrace_return_to_handler | ||
305 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||