diff options
author | David A. Long <dave.long@linaro.org> | 2014-03-07 11:23:04 -0500 |
---|---|---|
committer | David A. Long <dave.long@linaro.org> | 2014-03-18 16:39:40 -0400 |
commit | c7edc9e326d53ca5ef9bed82de0740c6b107d55b (patch) | |
tree | 262d901b5e4d61930d5bc8ff68b9ddd807e3f956 /arch/arm/include/asm | |
parent | b4cd605ca92d9a8a2f71355cb45dd943ebcb0c97 (diff) |
ARM: add uprobes support
Using Rabin Vincent's ARM uprobes patches as a base, enable uprobes
support on ARM.
Caveats:
- Thumb is not supported
Signed-off-by: Rabin Vincent <rabin@rab.in>
Signed-off-by: David A. Long <dave.long@linaro.org>
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r-- | arch/arm/include/asm/ptrace.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/thread_info.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/uprobes.h | 45 |
3 files changed, 55 insertions, 1 deletions
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 04c99f36ff7f..ee688b0a13c3 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -80,6 +80,12 @@ static inline long regs_return_value(struct pt_regs *regs) | |||
80 | 80 | ||
81 | #define instruction_pointer(regs) (regs)->ARM_pc | 81 | #define instruction_pointer(regs) (regs)->ARM_pc |
82 | 82 | ||
83 | static inline void instruction_pointer_set(struct pt_regs *regs, | ||
84 | unsigned long val) | ||
85 | { | ||
86 | instruction_pointer(regs) = val; | ||
87 | } | ||
88 | |||
83 | #ifdef CONFIG_SMP | 89 | #ifdef CONFIG_SMP |
84 | extern unsigned long profile_pc(struct pt_regs *regs); | 90 | extern unsigned long profile_pc(struct pt_regs *regs); |
85 | #else | 91 | #else |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 71a06b293489..f989d7c22dc5 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -153,6 +153,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
153 | #define TIF_SIGPENDING 0 | 153 | #define TIF_SIGPENDING 0 |
154 | #define TIF_NEED_RESCHED 1 | 154 | #define TIF_NEED_RESCHED 1 |
155 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ | 155 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ |
156 | #define TIF_UPROBE 7 | ||
156 | #define TIF_SYSCALL_TRACE 8 | 157 | #define TIF_SYSCALL_TRACE 8 |
157 | #define TIF_SYSCALL_AUDIT 9 | 158 | #define TIF_SYSCALL_AUDIT 9 |
158 | #define TIF_SYSCALL_TRACEPOINT 10 | 159 | #define TIF_SYSCALL_TRACEPOINT 10 |
@@ -165,6 +166,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
165 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 166 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
166 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 167 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
167 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | 168 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
169 | #define _TIF_UPROBE (1 << TIF_UPROBE) | ||
168 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 170 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
169 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 171 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
170 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) | 172 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) |
@@ -178,7 +180,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
178 | /* | 180 | /* |
179 | * Change these and you break ASM code in entry-common.S | 181 | * Change these and you break ASM code in entry-common.S |
180 | */ | 182 | */ |
181 | #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) | 183 | #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ |
184 | _TIF_NOTIFY_RESUME | _TIF_UPROBE) | ||
182 | 185 | ||
183 | #endif /* __KERNEL__ */ | 186 | #endif /* __KERNEL__ */ |
184 | #endif /* __ASM_ARM_THREAD_INFO_H */ | 187 | #endif /* __ASM_ARM_THREAD_INFO_H */ |
diff --git a/arch/arm/include/asm/uprobes.h b/arch/arm/include/asm/uprobes.h new file mode 100644 index 000000000000..9472c20b7d49 --- /dev/null +++ b/arch/arm/include/asm/uprobes.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Rabin Vincent <rabin at rab.in> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_UPROBES_H | ||
10 | #define _ASM_UPROBES_H | ||
11 | |||
12 | #include <asm/probes.h> | ||
13 | #include <asm/opcodes.h> | ||
14 | |||
15 | typedef u32 uprobe_opcode_t; | ||
16 | |||
17 | #define MAX_UINSN_BYTES 4 | ||
18 | #define UPROBE_XOL_SLOT_BYTES 64 | ||
19 | |||
20 | #define UPROBE_SWBP_ARM_INSN 0xe7f001f9 | ||
21 | #define UPROBE_SS_ARM_INSN 0xe7f001fa | ||
22 | #define UPROBE_SWBP_INSN __opcode_to_mem_arm(UPROBE_SWBP_ARM_INSN) | ||
23 | #define UPROBE_SWBP_INSN_SIZE 4 | ||
24 | |||
25 | struct arch_uprobe_task { | ||
26 | u32 backup; | ||
27 | unsigned long saved_trap_no; | ||
28 | }; | ||
29 | |||
30 | struct arch_uprobe { | ||
31 | u8 insn[MAX_UINSN_BYTES]; | ||
32 | unsigned long ixol[2]; | ||
33 | uprobe_opcode_t bpinsn; | ||
34 | bool simulate; | ||
35 | u32 pcreg; | ||
36 | void (*prehandler)(struct arch_uprobe *auprobe, | ||
37 | struct arch_uprobe_task *autask, | ||
38 | struct pt_regs *regs); | ||
39 | void (*posthandler)(struct arch_uprobe *auprobe, | ||
40 | struct arch_uprobe_task *autask, | ||
41 | struct pt_regs *regs); | ||
42 | struct arch_probes_insn asi; | ||
43 | }; | ||
44 | |||
45 | #endif | ||