aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-11-26 01:21:04 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-01-02 16:17:40 -0500
commit3fd996a29515df23b3f20c36d69788a3707254a9 (patch)
tree7b6b4484ec5da2e1a63993705d978f50ac16b3ac /kernel
parent34fee3a104cea1c4b658e51836e4bcd99bd76c70 (diff)
tracing/probes: Implement 'stack' fetch method for uprobes
Use separate method to fetch from stack. Move existing functions to trace_kprobe.c and make them static. Also add new stack fetch implementation for uprobes. Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: zhangwei(Jovi) <jovi.zhangwei@huawei.com> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_kprobe.c15
-rw-r--r--kernel/trace/trace_probe.c22
-rw-r--r--kernel/trace/trace_probe.h14
-rw-r--r--kernel/trace/trace_uprobe.c41
4 files changed, 66 insertions, 26 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index fe3f00c381c0..389f9e4744c8 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -88,6 +88,21 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
88static int kretprobe_dispatcher(struct kretprobe_instance *ri, 88static int kretprobe_dispatcher(struct kretprobe_instance *ri,
89 struct pt_regs *regs); 89 struct pt_regs *regs);
90 90
91/*
92 * Kprobes-specific fetch functions
93 */
94#define DEFINE_FETCH_stack(type) \
95static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
96 void *offset, void *dest) \
97{ \
98 *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \
99 (unsigned int)((unsigned long)offset)); \
100}
101DEFINE_BASIC_FETCH_FUNCS(stack)
102/* No string on the stack entry */
103#define fetch_stack_string NULL
104#define fetch_stack_string_size NULL
105
91/* Fetch type information table */ 106/* Fetch type information table */
92const struct fetch_type kprobes_fetch_type_table[] = { 107const struct fetch_type kprobes_fetch_type_table[] = {
93 /* Special types */ 108 /* Special types */
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 541036ec7392..77aa7d18821e 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -70,16 +70,6 @@ __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
70 70
71const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; 71const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
72 72
73/*
74 * Define macro for basic types - we don't need to define s* types, because
75 * we have to care only about bitwidth at recording time.
76 */
77#define DEFINE_BASIC_FETCH_FUNCS(method) \
78DEFINE_FETCH_##method(u8) \
79DEFINE_FETCH_##method(u16) \
80DEFINE_FETCH_##method(u32) \
81DEFINE_FETCH_##method(u64)
82
83#define CHECK_FETCH_FUNCS(method, fn) \ 73#define CHECK_FETCH_FUNCS(method, fn) \
84 (((FETCH_FUNC_NAME(method, u8) == fn) || \ 74 (((FETCH_FUNC_NAME(method, u8) == fn) || \
85 (FETCH_FUNC_NAME(method, u16) == fn) || \ 75 (FETCH_FUNC_NAME(method, u16) == fn) || \
@@ -102,18 +92,6 @@ DEFINE_BASIC_FETCH_FUNCS(reg)
102#define fetch_reg_string NULL 92#define fetch_reg_string NULL
103#define fetch_reg_string_size NULL 93#define fetch_reg_string_size NULL
104 94
105#define DEFINE_FETCH_stack(type) \
106__kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs, \
107 void *offset, void *dest) \
108{ \
109 *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \
110 (unsigned int)((unsigned long)offset)); \
111}
112DEFINE_BASIC_FETCH_FUNCS(stack)
113/* No string on the stack entry */
114#define fetch_stack_string NULL
115#define fetch_stack_string_size NULL
116
117#define DEFINE_FETCH_retval(type) \ 95#define DEFINE_FETCH_retval(type) \
118__kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ 96__kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \
119 void *dummy, void *dest) \ 97 void *dummy, void *dest) \
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 5b77798d1130..8211dd674ab6 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -167,10 +167,6 @@ DECLARE_BASIC_FETCH_FUNCS(reg);
167#define fetch_reg_string NULL 167#define fetch_reg_string NULL
168#define fetch_reg_string_size NULL 168#define fetch_reg_string_size NULL
169 169
170DECLARE_BASIC_FETCH_FUNCS(stack);
171#define fetch_stack_string NULL
172#define fetch_stack_string_size NULL
173
174DECLARE_BASIC_FETCH_FUNCS(retval); 170DECLARE_BASIC_FETCH_FUNCS(retval);
175#define fetch_retval_string NULL 171#define fetch_retval_string NULL
176#define fetch_retval_string_size NULL 172#define fetch_retval_string_size NULL
@@ -191,6 +187,16 @@ DECLARE_BASIC_FETCH_FUNCS(bitfield);
191#define fetch_bitfield_string NULL 187#define fetch_bitfield_string NULL
192#define fetch_bitfield_string_size NULL 188#define fetch_bitfield_string_size NULL
193 189
190/*
191 * Define macro for basic types - we don't need to define s* types, because
192 * we have to care only about bitwidth at recording time.
193 */
194#define DEFINE_BASIC_FETCH_FUNCS(method) \
195DEFINE_FETCH_##method(u8) \
196DEFINE_FETCH_##method(u16) \
197DEFINE_FETCH_##method(u32) \
198DEFINE_FETCH_##method(u64)
199
194/* Default (unsigned long) fetch type */ 200/* Default (unsigned long) fetch type */
195#define __DEFAULT_FETCH_TYPE(t) u##t 201#define __DEFAULT_FETCH_TYPE(t) u##t
196#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t) 202#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 2c60925ea073..5395d37e5e72 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -74,6 +74,47 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
74static int uretprobe_dispatcher(struct uprobe_consumer *con, 74static int uretprobe_dispatcher(struct uprobe_consumer *con,
75 unsigned long func, struct pt_regs *regs); 75 unsigned long func, struct pt_regs *regs);
76 76
77#ifdef CONFIG_STACK_GROWSUP
78static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n)
79{
80 return addr - (n * sizeof(long));
81}
82#else
83static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n)
84{
85 return addr + (n * sizeof(long));
86}
87#endif
88
89static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n)
90{
91 unsigned long ret;
92 unsigned long addr = user_stack_pointer(regs);
93
94 addr = adjust_stack_addr(addr, n);
95
96 if (copy_from_user(&ret, (void __force __user *) addr, sizeof(ret)))
97 return 0;
98
99 return ret;
100}
101
102/*
103 * Uprobes-specific fetch functions
104 */
105#define DEFINE_FETCH_stack(type) \
106static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
107 void *offset, void *dest) \
108{ \
109 *(type *)dest = (type)get_user_stack_nth(regs, \
110 ((unsigned long)offset)); \
111}
112DEFINE_BASIC_FETCH_FUNCS(stack)
113/* No string on the stack entry */
114#define fetch_stack_string NULL
115#define fetch_stack_string_size NULL
116
117
77/* Fetch type information table */ 118/* Fetch type information table */
78const struct fetch_type uprobes_fetch_type_table[] = { 119const struct fetch_type uprobes_fetch_type_table[] = {
79 /* Special types */ 120 /* Special types */