File tree 3 files changed +61
-2
lines changed
3 files changed +61
-2
lines changed Original file line number Diff line number Diff line change 18
18
19
19
#ifndef __ASSEMBLY__
20
20
extern void _mcount (unsigned long );
21
+ extern void * return_address (unsigned int );
21
22
22
23
struct dyn_arch_ftrace {
23
24
/* No extra data needed for arm64 */
@@ -33,6 +34,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
33
34
*/
34
35
return addr ;
35
36
}
36
- #endif /* __ASSEMBLY__ */
37
+
38
+ #define ftrace_return_address (n ) return_address(n)
39
+ #endif /* ifndef __ASSEMBLY__ */
37
40
38
41
#endif /* __ASM_FTRACE_H */
Original file line number Diff line number Diff line change @@ -7,12 +7,13 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7
7
8
8
CFLAGS_REMOVE_ftrace.o = -pg
9
9
CFLAGS_REMOVE_insn.o = -pg
10
+ CFLAGS_REMOVE_return_address.o = -pg
10
11
11
12
# Object file lists.
12
13
arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
13
14
entry-fpsimd.o process.o ptrace.o setup.o signal.o \
14
15
sys.o stacktrace.o time.o traps.o io.o vdso.o \
15
- hyp-stub.o psci.o cpu_ops.o insn.o
16
+ hyp-stub.o psci.o cpu_ops.o insn.o return_address.o
16
17
17
18
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
18
19
sys_compat.o
Original file line number Diff line number Diff line change
1
+ /*
2
+ * arch/arm64/kernel/return_address.c
3
+ *
4
+ * Copyright (C) 2013 Linaro Limited
5
+ * Author: AKASHI Takahiro <[email protected] >
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License version 2 as
9
+ * published by the Free Software Foundation.
10
+ */
11
+
12
+ #include <linux/export.h>
13
+ #include <linux/ftrace.h>
14
+
15
+ #include <asm/stacktrace.h>
16
+
17
+ struct return_address_data {
18
+ unsigned int level ;
19
+ void * addr ;
20
+ };
21
+
22
+ static int save_return_addr (struct stackframe * frame , void * d )
23
+ {
24
+ struct return_address_data * data = d ;
25
+
26
+ if (!data -> level ) {
27
+ data -> addr = (void * )frame -> pc ;
28
+ return 1 ;
29
+ } else {
30
+ -- data -> level ;
31
+ return 0 ;
32
+ }
33
+ }
34
+
35
+ void * return_address (unsigned int level )
36
+ {
37
+ struct return_address_data data ;
38
+ struct stackframe frame ;
39
+ register unsigned long current_sp asm ("sp" );
40
+
41
+ data .level = level + 2 ;
42
+ data .addr = NULL ;
43
+
44
+ frame .fp = (unsigned long )__builtin_frame_address (0 );
45
+ frame .sp = current_sp ;
46
+ frame .pc = (unsigned long )return_address ; /* dummy */
47
+
48
+ walk_stackframe (& frame , save_return_addr , & data );
49
+
50
+ if (!data .level )
51
+ return data .addr ;
52
+ else
53
+ return NULL ;
54
+ }
55
+ EXPORT_SYMBOL_GPL (return_address );
You can’t perform that action at this time.
0 commit comments