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:41 -0500 |
| commit | 1301a44e77557e928700f91c7083c5770054c212 (patch) | |
| tree | a2bb5e3dae59f410a2030790e1f2cdf2071e4487 /kernel/trace | |
| parent | 3fd996a29515df23b3f20c36d69788a3707254a9 (diff) | |
tracing/probes: Move 'symbol' fetch method to kprobes
Move existing functions to trace_kprobe.c and add NULL entries to the
uprobes fetch type table. I don't make them static since some generic
routines like update/free_XXX_fetch_param() require pointers to the
functions.
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/trace')
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 59 | ||||
| -rw-r--r-- | kernel/trace/trace_probe.c | 59 | ||||
| -rw-r--r-- | kernel/trace/trace_probe.h | 24 | ||||
| -rw-r--r-- | kernel/trace/trace_uprobe.c | 8 |
4 files changed, 91 insertions, 59 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 389f9e4744c8..d2a4fd2fd8c1 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -88,6 +88,51 @@ 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 | /* Memory fetching by symbol */ | ||
| 92 | struct symbol_cache { | ||
| 93 | char *symbol; | ||
| 94 | long offset; | ||
| 95 | unsigned long addr; | ||
| 96 | }; | ||
| 97 | |||
| 98 | unsigned long update_symbol_cache(struct symbol_cache *sc) | ||
| 99 | { | ||
| 100 | sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol); | ||
| 101 | |||
| 102 | if (sc->addr) | ||
| 103 | sc->addr += sc->offset; | ||
| 104 | |||
| 105 | return sc->addr; | ||
| 106 | } | ||
| 107 | |||
| 108 | void free_symbol_cache(struct symbol_cache *sc) | ||
| 109 | { | ||
| 110 | kfree(sc->symbol); | ||
| 111 | kfree(sc); | ||
| 112 | } | ||
| 113 | |||
| 114 | struct symbol_cache *alloc_symbol_cache(const char *sym, long offset) | ||
| 115 | { | ||
| 116 | struct symbol_cache *sc; | ||
| 117 | |||
| 118 | if (!sym || strlen(sym) == 0) | ||
| 119 | return NULL; | ||
| 120 | |||
| 121 | sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL); | ||
| 122 | if (!sc) | ||
| 123 | return NULL; | ||
| 124 | |||
| 125 | sc->symbol = kstrdup(sym, GFP_KERNEL); | ||
| 126 | if (!sc->symbol) { | ||
| 127 | kfree(sc); | ||
| 128 | return NULL; | ||
| 129 | } | ||
| 130 | sc->offset = offset; | ||
| 131 | update_symbol_cache(sc); | ||
| 132 | |||
| 133 | return sc; | ||
| 134 | } | ||
| 135 | |||
| 91 | /* | 136 | /* |
| 92 | * Kprobes-specific fetch functions | 137 | * Kprobes-specific fetch functions |
| 93 | */ | 138 | */ |
| @@ -103,6 +148,20 @@ DEFINE_BASIC_FETCH_FUNCS(stack) | |||
| 103 | #define fetch_stack_string NULL | 148 | #define fetch_stack_string NULL |
| 104 | #define fetch_stack_string_size NULL | 149 | #define fetch_stack_string_size NULL |
| 105 | 150 | ||
| 151 | #define DEFINE_FETCH_symbol(type) \ | ||
| 152 | __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, \ | ||
| 153 | void *data, void *dest) \ | ||
| 154 | { \ | ||
| 155 | struct symbol_cache *sc = data; \ | ||
| 156 | if (sc->addr) \ | ||
| 157 | fetch_memory_##type(regs, (void *)sc->addr, dest); \ | ||
| 158 | else \ | ||
| 159 | *(type *)dest = 0; \ | ||
| 160 | } | ||
| 161 | DEFINE_BASIC_FETCH_FUNCS(symbol) | ||
| 162 | DEFINE_FETCH_symbol(string) | ||
| 163 | DEFINE_FETCH_symbol(string_size) | ||
| 164 | |||
| 106 | /* Fetch type information table */ | 165 | /* Fetch type information table */ |
| 107 | const struct fetch_type kprobes_fetch_type_table[] = { | 166 | const struct fetch_type kprobes_fetch_type_table[] = { |
| 108 | /* Special types */ | 167 | /* Special types */ |
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 77aa7d18821e..a31ad478b7f6 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
| @@ -180,65 +180,6 @@ __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, | |||
| 180 | *(u32 *)dest = len; | 180 | *(u32 *)dest = len; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /* Memory fetching by symbol */ | ||
| 184 | struct symbol_cache { | ||
| 185 | char *symbol; | ||
| 186 | long offset; | ||
| 187 | unsigned long addr; | ||
| 188 | }; | ||
| 189 | |||
| 190 | static unsigned long update_symbol_cache(struct symbol_cache *sc) | ||
| 191 | { | ||
| 192 | sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol); | ||
| 193 | |||
| 194 | if (sc->addr) | ||
| 195 | sc->addr += sc->offset; | ||
| 196 | |||
| 197 | return sc->addr; | ||
| 198 | } | ||
| 199 | |||
| 200 | static void free_symbol_cache(struct symbol_cache *sc) | ||
| 201 | { | ||
| 202 | kfree(sc->symbol); | ||
| 203 | kfree(sc); | ||
| 204 | } | ||
| 205 | |||
| 206 | static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset) | ||
| 207 | { | ||
| 208 | struct symbol_cache *sc; | ||
| 209 | |||
| 210 | if (!sym || strlen(sym) == 0) | ||
| 211 | return NULL; | ||
| 212 | |||
| 213 | sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL); | ||
| 214 | if (!sc) | ||
| 215 | return NULL; | ||
| 216 | |||
| 217 | sc->symbol = kstrdup(sym, GFP_KERNEL); | ||
| 218 | if (!sc->symbol) { | ||
| 219 | kfree(sc); | ||
| 220 | return NULL; | ||
| 221 | } | ||
| 222 | sc->offset = offset; | ||
| 223 | update_symbol_cache(sc); | ||
| 224 | |||
| 225 | return sc; | ||
| 226 | } | ||
| 227 | |||
| 228 | #define DEFINE_FETCH_symbol(type) \ | ||
| 229 | __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, \ | ||
| 230 | void *data, void *dest) \ | ||
| 231 | { \ | ||
| 232 | struct symbol_cache *sc = data; \ | ||
| 233 | if (sc->addr) \ | ||
| 234 | fetch_memory_##type(regs, (void *)sc->addr, dest); \ | ||
| 235 | else \ | ||
| 236 | *(type *)dest = 0; \ | ||
| 237 | } | ||
| 238 | DEFINE_BASIC_FETCH_FUNCS(symbol) | ||
| 239 | DEFINE_FETCH_symbol(string) | ||
| 240 | DEFINE_FETCH_symbol(string_size) | ||
| 241 | |||
| 242 | /* Dereference memory access function */ | 183 | /* Dereference memory access function */ |
| 243 | struct deref_fetch_param { | 184 | struct deref_fetch_param { |
| 244 | struct fetch_param orig; | 185 | struct fetch_param orig; |
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 8211dd674ab6..8be84550ceb3 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h | |||
| @@ -239,6 +239,30 @@ ASSIGN_FETCH_FUNC(bitfield, ftype), \ | |||
| 239 | extern __weak const struct fetch_type kprobes_fetch_type_table[]; | 239 | extern __weak const struct fetch_type kprobes_fetch_type_table[]; |
| 240 | extern __weak const struct fetch_type uprobes_fetch_type_table[]; | 240 | extern __weak const struct fetch_type uprobes_fetch_type_table[]; |
| 241 | 241 | ||
| 242 | #ifdef CONFIG_KPROBE_EVENT | ||
| 243 | struct symbol_cache; | ||
| 244 | unsigned long update_symbol_cache(struct symbol_cache *sc); | ||
| 245 | void free_symbol_cache(struct symbol_cache *sc); | ||
| 246 | struct symbol_cache *alloc_symbol_cache(const char *sym, long offset); | ||
| 247 | #else | ||
| 248 | struct symbol_cache { | ||
| 249 | }; | ||
| 250 | static inline unsigned long __used update_symbol_cache(struct symbol_cache *sc) | ||
| 251 | { | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | static inline void __used free_symbol_cache(struct symbol_cache *sc) | ||
| 256 | { | ||
| 257 | } | ||
| 258 | |||
| 259 | static inline struct symbol_cache * __used | ||
| 260 | alloc_symbol_cache(const char *sym, long offset) | ||
| 261 | { | ||
| 262 | return NULL; | ||
| 263 | } | ||
| 264 | #endif /* CONFIG_KPROBE_EVENT */ | ||
| 265 | |||
| 242 | struct probe_arg { | 266 | struct probe_arg { |
| 243 | struct fetch_param fetch; | 267 | struct fetch_param fetch; |
| 244 | struct fetch_param fetch_size; | 268 | struct fetch_param fetch_size; |
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 5395d37e5e72..24ef6a33d93f 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
| @@ -115,6 +115,14 @@ DEFINE_BASIC_FETCH_FUNCS(stack) | |||
| 115 | #define fetch_stack_string_size NULL | 115 | #define fetch_stack_string_size NULL |
| 116 | 116 | ||
| 117 | 117 | ||
| 118 | /* uprobes do not support symbol fetch methods */ | ||
| 119 | #define fetch_symbol_u8 NULL | ||
| 120 | #define fetch_symbol_u16 NULL | ||
| 121 | #define fetch_symbol_u32 NULL | ||
| 122 | #define fetch_symbol_u64 NULL | ||
| 123 | #define fetch_symbol_string NULL | ||
| 124 | #define fetch_symbol_string_size NULL | ||
| 125 | |||
| 118 | /* Fetch type information table */ | 126 | /* Fetch type information table */ |
| 119 | const struct fetch_type uprobes_fetch_type_table[] = { | 127 | const struct fetch_type uprobes_fetch_type_table[] = { |
| 120 | /* Special types */ | 128 | /* Special types */ |
