diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2013-11-26 01:21:04 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2014-01-02 16:17:40 -0500 |
commit | 3fd996a29515df23b3f20c36d69788a3707254a9 (patch) | |
tree | 7b6b4484ec5da2e1a63993705d978f50ac16b3ac /kernel | |
parent | 34fee3a104cea1c4b658e51836e4bcd99bd76c70 (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.c | 15 | ||||
-rw-r--r-- | kernel/trace/trace_probe.c | 22 | ||||
-rw-r--r-- | kernel/trace/trace_probe.h | 14 | ||||
-rw-r--r-- | kernel/trace/trace_uprobe.c | 41 |
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); | |||
88 | static int kretprobe_dispatcher(struct kretprobe_instance *ri, | 88 | static 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) \ | ||
95 | static __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 | } | ||
101 | DEFINE_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 */ |
92 | const struct fetch_type kprobes_fetch_type_table[] = { | 107 | const 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 | ||
71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | 71 | const 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) \ | ||
78 | DEFINE_FETCH_##method(u8) \ | ||
79 | DEFINE_FETCH_##method(u16) \ | ||
80 | DEFINE_FETCH_##method(u32) \ | ||
81 | DEFINE_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 | } | ||
112 | DEFINE_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 | ||
170 | DECLARE_BASIC_FETCH_FUNCS(stack); | ||
171 | #define fetch_stack_string NULL | ||
172 | #define fetch_stack_string_size NULL | ||
173 | |||
174 | DECLARE_BASIC_FETCH_FUNCS(retval); | 170 | DECLARE_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) \ | ||
195 | DEFINE_FETCH_##method(u8) \ | ||
196 | DEFINE_FETCH_##method(u16) \ | ||
197 | DEFINE_FETCH_##method(u32) \ | ||
198 | DEFINE_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); | |||
74 | static int uretprobe_dispatcher(struct uprobe_consumer *con, | 74 | static 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 | ||
78 | static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n) | ||
79 | { | ||
80 | return addr - (n * sizeof(long)); | ||
81 | } | ||
82 | #else | ||
83 | static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n) | ||
84 | { | ||
85 | return addr + (n * sizeof(long)); | ||
86 | } | ||
87 | #endif | ||
88 | |||
89 | static 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) \ | ||
106 | static __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 | } | ||
112 | DEFINE_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 */ |
78 | const struct fetch_type uprobes_fetch_type_table[] = { | 119 | const struct fetch_type uprobes_fetch_type_table[] = { |
79 | /* Special types */ | 120 | /* Special types */ |