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:43 -0500 |
commit | 5baaa59ef09e8729aef101f7bf7d9d0af00852e3 (patch) | |
tree | adf05e51e33e06d0d9eb9689269364314b754c2c /kernel/trace/trace_uprobe.c | |
parent | 3925f4a5afa489e905a08edffc36a435a3434a63 (diff) |
tracing/probes: Implement 'memory' fetch method for uprobes
Use separate method to fetch from memory. Move existing functions to
trace_kprobe.c and make them static. Also add new memory fetch
implementation for uprobes.
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: Oleg Nesterov <oleg@redhat.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/trace/trace_uprobe.c')
-rw-r--r-- | kernel/trace/trace_uprobe.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 24ef6a33d93f..bebd2f5d9ea3 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -114,6 +114,58 @@ DEFINE_BASIC_FETCH_FUNCS(stack) | |||
114 | #define fetch_stack_string NULL | 114 | #define fetch_stack_string NULL |
115 | #define fetch_stack_string_size NULL | 115 | #define fetch_stack_string_size NULL |
116 | 116 | ||
117 | #define DEFINE_FETCH_memory(type) \ | ||
118 | static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ | ||
119 | void *addr, void *dest) \ | ||
120 | { \ | ||
121 | type retval; \ | ||
122 | void __user *vaddr = (void __force __user *) addr; \ | ||
123 | \ | ||
124 | if (copy_from_user(&retval, vaddr, sizeof(type))) \ | ||
125 | *(type *)dest = 0; \ | ||
126 | else \ | ||
127 | *(type *) dest = retval; \ | ||
128 | } | ||
129 | DEFINE_BASIC_FETCH_FUNCS(memory) | ||
130 | /* | ||
131 | * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max | ||
132 | * length and relative data location. | ||
133 | */ | ||
134 | static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, | ||
135 | void *addr, void *dest) | ||
136 | { | ||
137 | long ret; | ||
138 | u32 rloc = *(u32 *)dest; | ||
139 | int maxlen = get_rloc_len(rloc); | ||
140 | u8 *dst = get_rloc_data(dest); | ||
141 | void __user *src = (void __force __user *) addr; | ||
142 | |||
143 | if (!maxlen) | ||
144 | return; | ||
145 | |||
146 | ret = strncpy_from_user(dst, src, maxlen); | ||
147 | |||
148 | if (ret < 0) { /* Failed to fetch string */ | ||
149 | ((u8 *)get_rloc_data(dest))[0] = '\0'; | ||
150 | *(u32 *)dest = make_data_rloc(0, get_rloc_offs(rloc)); | ||
151 | } else { | ||
152 | *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(rloc)); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, | ||
157 | void *addr, void *dest) | ||
158 | { | ||
159 | int len; | ||
160 | void __user *vaddr = (void __force __user *) addr; | ||
161 | |||
162 | len = strnlen_user(vaddr, MAX_STRING_SIZE); | ||
163 | |||
164 | if (len == 0 || len > MAX_STRING_SIZE) /* Failed to check length */ | ||
165 | *(u32 *)dest = 0; | ||
166 | else | ||
167 | *(u32 *)dest = len; | ||
168 | } | ||
117 | 169 | ||
118 | /* uprobes do not support symbol fetch methods */ | 170 | /* uprobes do not support symbol fetch methods */ |
119 | #define fetch_symbol_u8 NULL | 171 | #define fetch_symbol_u8 NULL |