aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace/kprobetrace.txt4
-rw-r--r--kernel/trace/trace.h16
-rw-r--r--kernel/trace/trace_kprobe.c535
-rw-r--r--tools/perf/Documentation/perf-probe.txt11
-rw-r--r--tools/perf/builtin-probe.c78
-rw-r--r--tools/perf/util/hist.c28
-rw-r--r--tools/perf/util/probe-event.c898
-rw-r--r--tools/perf/util/probe-event.h33
-rw-r--r--tools/perf/util/probe-finder.c753
-rw-r--r--tools/perf/util/probe-finder.h1
-rw-r--r--tools/perf/util/sort.c42
-rw-r--r--tools/perf/util/sort.h12
12 files changed, 1634 insertions, 777 deletions
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt
index a9100b28eb84..ec94748ae65b 100644
--- a/Documentation/trace/kprobetrace.txt
+++ b/Documentation/trace/kprobetrace.txt
@@ -40,7 +40,9 @@ Synopsis of kprobe_events
40 $stack : Fetch stack address. 40 $stack : Fetch stack address.
41 $retval : Fetch return value.(*) 41 $retval : Fetch return value.(*)
42 +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) 42 +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
43 NAME=FETCHARG: Set NAME as the argument name of FETCHARG. 43 NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
44 FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
45 (u8/u16/u32/u64/s8/s16/s32/s64) are supported.
44 46
45 (*) only for return probe. 47 (*) only for return probe.
46 (**) this is useful for fetching a field of data structures. 48 (**) this is useful for fetching a field of data structures.
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index bec2c973ff0c..3ebdb6bd2362 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -102,29 +102,17 @@ struct syscall_trace_exit {
102 long ret; 102 long ret;
103}; 103};
104 104
105struct kprobe_trace_entry { 105struct kprobe_trace_entry_head {
106 struct trace_entry ent; 106 struct trace_entry ent;
107 unsigned long ip; 107 unsigned long ip;
108 int nargs;
109 unsigned long args[];
110}; 108};
111 109
112#define SIZEOF_KPROBE_TRACE_ENTRY(n) \ 110struct kretprobe_trace_entry_head {
113 (offsetof(struct kprobe_trace_entry, args) + \
114 (sizeof(unsigned long) * (n)))
115
116struct kretprobe_trace_entry {
117 struct trace_entry ent; 111 struct trace_entry ent;
118 unsigned long func; 112 unsigned long func;
119 unsigned long ret_ip; 113 unsigned long ret_ip;
120 int nargs;
121 unsigned long args[];
122}; 114};
123 115
124#define SIZEOF_KRETPROBE_TRACE_ENTRY(n) \
125 (offsetof(struct kretprobe_trace_entry, args) + \
126 (sizeof(unsigned long) * (n)))
127
128/* 116/*
129 * trace_flag_type is an enumeration that holds different 117 * trace_flag_type is an enumeration that holds different
130 * states when a trace occurs. These are: 118 * states when a trace occurs. These are:
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 1251e367bae9..a7514326052b 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -29,6 +29,8 @@
29#include <linux/ctype.h> 29#include <linux/ctype.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/perf_event.h> 31#include <linux/perf_event.h>
32#include <linux/stringify.h>
33#include <asm/bitsperlong.h>
32 34
33#include "trace.h" 35#include "trace.h"
34#include "trace_output.h" 36#include "trace_output.h"
@@ -40,7 +42,6 @@
40 42
41/* Reserved field names */ 43/* Reserved field names */
42#define FIELD_STRING_IP "__probe_ip" 44#define FIELD_STRING_IP "__probe_ip"
43#define FIELD_STRING_NARGS "__probe_nargs"
44#define FIELD_STRING_RETIP "__probe_ret_ip" 45#define FIELD_STRING_RETIP "__probe_ret_ip"
45#define FIELD_STRING_FUNC "__probe_func" 46#define FIELD_STRING_FUNC "__probe_func"
46 47
@@ -52,56 +53,102 @@ const char *reserved_field_names[] = {
52 "common_tgid", 53 "common_tgid",
53 "common_lock_depth", 54 "common_lock_depth",
54 FIELD_STRING_IP, 55 FIELD_STRING_IP,
55 FIELD_STRING_NARGS,
56 FIELD_STRING_RETIP, 56 FIELD_STRING_RETIP,
57 FIELD_STRING_FUNC, 57 FIELD_STRING_FUNC,
58}; 58};
59 59
60struct fetch_func { 60/* Printing function type */
61 unsigned long (*func)(struct pt_regs *, void *); 61typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *);
62#define PRINT_TYPE_FUNC_NAME(type) print_type_##type
63#define PRINT_TYPE_FMT_NAME(type) print_type_format_##type
64
65/* Printing in basic type function template */
66#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast) \
67static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \
68 const char *name, void *data)\
69{ \
70 return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
71} \
72static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
73
74DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
75DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
76DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
77DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
78DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
79DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
80DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
81DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
82
83/* Data fetch function type */
84typedef void (*fetch_func_t)(struct pt_regs *, void *, void *);
85
86struct fetch_param {
87 fetch_func_t fn;
62 void *data; 88 void *data;
63}; 89};
64 90
65static __kprobes unsigned long call_fetch(struct fetch_func *f, 91static __kprobes void call_fetch(struct fetch_param *fprm,
66 struct pt_regs *regs) 92 struct pt_regs *regs, void *dest)
67{ 93{
68 return f->func(regs, f->data); 94 return fprm->fn(regs, fprm->data, dest);
69} 95}
70 96
71/* fetch handlers */ 97#define FETCH_FUNC_NAME(kind, type) fetch_##kind##_##type
72static __kprobes unsigned long fetch_register(struct pt_regs *regs, 98/*
73 void *offset) 99 * Define macro for basic types - we don't need to define s* types, because
74{ 100 * we have to care only about bitwidth at recording time.
75 return regs_get_register(regs, (unsigned int)((unsigned long)offset)); 101 */
102#define DEFINE_BASIC_FETCH_FUNCS(kind) \
103DEFINE_FETCH_##kind(u8) \
104DEFINE_FETCH_##kind(u16) \
105DEFINE_FETCH_##kind(u32) \
106DEFINE_FETCH_##kind(u64)
107
108#define CHECK_BASIC_FETCH_FUNCS(kind, fn) \
109 ((FETCH_FUNC_NAME(kind, u8) == fn) || \
110 (FETCH_FUNC_NAME(kind, u16) == fn) || \
111 (FETCH_FUNC_NAME(kind, u32) == fn) || \
112 (FETCH_FUNC_NAME(kind, u64) == fn))
113
114/* Data fetch function templates */
115#define DEFINE_FETCH_reg(type) \
116static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \
117 void *offset, void *dest) \
118{ \
119 *(type *)dest = (type)regs_get_register(regs, \
120 (unsigned int)((unsigned long)offset)); \
76} 121}
77 122DEFINE_BASIC_FETCH_FUNCS(reg)
78static __kprobes unsigned long fetch_stack(struct pt_regs *regs, 123
79 void *num) 124#define DEFINE_FETCH_stack(type) \
80{ 125static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
81 return regs_get_kernel_stack_nth(regs, 126 void *offset, void *dest) \
82 (unsigned int)((unsigned long)num)); 127{ \
128 *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \
129 (unsigned int)((unsigned long)offset)); \
83} 130}
131DEFINE_BASIC_FETCH_FUNCS(stack)
84 132
85static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr) 133#define DEFINE_FETCH_retval(type) \
86{ 134static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
87 unsigned long retval; 135 void *dummy, void *dest) \
88 136{ \
89 if (probe_kernel_address(addr, retval)) 137 *(type *)dest = (type)regs_return_value(regs); \
90 return 0;
91 return retval;
92} 138}
93 139DEFINE_BASIC_FETCH_FUNCS(retval)
94static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, 140
95 void *dummy) 141#define DEFINE_FETCH_memory(type) \
96{ 142static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
97 return regs_return_value(regs); 143 void *addr, void *dest) \
98} 144{ \
99 145 type retval; \
100static __kprobes unsigned long fetch_stack_address(struct pt_regs *regs, 146 if (probe_kernel_address(addr, retval)) \
101 void *dummy) 147 *(type *)dest = 0; \
102{ 148 else \
103 return kernel_stack_pointer(regs); 149 *(type *)dest = retval; \
104} 150}
151DEFINE_BASIC_FETCH_FUNCS(memory)
105 152
106/* Memory fetching by symbol */ 153/* Memory fetching by symbol */
107struct symbol_cache { 154struct symbol_cache {
@@ -145,51 +192,126 @@ static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
145 return sc; 192 return sc;
146} 193}
147 194
148static __kprobes unsigned long fetch_symbol(struct pt_regs *regs, void *data) 195#define DEFINE_FETCH_symbol(type) \
149{ 196static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
150 struct symbol_cache *sc = data; 197 void *data, void *dest) \
151 198{ \
152 if (sc->addr) 199 struct symbol_cache *sc = data; \
153 return fetch_memory(regs, (void *)sc->addr); 200 if (sc->addr) \
154 else 201 fetch_memory_##type(regs, (void *)sc->addr, dest); \
155 return 0; 202 else \
203 *(type *)dest = 0; \
156} 204}
205DEFINE_BASIC_FETCH_FUNCS(symbol)
157 206
158/* Special indirect memory access interface */ 207/* Dereference memory access function */
159struct indirect_fetch_data { 208struct deref_fetch_param {
160 struct fetch_func orig; 209 struct fetch_param orig;
161 long offset; 210 long offset;
162}; 211};
163 212
164static __kprobes unsigned long fetch_indirect(struct pt_regs *regs, void *data) 213#define DEFINE_FETCH_deref(type) \
165{ 214static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
166 struct indirect_fetch_data *ind = data; 215 void *data, void *dest) \
167 unsigned long addr; 216{ \
168 217 struct deref_fetch_param *dprm = data; \
169 addr = call_fetch(&ind->orig, regs); 218 unsigned long addr; \
170 if (addr) { 219 call_fetch(&dprm->orig, regs, &addr); \
171 addr += ind->offset; 220 if (addr) { \
172 return fetch_memory(regs, (void *)addr); 221 addr += dprm->offset; \
173 } else 222 fetch_memory_##type(regs, (void *)addr, dest); \
174 return 0; 223 } else \
224 *(type *)dest = 0; \
175} 225}
226DEFINE_BASIC_FETCH_FUNCS(deref)
176 227
177static __kprobes void free_indirect_fetch_data(struct indirect_fetch_data *data) 228static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
178{ 229{
179 if (data->orig.func == fetch_indirect) 230 if (CHECK_BASIC_FETCH_FUNCS(deref, data->orig.fn))
180 free_indirect_fetch_data(data->orig.data); 231 free_deref_fetch_param(data->orig.data);
181 else if (data->orig.func == fetch_symbol) 232 else if (CHECK_BASIC_FETCH_FUNCS(symbol, data->orig.fn))
182 free_symbol_cache(data->orig.data); 233 free_symbol_cache(data->orig.data);
183 kfree(data); 234 kfree(data);
184} 235}
185 236
237/* Default (unsigned long) fetch type */
238#define __DEFAULT_FETCH_TYPE(t) u##t
239#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
240#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
241#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
242
243#define ASSIGN_FETCH_FUNC(kind, type) \
244 .kind = FETCH_FUNC_NAME(kind, type)
245
246#define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \
247 {.name = #ptype, \
248 .size = sizeof(ftype), \
249 .is_signed = sign, \
250 .print = PRINT_TYPE_FUNC_NAME(ptype), \
251 .fmt = PRINT_TYPE_FMT_NAME(ptype), \
252ASSIGN_FETCH_FUNC(reg, ftype), \
253ASSIGN_FETCH_FUNC(stack, ftype), \
254ASSIGN_FETCH_FUNC(retval, ftype), \
255ASSIGN_FETCH_FUNC(memory, ftype), \
256ASSIGN_FETCH_FUNC(symbol, ftype), \
257ASSIGN_FETCH_FUNC(deref, ftype), \
258 }
259
260/* Fetch type information table */
261static const struct fetch_type {
262 const char *name; /* Name of type */
263 size_t size; /* Byte size of type */
264 int is_signed; /* Signed flag */
265 print_type_func_t print; /* Print functions */
266 const char *fmt; /* Fromat string */
267 /* Fetch functions */
268 fetch_func_t reg;
269 fetch_func_t stack;
270 fetch_func_t retval;
271 fetch_func_t memory;
272 fetch_func_t symbol;
273 fetch_func_t deref;
274} fetch_type_table[] = {
275 ASSIGN_FETCH_TYPE(u8, u8, 0),
276 ASSIGN_FETCH_TYPE(u16, u16, 0),
277 ASSIGN_FETCH_TYPE(u32, u32, 0),
278 ASSIGN_FETCH_TYPE(u64, u64, 0),
279 ASSIGN_FETCH_TYPE(s8, u8, 1),
280 ASSIGN_FETCH_TYPE(s16, u16, 1),
281 ASSIGN_FETCH_TYPE(s32, u32, 1),
282 ASSIGN_FETCH_TYPE(s64, u64, 1),
283};
284
285static const struct fetch_type *find_fetch_type(const char *type)
286{
287 int i;
288
289 if (!type)
290 type = DEFAULT_FETCH_TYPE_STR;
291
292 for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
293 if (strcmp(type, fetch_type_table[i].name) == 0)
294 return &fetch_type_table[i];
295 return NULL;
296}
297
298/* Special function : only accept unsigned long */
299static __kprobes void fetch_stack_address(struct pt_regs *regs,
300 void *dummy, void *dest)
301{
302 *(unsigned long *)dest = kernel_stack_pointer(regs);
303}
304
186/** 305/**
187 * Kprobe event core functions 306 * Kprobe event core functions
188 */ 307 */
189 308
190struct probe_arg { 309struct probe_arg {
191 struct fetch_func fetch; 310 struct fetch_param fetch;
192 const char *name; 311 unsigned int offset; /* Offset from argument entry */
312 const char *name; /* Name of this argument */
313 const char *comm; /* Command of this argument */
314 const struct fetch_type *type; /* Type of this argument */
193}; 315};
194 316
195/* Flags for trace_probe */ 317/* Flags for trace_probe */
@@ -204,6 +326,7 @@ struct trace_probe {
204 const char *symbol; /* symbol name */ 326 const char *symbol; /* symbol name */
205 struct ftrace_event_call call; 327 struct ftrace_event_call call;
206 struct trace_event event; 328 struct trace_event event;
329 ssize_t size; /* trace entry size */
207 unsigned int nr_args; 330 unsigned int nr_args;
208 struct probe_arg args[]; 331 struct probe_arg args[];
209}; 332};
@@ -212,6 +335,7 @@ struct trace_probe {
212 (offsetof(struct trace_probe, args) + \ 335 (offsetof(struct trace_probe, args) + \
213 (sizeof(struct probe_arg) * (n))) 336 (sizeof(struct probe_arg) * (n)))
214 337
338
215static __kprobes int probe_is_return(struct trace_probe *tp) 339static __kprobes int probe_is_return(struct trace_probe *tp)
216{ 340{
217 return tp->rp.handler != NULL; 341 return tp->rp.handler != NULL;
@@ -222,49 +346,6 @@ static __kprobes const char *probe_symbol(struct trace_probe *tp)
222 return tp->symbol ? tp->symbol : "unknown"; 346 return tp->symbol ? tp->symbol : "unknown";
223} 347}
224 348
225static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff)
226{
227 int ret = -EINVAL;
228
229 if (ff->func == fetch_register) {
230 const char *name;
231 name = regs_query_register_name((unsigned int)((long)ff->data));
232 ret = snprintf(buf, n, "%%%s", name);
233 } else if (ff->func == fetch_stack)
234 ret = snprintf(buf, n, "$stack%lu", (unsigned long)ff->data);
235 else if (ff->func == fetch_memory)
236 ret = snprintf(buf, n, "@0x%p", ff->data);
237 else if (ff->func == fetch_symbol) {
238 struct symbol_cache *sc = ff->data;
239 if (sc->offset)
240 ret = snprintf(buf, n, "@%s%+ld", sc->symbol,
241 sc->offset);
242 else
243 ret = snprintf(buf, n, "@%s", sc->symbol);
244 } else if (ff->func == fetch_retvalue)
245 ret = snprintf(buf, n, "$retval");
246 else if (ff->func == fetch_stack_address)
247 ret = snprintf(buf, n, "$stack");
248 else if (ff->func == fetch_indirect) {
249 struct indirect_fetch_data *id = ff->data;
250 size_t l = 0;
251 ret = snprintf(buf, n, "%+ld(", id->offset);
252 if (ret >= n)
253 goto end;
254 l += ret;
255 ret = probe_arg_string(buf + l, n - l, &id->orig);
256 if (ret < 0)
257 goto end;
258 l += ret;
259 ret = snprintf(buf + l, n - l, ")");
260 ret += l;
261 }
262end:
263 if (ret >= n)
264 return -ENOSPC;
265 return ret;
266}
267
268static int register_probe_event(struct trace_probe *tp); 349static int register_probe_event(struct trace_probe *tp);
269static void unregister_probe_event(struct trace_probe *tp); 350static void unregister_probe_event(struct trace_probe *tp);
270 351
@@ -347,11 +428,12 @@ error:
347 428
348static void free_probe_arg(struct probe_arg *arg) 429static void free_probe_arg(struct probe_arg *arg)
349{ 430{
350 if (arg->fetch.func == fetch_symbol) 431 if (CHECK_BASIC_FETCH_FUNCS(deref, arg->fetch.fn))
432 free_deref_fetch_param(arg->fetch.data);
433 else if (CHECK_BASIC_FETCH_FUNCS(symbol, arg->fetch.fn))
351 free_symbol_cache(arg->fetch.data); 434 free_symbol_cache(arg->fetch.data);
352 else if (arg->fetch.func == fetch_indirect)
353 free_indirect_fetch_data(arg->fetch.data);
354 kfree(arg->name); 435 kfree(arg->name);
436 kfree(arg->comm);
355} 437}
356 438
357static void free_trace_probe(struct trace_probe *tp) 439static void free_trace_probe(struct trace_probe *tp)
@@ -457,28 +539,30 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
457#define PARAM_MAX_ARGS 16 539#define PARAM_MAX_ARGS 16
458#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) 540#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
459 541
460static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) 542static int parse_probe_vars(char *arg, const struct fetch_type *t,
543 struct fetch_param *f, int is_return)
461{ 544{
462 int ret = 0; 545 int ret = 0;
463 unsigned long param; 546 unsigned long param;
464 547
465 if (strcmp(arg, "retval") == 0) { 548 if (strcmp(arg, "retval") == 0) {
466 if (is_return) { 549 if (is_return)
467 ff->func = fetch_retvalue; 550 f->fn = t->retval;
468 ff->data = NULL; 551 else
469 } else
470 ret = -EINVAL; 552 ret = -EINVAL;
471 } else if (strncmp(arg, "stack", 5) == 0) { 553 } else if (strncmp(arg, "stack", 5) == 0) {
472 if (arg[5] == '\0') { 554 if (arg[5] == '\0') {
473 ff->func = fetch_stack_address; 555 if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
474 ff->data = NULL; 556 f->fn = fetch_stack_address;
557 else
558 ret = -EINVAL;
475 } else if (isdigit(arg[5])) { 559 } else if (isdigit(arg[5])) {
476 ret = strict_strtoul(arg + 5, 10, &param); 560 ret = strict_strtoul(arg + 5, 10, &param);
477 if (ret || param > PARAM_MAX_STACK) 561 if (ret || param > PARAM_MAX_STACK)
478 ret = -EINVAL; 562 ret = -EINVAL;
479 else { 563 else {
480 ff->func = fetch_stack; 564 f->fn = t->stack;
481 ff->data = (void *)param; 565 f->data = (void *)param;
482 } 566 }
483 } else 567 } else
484 ret = -EINVAL; 568 ret = -EINVAL;
@@ -488,7 +572,8 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
488} 572}
489 573
490/* Recursive argument parser */ 574/* Recursive argument parser */
491static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) 575static int __parse_probe_arg(char *arg, const struct fetch_type *t,
576 struct fetch_param *f, int is_return)
492{ 577{
493 int ret = 0; 578 int ret = 0;
494 unsigned long param; 579 unsigned long param;
@@ -497,13 +582,13 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
497 582
498 switch (arg[0]) { 583 switch (arg[0]) {
499 case '$': 584 case '$':
500 ret = parse_probe_vars(arg + 1, ff, is_return); 585 ret = parse_probe_vars(arg + 1, t, f, is_return);
501 break; 586 break;
502 case '%': /* named register */ 587 case '%': /* named register */
503 ret = regs_query_register_offset(arg + 1); 588 ret = regs_query_register_offset(arg + 1);
504 if (ret >= 0) { 589 if (ret >= 0) {
505 ff->func = fetch_register; 590 f->fn = t->reg;
506 ff->data = (void *)(unsigned long)ret; 591 f->data = (void *)(unsigned long)ret;
507 ret = 0; 592 ret = 0;
508 } 593 }
509 break; 594 break;
@@ -512,26 +597,22 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
512 ret = strict_strtoul(arg + 1, 0, &param); 597 ret = strict_strtoul(arg + 1, 0, &param);
513 if (ret) 598 if (ret)
514 break; 599 break;
515 ff->func = fetch_memory; 600 f->fn = t->memory;
516 ff->data = (void *)param; 601 f->data = (void *)param;
517 } else { 602 } else {
518 ret = split_symbol_offset(arg + 1, &offset); 603 ret = split_symbol_offset(arg + 1, &offset);
519 if (ret) 604 if (ret)
520 break; 605 break;
521 ff->data = alloc_symbol_cache(arg + 1, offset); 606 f->data = alloc_symbol_cache(arg + 1, offset);
522 if (ff->data) 607 if (f->data)
523 ff->func = fetch_symbol; 608 f->fn = t->symbol;
524 else
525 ret = -EINVAL;
526 } 609 }
527 break; 610 break;
528 case '+': /* indirect memory */ 611 case '+': /* deref memory */
529 case '-': 612 case '-':
530 tmp = strchr(arg, '('); 613 tmp = strchr(arg, '(');
531 if (!tmp) { 614 if (!tmp)
532 ret = -EINVAL;
533 break; 615 break;
534 }
535 *tmp = '\0'; 616 *tmp = '\0';
536 ret = strict_strtol(arg + 1, 0, &offset); 617 ret = strict_strtol(arg + 1, 0, &offset);
537 if (ret) 618 if (ret)
@@ -541,38 +622,58 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
541 arg = tmp + 1; 622 arg = tmp + 1;
542 tmp = strrchr(arg, ')'); 623 tmp = strrchr(arg, ')');
543 if (tmp) { 624 if (tmp) {
544 struct indirect_fetch_data *id; 625 struct deref_fetch_param *dprm;
626 const struct fetch_type *t2 = find_fetch_type(NULL);
545 *tmp = '\0'; 627 *tmp = '\0';
546 id = kzalloc(sizeof(struct indirect_fetch_data), 628 dprm = kzalloc(sizeof(struct deref_fetch_param),
547 GFP_KERNEL); 629 GFP_KERNEL);
548 if (!id) 630 if (!dprm)
549 return -ENOMEM; 631 return -ENOMEM;
550 id->offset = offset; 632 dprm->offset = offset;
551 ret = __parse_probe_arg(arg, &id->orig, is_return); 633 ret = __parse_probe_arg(arg, t2, &dprm->orig,
634 is_return);
552 if (ret) 635 if (ret)
553 kfree(id); 636 kfree(dprm);
554 else { 637 else {
555 ff->func = fetch_indirect; 638 f->fn = t->deref;
556 ff->data = (void *)id; 639 f->data = (void *)dprm;
557 } 640 }
558 } else 641 }
559 ret = -EINVAL;
560 break; 642 break;
561 default:
562 /* TODO: support custom handler */
563 ret = -EINVAL;
564 } 643 }
644 if (!ret && !f->fn)
645 ret = -EINVAL;
565 return ret; 646 return ret;
566} 647}
567 648
568/* String length checking wrapper */ 649/* String length checking wrapper */
569static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) 650static int parse_probe_arg(char *arg, struct trace_probe *tp,
651 struct probe_arg *parg, int is_return)
570{ 652{
653 const char *t;
654
571 if (strlen(arg) > MAX_ARGSTR_LEN) { 655 if (strlen(arg) > MAX_ARGSTR_LEN) {
572 pr_info("Argument is too long.: %s\n", arg); 656 pr_info("Argument is too long.: %s\n", arg);
573 return -ENOSPC; 657 return -ENOSPC;
574 } 658 }
575 return __parse_probe_arg(arg, ff, is_return); 659 parg->comm = kstrdup(arg, GFP_KERNEL);
660 if (!parg->comm) {
661 pr_info("Failed to allocate memory for command '%s'.\n", arg);
662 return -ENOMEM;
663 }
664 t = strchr(parg->comm, ':');
665 if (t) {
666 arg[t - parg->comm] = '\0';
667 t++;
668 }
669 parg->type = find_fetch_type(t);
670 if (!parg->type) {
671 pr_info("Unsupported type: %s\n", t);
672 return -EINVAL;
673 }
674 parg->offset = tp->size;
675 tp->size += parg->type->size;
676 return __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
576} 677}
577 678
578/* Return 1 if name is reserved or already used by another argument */ 679/* Return 1 if name is reserved or already used by another argument */
@@ -602,15 +703,18 @@ static int create_trace_probe(int argc, char **argv)
602 * @ADDR : fetch memory at ADDR (ADDR should be in kernel) 703 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
603 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) 704 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
604 * %REG : fetch register REG 705 * %REG : fetch register REG
605 * Indirect memory fetch: 706 * Dereferencing memory fetch:
606 * +|-offs(ARG) : fetch memory at ARG +|- offs address. 707 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
607 * Alias name of args: 708 * Alias name of args:
608 * NAME=FETCHARG : set NAME as alias of FETCHARG. 709 * NAME=FETCHARG : set NAME as alias of FETCHARG.
710 * Type of args:
711 * FETCHARG:TYPE : use TYPE instead of unsigned long.
609 */ 712 */
610 struct trace_probe *tp; 713 struct trace_probe *tp;
611 int i, ret = 0; 714 int i, ret = 0;
612 int is_return = 0, is_delete = 0; 715 int is_return = 0, is_delete = 0;
613 char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL; 716 char *symbol = NULL, *event = NULL, *group = NULL;
717 char *arg, *tmp;
614 unsigned long offset = 0; 718 unsigned long offset = 0;
615 void *addr = NULL; 719 void *addr = NULL;
616 char buf[MAX_EVENT_NAME_LEN]; 720 char buf[MAX_EVENT_NAME_LEN];
@@ -723,13 +827,6 @@ static int create_trace_probe(int argc, char **argv)
723 else 827 else
724 arg = argv[i]; 828 arg = argv[i];
725 829
726 if (conflict_field_name(argv[i], tp->args, i)) {
727 pr_info("Argument%d name '%s' conflicts with "
728 "another field.\n", i, argv[i]);
729 ret = -EINVAL;
730 goto error;
731 }
732
733 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL); 830 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
734 if (!tp->args[i].name) { 831 if (!tp->args[i].name) {
735 pr_info("Failed to allocate argument%d name '%s'.\n", 832 pr_info("Failed to allocate argument%d name '%s'.\n",
@@ -737,9 +834,19 @@ static int create_trace_probe(int argc, char **argv)
737 ret = -ENOMEM; 834 ret = -ENOMEM;
738 goto error; 835 goto error;
739 } 836 }
837 tmp = strchr(tp->args[i].name, ':');
838 if (tmp)
839 *tmp = '_'; /* convert : to _ */
840
841 if (conflict_field_name(tp->args[i].name, tp->args, i)) {
842 pr_info("Argument%d name '%s' conflicts with "
843 "another field.\n", i, argv[i]);
844 ret = -EINVAL;
845 goto error;
846 }
740 847
741 /* Parse fetch argument */ 848 /* Parse fetch argument */
742 ret = parse_probe_arg(arg, &tp->args[i].fetch, is_return); 849 ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
743 if (ret) { 850 if (ret) {
744 pr_info("Parse error at argument%d. (%d)\n", i, ret); 851 pr_info("Parse error at argument%d. (%d)\n", i, ret);
745 kfree(tp->args[i].name); 852 kfree(tp->args[i].name);
@@ -794,8 +901,7 @@ static void probes_seq_stop(struct seq_file *m, void *v)
794static int probes_seq_show(struct seq_file *m, void *v) 901static int probes_seq_show(struct seq_file *m, void *v)
795{ 902{
796 struct trace_probe *tp = v; 903 struct trace_probe *tp = v;
797 int i, ret; 904 int i;
798 char buf[MAX_ARGSTR_LEN + 1];
799 905
800 seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p'); 906 seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p');
801 seq_printf(m, ":%s/%s", tp->call.system, tp->call.name); 907 seq_printf(m, ":%s/%s", tp->call.system, tp->call.name);
@@ -807,15 +913,10 @@ static int probes_seq_show(struct seq_file *m, void *v)
807 else 913 else
808 seq_printf(m, " %s", probe_symbol(tp)); 914 seq_printf(m, " %s", probe_symbol(tp));
809 915
810 for (i = 0; i < tp->nr_args; i++) { 916 for (i = 0; i < tp->nr_args; i++)
811 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i].fetch); 917 seq_printf(m, " %s=%s", tp->args[i].name, tp->args[i].comm);
812 if (ret < 0) {
813 pr_warning("Argument%d decoding error(%d).\n", i, ret);
814 return ret;
815 }
816 seq_printf(m, " %s=%s", tp->args[i].name, buf);
817 }
818 seq_printf(m, "\n"); 918 seq_printf(m, "\n");
919
819 return 0; 920 return 0;
820} 921}
821 922
@@ -945,9 +1046,10 @@ static const struct file_operations kprobe_profile_ops = {
945static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) 1046static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
946{ 1047{
947 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); 1048 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
948 struct kprobe_trace_entry *entry; 1049 struct kprobe_trace_entry_head *entry;
949 struct ring_buffer_event *event; 1050 struct ring_buffer_event *event;
950 struct ring_buffer *buffer; 1051 struct ring_buffer *buffer;
1052 u8 *data;
951 int size, i, pc; 1053 int size, i, pc;
952 unsigned long irq_flags; 1054 unsigned long irq_flags;
953 struct ftrace_event_call *call = &tp->call; 1055 struct ftrace_event_call *call = &tp->call;
@@ -957,7 +1059,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
957 local_save_flags(irq_flags); 1059 local_save_flags(irq_flags);
958 pc = preempt_count(); 1060 pc = preempt_count();
959 1061
960 size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); 1062 size = sizeof(*entry) + tp->size;
961 1063
962 event = trace_current_buffer_lock_reserve(&buffer, call->id, size, 1064 event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
963 irq_flags, pc); 1065 irq_flags, pc);
@@ -965,10 +1067,10 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
965 return; 1067 return;
966 1068
967 entry = ring_buffer_event_data(event); 1069 entry = ring_buffer_event_data(event);
968 entry->nargs = tp->nr_args;
969 entry->ip = (unsigned long)kp->addr; 1070 entry->ip = (unsigned long)kp->addr;
1071 data = (u8 *)&entry[1];
970 for (i = 0; i < tp->nr_args; i++) 1072 for (i = 0; i < tp->nr_args; i++)
971 entry->args[i] = call_fetch(&tp->args[i].fetch, regs); 1073 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
972 1074
973 if (!filter_current_check_discard(buffer, call, entry, event)) 1075 if (!filter_current_check_discard(buffer, call, entry, event))
974 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 1076 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -979,9 +1081,10 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
979 struct pt_regs *regs) 1081 struct pt_regs *regs)
980{ 1082{
981 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); 1083 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
982 struct kretprobe_trace_entry *entry; 1084 struct kretprobe_trace_entry_head *entry;
983 struct ring_buffer_event *event; 1085 struct ring_buffer_event *event;
984 struct ring_buffer *buffer; 1086 struct ring_buffer *buffer;
1087 u8 *data;
985 int size, i, pc; 1088 int size, i, pc;
986 unsigned long irq_flags; 1089 unsigned long irq_flags;
987 struct ftrace_event_call *call = &tp->call; 1090 struct ftrace_event_call *call = &tp->call;
@@ -989,7 +1092,7 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
989 local_save_flags(irq_flags); 1092 local_save_flags(irq_flags);
990 pc = preempt_count(); 1093 pc = preempt_count();
991 1094
992 size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); 1095 size = sizeof(*entry) + tp->size;
993 1096
994 event = trace_current_buffer_lock_reserve(&buffer, call->id, size, 1097 event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
995 irq_flags, pc); 1098 irq_flags, pc);
@@ -997,11 +1100,11 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
997 return; 1100 return;
998 1101
999 entry = ring_buffer_event_data(event); 1102 entry = ring_buffer_event_data(event);
1000 entry->nargs = tp->nr_args;
1001 entry->func = (unsigned long)tp->rp.kp.addr; 1103 entry->func = (unsigned long)tp->rp.kp.addr;
1002 entry->ret_ip = (unsigned long)ri->ret_addr; 1104 entry->ret_ip = (unsigned long)ri->ret_addr;
1105 data = (u8 *)&entry[1];
1003 for (i = 0; i < tp->nr_args; i++) 1106 for (i = 0; i < tp->nr_args; i++)
1004 entry->args[i] = call_fetch(&tp->args[i].fetch, regs); 1107 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
1005 1108
1006 if (!filter_current_check_discard(buffer, call, entry, event)) 1109 if (!filter_current_check_discard(buffer, call, entry, event))
1007 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 1110 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -1011,13 +1114,14 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
1011enum print_line_t 1114enum print_line_t
1012print_kprobe_event(struct trace_iterator *iter, int flags) 1115print_kprobe_event(struct trace_iterator *iter, int flags)
1013{ 1116{
1014 struct kprobe_trace_entry *field; 1117 struct kprobe_trace_entry_head *field;
1015 struct trace_seq *s = &iter->seq; 1118 struct trace_seq *s = &iter->seq;
1016 struct trace_event *event; 1119 struct trace_event *event;
1017 struct trace_probe *tp; 1120 struct trace_probe *tp;
1121 u8 *data;
1018 int i; 1122 int i;
1019 1123
1020 field = (struct kprobe_trace_entry *)iter->ent; 1124 field = (struct kprobe_trace_entry_head *)iter->ent;
1021 event = ftrace_find_event(field->ent.type); 1125 event = ftrace_find_event(field->ent.type);
1022 tp = container_of(event, struct trace_probe, event); 1126 tp = container_of(event, struct trace_probe, event);
1023 1127
@@ -1030,9 +1134,10 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
1030 if (!trace_seq_puts(s, ")")) 1134 if (!trace_seq_puts(s, ")"))
1031 goto partial; 1135 goto partial;
1032 1136
1033 for (i = 0; i < field->nargs; i++) 1137 data = (u8 *)&field[1];
1034 if (!trace_seq_printf(s, " %s=%lx", 1138 for (i = 0; i < tp->nr_args; i++)
1035 tp->args[i].name, field->args[i])) 1139 if (!tp->args[i].type->print(s, tp->args[i].name,
1140 data + tp->args[i].offset))
1036 goto partial; 1141 goto partial;
1037 1142
1038 if (!trace_seq_puts(s, "\n")) 1143 if (!trace_seq_puts(s, "\n"))
@@ -1046,13 +1151,14 @@ partial:
1046enum print_line_t 1151enum print_line_t
1047print_kretprobe_event(struct trace_iterator *iter, int flags) 1152print_kretprobe_event(struct trace_iterator *iter, int flags)
1048{ 1153{
1049 struct kretprobe_trace_entry *field; 1154 struct kretprobe_trace_entry_head *field;
1050 struct trace_seq *s = &iter->seq; 1155 struct trace_seq *s = &iter->seq;
1051 struct trace_event *event; 1156 struct trace_event *event;
1052 struct trace_probe *tp; 1157 struct trace_probe *tp;
1158 u8 *data;
1053 int i; 1159 int i;
1054 1160
1055 field = (struct kretprobe_trace_entry *)iter->ent; 1161 field = (struct kretprobe_trace_entry_head *)iter->ent;
1056 event = ftrace_find_event(field->ent.type); 1162 event = ftrace_find_event(field->ent.type);
1057 tp = container_of(event, struct trace_probe, event); 1163 tp = container_of(event, struct trace_probe, event);
1058 1164
@@ -1071,9 +1177,10 @@ print_kretprobe_event(struct trace_iterator *iter, int flags)
1071 if (!trace_seq_puts(s, ")")) 1177 if (!trace_seq_puts(s, ")"))
1072 goto partial; 1178 goto partial;
1073 1179
1074 for (i = 0; i < field->nargs; i++) 1180 data = (u8 *)&field[1];
1075 if (!trace_seq_printf(s, " %s=%lx", 1181 for (i = 0; i < tp->nr_args; i++)
1076 tp->args[i].name, field->args[i])) 1182 if (!tp->args[i].type->print(s, tp->args[i].name,
1183 data + tp->args[i].offset))
1077 goto partial; 1184 goto partial;
1078 1185
1079 if (!trace_seq_puts(s, "\n")) 1186 if (!trace_seq_puts(s, "\n"))
@@ -1129,29 +1236,43 @@ static int probe_event_raw_init(struct ftrace_event_call *event_call)
1129static int kprobe_event_define_fields(struct ftrace_event_call *event_call) 1236static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
1130{ 1237{
1131 int ret, i; 1238 int ret, i;
1132 struct kprobe_trace_entry field; 1239 struct kprobe_trace_entry_head field;
1133 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1240 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1134 1241
1135 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); 1242 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
1136 DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
1137 /* Set argument names as fields */ 1243 /* Set argument names as fields */
1138 for (i = 0; i < tp->nr_args; i++) 1244 for (i = 0; i < tp->nr_args; i++) {
1139 DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0); 1245 ret = trace_define_field(event_call, tp->args[i].type->name,
1246 tp->args[i].name,
1247 sizeof(field) + tp->args[i].offset,
1248 tp->args[i].type->size,
1249 tp->args[i].type->is_signed,
1250 FILTER_OTHER);
1251 if (ret)
1252 return ret;
1253 }
1140 return 0; 1254 return 0;
1141} 1255}
1142 1256
1143static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) 1257static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
1144{ 1258{
1145 int ret, i; 1259 int ret, i;
1146 struct kretprobe_trace_entry field; 1260 struct kretprobe_trace_entry_head field;
1147 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1261 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1148 1262
1149 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); 1263 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1150 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); 1264 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
1151 DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
1152 /* Set argument names as fields */ 1265 /* Set argument names as fields */
1153 for (i = 0; i < tp->nr_args; i++) 1266 for (i = 0; i < tp->nr_args; i++) {
1154 DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0); 1267 ret = trace_define_field(event_call, tp->args[i].type->name,
1268 tp->args[i].name,
1269 sizeof(field) + tp->args[i].offset,
1270 tp->args[i].type->size,
1271 tp->args[i].type->is_signed,
1272 FILTER_OTHER);
1273 if (ret)
1274 return ret;
1275 }
1155 return 0; 1276 return 0;
1156} 1277}
1157 1278
@@ -1176,8 +1297,8 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len)
1176 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt); 1297 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
1177 1298
1178 for (i = 0; i < tp->nr_args; i++) { 1299 for (i = 0; i < tp->nr_args; i++) {
1179 pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%%lx", 1300 pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
1180 tp->args[i].name); 1301 tp->args[i].name, tp->args[i].type->fmt);
1181 } 1302 }
1182 1303
1183 pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); 1304 pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
@@ -1219,12 +1340,13 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
1219{ 1340{
1220 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); 1341 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
1221 struct ftrace_event_call *call = &tp->call; 1342 struct ftrace_event_call *call = &tp->call;
1222 struct kprobe_trace_entry *entry; 1343 struct kprobe_trace_entry_head *entry;
1344 u8 *data;
1223 int size, __size, i; 1345 int size, __size, i;
1224 unsigned long irq_flags; 1346 unsigned long irq_flags;
1225 int rctx; 1347 int rctx;
1226 1348
1227 __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); 1349 __size = sizeof(*entry) + tp->size;
1228 size = ALIGN(__size + sizeof(u32), sizeof(u64)); 1350 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1229 size -= sizeof(u32); 1351 size -= sizeof(u32);
1230 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, 1352 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1235,10 +1357,10 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
1235 if (!entry) 1357 if (!entry)
1236 return; 1358 return;
1237 1359
1238 entry->nargs = tp->nr_args;
1239 entry->ip = (unsigned long)kp->addr; 1360 entry->ip = (unsigned long)kp->addr;
1361 data = (u8 *)&entry[1];
1240 for (i = 0; i < tp->nr_args; i++) 1362 for (i = 0; i < tp->nr_args; i++)
1241 entry->args[i] = call_fetch(&tp->args[i].fetch, regs); 1363 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
1242 1364
1243 perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs); 1365 perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs);
1244} 1366}
@@ -1249,12 +1371,13 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
1249{ 1371{
1250 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); 1372 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
1251 struct ftrace_event_call *call = &tp->call; 1373 struct ftrace_event_call *call = &tp->call;
1252 struct kretprobe_trace_entry *entry; 1374 struct kretprobe_trace_entry_head *entry;
1375 u8 *data;
1253 int size, __size, i; 1376 int size, __size, i;
1254 unsigned long irq_flags; 1377 unsigned long irq_flags;
1255 int rctx; 1378 int rctx;
1256 1379
1257 __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); 1380 __size = sizeof(*entry) + tp->size;
1258 size = ALIGN(__size + sizeof(u32), sizeof(u64)); 1381 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1259 size -= sizeof(u32); 1382 size -= sizeof(u32);
1260 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, 1383 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1265,11 +1388,11 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
1265 if (!entry) 1388 if (!entry)
1266 return; 1389 return;
1267 1390
1268 entry->nargs = tp->nr_args;
1269 entry->func = (unsigned long)tp->rp.kp.addr; 1391 entry->func = (unsigned long)tp->rp.kp.addr;
1270 entry->ret_ip = (unsigned long)ri->ret_addr; 1392 entry->ret_ip = (unsigned long)ri->ret_addr;
1393 data = (u8 *)&entry[1];
1271 for (i = 0; i < tp->nr_args; i++) 1394 for (i = 0; i < tp->nr_args; i++)
1272 entry->args[i] = call_fetch(&tp->args[i].fetch, regs); 1395 call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
1273 1396
1274 perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, 1397 perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1,
1275 irq_flags, regs); 1398 irq_flags, regs);
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index bb671b346774..63c25d304880 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -79,7 +79,16 @@ Probe points are defined by following syntax.
79'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'. 79'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
80'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function. 80'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
81It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern. 81It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
82'ARG' specifies the arguments of this probe point. You can use the name of local variable, or kprobe-tracer argument format (e.g. $retval, %ax, etc). 82'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
83
84PROBE ARGUMENT
85--------------
86Each probe argument follows below syntax.
87
88 [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
89
90'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
91'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo.
83 92
84LINE SYNTAX 93LINE SYNTAX
85----------- 94-----------
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index bfc47fff9c59..c1e54035e8cf 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -40,7 +40,6 @@
40#include "util/debug.h" 40#include "util/debug.h"
41#include "util/debugfs.h" 41#include "util/debugfs.h"
42#include "util/parse-options.h" 42#include "util/parse-options.h"
43#include "util/parse-events.h" /* For debugfs_path */
44#include "util/probe-finder.h" 43#include "util/probe-finder.h"
45#include "util/probe-event.h" 44#include "util/probe-event.h"
46 45
@@ -59,23 +58,25 @@ static struct {
59 58
60 59
61/* Parse an event definition. Note that any error must die. */ 60/* Parse an event definition. Note that any error must die. */
62static void parse_probe_event(const char *str) 61static int parse_probe_event(const char *str)
63{ 62{
64 struct perf_probe_event *pev = &params.events[params.nevents]; 63 struct perf_probe_event *pev = &params.events[params.nevents];
64 int ret;
65 65
66 pr_debug("probe-definition(%d): %s\n", params.nevents, str); 66 pr_debug("probe-definition(%d): %s\n", params.nevents, str);
67 if (++params.nevents == MAX_PROBES) 67 if (++params.nevents == MAX_PROBES)
68 die("Too many probes (> %d) are specified.", MAX_PROBES); 68 die("Too many probes (> %d) are specified.", MAX_PROBES);
69 69
70 /* Parse a perf-probe command into event */ 70 /* Parse a perf-probe command into event */
71 parse_perf_probe_command(str, pev); 71 ret = parse_perf_probe_command(str, pev);
72
73 pr_debug("%d arguments\n", pev->nargs); 72 pr_debug("%d arguments\n", pev->nargs);
73
74 return ret;
74} 75}
75 76
76static void parse_probe_event_argv(int argc, const char **argv) 77static int parse_probe_event_argv(int argc, const char **argv)
77{ 78{
78 int i, len; 79 int i, len, ret;
79 char *buf; 80 char *buf;
80 81
81 /* Bind up rest arguments */ 82 /* Bind up rest arguments */
@@ -86,16 +87,18 @@ static void parse_probe_event_argv(int argc, const char **argv)
86 len = 0; 87 len = 0;
87 for (i = 0; i < argc; i++) 88 for (i = 0; i < argc; i++)
88 len += sprintf(&buf[len], "%s ", argv[i]); 89 len += sprintf(&buf[len], "%s ", argv[i]);
89 parse_probe_event(buf); 90 ret = parse_probe_event(buf);
90 free(buf); 91 free(buf);
92 return ret;
91} 93}
92 94
93static int opt_add_probe_event(const struct option *opt __used, 95static int opt_add_probe_event(const struct option *opt __used,
94 const char *str, int unset __used) 96 const char *str, int unset __used)
95{ 97{
96 if (str) 98 if (str)
97 parse_probe_event(str); 99 return parse_probe_event(str);
98 return 0; 100 else
101 return 0;
99} 102}
100 103
101static int opt_del_probe_event(const struct option *opt __used, 104static int opt_del_probe_event(const struct option *opt __used,
@@ -113,11 +116,14 @@ static int opt_del_probe_event(const struct option *opt __used,
113static int opt_show_lines(const struct option *opt __used, 116static int opt_show_lines(const struct option *opt __used,
114 const char *str, int unset __used) 117 const char *str, int unset __used)
115{ 118{
119 int ret = 0;
120
116 if (str) 121 if (str)
117 parse_line_range_desc(str, &params.line_range); 122 ret = parse_line_range_desc(str, &params.line_range);
118 INIT_LIST_HEAD(&params.line_range.line_list); 123 INIT_LIST_HEAD(&params.line_range.line_list);
119 params.show_lines = true; 124 params.show_lines = true;
120 return 0; 125
126 return ret;
121} 127}
122#endif 128#endif
123 129
@@ -142,9 +148,9 @@ static const struct option options[] = {
142 OPT_CALLBACK('a', "add", NULL, 148 OPT_CALLBACK('a', "add", NULL,
143#ifdef DWARF_SUPPORT 149#ifdef DWARF_SUPPORT
144 "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT" 150 "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
145 " [ARG ...]", 151 " [[NAME=]ARG ...]",
146#else 152#else
147 "[EVENT=]FUNC[+OFF|%return] [ARG ...]", 153 "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
148#endif 154#endif
149 "probe point definition, where\n" 155 "probe point definition, where\n"
150 "\t\tGROUP:\tGroup name (optional)\n" 156 "\t\tGROUP:\tGroup name (optional)\n"
@@ -178,6 +184,8 @@ static const struct option options[] = {
178 184
179int cmd_probe(int argc, const char **argv, const char *prefix __used) 185int cmd_probe(int argc, const char **argv, const char *prefix __used)
180{ 186{
187 int ret;
188
181 argc = parse_options(argc, argv, options, probe_usage, 189 argc = parse_options(argc, argv, options, probe_usage,
182 PARSE_OPT_STOP_AT_NON_OPTION); 190 PARSE_OPT_STOP_AT_NON_OPTION);
183 if (argc > 0) { 191 if (argc > 0) {
@@ -185,28 +193,31 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
185 pr_warning(" Error: '-' is not supported.\n"); 193 pr_warning(" Error: '-' is not supported.\n");
186 usage_with_options(probe_usage, options); 194 usage_with_options(probe_usage, options);
187 } 195 }
188 parse_probe_event_argv(argc, argv); 196 ret = parse_probe_event_argv(argc, argv);
197 if (ret < 0) {
198 pr_err(" Error: Parse Error. (%d)\n", ret);
199 return ret;
200 }
189 } 201 }
190 202
191 if ((!params.nevents && !params.dellist && !params.list_events && 203 if ((!params.nevents && !params.dellist && !params.list_events &&
192 !params.show_lines)) 204 !params.show_lines))
193 usage_with_options(probe_usage, options); 205 usage_with_options(probe_usage, options);
194 206
195 if (debugfs_valid_mountpoint(debugfs_path) < 0)
196 die("Failed to find debugfs path.");
197
198 if (params.list_events) { 207 if (params.list_events) {
199 if (params.nevents != 0 || params.dellist) { 208 if (params.nevents != 0 || params.dellist) {
200 pr_warning(" Error: Don't use --list with" 209 pr_err(" Error: Don't use --list with --add/--del.\n");
201 " --add/--del.\n");
202 usage_with_options(probe_usage, options); 210 usage_with_options(probe_usage, options);
203 } 211 }
204 if (params.show_lines) { 212 if (params.show_lines) {
205 pr_warning(" Error: Don't use --list with --line.\n"); 213 pr_err(" Error: Don't use --list with --line.\n");
206 usage_with_options(probe_usage, options); 214 usage_with_options(probe_usage, options);
207 } 215 }
208 show_perf_probe_events(); 216 ret = show_perf_probe_events();
209 return 0; 217 if (ret < 0)
218 pr_err(" Error: Failed to show event list. (%d)\n",
219 ret);
220 return ret;
210 } 221 }
211 222
212#ifdef DWARF_SUPPORT 223#ifdef DWARF_SUPPORT
@@ -217,19 +228,30 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
217 usage_with_options(probe_usage, options); 228 usage_with_options(probe_usage, options);
218 } 229 }
219 230
220 show_line_range(&params.line_range); 231 ret = show_line_range(&params.line_range);
221 return 0; 232 if (ret < 0)
233 pr_err(" Error: Failed to show lines. (%d)\n", ret);
234 return ret;
222 } 235 }
223#endif 236#endif
224 237
225 if (params.dellist) { 238 if (params.dellist) {
226 del_perf_probe_events(params.dellist); 239 ret = del_perf_probe_events(params.dellist);
227 strlist__delete(params.dellist); 240 strlist__delete(params.dellist);
228 if (params.nevents == 0) 241 if (ret < 0) {
229 return 0; 242 pr_err(" Error: Failed to delete events. (%d)\n", ret);
243 return ret;
244 }
230 } 245 }
231 246
232 add_perf_probe_events(params.events, params.nevents, params.force_add); 247 if (params.nevents) {
248 ret = add_perf_probe_events(params.events, params.nevents,
249 params.force_add);
250 if (ret < 0) {
251 pr_err(" Error: Failed to add events. (%d)\n", ret);
252 return ret;
253 }
254 }
233 return 0; 255 return 0;
234} 256}
235 257
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 18cf8b321608..9c2b8743cef6 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -68,7 +68,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
68 int64_t cmp = 0; 68 int64_t cmp = 0;
69 69
70 list_for_each_entry(se, &hist_entry__sort_list, list) { 70 list_for_each_entry(se, &hist_entry__sort_list, list) {
71 cmp = se->cmp(left, right); 71 cmp = se->se_cmp(left, right);
72 if (cmp) 72 if (cmp)
73 break; 73 break;
74 } 74 }
@@ -85,7 +85,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
85 list_for_each_entry(se, &hist_entry__sort_list, list) { 85 list_for_each_entry(se, &hist_entry__sort_list, list) {
86 int64_t (*f)(struct hist_entry *, struct hist_entry *); 86 int64_t (*f)(struct hist_entry *, struct hist_entry *);
87 87
88 f = se->collapse ?: se->cmp; 88 f = se->se_collapse ?: se->se_cmp;
89 89
90 cmp = f(left, right); 90 cmp = f(left, right);
91 if (cmp) 91 if (cmp)
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
536 continue; 536 continue;
537 537
538 ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); 538 ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
539 ret += se->snprintf(self, s + ret, size - ret, 539 ret += se->se_snprintf(self, s + ret, size - ret,
540 se->width ? *se->width : 0); 540 se->se_width ? *se->se_width : 0);
541 } 541 }
542 542
543 return ret; 543 return ret;
@@ -564,7 +564,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
564 if (sort__first_dimension == SORT_COMM) { 564 if (sort__first_dimension == SORT_COMM) {
565 struct sort_entry *se = list_first_entry(&hist_entry__sort_list, 565 struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
566 typeof(*se), list); 566 typeof(*se), list);
567 left_margin = se->width ? *se->width : 0; 567 left_margin = se->se_width ? *se->se_width : 0;
568 left_margin -= thread__comm_len(self->thread); 568 left_margin -= thread__comm_len(self->thread);
569 } 569 }
570 570
@@ -615,22 +615,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
615 if (se->elide) 615 if (se->elide)
616 continue; 616 continue;
617 if (sep) { 617 if (sep) {
618 fprintf(fp, "%c%s", *sep, se->header); 618 fprintf(fp, "%c%s", *sep, se->se_header);
619 continue; 619 continue;
620 } 620 }
621 width = strlen(se->header); 621 width = strlen(se->se_header);
622 if (se->width) { 622 if (se->se_width) {
623 if (symbol_conf.col_width_list_str) { 623 if (symbol_conf.col_width_list_str) {
624 if (col_width) { 624 if (col_width) {
625 *se->width = atoi(col_width); 625 *se->se_width = atoi(col_width);
626 col_width = strchr(col_width, ','); 626 col_width = strchr(col_width, ',');
627 if (col_width) 627 if (col_width)
628 ++col_width; 628 ++col_width;
629 } 629 }
630 } 630 }
631 width = *se->width = max(*se->width, width); 631 width = *se->se_width = max(*se->se_width, width);
632 } 632 }
633 fprintf(fp, " %*s", width, se->header); 633 fprintf(fp, " %*s", width, se->se_header);
634 } 634 }
635 fprintf(fp, "\n"); 635 fprintf(fp, "\n");
636 636
@@ -652,10 +652,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
652 continue; 652 continue;
653 653
654 fprintf(fp, " "); 654 fprintf(fp, " ");
655 if (se->width) 655 if (se->se_width)
656 width = *se->width; 656 width = *se->se_width;
657 else 657 else
658 width = strlen(se->header); 658 width = strlen(se->se_header);
659 for (i = 0; i < width; i++) 659 for (i = 0; i < width; i++)
660 fprintf(fp, "."); 660 fprintf(fp, ".");
661 } 661 }
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3fc0be741b8e..5bf8ab034466 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -42,8 +42,8 @@
42#include "color.h" 42#include "color.h"
43#include "symbol.h" 43#include "symbol.h"
44#include "thread.h" 44#include "thread.h"
45#include "debugfs.h"
45#include "trace-event.h" /* For __unused */ 46#include "trace-event.h" /* For __unused */
46#include "parse-events.h" /* For debugfs_path */
47#include "probe-event.h" 47#include "probe-event.h"
48#include "probe-finder.h" 48#include "probe-finder.h"
49 49
@@ -53,7 +53,7 @@
53 53
54bool probe_event_dry_run; /* Dry run flag */ 54bool probe_event_dry_run; /* Dry run flag */
55 55
56#define semantic_error(msg ...) die("Semantic error :" msg) 56#define semantic_error(msg ...) pr_err("Semantic error :" msg)
57 57
58/* If there is no space to write, returns -E2BIG. */ 58/* If there is no space to write, returns -E2BIG. */
59static int e_snprintf(char *str, size_t size, const char *format, ...) 59static int e_snprintf(char *str, size_t size, const char *format, ...)
@@ -76,19 +76,30 @@ static struct map_groups kmap_groups;
76static struct map *kmaps[MAP__NR_TYPES]; 76static struct map *kmaps[MAP__NR_TYPES];
77 77
78/* Initialize symbol maps and path of vmlinux */ 78/* Initialize symbol maps and path of vmlinux */
79static void init_vmlinux(void) 79static int init_vmlinux(void)
80{ 80{
81 int ret;
82
81 symbol_conf.sort_by_name = true; 83 symbol_conf.sort_by_name = true;
82 if (symbol_conf.vmlinux_name == NULL) 84 if (symbol_conf.vmlinux_name == NULL)
83 symbol_conf.try_vmlinux_path = true; 85 symbol_conf.try_vmlinux_path = true;
84 else 86 else
85 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 87 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
86 if (symbol__init() < 0) 88 ret = symbol__init();
87 die("Failed to init symbol map."); 89 if (ret < 0) {
90 pr_debug("Failed to init symbol map.\n");
91 goto out;
92 }
88 93
89 map_groups__init(&kmap_groups); 94 map_groups__init(&kmap_groups);
90 if (map_groups__create_kernel_maps(&kmap_groups, kmaps) < 0) 95 ret = map_groups__create_kernel_maps(&kmap_groups, kmaps);
91 die("Failed to create kernel maps."); 96 if (ret < 0)
97 pr_debug("Failed to create kernel maps.\n");
98
99out:
100 if (ret < 0)
101 pr_warning("Failed to init vmlinux path.\n");
102 return ret;
92} 103}
93 104
94#ifdef DWARF_SUPPORT 105#ifdef DWARF_SUPPORT
@@ -102,24 +113,34 @@ static int open_vmlinux(void)
102 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY); 113 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
103} 114}
104 115
105static void convert_to_perf_probe_point(struct kprobe_trace_point *tp, 116/* Convert trace point to probe point with debuginfo */
106 struct perf_probe_point *pp) 117static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
118 struct perf_probe_point *pp)
107{ 119{
108 struct symbol *sym; 120 struct symbol *sym;
109 int fd, ret = 0; 121 int fd, ret = -ENOENT;
110 122
111 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 123 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
112 tp->symbol, NULL); 124 tp->symbol, NULL);
113 if (sym) { 125 if (sym) {
114 fd = open_vmlinux(); 126 fd = open_vmlinux();
115 ret = find_perf_probe_point(fd, sym->start + tp->offset, pp); 127 if (fd >= 0) {
116 close(fd); 128 ret = find_perf_probe_point(fd,
129 sym->start + tp->offset, pp);
130 close(fd);
131 }
117 } 132 }
118 if (ret <= 0) { 133 if (ret <= 0) {
119 pp->function = xstrdup(tp->symbol); 134 pr_debug("Failed to find corresponding probes from "
135 "debuginfo. Use kprobe event information.\n");
136 pp->function = strdup(tp->symbol);
137 if (pp->function == NULL)
138 return -ENOMEM;
120 pp->offset = tp->offset; 139 pp->offset = tp->offset;
121 } 140 }
122 pp->retprobe = tp->retprobe; 141 pp->retprobe = tp->retprobe;
142
143 return 0;
123} 144}
124 145
125/* Try to find perf_probe_event with debuginfo */ 146/* Try to find perf_probe_event with debuginfo */
@@ -131,9 +152,10 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
131 152
132 fd = open_vmlinux(); 153 fd = open_vmlinux();
133 if (fd < 0) { 154 if (fd < 0) {
134 if (need_dwarf) 155 if (need_dwarf) {
135 die("Could not open debuginfo file."); 156 pr_warning("Failed to open debuginfo file.\n");
136 157 return fd;
158 }
137 pr_debug("Could not open vmlinux. Try to use symbols.\n"); 159 pr_debug("Could not open vmlinux. Try to use symbols.\n");
138 return 0; 160 return 0;
139 } 161 }
@@ -142,30 +164,32 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
142 ntevs = find_kprobe_trace_events(fd, pev, tevs); 164 ntevs = find_kprobe_trace_events(fd, pev, tevs);
143 close(fd); 165 close(fd);
144 166
145 if (ntevs > 0) /* Succeeded to find trace events */ 167 if (ntevs > 0) { /* Succeeded to find trace events */
168 pr_debug("find %d kprobe_trace_events.\n", ntevs);
146 return ntevs; 169 return ntevs;
170 }
147 171
148 if (ntevs == 0) /* No error but failed to find probe point. */ 172 if (ntevs == 0) { /* No error but failed to find probe point. */
149 die("Probe point '%s' not found. - probe not added.", 173 pr_warning("Probe point '%s' not found.\n",
150 synthesize_perf_probe_point(&pev->point)); 174 synthesize_perf_probe_point(&pev->point));
151 175 return -ENOENT;
152 /* Error path */ 176 }
177 /* Error path : ntevs < 0 */
153 if (need_dwarf) { 178 if (need_dwarf) {
154 if (ntevs == -ENOENT) 179 if (ntevs == -EBADF)
155 pr_warning("No dwarf info found in the vmlinux - " 180 pr_warning("No dwarf info found in the vmlinux - "
156 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 181 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
157 die("Could not analyze debuginfo."); 182 return ntevs;
158 } 183 }
159 pr_debug("An error occurred in debuginfo analysis." 184 pr_debug("An error occurred in debuginfo analysis."
160 " Try to use symbols.\n"); 185 " Try to use symbols.\n");
161 return 0; 186 return 0;
162
163} 187}
164 188
165#define LINEBUF_SIZE 256 189#define LINEBUF_SIZE 256
166#define NR_ADDITIONAL_LINES 2 190#define NR_ADDITIONAL_LINES 2
167 191
168static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num) 192static int show_one_line(FILE *fp, int l, bool skip, bool show_num)
169{ 193{
170 char buf[LINEBUF_SIZE]; 194 char buf[LINEBUF_SIZE];
171 const char *color = PERF_COLOR_BLUE; 195 const char *color = PERF_COLOR_BLUE;
@@ -174,7 +198,7 @@ static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
174 goto error; 198 goto error;
175 if (!skip) { 199 if (!skip) {
176 if (show_num) 200 if (show_num)
177 fprintf(stdout, "%7u %s", l, buf); 201 fprintf(stdout, "%7d %s", l, buf);
178 else 202 else
179 color_fprintf(stdout, color, " %s", buf); 203 color_fprintf(stdout, color, " %s", buf);
180 } 204 }
@@ -190,34 +214,48 @@ static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
190 color_fprintf(stdout, color, "%s", buf); 214 color_fprintf(stdout, color, "%s", buf);
191 } 215 }
192 } 216 }
193 return; 217
218 return 0;
194error: 219error:
195 if (feof(fp)) 220 if (feof(fp))
196 die("Source file is shorter than expected."); 221 pr_warning("Source file is shorter than expected.\n");
197 else 222 else
198 die("File read error: %s", strerror(errno)); 223 pr_warning("File read error: %s\n", strerror(errno));
224
225 return -1;
199} 226}
200 227
201/* 228/*
202 * Show line-range always requires debuginfo to find source file and 229 * Show line-range always requires debuginfo to find source file and
203 * line number. 230 * line number.
204 */ 231 */
205void show_line_range(struct line_range *lr) 232int show_line_range(struct line_range *lr)
206{ 233{
207 unsigned int l = 1; 234 int l = 1;
208 struct line_node *ln; 235 struct line_node *ln;
209 FILE *fp; 236 FILE *fp;
210 int fd, ret; 237 int fd, ret;
211 238
212 /* Search a line range */ 239 /* Search a line range */
213 init_vmlinux(); 240 ret = init_vmlinux();
241 if (ret < 0)
242 return ret;
243
214 fd = open_vmlinux(); 244 fd = open_vmlinux();
215 if (fd < 0) 245 if (fd < 0) {
216 die("Could not open debuginfo file."); 246 pr_warning("Failed to open debuginfo file.\n");
247 return fd;
248 }
249
217 ret = find_line_range(fd, lr); 250 ret = find_line_range(fd, lr);
218 if (ret <= 0)
219 die("Source line is not found.\n");
220 close(fd); 251 close(fd);
252 if (ret == 0) {
253 pr_warning("Specified source line is not found.\n");
254 return -ENOENT;
255 } else if (ret < 0) {
256 pr_warning("Debuginfo analysis failed. (%d)\n", ret);
257 return ret;
258 }
221 259
222 setup_pager(); 260 setup_pager();
223 261
@@ -228,52 +266,70 @@ void show_line_range(struct line_range *lr)
228 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start); 266 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
229 267
230 fp = fopen(lr->path, "r"); 268 fp = fopen(lr->path, "r");
231 if (fp == NULL) 269 if (fp == NULL) {
232 die("Failed to open %s: %s", lr->path, strerror(errno)); 270 pr_warning("Failed to open %s: %s\n", lr->path,
271 strerror(errno));
272 return -errno;
273 }
233 /* Skip to starting line number */ 274 /* Skip to starting line number */
234 while (l < lr->start) 275 while (l < lr->start && ret >= 0)
235 show_one_line(fp, l++, true, false); 276 ret = show_one_line(fp, l++, true, false);
277 if (ret < 0)
278 goto end;
236 279
237 list_for_each_entry(ln, &lr->line_list, list) { 280 list_for_each_entry(ln, &lr->line_list, list) {
238 while (ln->line > l) 281 while (ln->line > l && ret >= 0)
239 show_one_line(fp, (l++) - lr->offset, false, false); 282 ret = show_one_line(fp, (l++) - lr->offset,
240 show_one_line(fp, (l++) - lr->offset, false, true); 283 false, false);
284 if (ret >= 0)
285 ret = show_one_line(fp, (l++) - lr->offset,
286 false, true);
287 if (ret < 0)
288 goto end;
241 } 289 }
242 290
243 if (lr->end == INT_MAX) 291 if (lr->end == INT_MAX)
244 lr->end = l + NR_ADDITIONAL_LINES; 292 lr->end = l + NR_ADDITIONAL_LINES;
245 while (l < lr->end && !feof(fp)) 293 while (l <= lr->end && !feof(fp) && ret >= 0)
246 show_one_line(fp, (l++) - lr->offset, false, false); 294 ret = show_one_line(fp, (l++) - lr->offset, false, false);
247 295end:
248 fclose(fp); 296 fclose(fp);
297 return ret;
249} 298}
250 299
251#else /* !DWARF_SUPPORT */ 300#else /* !DWARF_SUPPORT */
252 301
253static void convert_to_perf_probe_point(struct kprobe_trace_point *tp, 302static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
254 struct perf_probe_point *pp) 303 struct perf_probe_point *pp)
255{ 304{
256 pp->function = xstrdup(tp->symbol); 305 pp->function = strdup(tp->symbol);
306 if (pp->function == NULL)
307 return -ENOMEM;
257 pp->offset = tp->offset; 308 pp->offset = tp->offset;
258 pp->retprobe = tp->retprobe; 309 pp->retprobe = tp->retprobe;
310
311 return 0;
259} 312}
260 313
261static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 314static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
262 struct kprobe_trace_event **tevs __unused) 315 struct kprobe_trace_event **tevs __unused)
263{ 316{
264 if (perf_probe_event_need_dwarf(pev)) 317 if (perf_probe_event_need_dwarf(pev)) {
265 die("Debuginfo-analysis is not supported"); 318 pr_warning("Debuginfo-analysis is not supported.\n");
319 return -ENOSYS;
320 }
266 return 0; 321 return 0;
267} 322}
268 323
269void show_line_range(struct line_range *lr __unused) 324int show_line_range(struct line_range *lr __unused)
270{ 325{
271 die("Debuginfo-analysis is not supported"); 326 pr_warning("Debuginfo-analysis is not supported.\n");
327 return -ENOSYS;
272} 328}
273 329
274#endif 330#endif
275 331
276void parse_line_range_desc(const char *arg, struct line_range *lr) 332int parse_line_range_desc(const char *arg, struct line_range *lr)
277{ 333{
278 const char *ptr; 334 const char *ptr;
279 char *tmp; 335 char *tmp;
@@ -284,29 +340,45 @@ void parse_line_range_desc(const char *arg, struct line_range *lr)
284 */ 340 */
285 ptr = strchr(arg, ':'); 341 ptr = strchr(arg, ':');
286 if (ptr) { 342 if (ptr) {
287 lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0); 343 lr->start = (int)strtoul(ptr + 1, &tmp, 0);
288 if (*tmp == '+') 344 if (*tmp == '+') {
289 lr->end = lr->start + (unsigned int)strtoul(tmp + 1, 345 lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
290 &tmp, 0); 346 lr->end--; /*
291 else if (*tmp == '-') 347 * Adjust the number of lines here.
292 lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0); 348 * If the number of lines == 1, the
349 * the end of line should be equal to
350 * the start of line.
351 */
352 } else if (*tmp == '-')
353 lr->end = (int)strtoul(tmp + 1, &tmp, 0);
293 else 354 else
294 lr->end = 0; 355 lr->end = INT_MAX;
295 pr_debug("Line range is %u to %u\n", lr->start, lr->end); 356 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
296 if (lr->end && lr->start > lr->end) 357 if (lr->start > lr->end) {
297 semantic_error("Start line must be smaller" 358 semantic_error("Start line must be smaller"
298 " than end line."); 359 " than end line.\n");
299 if (*tmp != '\0') 360 return -EINVAL;
300 semantic_error("Tailing with invalid character '%d'.", 361 }
362 if (*tmp != '\0') {
363 semantic_error("Tailing with invalid character '%d'.\n",
301 *tmp); 364 *tmp);
302 tmp = xstrndup(arg, (ptr - arg)); 365 return -EINVAL;
303 } else 366 }
304 tmp = xstrdup(arg); 367 tmp = strndup(arg, (ptr - arg));
368 } else {
369 tmp = strdup(arg);
370 lr->end = INT_MAX;
371 }
372
373 if (tmp == NULL)
374 return -ENOMEM;
305 375
306 if (strchr(tmp, '.')) 376 if (strchr(tmp, '.'))
307 lr->file = tmp; 377 lr->file = tmp;
308 else 378 else
309 lr->function = tmp; 379 lr->function = tmp;
380
381 return 0;
310} 382}
311 383
312/* Check the name is good for event/group */ 384/* Check the name is good for event/group */
@@ -322,7 +394,7 @@ static bool check_event_name(const char *name)
322} 394}
323 395
324/* Parse probepoint definition. */ 396/* Parse probepoint definition. */
325static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 397static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
326{ 398{
327 struct perf_probe_point *pp = &pev->point; 399 struct perf_probe_point *pp = &pev->point;
328 char *ptr, *tmp; 400 char *ptr, *tmp;
@@ -339,13 +411,18 @@ static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
339 if (ptr && *ptr == '=') { /* Event name */ 411 if (ptr && *ptr == '=') { /* Event name */
340 *ptr = '\0'; 412 *ptr = '\0';
341 tmp = ptr + 1; 413 tmp = ptr + 1;
342 ptr = strchr(arg, ':'); 414 if (strchr(arg, ':')) {
343 if (ptr) /* Group name is not supported yet. */ 415 semantic_error("Group name is not supported yet.\n");
344 semantic_error("Group name is not supported yet."); 416 return -ENOTSUP;
345 if (!check_event_name(arg)) 417 }
418 if (!check_event_name(arg)) {
346 semantic_error("%s is bad for event name -it must " 419 semantic_error("%s is bad for event name -it must "
347 "follow C symbol-naming rule.", arg); 420 "follow C symbol-naming rule.\n", arg);
348 pev->event = xstrdup(arg); 421 return -EINVAL;
422 }
423 pev->event = strdup(arg);
424 if (pev->event == NULL)
425 return -ENOMEM;
349 pev->group = NULL; 426 pev->group = NULL;
350 arg = tmp; 427 arg = tmp;
351 } 428 }
@@ -356,18 +433,24 @@ static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
356 *ptr++ = '\0'; 433 *ptr++ = '\0';
357 } 434 }
358 435
436 tmp = strdup(arg);
437 if (tmp == NULL)
438 return -ENOMEM;
439
359 /* Check arg is function or file and copy it */ 440 /* Check arg is function or file and copy it */
360 if (strchr(arg, '.')) /* File */ 441 if (strchr(tmp, '.')) /* File */
361 pp->file = xstrdup(arg); 442 pp->file = tmp;
362 else /* Function */ 443 else /* Function */
363 pp->function = xstrdup(arg); 444 pp->function = tmp;
364 445
365 /* Parse other options */ 446 /* Parse other options */
366 while (ptr) { 447 while (ptr) {
367 arg = ptr; 448 arg = ptr;
368 c = nc; 449 c = nc;
369 if (c == ';') { /* Lazy pattern must be the last part */ 450 if (c == ';') { /* Lazy pattern must be the last part */
370 pp->lazy_line = xstrdup(arg); 451 pp->lazy_line = strdup(arg);
452 if (pp->lazy_line == NULL)
453 return -ENOMEM;
371 break; 454 break;
372 } 455 }
373 ptr = strpbrk(arg, ";:+@%"); 456 ptr = strpbrk(arg, ";:+@%");
@@ -378,131 +461,211 @@ static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
378 switch (c) { 461 switch (c) {
379 case ':': /* Line number */ 462 case ':': /* Line number */
380 pp->line = strtoul(arg, &tmp, 0); 463 pp->line = strtoul(arg, &tmp, 0);
381 if (*tmp != '\0') 464 if (*tmp != '\0') {
382 semantic_error("There is non-digit char" 465 semantic_error("There is non-digit char"
383 " in line number."); 466 " in line number.\n");
467 return -EINVAL;
468 }
384 break; 469 break;
385 case '+': /* Byte offset from a symbol */ 470 case '+': /* Byte offset from a symbol */
386 pp->offset = strtoul(arg, &tmp, 0); 471 pp->offset = strtoul(arg, &tmp, 0);
387 if (*tmp != '\0') 472 if (*tmp != '\0') {
388 semantic_error("There is non-digit character" 473 semantic_error("There is non-digit character"
389 " in offset."); 474 " in offset.\n");
475 return -EINVAL;
476 }
390 break; 477 break;
391 case '@': /* File name */ 478 case '@': /* File name */
392 if (pp->file) 479 if (pp->file) {
393 semantic_error("SRC@SRC is not allowed."); 480 semantic_error("SRC@SRC is not allowed.\n");
394 pp->file = xstrdup(arg); 481 return -EINVAL;
482 }
483 pp->file = strdup(arg);
484 if (pp->file == NULL)
485 return -ENOMEM;
395 break; 486 break;
396 case '%': /* Probe places */ 487 case '%': /* Probe places */
397 if (strcmp(arg, "return") == 0) { 488 if (strcmp(arg, "return") == 0) {
398 pp->retprobe = 1; 489 pp->retprobe = 1;
399 } else /* Others not supported yet */ 490 } else { /* Others not supported yet */
400 semantic_error("%%%s is not supported.", arg); 491 semantic_error("%%%s is not supported.\n", arg);
492 return -ENOTSUP;
493 }
401 break; 494 break;
402 default: 495 default: /* Buggy case */
403 DIE_IF("Program has a bug."); 496 pr_err("This program has a bug at %s:%d.\n",
497 __FILE__, __LINE__);
498 return -ENOTSUP;
404 break; 499 break;
405 } 500 }
406 } 501 }
407 502
408 /* Exclusion check */ 503 /* Exclusion check */
409 if (pp->lazy_line && pp->line) 504 if (pp->lazy_line && pp->line) {
410 semantic_error("Lazy pattern can't be used with line number."); 505 semantic_error("Lazy pattern can't be used with line number.");
506 return -EINVAL;
507 }
411 508
412 if (pp->lazy_line && pp->offset) 509 if (pp->lazy_line && pp->offset) {
413 semantic_error("Lazy pattern can't be used with offset."); 510 semantic_error("Lazy pattern can't be used with offset.");
511 return -EINVAL;
512 }
414 513
415 if (pp->line && pp->offset) 514 if (pp->line && pp->offset) {
416 semantic_error("Offset can't be used with line number."); 515 semantic_error("Offset can't be used with line number.");
516 return -EINVAL;
517 }
417 518
418 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) 519 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
419 semantic_error("File always requires line number or " 520 semantic_error("File always requires line number or "
420 "lazy pattern."); 521 "lazy pattern.");
522 return -EINVAL;
523 }
421 524
422 if (pp->offset && !pp->function) 525 if (pp->offset && !pp->function) {
423 semantic_error("Offset requires an entry function."); 526 semantic_error("Offset requires an entry function.");
527 return -EINVAL;
528 }
424 529
425 if (pp->retprobe && !pp->function) 530 if (pp->retprobe && !pp->function) {
426 semantic_error("Return probe requires an entry function."); 531 semantic_error("Return probe requires an entry function.");
532 return -EINVAL;
533 }
427 534
428 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) 535 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
429 semantic_error("Offset/Line/Lazy pattern can't be used with " 536 semantic_error("Offset/Line/Lazy pattern can't be used with "
430 "return probe."); 537 "return probe.");
538 return -EINVAL;
539 }
431 540
432 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n", 541 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
433 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 542 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
434 pp->lazy_line); 543 pp->lazy_line);
544 return 0;
435} 545}
436 546
437/* Parse perf-probe event argument */ 547/* Parse perf-probe event argument */
438static void parse_perf_probe_arg(const char *str, struct perf_probe_arg *arg) 548static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
439{ 549{
440 const char *tmp; 550 char *tmp;
441 struct perf_probe_arg_field **fieldp; 551 struct perf_probe_arg_field **fieldp;
442 552
443 pr_debug("parsing arg: %s into ", str); 553 pr_debug("parsing arg: %s into ", str);
444 554
555 tmp = strchr(str, '=');
556 if (tmp) {
557 arg->name = strndup(str, tmp - str);
558 if (arg->name == NULL)
559 return -ENOMEM;
560 pr_debug("name:%s ", arg->name);
561 str = tmp + 1;
562 }
563
564 tmp = strchr(str, ':');
565 if (tmp) { /* Type setting */
566 *tmp = '\0';
567 arg->type = strdup(tmp + 1);
568 if (arg->type == NULL)
569 return -ENOMEM;
570 pr_debug("type:%s ", arg->type);
571 }
572
445 tmp = strpbrk(str, "-."); 573 tmp = strpbrk(str, "-.");
446 if (!is_c_varname(str) || !tmp) { 574 if (!is_c_varname(str) || !tmp) {
447 /* A variable, register, symbol or special value */ 575 /* A variable, register, symbol or special value */
448 arg->name = xstrdup(str); 576 arg->var = strdup(str);
449 pr_debug("%s\n", arg->name); 577 if (arg->var == NULL)
450 return; 578 return -ENOMEM;
579 pr_debug("%s\n", arg->var);
580 return 0;
451 } 581 }
452 582
453 /* Structure fields */ 583 /* Structure fields */
454 arg->name = xstrndup(str, tmp - str); 584 arg->var = strndup(str, tmp - str);
455 pr_debug("%s, ", arg->name); 585 if (arg->var == NULL)
586 return -ENOMEM;
587 pr_debug("%s, ", arg->var);
456 fieldp = &arg->field; 588 fieldp = &arg->field;
457 589
458 do { 590 do {
459 *fieldp = xzalloc(sizeof(struct perf_probe_arg_field)); 591 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
592 if (*fieldp == NULL)
593 return -ENOMEM;
460 if (*tmp == '.') { 594 if (*tmp == '.') {
461 str = tmp + 1; 595 str = tmp + 1;
462 (*fieldp)->ref = false; 596 (*fieldp)->ref = false;
463 } else if (tmp[1] == '>') { 597 } else if (tmp[1] == '>') {
464 str = tmp + 2; 598 str = tmp + 2;
465 (*fieldp)->ref = true; 599 (*fieldp)->ref = true;
466 } else 600 } else {
467 semantic_error("Argument parse error: %s", str); 601 semantic_error("Argument parse error: %s\n", str);
602 return -EINVAL;
603 }
468 604
469 tmp = strpbrk(str, "-."); 605 tmp = strpbrk(str, "-.");
470 if (tmp) { 606 if (tmp) {
471 (*fieldp)->name = xstrndup(str, tmp - str); 607 (*fieldp)->name = strndup(str, tmp - str);
608 if ((*fieldp)->name == NULL)
609 return -ENOMEM;
472 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); 610 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
473 fieldp = &(*fieldp)->next; 611 fieldp = &(*fieldp)->next;
474 } 612 }
475 } while (tmp); 613 } while (tmp);
476 (*fieldp)->name = xstrdup(str); 614 (*fieldp)->name = strdup(str);
615 if ((*fieldp)->name == NULL)
616 return -ENOMEM;
477 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); 617 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
618
619 /* If no name is specified, set the last field name */
620 if (!arg->name) {
621 arg->name = strdup((*fieldp)->name);
622 if (arg->name == NULL)
623 return -ENOMEM;
624 }
625 return 0;
478} 626}
479 627
480/* Parse perf-probe event command */ 628/* Parse perf-probe event command */
481void parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) 629int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
482{ 630{
483 char **argv; 631 char **argv;
484 int argc, i; 632 int argc, i, ret = 0;
485 633
486 argv = argv_split(cmd, &argc); 634 argv = argv_split(cmd, &argc);
487 if (!argv) 635 if (!argv) {
488 die("argv_split failed."); 636 pr_debug("Failed to split arguments.\n");
489 if (argc > MAX_PROBE_ARGS + 1) 637 return -ENOMEM;
490 semantic_error("Too many arguments"); 638 }
491 639 if (argc - 1 > MAX_PROBE_ARGS) {
640 semantic_error("Too many probe arguments (%d).\n", argc - 1);
641 ret = -ERANGE;
642 goto out;
643 }
492 /* Parse probe point */ 644 /* Parse probe point */
493 parse_perf_probe_point(argv[0], pev); 645 ret = parse_perf_probe_point(argv[0], pev);
646 if (ret < 0)
647 goto out;
494 648
495 /* Copy arguments and ensure return probe has no C argument */ 649 /* Copy arguments and ensure return probe has no C argument */
496 pev->nargs = argc - 1; 650 pev->nargs = argc - 1;
497 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); 651 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
498 for (i = 0; i < pev->nargs; i++) { 652 if (pev->args == NULL) {
499 parse_perf_probe_arg(argv[i + 1], &pev->args[i]); 653 ret = -ENOMEM;
500 if (is_c_varname(pev->args[i].name) && pev->point.retprobe) 654 goto out;
655 }
656 for (i = 0; i < pev->nargs && ret >= 0; i++) {
657 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
658 if (ret >= 0 &&
659 is_c_varname(pev->args[i].var) && pev->point.retprobe) {
501 semantic_error("You can't specify local variable for" 660 semantic_error("You can't specify local variable for"
502 " kretprobe"); 661 " kretprobe.\n");
662 ret = -EINVAL;
663 }
503 } 664 }
504 665out:
505 argv_free(argv); 666 argv_free(argv);
667
668 return ret;
506} 669}
507 670
508/* Return true if this perf_probe_event requires debuginfo */ 671/* Return true if this perf_probe_event requires debuginfo */
@@ -514,14 +677,14 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
514 return true; 677 return true;
515 678
516 for (i = 0; i < pev->nargs; i++) 679 for (i = 0; i < pev->nargs; i++)
517 if (is_c_varname(pev->args[i].name)) 680 if (is_c_varname(pev->args[i].var))
518 return true; 681 return true;
519 682
520 return false; 683 return false;
521} 684}
522 685
523/* Parse kprobe_events event into struct probe_point */ 686/* Parse kprobe_events event into struct probe_point */
524void parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev) 687int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
525{ 688{
526 struct kprobe_trace_point *tp = &tev->point; 689 struct kprobe_trace_point *tp = &tev->point;
527 char pr; 690 char pr;
@@ -531,17 +694,25 @@ void parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
531 694
532 pr_debug("Parsing kprobe_events: %s\n", cmd); 695 pr_debug("Parsing kprobe_events: %s\n", cmd);
533 argv = argv_split(cmd, &argc); 696 argv = argv_split(cmd, &argc);
534 if (!argv) 697 if (!argv) {
535 die("argv_split failed."); 698 pr_debug("Failed to split arguments.\n");
536 if (argc < 2) 699 return -ENOMEM;
537 semantic_error("Too less arguments."); 700 }
701 if (argc < 2) {
702 semantic_error("Too few probe arguments.\n");
703 ret = -ERANGE;
704 goto out;
705 }
538 706
539 /* Scan event and group name. */ 707 /* Scan event and group name. */
540 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 708 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
541 &pr, (float *)(void *)&tev->group, 709 &pr, (float *)(void *)&tev->group,
542 (float *)(void *)&tev->event); 710 (float *)(void *)&tev->event);
543 if (ret != 3) 711 if (ret != 3) {
544 semantic_error("Failed to parse event name: %s", argv[0]); 712 semantic_error("Failed to parse event name: %s\n", argv[0]);
713 ret = -EINVAL;
714 goto out;
715 }
545 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 716 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
546 717
547 tp->retprobe = (pr == 'r'); 718 tp->retprobe = (pr == 'r');
@@ -553,19 +724,29 @@ void parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
553 tp->offset = 0; 724 tp->offset = 0;
554 725
555 tev->nargs = argc - 2; 726 tev->nargs = argc - 2;
556 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); 727 tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
728 if (tev->args == NULL) {
729 ret = -ENOMEM;
730 goto out;
731 }
557 for (i = 0; i < tev->nargs; i++) { 732 for (i = 0; i < tev->nargs; i++) {
558 p = strchr(argv[i + 2], '='); 733 p = strchr(argv[i + 2], '=');
559 if (p) /* We don't need which register is assigned. */ 734 if (p) /* We don't need which register is assigned. */
560 *p++ = '\0'; 735 *p++ = '\0';
561 else 736 else
562 p = argv[i + 2]; 737 p = argv[i + 2];
563 tev->args[i].name = xstrdup(argv[i + 2]); 738 tev->args[i].name = strdup(argv[i + 2]);
564 /* TODO: parse regs and offset */ 739 /* TODO: parse regs and offset */
565 tev->args[i].value = xstrdup(p); 740 tev->args[i].value = strdup(p);
741 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
742 ret = -ENOMEM;
743 goto out;
744 }
566 } 745 }
567 746 ret = 0;
747out:
568 argv_free(argv); 748 argv_free(argv);
749 return ret;
569} 750}
570 751
571/* Compose only probe arg */ 752/* Compose only probe arg */
@@ -575,7 +756,10 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
575 int ret; 756 int ret;
576 char *tmp = buf; 757 char *tmp = buf;
577 758
578 ret = e_snprintf(tmp, len, "%s", pa->name); 759 if (pa->name && pa->var)
760 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
761 else
762 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
579 if (ret <= 0) 763 if (ret <= 0)
580 goto error; 764 goto error;
581 tmp += ret; 765 tmp += ret;
@@ -590,9 +774,20 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
590 len -= ret; 774 len -= ret;
591 field = field->next; 775 field = field->next;
592 } 776 }
777
778 if (pa->type) {
779 ret = e_snprintf(tmp, len, ":%s", pa->type);
780 if (ret <= 0)
781 goto error;
782 tmp += ret;
783 len -= ret;
784 }
785
593 return tmp - buf; 786 return tmp - buf;
594error: 787error:
595 die("Failed to synthesize perf probe argument: %s", strerror(-ret)); 788 pr_debug("Failed to synthesize perf probe argument: %s",
789 strerror(-ret));
790 return ret;
596} 791}
597 792
598/* Compose only probe point (not argument) */ 793/* Compose only probe point (not argument) */
@@ -602,7 +797,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
602 char offs[32] = "", line[32] = "", file[32] = ""; 797 char offs[32] = "", line[32] = "", file[32] = "";
603 int ret, len; 798 int ret, len;
604 799
605 buf = xzalloc(MAX_CMDLEN); 800 buf = zalloc(MAX_CMDLEN);
801 if (buf == NULL) {
802 ret = -ENOMEM;
803 goto error;
804 }
606 if (pp->offset) { 805 if (pp->offset) {
607 ret = e_snprintf(offs, 32, "+%lu", pp->offset); 806 ret = e_snprintf(offs, 32, "+%lu", pp->offset);
608 if (ret <= 0) 807 if (ret <= 0)
@@ -614,12 +813,12 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
614 goto error; 813 goto error;
615 } 814 }
616 if (pp->file) { 815 if (pp->file) {
617 len = strlen(pp->file) - 32; 816 len = strlen(pp->file) - 31;
618 if (len < 0) 817 if (len < 0)
619 len = 0; 818 len = 0;
620 tmp = strchr(pp->file + len, '/'); 819 tmp = strchr(pp->file + len, '/');
621 if (!tmp) 820 if (!tmp)
622 tmp = pp->file + len - 1; 821 tmp = pp->file + len;
623 ret = e_snprintf(file, 32, "@%s", tmp + 1); 822 ret = e_snprintf(file, 32, "@%s", tmp + 1);
624 if (ret <= 0) 823 if (ret <= 0)
625 goto error; 824 goto error;
@@ -636,7 +835,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
636 835
637 return buf; 836 return buf;
638error: 837error:
639 die("Failed to synthesize perf probe point: %s", strerror(-ret)); 838 pr_debug("Failed to synthesize perf probe point: %s",
839 strerror(-ret));
840 if (buf)
841 free(buf);
842 return NULL;
640} 843}
641 844
642#if 0 845#if 0
@@ -727,6 +930,13 @@ static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
727 buf += ret; 930 buf += ret;
728 buflen -= ret; 931 buflen -= ret;
729 } 932 }
933 /* Print argument type */
934 if (arg->type) {
935 ret = e_snprintf(buf, buflen, ":%s", arg->type);
936 if (ret <= 0)
937 return ret;
938 buf += ret;
939 }
730 940
731 return buf - tmp; 941 return buf - tmp;
732} 942}
@@ -737,7 +947,10 @@ char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
737 char *buf; 947 char *buf;
738 int i, len, ret; 948 int i, len, ret;
739 949
740 buf = xzalloc(MAX_CMDLEN); 950 buf = zalloc(MAX_CMDLEN);
951 if (buf == NULL)
952 return NULL;
953
741 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu", 954 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
742 tp->retprobe ? 'r' : 'p', 955 tp->retprobe ? 'r' : 'p',
743 tev->group, tev->event, 956 tev->group, tev->event,
@@ -759,29 +972,44 @@ error:
759 return NULL; 972 return NULL;
760} 973}
761 974
762void convert_to_perf_probe_event(struct kprobe_trace_event *tev, 975int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
763 struct perf_probe_event *pev) 976 struct perf_probe_event *pev)
764{ 977{
765 char buf[64]; 978 char buf[64] = "";
766 int i; 979 int i, ret;
767 980
768 /* Convert event/group name */ 981 /* Convert event/group name */
769 pev->event = xstrdup(tev->event); 982 pev->event = strdup(tev->event);
770 pev->group = xstrdup(tev->group); 983 pev->group = strdup(tev->group);
984 if (pev->event == NULL || pev->group == NULL)
985 return -ENOMEM;
771 986
772 /* Convert trace_point to probe_point */ 987 /* Convert trace_point to probe_point */
773 convert_to_perf_probe_point(&tev->point, &pev->point); 988 ret = convert_to_perf_probe_point(&tev->point, &pev->point);
989 if (ret < 0)
990 return ret;
774 991
775 /* Convert trace_arg to probe_arg */ 992 /* Convert trace_arg to probe_arg */
776 pev->nargs = tev->nargs; 993 pev->nargs = tev->nargs;
777 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); 994 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
778 for (i = 0; i < tev->nargs; i++) 995 if (pev->args == NULL)
996 return -ENOMEM;
997 for (i = 0; i < tev->nargs && ret >= 0; i++) {
779 if (tev->args[i].name) 998 if (tev->args[i].name)
780 pev->args[i].name = xstrdup(tev->args[i].name); 999 pev->args[i].name = strdup(tev->args[i].name);
781 else { 1000 else {
782 synthesize_kprobe_trace_arg(&tev->args[i], buf, 64); 1001 ret = synthesize_kprobe_trace_arg(&tev->args[i],
783 pev->args[i].name = xstrdup(buf); 1002 buf, 64);
1003 pev->args[i].name = strdup(buf);
784 } 1004 }
1005 if (pev->args[i].name == NULL && ret >= 0)
1006 ret = -ENOMEM;
1007 }
1008
1009 if (ret < 0)
1010 clear_perf_probe_event(pev);
1011
1012 return ret;
785} 1013}
786 1014
787void clear_perf_probe_event(struct perf_probe_event *pev) 1015void clear_perf_probe_event(struct perf_probe_event *pev)
@@ -803,6 +1031,10 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
803 for (i = 0; i < pev->nargs; i++) { 1031 for (i = 0; i < pev->nargs; i++) {
804 if (pev->args[i].name) 1032 if (pev->args[i].name)
805 free(pev->args[i].name); 1033 free(pev->args[i].name);
1034 if (pev->args[i].var)
1035 free(pev->args[i].var);
1036 if (pev->args[i].type)
1037 free(pev->args[i].type);
806 field = pev->args[i].field; 1038 field = pev->args[i].field;
807 while (field) { 1039 while (field) {
808 next = field->next; 1040 next = field->next;
@@ -833,6 +1065,8 @@ void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
833 free(tev->args[i].name); 1065 free(tev->args[i].name);
834 if (tev->args[i].value) 1066 if (tev->args[i].value)
835 free(tev->args[i].value); 1067 free(tev->args[i].value);
1068 if (tev->args[i].type)
1069 free(tev->args[i].type);
836 ref = tev->args[i].ref; 1070 ref = tev->args[i].ref;
837 while (ref) { 1071 while (ref) {
838 next = ref->next; 1072 next = ref->next;
@@ -848,24 +1082,31 @@ void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
848static int open_kprobe_events(bool readwrite) 1082static int open_kprobe_events(bool readwrite)
849{ 1083{
850 char buf[PATH_MAX]; 1084 char buf[PATH_MAX];
1085 const char *__debugfs;
851 int ret; 1086 int ret;
852 1087
853 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path); 1088 __debugfs = debugfs_find_mountpoint();
854 if (ret < 0) 1089 if (__debugfs == NULL) {
855 die("Failed to make kprobe_events path."); 1090 pr_warning("Debugfs is not mounted.\n");
1091 return -ENOENT;
1092 }
856 1093
857 if (readwrite && !probe_event_dry_run) 1094 ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
858 ret = open(buf, O_RDWR, O_APPEND); 1095 if (ret >= 0) {
859 else 1096 pr_debug("Opening %s write=%d\n", buf, readwrite);
860 ret = open(buf, O_RDONLY, 0); 1097 if (readwrite && !probe_event_dry_run)
1098 ret = open(buf, O_RDWR, O_APPEND);
1099 else
1100 ret = open(buf, O_RDONLY, 0);
1101 }
861 1102
862 if (ret < 0) { 1103 if (ret < 0) {
863 if (errno == ENOENT) 1104 if (errno == ENOENT)
864 die("kprobe_events file does not exist -" 1105 pr_warning("kprobe_events file does not exist - please"
865 " please rebuild with CONFIG_KPROBE_EVENT."); 1106 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
866 else 1107 else
867 die("Could not open kprobe_events file: %s", 1108 pr_warning("Failed to open kprobe_events file: %s\n",
868 strerror(errno)); 1109 strerror(errno));
869 } 1110 }
870 return ret; 1111 return ret;
871} 1112}
@@ -891,8 +1132,11 @@ static struct strlist *get_kprobe_trace_command_rawlist(int fd)
891 if (p[idx] == '\n') 1132 if (p[idx] == '\n')
892 p[idx] = '\0'; 1133 p[idx] = '\0';
893 ret = strlist__add(sl, buf); 1134 ret = strlist__add(sl, buf);
894 if (ret < 0) 1135 if (ret < 0) {
895 die("strlist__add failed: %s", strerror(-ret)); 1136 pr_debug("strlist__add failed: %s\n", strerror(-ret));
1137 strlist__delete(sl);
1138 return NULL;
1139 }
896 } 1140 }
897 fclose(fp); 1141 fclose(fp);
898 1142
@@ -900,7 +1144,7 @@ static struct strlist *get_kprobe_trace_command_rawlist(int fd)
900} 1144}
901 1145
902/* Show an event */ 1146/* Show an event */
903static void show_perf_probe_event(struct perf_probe_event *pev) 1147static int show_perf_probe_event(struct perf_probe_event *pev)
904{ 1148{
905 int i, ret; 1149 int i, ret;
906 char buf[128]; 1150 char buf[128];
@@ -908,52 +1152,71 @@ static void show_perf_probe_event(struct perf_probe_event *pev)
908 1152
909 /* Synthesize only event probe point */ 1153 /* Synthesize only event probe point */
910 place = synthesize_perf_probe_point(&pev->point); 1154 place = synthesize_perf_probe_point(&pev->point);
1155 if (!place)
1156 return -EINVAL;
911 1157
912 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event); 1158 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
913 if (ret < 0) 1159 if (ret < 0)
914 die("Failed to copy event: %s", strerror(-ret)); 1160 return ret;
1161
915 printf(" %-20s (on %s", buf, place); 1162 printf(" %-20s (on %s", buf, place);
916 1163
917 if (pev->nargs > 0) { 1164 if (pev->nargs > 0) {
918 printf(" with"); 1165 printf(" with");
919 for (i = 0; i < pev->nargs; i++) { 1166 for (i = 0; i < pev->nargs; i++) {
920 synthesize_perf_probe_arg(&pev->args[i], buf, 128); 1167 ret = synthesize_perf_probe_arg(&pev->args[i],
1168 buf, 128);
1169 if (ret < 0)
1170 break;
921 printf(" %s", buf); 1171 printf(" %s", buf);
922 } 1172 }
923 } 1173 }
924 printf(")\n"); 1174 printf(")\n");
925 free(place); 1175 free(place);
1176 return ret;
926} 1177}
927 1178
928/* List up current perf-probe events */ 1179/* List up current perf-probe events */
929void show_perf_probe_events(void) 1180int show_perf_probe_events(void)
930{ 1181{
931 int fd; 1182 int fd, ret;
932 struct kprobe_trace_event tev; 1183 struct kprobe_trace_event tev;
933 struct perf_probe_event pev; 1184 struct perf_probe_event pev;
934 struct strlist *rawlist; 1185 struct strlist *rawlist;
935 struct str_node *ent; 1186 struct str_node *ent;
936 1187
937 setup_pager(); 1188 setup_pager();
938 init_vmlinux(); 1189 ret = init_vmlinux();
1190 if (ret < 0)
1191 return ret;
939 1192
940 memset(&tev, 0, sizeof(tev)); 1193 memset(&tev, 0, sizeof(tev));
941 memset(&pev, 0, sizeof(pev)); 1194 memset(&pev, 0, sizeof(pev));
942 1195
943 fd = open_kprobe_events(false); 1196 fd = open_kprobe_events(false);
1197 if (fd < 0)
1198 return fd;
1199
944 rawlist = get_kprobe_trace_command_rawlist(fd); 1200 rawlist = get_kprobe_trace_command_rawlist(fd);
945 close(fd); 1201 close(fd);
1202 if (!rawlist)
1203 return -ENOENT;
946 1204
947 strlist__for_each(ent, rawlist) { 1205 strlist__for_each(ent, rawlist) {
948 parse_kprobe_trace_command(ent->s, &tev); 1206 ret = parse_kprobe_trace_command(ent->s, &tev);
949 convert_to_perf_probe_event(&tev, &pev); 1207 if (ret >= 0) {
950 /* Show an event */ 1208 ret = convert_to_perf_probe_event(&tev, &pev);
951 show_perf_probe_event(&pev); 1209 if (ret >= 0)
1210 ret = show_perf_probe_event(&pev);
1211 }
952 clear_perf_probe_event(&pev); 1212 clear_perf_probe_event(&pev);
953 clear_kprobe_trace_event(&tev); 1213 clear_kprobe_trace_event(&tev);
1214 if (ret < 0)
1215 break;
954 } 1216 }
955
956 strlist__delete(rawlist); 1217 strlist__delete(rawlist);
1218
1219 return ret;
957} 1220}
958 1221
959/* Get current perf-probe event names */ 1222/* Get current perf-probe event names */
@@ -963,86 +1226,116 @@ static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
963 struct strlist *sl, *rawlist; 1226 struct strlist *sl, *rawlist;
964 struct str_node *ent; 1227 struct str_node *ent;
965 struct kprobe_trace_event tev; 1228 struct kprobe_trace_event tev;
1229 int ret = 0;
966 1230
967 memset(&tev, 0, sizeof(tev)); 1231 memset(&tev, 0, sizeof(tev));
968 1232
969 rawlist = get_kprobe_trace_command_rawlist(fd); 1233 rawlist = get_kprobe_trace_command_rawlist(fd);
970 sl = strlist__new(true, NULL); 1234 sl = strlist__new(true, NULL);
971 strlist__for_each(ent, rawlist) { 1235 strlist__for_each(ent, rawlist) {
972 parse_kprobe_trace_command(ent->s, &tev); 1236 ret = parse_kprobe_trace_command(ent->s, &tev);
1237 if (ret < 0)
1238 break;
973 if (include_group) { 1239 if (include_group) {
974 if (e_snprintf(buf, 128, "%s:%s", tev.group, 1240 ret = e_snprintf(buf, 128, "%s:%s", tev.group,
975 tev.event) < 0) 1241 tev.event);
976 die("Failed to copy group:event name."); 1242 if (ret >= 0)
977 strlist__add(sl, buf); 1243 ret = strlist__add(sl, buf);
978 } else 1244 } else
979 strlist__add(sl, tev.event); 1245 ret = strlist__add(sl, tev.event);
980 clear_kprobe_trace_event(&tev); 1246 clear_kprobe_trace_event(&tev);
1247 if (ret < 0)
1248 break;
981 } 1249 }
982
983 strlist__delete(rawlist); 1250 strlist__delete(rawlist);
984 1251
1252 if (ret < 0) {
1253 strlist__delete(sl);
1254 return NULL;
1255 }
985 return sl; 1256 return sl;
986} 1257}
987 1258
988static void write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev) 1259static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
989{ 1260{
990 int ret; 1261 int ret;
991 char *buf = synthesize_kprobe_trace_command(tev); 1262 char *buf = synthesize_kprobe_trace_command(tev);
992 1263
1264 if (!buf) {
1265 pr_debug("Failed to synthesize kprobe trace event.\n");
1266 return -EINVAL;
1267 }
1268
993 pr_debug("Writing event: %s\n", buf); 1269 pr_debug("Writing event: %s\n", buf);
994 if (!probe_event_dry_run) { 1270 if (!probe_event_dry_run) {
995 ret = write(fd, buf, strlen(buf)); 1271 ret = write(fd, buf, strlen(buf));
996 if (ret <= 0) 1272 if (ret <= 0)
997 die("Failed to write event: %s", strerror(errno)); 1273 pr_warning("Failed to write event: %s\n",
1274 strerror(errno));
998 } 1275 }
999 free(buf); 1276 free(buf);
1277 return ret;
1000} 1278}
1001 1279
1002static void get_new_event_name(char *buf, size_t len, const char *base, 1280static int get_new_event_name(char *buf, size_t len, const char *base,
1003 struct strlist *namelist, bool allow_suffix) 1281 struct strlist *namelist, bool allow_suffix)
1004{ 1282{
1005 int i, ret; 1283 int i, ret;
1006 1284
1007 /* Try no suffix */ 1285 /* Try no suffix */
1008 ret = e_snprintf(buf, len, "%s", base); 1286 ret = e_snprintf(buf, len, "%s", base);
1009 if (ret < 0) 1287 if (ret < 0) {
1010 die("snprintf() failed: %s", strerror(-ret)); 1288 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1289 return ret;
1290 }
1011 if (!strlist__has_entry(namelist, buf)) 1291 if (!strlist__has_entry(namelist, buf))
1012 return; 1292 return 0;
1013 1293
1014 if (!allow_suffix) { 1294 if (!allow_suffix) {
1015 pr_warning("Error: event \"%s\" already exists. " 1295 pr_warning("Error: event \"%s\" already exists. "
1016 "(Use -f to force duplicates.)\n", base); 1296 "(Use -f to force duplicates.)\n", base);
1017 die("Can't add new event."); 1297 return -EEXIST;
1018 } 1298 }
1019 1299
1020 /* Try to add suffix */ 1300 /* Try to add suffix */
1021 for (i = 1; i < MAX_EVENT_INDEX; i++) { 1301 for (i = 1; i < MAX_EVENT_INDEX; i++) {
1022 ret = e_snprintf(buf, len, "%s_%d", base, i); 1302 ret = e_snprintf(buf, len, "%s_%d", base, i);
1023 if (ret < 0) 1303 if (ret < 0) {
1024 die("snprintf() failed: %s", strerror(-ret)); 1304 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1305 return ret;
1306 }
1025 if (!strlist__has_entry(namelist, buf)) 1307 if (!strlist__has_entry(namelist, buf))
1026 break; 1308 break;
1027 } 1309 }
1028 if (i == MAX_EVENT_INDEX) 1310 if (i == MAX_EVENT_INDEX) {
1029 die("Too many events are on the same function."); 1311 pr_warning("Too many events are on the same function.\n");
1312 ret = -ERANGE;
1313 }
1314
1315 return ret;
1030} 1316}
1031 1317
1032static void __add_kprobe_trace_events(struct perf_probe_event *pev, 1318static int __add_kprobe_trace_events(struct perf_probe_event *pev,
1033 struct kprobe_trace_event *tevs, 1319 struct kprobe_trace_event *tevs,
1034 int ntevs, bool allow_suffix) 1320 int ntevs, bool allow_suffix)
1035{ 1321{
1036 int i, fd; 1322 int i, fd, ret;
1037 struct kprobe_trace_event *tev = NULL; 1323 struct kprobe_trace_event *tev = NULL;
1038 char buf[64]; 1324 char buf[64];
1039 const char *event, *group; 1325 const char *event, *group;
1040 struct strlist *namelist; 1326 struct strlist *namelist;
1041 1327
1042 fd = open_kprobe_events(true); 1328 fd = open_kprobe_events(true);
1329 if (fd < 0)
1330 return fd;
1043 /* Get current event names */ 1331 /* Get current event names */
1044 namelist = get_kprobe_trace_event_names(fd, false); 1332 namelist = get_kprobe_trace_event_names(fd, false);
1333 if (!namelist) {
1334 pr_debug("Failed to get current event list.\n");
1335 return -EIO;
1336 }
1045 1337
1338 ret = 0;
1046 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":"); 1339 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
1047 for (i = 0; i < ntevs; i++) { 1340 for (i = 0; i < ntevs; i++) {
1048 tev = &tevs[i]; 1341 tev = &tevs[i];
@@ -1059,12 +1352,21 @@ static void __add_kprobe_trace_events(struct perf_probe_event *pev,
1059 group = PERFPROBE_GROUP; 1352 group = PERFPROBE_GROUP;
1060 1353
1061 /* Get an unused new event name */ 1354 /* Get an unused new event name */
1062 get_new_event_name(buf, 64, event, namelist, allow_suffix); 1355 ret = get_new_event_name(buf, 64, event,
1356 namelist, allow_suffix);
1357 if (ret < 0)
1358 break;
1063 event = buf; 1359 event = buf;
1064 1360
1065 tev->event = xstrdup(event); 1361 tev->event = strdup(event);
1066 tev->group = xstrdup(group); 1362 tev->group = strdup(group);
1067 write_kprobe_trace_event(fd, tev); 1363 if (tev->event == NULL || tev->group == NULL) {
1364 ret = -ENOMEM;
1365 break;
1366 }
1367 ret = write_kprobe_trace_event(fd, tev);
1368 if (ret < 0)
1369 break;
1068 /* Add added event name to namelist */ 1370 /* Add added event name to namelist */
1069 strlist__add(namelist, event); 1371 strlist__add(namelist, event);
1070 1372
@@ -1086,49 +1388,90 @@ static void __add_kprobe_trace_events(struct perf_probe_event *pev,
1086 */ 1388 */
1087 allow_suffix = true; 1389 allow_suffix = true;
1088 } 1390 }
1089 /* Show how to use the event. */ 1391
1090 printf("\nYou can now use it on all perf tools, such as:\n\n"); 1392 if (ret >= 0) {
1091 printf("\tperf record -e %s:%s -a sleep 1\n\n", tev->group, tev->event); 1393 /* Show how to use the event. */
1394 printf("\nYou can now use it on all perf tools, such as:\n\n");
1395 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
1396 tev->event);
1397 }
1092 1398
1093 strlist__delete(namelist); 1399 strlist__delete(namelist);
1094 close(fd); 1400 close(fd);
1401 return ret;
1095} 1402}
1096 1403
1097static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, 1404static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
1098 struct kprobe_trace_event **tevs) 1405 struct kprobe_trace_event **tevs)
1099{ 1406{
1100 struct symbol *sym; 1407 struct symbol *sym;
1101 int ntevs = 0, i; 1408 int ret = 0, i;
1102 struct kprobe_trace_event *tev; 1409 struct kprobe_trace_event *tev;
1103 1410
1104 /* Convert perf_probe_event with debuginfo */ 1411 /* Convert perf_probe_event with debuginfo */
1105 ntevs = try_to_find_kprobe_trace_events(pev, tevs); 1412 ret = try_to_find_kprobe_trace_events(pev, tevs);
1106 if (ntevs > 0) 1413 if (ret != 0)
1107 return ntevs; 1414 return ret;
1108 1415
1109 /* Allocate trace event buffer */ 1416 /* Allocate trace event buffer */
1110 ntevs = 1; 1417 tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
1111 tev = *tevs = xzalloc(sizeof(struct kprobe_trace_event)); 1418 if (tev == NULL)
1419 return -ENOMEM;
1112 1420
1113 /* Copy parameters */ 1421 /* Copy parameters */
1114 tev->point.symbol = xstrdup(pev->point.function); 1422 tev->point.symbol = strdup(pev->point.function);
1423 if (tev->point.symbol == NULL) {
1424 ret = -ENOMEM;
1425 goto error;
1426 }
1115 tev->point.offset = pev->point.offset; 1427 tev->point.offset = pev->point.offset;
1116 tev->nargs = pev->nargs; 1428 tev->nargs = pev->nargs;
1117 if (tev->nargs) { 1429 if (tev->nargs) {
1118 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) 1430 tev->args = zalloc(sizeof(struct kprobe_trace_arg)
1119 * tev->nargs); 1431 * tev->nargs);
1120 for (i = 0; i < tev->nargs; i++) 1432 if (tev->args == NULL) {
1121 tev->args[i].value = xstrdup(pev->args[i].name); 1433 ret = -ENOMEM;
1434 goto error;
1435 }
1436 for (i = 0; i < tev->nargs; i++) {
1437 if (pev->args[i].name) {
1438 tev->args[i].name = strdup(pev->args[i].name);
1439 if (tev->args[i].name == NULL) {
1440 ret = -ENOMEM;
1441 goto error;
1442 }
1443 }
1444 tev->args[i].value = strdup(pev->args[i].var);
1445 if (tev->args[i].value == NULL) {
1446 ret = -ENOMEM;
1447 goto error;
1448 }
1449 if (pev->args[i].type) {
1450 tev->args[i].type = strdup(pev->args[i].type);
1451 if (tev->args[i].type == NULL) {
1452 ret = -ENOMEM;
1453 goto error;
1454 }
1455 }
1456 }
1122 } 1457 }
1123 1458
1124 /* Currently just checking function name from symbol map */ 1459 /* Currently just checking function name from symbol map */
1125 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 1460 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
1126 tev->point.symbol, NULL); 1461 tev->point.symbol, NULL);
1127 if (!sym) 1462 if (!sym) {
1128 die("Kernel symbol \'%s\' not found - probe not added.", 1463 pr_warning("Kernel symbol \'%s\' not found.\n",
1129 tev->point.symbol); 1464 tev->point.symbol);
1465 ret = -ENOENT;
1466 goto error;
1467 }
1130 1468
1131 return ntevs; 1469 return 1;
1470error:
1471 clear_kprobe_trace_event(tev);
1472 free(tev);
1473 *tevs = NULL;
1474 return ret;
1132} 1475}
1133 1476
1134struct __event_package { 1477struct __event_package {
@@ -1137,96 +1480,137 @@ struct __event_package {
1137 int ntevs; 1480 int ntevs;
1138}; 1481};
1139 1482
1140void add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 1483int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
1141 bool force_add) 1484 bool force_add)
1142{ 1485{
1143 int i; 1486 int i, j, ret;
1144 struct __event_package *pkgs; 1487 struct __event_package *pkgs;
1145 1488
1146 pkgs = xzalloc(sizeof(struct __event_package) * npevs); 1489 pkgs = zalloc(sizeof(struct __event_package) * npevs);
1490 if (pkgs == NULL)
1491 return -ENOMEM;
1147 1492
1148 /* Init vmlinux path */ 1493 /* Init vmlinux path */
1149 init_vmlinux(); 1494 ret = init_vmlinux();
1495 if (ret < 0)
1496 return ret;
1150 1497
1151 /* Loop 1: convert all events */ 1498 /* Loop 1: convert all events */
1152 for (i = 0; i < npevs; i++) { 1499 for (i = 0; i < npevs; i++) {
1153 pkgs[i].pev = &pevs[i]; 1500 pkgs[i].pev = &pevs[i];
1154 /* Convert with or without debuginfo */ 1501 /* Convert with or without debuginfo */
1155 pkgs[i].ntevs = convert_to_kprobe_trace_events(pkgs[i].pev, 1502 ret = convert_to_kprobe_trace_events(pkgs[i].pev,
1156 &pkgs[i].tevs); 1503 &pkgs[i].tevs);
1504 if (ret < 0)
1505 goto end;
1506 pkgs[i].ntevs = ret;
1157 } 1507 }
1158 1508
1159 /* Loop 2: add all events */ 1509 /* Loop 2: add all events */
1510 for (i = 0; i < npevs && ret >= 0; i++)
1511 ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
1512 pkgs[i].ntevs, force_add);
1513end:
1514 /* Loop 3: cleanup trace events */
1160 for (i = 0; i < npevs; i++) 1515 for (i = 0; i < npevs; i++)
1161 __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs, 1516 for (j = 0; j < pkgs[i].ntevs; j++)
1162 pkgs[i].ntevs, force_add); 1517 clear_kprobe_trace_event(&pkgs[i].tevs[j]);
1163 /* TODO: cleanup all trace events? */ 1518
1519 return ret;
1164} 1520}
1165 1521
1166static void __del_trace_kprobe_event(int fd, struct str_node *ent) 1522static int __del_trace_kprobe_event(int fd, struct str_node *ent)
1167{ 1523{
1168 char *p; 1524 char *p;
1169 char buf[128]; 1525 char buf[128];
1170 int ret; 1526 int ret;
1171 1527
1172 /* Convert from perf-probe event to trace-kprobe event */ 1528 /* Convert from perf-probe event to trace-kprobe event */
1173 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) 1529 ret = e_snprintf(buf, 128, "-:%s", ent->s);
1174 die("Failed to copy event."); 1530 if (ret < 0)
1531 goto error;
1532
1175 p = strchr(buf + 2, ':'); 1533 p = strchr(buf + 2, ':');
1176 if (!p) 1534 if (!p) {
1177 die("Internal error: %s should have ':' but not.", ent->s); 1535 pr_debug("Internal error: %s should have ':' but not.\n",
1536 ent->s);
1537 ret = -ENOTSUP;
1538 goto error;
1539 }
1178 *p = '/'; 1540 *p = '/';
1179 1541
1180 pr_debug("Writing event: %s\n", buf); 1542 pr_debug("Writing event: %s\n", buf);
1181 ret = write(fd, buf, strlen(buf)); 1543 ret = write(fd, buf, strlen(buf));
1182 if (ret <= 0) 1544 if (ret < 0)
1183 die("Failed to write event: %s", strerror(errno)); 1545 goto error;
1546
1184 printf("Remove event: %s\n", ent->s); 1547 printf("Remove event: %s\n", ent->s);
1548 return 0;
1549error:
1550 pr_warning("Failed to delete event: %s\n", strerror(-ret));
1551 return ret;
1185} 1552}
1186 1553
1187static void del_trace_kprobe_event(int fd, const char *group, 1554static int del_trace_kprobe_event(int fd, const char *group,
1188 const char *event, struct strlist *namelist) 1555 const char *event, struct strlist *namelist)
1189{ 1556{
1190 char buf[128]; 1557 char buf[128];
1191 struct str_node *ent, *n; 1558 struct str_node *ent, *n;
1192 int found = 0; 1559 int found = 0, ret = 0;
1193 1560
1194 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0) 1561 ret = e_snprintf(buf, 128, "%s:%s", group, event);
1195 die("Failed to copy event."); 1562 if (ret < 0) {
1563 pr_err("Failed to copy event.");
1564 return ret;
1565 }
1196 1566
1197 if (strpbrk(buf, "*?")) { /* Glob-exp */ 1567 if (strpbrk(buf, "*?")) { /* Glob-exp */
1198 strlist__for_each_safe(ent, n, namelist) 1568 strlist__for_each_safe(ent, n, namelist)
1199 if (strglobmatch(ent->s, buf)) { 1569 if (strglobmatch(ent->s, buf)) {
1200 found++; 1570 found++;
1201 __del_trace_kprobe_event(fd, ent); 1571 ret = __del_trace_kprobe_event(fd, ent);
1572 if (ret < 0)
1573 break;
1202 strlist__remove(namelist, ent); 1574 strlist__remove(namelist, ent);
1203 } 1575 }
1204 } else { 1576 } else {
1205 ent = strlist__find(namelist, buf); 1577 ent = strlist__find(namelist, buf);
1206 if (ent) { 1578 if (ent) {
1207 found++; 1579 found++;
1208 __del_trace_kprobe_event(fd, ent); 1580 ret = __del_trace_kprobe_event(fd, ent);
1209 strlist__remove(namelist, ent); 1581 if (ret >= 0)
1582 strlist__remove(namelist, ent);
1210 } 1583 }
1211 } 1584 }
1212 if (found == 0) 1585 if (found == 0 && ret >= 0)
1213 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); 1586 pr_info("Info: Event \"%s\" does not exist.\n", buf);
1587
1588 return ret;
1214} 1589}
1215 1590
1216void del_perf_probe_events(struct strlist *dellist) 1591int del_perf_probe_events(struct strlist *dellist)
1217{ 1592{
1218 int fd; 1593 int fd, ret = 0;
1219 const char *group, *event; 1594 const char *group, *event;
1220 char *p, *str; 1595 char *p, *str;
1221 struct str_node *ent; 1596 struct str_node *ent;
1222 struct strlist *namelist; 1597 struct strlist *namelist;
1223 1598
1224 fd = open_kprobe_events(true); 1599 fd = open_kprobe_events(true);
1600 if (fd < 0)
1601 return fd;
1602
1225 /* Get current event names */ 1603 /* Get current event names */
1226 namelist = get_kprobe_trace_event_names(fd, true); 1604 namelist = get_kprobe_trace_event_names(fd, true);
1605 if (namelist == NULL)
1606 return -EINVAL;
1227 1607
1228 strlist__for_each(ent, dellist) { 1608 strlist__for_each(ent, dellist) {
1229 str = xstrdup(ent->s); 1609 str = strdup(ent->s);
1610 if (str == NULL) {
1611 ret = -ENOMEM;
1612 break;
1613 }
1230 pr_debug("Parsing: %s\n", str); 1614 pr_debug("Parsing: %s\n", str);
1231 p = strchr(str, ':'); 1615 p = strchr(str, ':');
1232 if (p) { 1616 if (p) {
@@ -1238,10 +1622,14 @@ void del_perf_probe_events(struct strlist *dellist)
1238 event = str; 1622 event = str;
1239 } 1623 }
1240 pr_debug("Group: %s, Event: %s\n", group, event); 1624 pr_debug("Group: %s, Event: %s\n", group, event);
1241 del_trace_kprobe_event(fd, group, event, namelist); 1625 ret = del_trace_kprobe_event(fd, group, event, namelist);
1242 free(str); 1626 free(str);
1627 if (ret < 0)
1628 break;
1243 } 1629 }
1244 strlist__delete(namelist); 1630 strlist__delete(namelist);
1245 close(fd); 1631 close(fd);
1632
1633 return ret;
1246} 1634}
1247 1635
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 9d99fc24c4fc..e7ff0d02c0d4 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -23,6 +23,7 @@ struct kprobe_trace_arg_ref {
23struct kprobe_trace_arg { 23struct kprobe_trace_arg {
24 char *name; /* Argument name */ 24 char *name; /* Argument name */
25 char *value; /* Base value */ 25 char *value; /* Base value */
26 char *type; /* Type name */
26 struct kprobe_trace_arg_ref *ref; /* Referencing offset */ 27 struct kprobe_trace_arg_ref *ref; /* Referencing offset */
27}; 28};
28 29
@@ -55,6 +56,8 @@ struct perf_probe_arg_field {
55/* Perf probe probing argument */ 56/* Perf probe probing argument */
56struct perf_probe_arg { 57struct perf_probe_arg {
57 char *name; /* Argument name */ 58 char *name; /* Argument name */
59 char *var; /* Variable name */
60 char *type; /* Type name */
58 struct perf_probe_arg_field *field; /* Structure fields */ 61 struct perf_probe_arg_field *field; /* Structure fields */
59}; 62};
60 63
@@ -71,25 +74,25 @@ struct perf_probe_event {
71/* Line number container */ 74/* Line number container */
72struct line_node { 75struct line_node {
73 struct list_head list; 76 struct list_head list;
74 unsigned int line; 77 int line;
75}; 78};
76 79
77/* Line range */ 80/* Line range */
78struct line_range { 81struct line_range {
79 char *file; /* File name */ 82 char *file; /* File name */
80 char *function; /* Function name */ 83 char *function; /* Function name */
81 unsigned int start; /* Start line number */ 84 int start; /* Start line number */
82 unsigned int end; /* End line number */ 85 int end; /* End line number */
83 int offset; /* Start line offset */ 86 int offset; /* Start line offset */
84 char *path; /* Real path name */ 87 char *path; /* Real path name */
85 struct list_head line_list; /* Visible lines */ 88 struct list_head line_list; /* Visible lines */
86}; 89};
87 90
88/* Command string to events */ 91/* Command string to events */
89extern void parse_perf_probe_command(const char *cmd, 92extern int parse_perf_probe_command(const char *cmd,
90 struct perf_probe_event *pev); 93 struct perf_probe_event *pev);
91extern void parse_kprobe_trace_command(const char *cmd, 94extern int parse_kprobe_trace_command(const char *cmd,
92 struct kprobe_trace_event *tev); 95 struct kprobe_trace_event *tev);
93 96
94/* Events to command string */ 97/* Events to command string */
95extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); 98extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
@@ -101,22 +104,22 @@ extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
101extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); 104extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
102 105
103/* Convert from kprobe_trace_event to perf_probe_event */ 106/* Convert from kprobe_trace_event to perf_probe_event */
104extern void convert_to_perf_probe_event(struct kprobe_trace_event *tev, 107extern int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
105 struct perf_probe_event *pev); 108 struct perf_probe_event *pev);
106 109
107/* Release event contents */ 110/* Release event contents */
108extern void clear_perf_probe_event(struct perf_probe_event *pev); 111extern void clear_perf_probe_event(struct perf_probe_event *pev);
109extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev); 112extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev);
110 113
111/* Command string to line-range */ 114/* Command string to line-range */
112extern void parse_line_range_desc(const char *cmd, struct line_range *lr); 115extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
113 116
114 117
115extern void add_perf_probe_events(struct perf_probe_event *pevs, int ntevs, 118extern int add_perf_probe_events(struct perf_probe_event *pevs, int ntevs,
116 bool force_add); 119 bool force_add);
117extern void del_perf_probe_events(struct strlist *dellist); 120extern int del_perf_probe_events(struct strlist *dellist);
118extern void show_perf_probe_events(void); 121extern int show_perf_probe_events(void);
119extern void show_line_range(struct line_range *lr); 122extern int show_line_range(struct line_range *lr);
120 123
121 124
122/* Maximum index number of event-name postfix */ 125/* Maximum index number of event-name postfix */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a8513772df08..3e7977560be5 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -84,6 +84,9 @@ const char *x86_64_regs_table[X86_64_MAX_REGS] = {
84#define arch_regs_table x86_32_regs_table 84#define arch_regs_table x86_32_regs_table
85#endif 85#endif
86 86
87/* Kprobe tracer basic type is up to u64 */
88#define MAX_BASIC_TYPE_BITS 64
89
87/* Return architecture dependent register string (for kprobe-tracer) */ 90/* Return architecture dependent register string (for kprobe-tracer) */
88static const char *get_arch_regstr(unsigned int n) 91static const char *get_arch_regstr(unsigned int n)
89{ 92{
@@ -108,7 +111,7 @@ static int strtailcmp(const char *s1, const char *s2)
108/* Line number list operations */ 111/* Line number list operations */
109 112
110/* Add a line to line number list */ 113/* Add a line to line number list */
111static void line_list__add_line(struct list_head *head, unsigned int line) 114static int line_list__add_line(struct list_head *head, int line)
112{ 115{
113 struct line_node *ln; 116 struct line_node *ln;
114 struct list_head *p; 117 struct list_head *p;
@@ -119,20 +122,23 @@ static void line_list__add_line(struct list_head *head, unsigned int line)
119 p = &ln->list; 122 p = &ln->list;
120 goto found; 123 goto found;
121 } else if (ln->line == line) /* Already exist */ 124 } else if (ln->line == line) /* Already exist */
122 return ; 125 return 1;
123 } 126 }
124 /* List is empty, or the smallest entry */ 127 /* List is empty, or the smallest entry */
125 p = head; 128 p = head;
126found: 129found:
127 pr_debug("line list: add a line %u\n", line); 130 pr_debug("line list: add a line %u\n", line);
128 ln = xzalloc(sizeof(struct line_node)); 131 ln = zalloc(sizeof(struct line_node));
132 if (ln == NULL)
133 return -ENOMEM;
129 ln->line = line; 134 ln->line = line;
130 INIT_LIST_HEAD(&ln->list); 135 INIT_LIST_HEAD(&ln->list);
131 list_add(&ln->list, p); 136 list_add(&ln->list, p);
137 return 0;
132} 138}
133 139
134/* Check if the line in line number list */ 140/* Check if the line in line number list */
135static int line_list__has_line(struct list_head *head, unsigned int line) 141static int line_list__has_line(struct list_head *head, int line)
136{ 142{
137 struct line_node *ln; 143 struct line_node *ln;
138 144
@@ -193,19 +199,7 @@ static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
193{ 199{
194 const char *name; 200 const char *name;
195 name = dwarf_diename(dw_die); 201 name = dwarf_diename(dw_die);
196 DIE_IF(name == NULL); 202 return name ? strcmp(tname, name) : -1;
197 return strcmp(tname, name);
198}
199
200/* Get entry pc(or low pc, 1st entry of ranges) of the die */
201static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die)
202{
203 Dwarf_Addr epc;
204 int ret;
205
206 ret = dwarf_entrypc(dw_die, &epc);
207 DIE_IF(ret == -1);
208 return epc;
209} 203}
210 204
211/* Get type die, but skip qualifiers and typedef */ 205/* Get type die, but skip qualifiers and typedef */
@@ -230,6 +224,58 @@ static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
230 return die_mem; 224 return die_mem;
231} 225}
232 226
227static bool die_is_signed_type(Dwarf_Die *tp_die)
228{
229 Dwarf_Attribute attr;
230 Dwarf_Word ret;
231
232 if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL ||
233 dwarf_formudata(&attr, &ret) != 0)
234 return false;
235
236 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
237 ret == DW_ATE_signed_fixed);
238}
239
240static int die_get_byte_size(Dwarf_Die *tp_die)
241{
242 Dwarf_Attribute attr;
243 Dwarf_Word ret;
244
245 if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL ||
246 dwarf_formudata(&attr, &ret) != 0)
247 return 0;
248
249 return (int)ret;
250}
251
252/* Get data_member_location offset */
253static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
254{
255 Dwarf_Attribute attr;
256 Dwarf_Op *expr;
257 size_t nexpr;
258 int ret;
259
260 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
261 return -ENOENT;
262
263 if (dwarf_formudata(&attr, offs) != 0) {
264 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
265 ret = dwarf_getlocation(&attr, &expr, &nexpr);
266 if (ret < 0 || nexpr == 0)
267 return -ENOENT;
268
269 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
270 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
271 expr[0].atom, nexpr);
272 return -ENOTSUP;
273 }
274 *offs = (Dwarf_Word)expr[0].number;
275 }
276 return 0;
277}
278
233/* Return values for die_find callbacks */ 279/* Return values for die_find callbacks */
234enum { 280enum {
235 DIE_FIND_CB_FOUND = 0, /* End of Search */ 281 DIE_FIND_CB_FOUND = 0, /* End of Search */
@@ -362,7 +408,7 @@ static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
362 */ 408 */
363 409
364/* Show a location */ 410/* Show a location */
365static void convert_location(Dwarf_Op *op, struct probe_finder *pf) 411static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
366{ 412{
367 unsigned int regn; 413 unsigned int regn;
368 Dwarf_Word offs = 0; 414 Dwarf_Word offs = 0;
@@ -370,11 +416,13 @@ static void convert_location(Dwarf_Op *op, struct probe_finder *pf)
370 const char *regs; 416 const char *regs;
371 struct kprobe_trace_arg *tvar = pf->tvar; 417 struct kprobe_trace_arg *tvar = pf->tvar;
372 418
373 /* TODO: support CFA */
374 /* If this is based on frame buffer, set the offset */ 419 /* If this is based on frame buffer, set the offset */
375 if (op->atom == DW_OP_fbreg) { 420 if (op->atom == DW_OP_fbreg) {
376 if (pf->fb_ops == NULL) 421 if (pf->fb_ops == NULL) {
377 die("The attribute of frame base is not supported.\n"); 422 pr_warning("The attribute of frame base is not "
423 "supported.\n");
424 return -ENOTSUP;
425 }
378 ref = true; 426 ref = true;
379 offs = op->number; 427 offs = op->number;
380 op = &pf->fb_ops[0]; 428 op = &pf->fb_ops[0];
@@ -392,84 +440,155 @@ static void convert_location(Dwarf_Op *op, struct probe_finder *pf)
392 ref = true; 440 ref = true;
393 } else if (op->atom == DW_OP_regx) { 441 } else if (op->atom == DW_OP_regx) {
394 regn = op->number; 442 regn = op->number;
395 } else 443 } else {
396 die("DW_OP %d is not supported.", op->atom); 444 pr_warning("DW_OP %x is not supported.\n", op->atom);
445 return -ENOTSUP;
446 }
397 447
398 regs = get_arch_regstr(regn); 448 regs = get_arch_regstr(regn);
399 if (!regs) 449 if (!regs) {
400 die("%u exceeds max register number.", regn); 450 pr_warning("%u exceeds max register number.\n", regn);
451 return -ERANGE;
452 }
453
454 tvar->value = strdup(regs);
455 if (tvar->value == NULL)
456 return -ENOMEM;
401 457
402 tvar->value = xstrdup(regs);
403 if (ref) { 458 if (ref) {
404 tvar->ref = xzalloc(sizeof(struct kprobe_trace_arg_ref)); 459 tvar->ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
460 if (tvar->ref == NULL)
461 return -ENOMEM;
405 tvar->ref->offset = (long)offs; 462 tvar->ref->offset = (long)offs;
406 } 463 }
464 return 0;
465}
466
467static int convert_variable_type(Dwarf_Die *vr_die,
468 struct kprobe_trace_arg *targ)
469{
470 Dwarf_Die type;
471 char buf[16];
472 int ret;
473
474 if (die_get_real_type(vr_die, &type) == NULL) {
475 pr_warning("Failed to get a type information of %s.\n",
476 dwarf_diename(vr_die));
477 return -ENOENT;
478 }
479
480 ret = die_get_byte_size(&type) * 8;
481 if (ret) {
482 /* Check the bitwidth */
483 if (ret > MAX_BASIC_TYPE_BITS) {
484 pr_info("%s exceeds max-bitwidth."
485 " Cut down to %d bits.\n",
486 dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
487 ret = MAX_BASIC_TYPE_BITS;
488 }
489
490 ret = snprintf(buf, 16, "%c%d",
491 die_is_signed_type(&type) ? 's' : 'u', ret);
492 if (ret < 0 || ret >= 16) {
493 if (ret >= 16)
494 ret = -E2BIG;
495 pr_warning("Failed to convert variable type: %s\n",
496 strerror(-ret));
497 return ret;
498 }
499 targ->type = strdup(buf);
500 if (targ->type == NULL)
501 return -ENOMEM;
502 }
503 return 0;
407} 504}
408 505
409static void convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 506static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
410 struct perf_probe_arg_field *field, 507 struct perf_probe_arg_field *field,
411 struct kprobe_trace_arg_ref **ref_ptr) 508 struct kprobe_trace_arg_ref **ref_ptr,
509 Dwarf_Die *die_mem)
412{ 510{
413 struct kprobe_trace_arg_ref *ref = *ref_ptr; 511 struct kprobe_trace_arg_ref *ref = *ref_ptr;
414 Dwarf_Attribute attr;
415 Dwarf_Die member;
416 Dwarf_Die type; 512 Dwarf_Die type;
417 Dwarf_Word offs; 513 Dwarf_Word offs;
514 int ret;
418 515
419 pr_debug("converting %s in %s\n", field->name, varname); 516 pr_debug("converting %s in %s\n", field->name, varname);
420 if (die_get_real_type(vr_die, &type) == NULL) 517 if (die_get_real_type(vr_die, &type) == NULL) {
421 die("Failed to get a type information of %s.", varname); 518 pr_warning("Failed to get the type of %s.\n", varname);
519 return -ENOENT;
520 }
422 521
423 /* Check the pointer and dereference */ 522 /* Check the pointer and dereference */
424 if (dwarf_tag(&type) == DW_TAG_pointer_type) { 523 if (dwarf_tag(&type) == DW_TAG_pointer_type) {
425 if (!field->ref) 524 if (!field->ref) {
426 die("Semantic error: %s must be referred by '->'", 525 pr_err("Semantic error: %s must be referred by '->'\n",
427 field->name); 526 field->name);
527 return -EINVAL;
528 }
428 /* Get the type pointed by this pointer */ 529 /* Get the type pointed by this pointer */
429 if (die_get_real_type(&type, &type) == NULL) 530 if (die_get_real_type(&type, &type) == NULL) {
430 die("Failed to get a type information of %s.", varname); 531 pr_warning("Failed to get the type of %s.\n", varname);
431 532 return -ENOENT;
533 }
432 /* Verify it is a data structure */ 534 /* Verify it is a data structure */
433 if (dwarf_tag(&type) != DW_TAG_structure_type) 535 if (dwarf_tag(&type) != DW_TAG_structure_type) {
434 die("%s is not a data structure.", varname); 536 pr_warning("%s is not a data structure.\n", varname);
537 return -EINVAL;
538 }
435 539
436 ref = xzalloc(sizeof(struct kprobe_trace_arg_ref)); 540 ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
541 if (ref == NULL)
542 return -ENOMEM;
437 if (*ref_ptr) 543 if (*ref_ptr)
438 (*ref_ptr)->next = ref; 544 (*ref_ptr)->next = ref;
439 else 545 else
440 *ref_ptr = ref; 546 *ref_ptr = ref;
441 } else { 547 } else {
442 /* Verify it is a data structure */ 548 /* Verify it is a data structure */
443 if (dwarf_tag(&type) != DW_TAG_structure_type) 549 if (dwarf_tag(&type) != DW_TAG_structure_type) {
444 die("%s is not a data structure.", varname); 550 pr_warning("%s is not a data structure.\n", varname);
445 551 return -EINVAL;
446 if (field->ref) 552 }
447 die("Semantic error: %s must be referred by '.'", 553 if (field->ref) {
448 field->name); 554 pr_err("Semantic error: %s must be referred by '.'\n",
449 if (!ref) 555 field->name);
450 die("Structure on a register is not supported yet."); 556 return -EINVAL;
557 }
558 if (!ref) {
559 pr_warning("Structure on a register is not "
560 "supported yet.\n");
561 return -ENOTSUP;
562 }
451 } 563 }
452 564
453 if (die_find_member(&type, field->name, &member) == NULL) 565 if (die_find_member(&type, field->name, die_mem) == NULL) {
454 die("%s(tyep:%s) has no member %s.", varname, 566 pr_warning("%s(tyep:%s) has no member %s.\n", varname,
455 dwarf_diename(&type), field->name); 567 dwarf_diename(&type), field->name);
568 return -EINVAL;
569 }
456 570
457 /* Get the offset of the field */ 571 /* Get the offset of the field */
458 if (dwarf_attr(&member, DW_AT_data_member_location, &attr) == NULL || 572 ret = die_get_data_member_location(die_mem, &offs);
459 dwarf_formudata(&attr, &offs) != 0) 573 if (ret < 0) {
460 die("Failed to get the offset of %s.", field->name); 574 pr_warning("Failed to get the offset of %s.\n", field->name);
575 return ret;
576 }
461 ref->offset += (long)offs; 577 ref->offset += (long)offs;
462 578
463 /* Converting next field */ 579 /* Converting next field */
464 if (field->next) 580 if (field->next)
465 convert_variable_fields(&member, field->name, field->next, 581 return convert_variable_fields(die_mem, field->name,
466 &ref); 582 field->next, &ref, die_mem);
583 else
584 return 0;
467} 585}
468 586
469/* Show a variables in kprobe event format */ 587/* Show a variables in kprobe event format */
470static void convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) 588static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
471{ 589{
472 Dwarf_Attribute attr; 590 Dwarf_Attribute attr;
591 Dwarf_Die die_mem;
473 Dwarf_Op *expr; 592 Dwarf_Op *expr;
474 size_t nexpr; 593 size_t nexpr;
475 int ret; 594 int ret;
@@ -481,44 +600,74 @@ static void convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
481 if (ret <= 0 || nexpr == 0) 600 if (ret <= 0 || nexpr == 0)
482 goto error; 601 goto error;
483 602
484 convert_location(expr, pf); 603 ret = convert_location(expr, pf);
485 604 if (ret == 0 && pf->pvar->field) {
486 if (pf->pvar->field) 605 ret = convert_variable_fields(vr_die, pf->pvar->var,
487 convert_variable_fields(vr_die, pf->pvar->name, 606 pf->pvar->field, &pf->tvar->ref,
488 pf->pvar->field, &pf->tvar->ref); 607 &die_mem);
608 vr_die = &die_mem;
609 }
610 if (ret == 0) {
611 if (pf->pvar->type) {
612 pf->tvar->type = strdup(pf->pvar->type);
613 if (pf->tvar->type == NULL)
614 ret = -ENOMEM;
615 } else
616 ret = convert_variable_type(vr_die, pf->tvar);
617 }
489 /* *expr will be cached in libdw. Don't free it. */ 618 /* *expr will be cached in libdw. Don't free it. */
490 return ; 619 return ret;
491error: 620error:
492 /* TODO: Support const_value */ 621 /* TODO: Support const_value */
493 die("Failed to find the location of %s at this address.\n" 622 pr_err("Failed to find the location of %s at this address.\n"
494 " Perhaps, it has been optimized out.", pf->pvar->name); 623 " Perhaps, it has been optimized out.\n", pf->pvar->var);
624 return -ENOENT;
495} 625}
496 626
497/* Find a variable in a subprogram die */ 627/* Find a variable in a subprogram die */
498static void find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) 628static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
499{ 629{
500 Dwarf_Die vr_die; 630 Dwarf_Die vr_die;
501 char buf[128]; 631 char buf[32], *ptr;
632 int ret;
633
634 /* TODO: Support arrays */
635 if (pf->pvar->name)
636 pf->tvar->name = strdup(pf->pvar->name);
637 else {
638 ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
639 if (ret < 0)
640 return ret;
641 ptr = strchr(buf, ':'); /* Change type separator to _ */
642 if (ptr)
643 *ptr = '_';
644 pf->tvar->name = strdup(buf);
645 }
646 if (pf->tvar->name == NULL)
647 return -ENOMEM;
502 648
503 /* TODO: Support struct members and arrays */ 649 if (!is_c_varname(pf->pvar->var)) {
504 if (!is_c_varname(pf->pvar->name)) {
505 /* Copy raw parameters */ 650 /* Copy raw parameters */
506 pf->tvar->value = xstrdup(pf->pvar->name); 651 pf->tvar->value = strdup(pf->pvar->var);
507 } else { 652 if (pf->tvar->value == NULL)
508 synthesize_perf_probe_arg(pf->pvar, buf, 128); 653 return -ENOMEM;
509 pf->tvar->name = xstrdup(buf); 654 else
510 pr_debug("Searching '%s' variable in context.\n", 655 return 0;
511 pf->pvar->name); 656 }
512 /* Search child die for local variables and parameters. */ 657
513 if (!die_find_variable(sp_die, pf->pvar->name, &vr_die)) 658 pr_debug("Searching '%s' variable in context.\n",
514 die("Failed to find '%s' in this function.", 659 pf->pvar->var);
515 pf->pvar->name); 660 /* Search child die for local variables and parameters. */
516 convert_variable(&vr_die, pf); 661 if (!die_find_variable(sp_die, pf->pvar->var, &vr_die)) {
662 pr_warning("Failed to find '%s' in this function.\n",
663 pf->pvar->var);
664 return -ENOENT;
517 } 665 }
666 return convert_variable(&vr_die, pf);
518} 667}
519 668
520/* Show a probe point to output buffer */ 669/* Show a probe point to output buffer */
521static void convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) 670static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
522{ 671{
523 struct kprobe_trace_event *tev; 672 struct kprobe_trace_event *tev;
524 Dwarf_Addr eaddr; 673 Dwarf_Addr eaddr;
@@ -528,23 +677,34 @@ static void convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
528 Dwarf_Attribute fb_attr; 677 Dwarf_Attribute fb_attr;
529 size_t nops; 678 size_t nops;
530 679
531 if (pf->ntevs == MAX_PROBES) 680 if (pf->ntevs == MAX_PROBES) {
532 die("Too many( > %d) probe point found.\n", MAX_PROBES); 681 pr_warning("Too many( > %d) probe point found.\n", MAX_PROBES);
682 return -ERANGE;
683 }
533 tev = &pf->tevs[pf->ntevs++]; 684 tev = &pf->tevs[pf->ntevs++];
534 685
535 /* If no real subprogram, find a real one */ 686 /* If no real subprogram, find a real one */
536 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 687 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
537 sp_die = die_find_real_subprogram(&pf->cu_die, 688 sp_die = die_find_real_subprogram(&pf->cu_die,
538 pf->addr, &die_mem); 689 pf->addr, &die_mem);
539 if (!sp_die) 690 if (!sp_die) {
540 die("Probe point is not found in subprograms."); 691 pr_warning("Failed to find probe point in any "
692 "functions.\n");
693 return -ENOENT;
694 }
541 } 695 }
542 696
543 /* Copy the name of probe point */ 697 /* Copy the name of probe point */
544 name = dwarf_diename(sp_die); 698 name = dwarf_diename(sp_die);
545 if (name) { 699 if (name) {
546 dwarf_entrypc(sp_die, &eaddr); 700 if (dwarf_entrypc(sp_die, &eaddr) != 0) {
547 tev->point.symbol = xstrdup(name); 701 pr_warning("Failed to get entry pc of %s\n",
702 dwarf_diename(sp_die));
703 return -ENOENT;
704 }
705 tev->point.symbol = strdup(name);
706 if (tev->point.symbol == NULL)
707 return -ENOMEM;
548 tev->point.offset = (unsigned long)(pf->addr - eaddr); 708 tev->point.offset = (unsigned long)(pf->addr - eaddr);
549 } else 709 } else
550 /* This function has no name. */ 710 /* This function has no name. */
@@ -556,55 +716,74 @@ static void convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
556 /* Get the frame base attribute/ops */ 716 /* Get the frame base attribute/ops */
557 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 717 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
558 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 718 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
559 if (ret <= 0 || nops == 0) 719 if (ret <= 0 || nops == 0) {
560 pf->fb_ops = NULL; 720 pf->fb_ops = NULL;
721 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
722 pf->cfi != NULL) {
723 Dwarf_Frame *frame;
724 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
725 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
726 pr_warning("Failed to get CFA on 0x%jx\n",
727 (uintmax_t)pf->addr);
728 return -ENOENT;
729 }
730 }
561 731
562 /* Find each argument */ 732 /* Find each argument */
563 /* TODO: use dwarf_cfi_addrframe */
564 tev->nargs = pf->pev->nargs; 733 tev->nargs = pf->pev->nargs;
565 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); 734 tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
735 if (tev->args == NULL)
736 return -ENOMEM;
566 for (i = 0; i < pf->pev->nargs; i++) { 737 for (i = 0; i < pf->pev->nargs; i++) {
567 pf->pvar = &pf->pev->args[i]; 738 pf->pvar = &pf->pev->args[i];
568 pf->tvar = &tev->args[i]; 739 pf->tvar = &tev->args[i];
569 find_variable(sp_die, pf); 740 ret = find_variable(sp_die, pf);
741 if (ret != 0)
742 return ret;
570 } 743 }
571 744
572 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 745 /* *pf->fb_ops will be cached in libdw. Don't free it. */
573 pf->fb_ops = NULL; 746 pf->fb_ops = NULL;
747 return 0;
574} 748}
575 749
576/* Find probe point from its line number */ 750/* Find probe point from its line number */
577static void find_probe_point_by_line(struct probe_finder *pf) 751static int find_probe_point_by_line(struct probe_finder *pf)
578{ 752{
579 Dwarf_Lines *lines; 753 Dwarf_Lines *lines;
580 Dwarf_Line *line; 754 Dwarf_Line *line;
581 size_t nlines, i; 755 size_t nlines, i;
582 Dwarf_Addr addr; 756 Dwarf_Addr addr;
583 int lineno; 757 int lineno;
584 int ret; 758 int ret = 0;
585 759
586 ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines); 760 if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
587 DIE_IF(ret != 0); 761 pr_warning("No source lines found in this CU.\n");
762 return -ENOENT;
763 }
588 764
589 for (i = 0; i < nlines; i++) { 765 for (i = 0; i < nlines && ret == 0; i++) {
590 line = dwarf_onesrcline(lines, i); 766 line = dwarf_onesrcline(lines, i);
591 dwarf_lineno(line, &lineno); 767 if (dwarf_lineno(line, &lineno) != 0 ||
592 if (lineno != pf->lno) 768 lineno != pf->lno)
593 continue; 769 continue;
594 770
595 /* TODO: Get fileno from line, but how? */ 771 /* TODO: Get fileno from line, but how? */
596 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0) 772 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
597 continue; 773 continue;
598 774
599 ret = dwarf_lineaddr(line, &addr); 775 if (dwarf_lineaddr(line, &addr) != 0) {
600 DIE_IF(ret != 0); 776 pr_warning("Failed to get the address of the line.\n");
777 return -ENOENT;
778 }
601 pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n", 779 pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
602 (int)i, lineno, (uintmax_t)addr); 780 (int)i, lineno, (uintmax_t)addr);
603 pf->addr = addr; 781 pf->addr = addr;
604 782
605 convert_probe_point(NULL, pf); 783 ret = convert_probe_point(NULL, pf);
606 /* Continuing, because target line might be inlined. */ 784 /* Continuing, because target line might be inlined. */
607 } 785 }
786 return ret;
608} 787}
609 788
610/* Find lines which match lazy pattern */ 789/* Find lines which match lazy pattern */
@@ -612,15 +791,27 @@ static int find_lazy_match_lines(struct list_head *head,
612 const char *fname, const char *pat) 791 const char *fname, const char *pat)
613{ 792{
614 char *fbuf, *p1, *p2; 793 char *fbuf, *p1, *p2;
615 int fd, line, nlines = 0; 794 int fd, ret, line, nlines = 0;
616 struct stat st; 795 struct stat st;
617 796
618 fd = open(fname, O_RDONLY); 797 fd = open(fname, O_RDONLY);
619 if (fd < 0) 798 if (fd < 0) {
620 die("failed to open %s", fname); 799 pr_warning("Failed to open %s: %s\n", fname, strerror(-fd));
621 DIE_IF(fstat(fd, &st) < 0); 800 return fd;
801 }
802
803 ret = fstat(fd, &st);
804 if (ret < 0) {
805 pr_warning("Failed to get the size of %s: %s\n",
806 fname, strerror(errno));
807 return ret;
808 }
622 fbuf = xmalloc(st.st_size + 2); 809 fbuf = xmalloc(st.st_size + 2);
623 DIE_IF(read(fd, fbuf, st.st_size) < 0); 810 ret = read(fd, fbuf, st.st_size);
811 if (ret < 0) {
812 pr_warning("Failed to read %s: %s\n", fname, strerror(errno));
813 return ret;
814 }
624 close(fd); 815 close(fd);
625 fbuf[st.st_size] = '\n'; /* Dummy line */ 816 fbuf[st.st_size] = '\n'; /* Dummy line */
626 fbuf[st.st_size + 1] = '\0'; 817 fbuf[st.st_size + 1] = '\0';
@@ -640,7 +831,7 @@ static int find_lazy_match_lines(struct list_head *head,
640} 831}
641 832
642/* Find probe points from lazy pattern */ 833/* Find probe points from lazy pattern */
643static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) 834static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
644{ 835{
645 Dwarf_Lines *lines; 836 Dwarf_Lines *lines;
646 Dwarf_Line *line; 837 Dwarf_Line *line;
@@ -648,31 +839,40 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
648 Dwarf_Addr addr; 839 Dwarf_Addr addr;
649 Dwarf_Die die_mem; 840 Dwarf_Die die_mem;
650 int lineno; 841 int lineno;
651 int ret; 842 int ret = 0;
652 843
653 if (list_empty(&pf->lcache)) { 844 if (list_empty(&pf->lcache)) {
654 /* Matching lazy line pattern */ 845 /* Matching lazy line pattern */
655 ret = find_lazy_match_lines(&pf->lcache, pf->fname, 846 ret = find_lazy_match_lines(&pf->lcache, pf->fname,
656 pf->pev->point.lazy_line); 847 pf->pev->point.lazy_line);
657 if (ret <= 0) 848 if (ret == 0) {
658 die("No matched lines found in %s.", pf->fname); 849 pr_debug("No matched lines found in %s.\n", pf->fname);
850 return 0;
851 } else if (ret < 0)
852 return ret;
659 } 853 }
660 854
661 ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines); 855 if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
662 DIE_IF(ret != 0); 856 pr_warning("No source lines found in this CU.\n");
663 for (i = 0; i < nlines; i++) { 857 return -ENOENT;
858 }
859
860 for (i = 0; i < nlines && ret >= 0; i++) {
664 line = dwarf_onesrcline(lines, i); 861 line = dwarf_onesrcline(lines, i);
665 862
666 dwarf_lineno(line, &lineno); 863 if (dwarf_lineno(line, &lineno) != 0 ||
667 if (!line_list__has_line(&pf->lcache, lineno)) 864 !line_list__has_line(&pf->lcache, lineno))
668 continue; 865 continue;
669 866
670 /* TODO: Get fileno from line, but how? */ 867 /* TODO: Get fileno from line, but how? */
671 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0) 868 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
672 continue; 869 continue;
673 870
674 ret = dwarf_lineaddr(line, &addr); 871 if (dwarf_lineaddr(line, &addr) != 0) {
675 DIE_IF(ret != 0); 872 pr_debug("Failed to get the address of line %d.\n",
873 lineno);
874 continue;
875 }
676 if (sp_die) { 876 if (sp_die) {
677 /* Address filtering 1: does sp_die include addr? */ 877 /* Address filtering 1: does sp_die include addr? */
678 if (!dwarf_haspc(sp_die, addr)) 878 if (!dwarf_haspc(sp_die, addr))
@@ -686,27 +886,42 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
686 (int)i, lineno, (unsigned long long)addr); 886 (int)i, lineno, (unsigned long long)addr);
687 pf->addr = addr; 887 pf->addr = addr;
688 888
689 convert_probe_point(sp_die, pf); 889 ret = convert_probe_point(sp_die, pf);
690 /* Continuing, because target line might be inlined. */ 890 /* Continuing, because target line might be inlined. */
691 } 891 }
692 /* TODO: deallocate lines, but how? */ 892 /* TODO: deallocate lines, but how? */
893 return ret;
693} 894}
694 895
896/* Callback parameter with return value */
897struct dwarf_callback_param {
898 void *data;
899 int retval;
900};
901
695static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 902static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
696{ 903{
697 struct probe_finder *pf = (struct probe_finder *)data; 904 struct dwarf_callback_param *param = data;
905 struct probe_finder *pf = param->data;
698 struct perf_probe_point *pp = &pf->pev->point; 906 struct perf_probe_point *pp = &pf->pev->point;
907 Dwarf_Addr addr;
699 908
700 if (pp->lazy_line) 909 if (pp->lazy_line)
701 find_probe_point_lazy(in_die, pf); 910 param->retval = find_probe_point_lazy(in_die, pf);
702 else { 911 else {
703 /* Get probe address */ 912 /* Get probe address */
704 pf->addr = die_get_entrypc(in_die); 913 if (dwarf_entrypc(in_die, &addr) != 0) {
914 pr_warning("Failed to get entry pc of %s.\n",
915 dwarf_diename(in_die));
916 param->retval = -ENOENT;
917 return DWARF_CB_ABORT;
918 }
919 pf->addr = addr;
705 pf->addr += pp->offset; 920 pf->addr += pp->offset;
706 pr_debug("found inline addr: 0x%jx\n", 921 pr_debug("found inline addr: 0x%jx\n",
707 (uintmax_t)pf->addr); 922 (uintmax_t)pf->addr);
708 923
709 convert_probe_point(in_die, pf); 924 param->retval = convert_probe_point(in_die, pf);
710 } 925 }
711 926
712 return DWARF_CB_OK; 927 return DWARF_CB_OK;
@@ -715,39 +930,53 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
715/* Search function from function name */ 930/* Search function from function name */
716static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 931static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
717{ 932{
718 struct probe_finder *pf = (struct probe_finder *)data; 933 struct dwarf_callback_param *param = data;
934 struct probe_finder *pf = param->data;
719 struct perf_probe_point *pp = &pf->pev->point; 935 struct perf_probe_point *pp = &pf->pev->point;
720 936
721 /* Check tag and diename */ 937 /* Check tag and diename */
722 if (dwarf_tag(sp_die) != DW_TAG_subprogram || 938 if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
723 die_compare_name(sp_die, pp->function) != 0) 939 die_compare_name(sp_die, pp->function) != 0)
724 return 0; 940 return DWARF_CB_OK;
725 941
726 pf->fname = dwarf_decl_file(sp_die); 942 pf->fname = dwarf_decl_file(sp_die);
727 if (pp->line) { /* Function relative line */ 943 if (pp->line) { /* Function relative line */
728 dwarf_decl_line(sp_die, &pf->lno); 944 dwarf_decl_line(sp_die, &pf->lno);
729 pf->lno += pp->line; 945 pf->lno += pp->line;
730 find_probe_point_by_line(pf); 946 param->retval = find_probe_point_by_line(pf);
731 } else if (!dwarf_func_inline(sp_die)) { 947 } else if (!dwarf_func_inline(sp_die)) {
732 /* Real function */ 948 /* Real function */
733 if (pp->lazy_line) 949 if (pp->lazy_line)
734 find_probe_point_lazy(sp_die, pf); 950 param->retval = find_probe_point_lazy(sp_die, pf);
735 else { 951 else {
736 pf->addr = die_get_entrypc(sp_die); 952 if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
953 pr_warning("Failed to get entry pc of %s.\n",
954 dwarf_diename(sp_die));
955 param->retval = -ENOENT;
956 return DWARF_CB_ABORT;
957 }
737 pf->addr += pp->offset; 958 pf->addr += pp->offset;
738 /* TODO: Check the address in this function */ 959 /* TODO: Check the address in this function */
739 convert_probe_point(sp_die, pf); 960 param->retval = convert_probe_point(sp_die, pf);
740 } 961 }
741 } else 962 } else {
963 struct dwarf_callback_param _param = {.data = (void *)pf,
964 .retval = 0};
742 /* Inlined function: search instances */ 965 /* Inlined function: search instances */
743 dwarf_func_inline_instances(sp_die, probe_point_inline_cb, pf); 966 dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
967 &_param);
968 param->retval = _param.retval;
969 }
744 970
745 return 1; /* Exit; no same symbol in this CU. */ 971 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
746} 972}
747 973
748static void find_probe_point_by_func(struct probe_finder *pf) 974static int find_probe_point_by_func(struct probe_finder *pf)
749{ 975{
750 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, pf, 0); 976 struct dwarf_callback_param _param = {.data = (void *)pf,
977 .retval = 0};
978 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
979 return _param.retval;
751} 980}
752 981
753/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ 982/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
@@ -760,19 +989,29 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
760 size_t cuhl; 989 size_t cuhl;
761 Dwarf_Die *diep; 990 Dwarf_Die *diep;
762 Dwarf *dbg; 991 Dwarf *dbg;
992 int ret = 0;
763 993
764 pf.tevs = xzalloc(sizeof(struct kprobe_trace_event) * MAX_PROBES); 994 pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * MAX_PROBES);
995 if (pf.tevs == NULL)
996 return -ENOMEM;
765 *tevs = pf.tevs; 997 *tevs = pf.tevs;
766 pf.ntevs = 0; 998 pf.ntevs = 0;
767 999
768 dbg = dwarf_begin(fd, DWARF_C_READ); 1000 dbg = dwarf_begin(fd, DWARF_C_READ);
769 if (!dbg) 1001 if (!dbg) {
770 return -ENOENT; 1002 pr_warning("No dwarf info found in the vmlinux - "
1003 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1004 return -EBADF;
1005 }
1006
1007 /* Get the call frame information from this dwarf */
1008 pf.cfi = dwarf_getcfi(dbg);
771 1009
772 off = 0; 1010 off = 0;
773 line_list__init(&pf.lcache); 1011 line_list__init(&pf.lcache);
774 /* Loop on CUs (Compilation Unit) */ 1012 /* Loop on CUs (Compilation Unit) */
775 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1013 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) &&
1014 ret >= 0) {
776 /* Get the DIE(Debugging Information Entry) of this CU */ 1015 /* Get the DIE(Debugging Information Entry) of this CU */
777 diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die); 1016 diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die);
778 if (!diep) 1017 if (!diep)
@@ -786,12 +1025,12 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
786 1025
787 if (!pp->file || pf.fname) { 1026 if (!pp->file || pf.fname) {
788 if (pp->function) 1027 if (pp->function)
789 find_probe_point_by_func(&pf); 1028 ret = find_probe_point_by_func(&pf);
790 else if (pp->lazy_line) 1029 else if (pp->lazy_line)
791 find_probe_point_lazy(NULL, &pf); 1030 ret = find_probe_point_lazy(NULL, &pf);
792 else { 1031 else {
793 pf.lno = pp->line; 1032 pf.lno = pp->line;
794 find_probe_point_by_line(&pf); 1033 ret = find_probe_point_by_line(&pf);
795 } 1034 }
796 } 1035 }
797 off = noff; 1036 off = noff;
@@ -799,7 +1038,7 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
799 line_list__free(&pf.lcache); 1038 line_list__free(&pf.lcache);
800 dwarf_end(dbg); 1039 dwarf_end(dbg);
801 1040
802 return pf.ntevs; 1041 return (ret < 0) ? ret : pf.ntevs;
803} 1042}
804 1043
805/* Reverse search */ 1044/* Reverse search */
@@ -812,10 +1051,11 @@ int find_perf_probe_point(int fd, unsigned long addr,
812 Dwarf_Addr laddr, eaddr; 1051 Dwarf_Addr laddr, eaddr;
813 const char *tmp; 1052 const char *tmp;
814 int lineno, ret = 0; 1053 int lineno, ret = 0;
1054 bool found = false;
815 1055
816 dbg = dwarf_begin(fd, DWARF_C_READ); 1056 dbg = dwarf_begin(fd, DWARF_C_READ);
817 if (!dbg) 1057 if (!dbg)
818 return -ENOENT; 1058 return -EBADF;
819 1059
820 /* Find cu die */ 1060 /* Find cu die */
821 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) { 1061 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) {
@@ -826,82 +1066,135 @@ int find_perf_probe_point(int fd, unsigned long addr,
826 /* Find a corresponding line */ 1066 /* Find a corresponding line */
827 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr); 1067 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
828 if (line) { 1068 if (line) {
829 dwarf_lineaddr(line, &laddr); 1069 if (dwarf_lineaddr(line, &laddr) == 0 &&
830 if ((Dwarf_Addr)addr == laddr) { 1070 (Dwarf_Addr)addr == laddr &&
831 dwarf_lineno(line, &lineno); 1071 dwarf_lineno(line, &lineno) == 0) {
832 ppt->line = lineno;
833
834 tmp = dwarf_linesrc(line, NULL, NULL); 1072 tmp = dwarf_linesrc(line, NULL, NULL);
835 DIE_IF(!tmp); 1073 if (tmp) {
836 ppt->file = xstrdup(tmp); 1074 ppt->line = lineno;
837 ret = 1; 1075 ppt->file = strdup(tmp);
1076 if (ppt->file == NULL) {
1077 ret = -ENOMEM;
1078 goto end;
1079 }
1080 found = true;
1081 }
838 } 1082 }
839 } 1083 }
840 1084
841 /* Find a corresponding function */ 1085 /* Find a corresponding function */
842 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1086 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
843 tmp = dwarf_diename(&spdie); 1087 tmp = dwarf_diename(&spdie);
844 if (!tmp) 1088 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
845 goto end; 1089 goto end;
846 1090
847 dwarf_entrypc(&spdie, &eaddr); 1091 if (ppt->line) {
848 if (!lineno) { 1092 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
849 /* We don't have a line number, let's use offset */ 1093 &indie)) {
850 ppt->function = xstrdup(tmp); 1094 /* addr in an inline function */
851 ppt->offset = addr - (unsigned long)eaddr; 1095 tmp = dwarf_diename(&indie);
852 ret = 1; 1096 if (!tmp)
853 goto end; 1097 goto end;
1098 ret = dwarf_decl_line(&indie, &lineno);
1099 } else {
1100 if (eaddr == addr) { /* Function entry */
1101 lineno = ppt->line;
1102 ret = 0;
1103 } else
1104 ret = dwarf_decl_line(&spdie, &lineno);
1105 }
1106 if (ret == 0) {
1107 /* Make a relative line number */
1108 ppt->line -= lineno;
1109 goto found;
1110 }
854 } 1111 }
855 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, &indie)) { 1112 /* We don't have a line number, let's use offset */
856 /* addr in an inline function */ 1113 ppt->offset = addr - (unsigned long)eaddr;
857 tmp = dwarf_diename(&indie); 1114found:
858 if (!tmp) 1115 ppt->function = strdup(tmp);
859 goto end; 1116 if (ppt->function == NULL) {
860 dwarf_decl_line(&indie, &lineno); 1117 ret = -ENOMEM;
861 } else { 1118 goto end;
862 if (eaddr == addr) /* No offset: function entry */
863 lineno = ppt->line;
864 else
865 dwarf_decl_line(&spdie, &lineno);
866 } 1119 }
867 ppt->function = xstrdup(tmp); 1120 found = true;
868 ppt->line -= lineno; /* Make a relative line number */
869 } 1121 }
870 1122
871end: 1123end:
872 dwarf_end(dbg); 1124 dwarf_end(dbg);
1125 if (ret >= 0)
1126 ret = found ? 1 : 0;
873 return ret; 1127 return ret;
874} 1128}
875 1129
1130/* Add a line and store the src path */
1131static int line_range_add_line(const char *src, unsigned int lineno,
1132 struct line_range *lr)
1133{
1134 /* Copy real path */
1135 if (!lr->path) {
1136 lr->path = strdup(src);
1137 if (lr->path == NULL)
1138 return -ENOMEM;
1139 }
1140 return line_list__add_line(&lr->line_list, lineno);
1141}
1142
1143/* Search function declaration lines */
1144static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data)
1145{
1146 struct dwarf_callback_param *param = data;
1147 struct line_finder *lf = param->data;
1148 const char *src;
1149 int lineno;
1150
1151 src = dwarf_decl_file(sp_die);
1152 if (src && strtailcmp(src, lf->fname) != 0)
1153 return DWARF_CB_OK;
1154
1155 if (dwarf_decl_line(sp_die, &lineno) != 0 ||
1156 (lf->lno_s > lineno || lf->lno_e < lineno))
1157 return DWARF_CB_OK;
1158
1159 param->retval = line_range_add_line(src, lineno, lf->lr);
1160 return DWARF_CB_OK;
1161}
1162
1163static int find_line_range_func_decl_lines(struct line_finder *lf)
1164{
1165 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1166 dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, &param, 0);
1167 return param.retval;
1168}
876 1169
877/* Find line range from its line number */ 1170/* Find line range from its line number */
878static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1171static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
879{ 1172{
880 Dwarf_Lines *lines; 1173 Dwarf_Lines *lines;
881 Dwarf_Line *line; 1174 Dwarf_Line *line;
882 size_t nlines, i; 1175 size_t nlines, i;
883 Dwarf_Addr addr; 1176 Dwarf_Addr addr;
884 int lineno; 1177 int lineno, ret = 0;
885 int ret;
886 const char *src; 1178 const char *src;
887 Dwarf_Die die_mem; 1179 Dwarf_Die die_mem;
888 1180
889 line_list__init(&lf->lr->line_list); 1181 line_list__init(&lf->lr->line_list);
890 ret = dwarf_getsrclines(&lf->cu_die, &lines, &nlines); 1182 if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
891 DIE_IF(ret != 0); 1183 pr_warning("No source lines found in this CU.\n");
1184 return -ENOENT;
1185 }
892 1186
1187 /* Search probable lines on lines list */
893 for (i = 0; i < nlines; i++) { 1188 for (i = 0; i < nlines; i++) {
894 line = dwarf_onesrcline(lines, i); 1189 line = dwarf_onesrcline(lines, i);
895 ret = dwarf_lineno(line, &lineno); 1190 if (dwarf_lineno(line, &lineno) != 0 ||
896 DIE_IF(ret != 0); 1191 (lf->lno_s > lineno || lf->lno_e < lineno))
897 if (lf->lno_s > lineno || lf->lno_e < lineno)
898 continue; 1192 continue;
899 1193
900 if (sp_die) { 1194 if (sp_die) {
901 /* Address filtering 1: does sp_die include addr? */ 1195 /* Address filtering 1: does sp_die include addr? */
902 ret = dwarf_lineaddr(line, &addr); 1196 if (dwarf_lineaddr(line, &addr) != 0 ||
903 DIE_IF(ret != 0); 1197 !dwarf_haspc(sp_die, addr))
904 if (!dwarf_haspc(sp_die, addr))
905 continue; 1198 continue;
906 1199
907 /* Address filtering 2: No child include addr? */ 1200 /* Address filtering 2: No child include addr? */
@@ -914,30 +1207,49 @@ static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
914 if (strtailcmp(src, lf->fname) != 0) 1207 if (strtailcmp(src, lf->fname) != 0)
915 continue; 1208 continue;
916 1209
917 /* Copy real path */ 1210 ret = line_range_add_line(src, lineno, lf->lr);
918 if (!lf->lr->path) 1211 if (ret < 0)
919 lf->lr->path = xstrdup(src); 1212 return ret;
920 line_list__add_line(&lf->lr->line_list, (unsigned int)lineno);
921 } 1213 }
1214
1215 /*
1216 * Dwarf lines doesn't include function declarations. We have to
1217 * check functions list or given function.
1218 */
1219 if (sp_die) {
1220 src = dwarf_decl_file(sp_die);
1221 if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
1222 (lf->lno_s <= lineno && lf->lno_e >= lineno))
1223 ret = line_range_add_line(src, lineno, lf->lr);
1224 } else
1225 ret = find_line_range_func_decl_lines(lf);
1226
922 /* Update status */ 1227 /* Update status */
923 if (!list_empty(&lf->lr->line_list)) 1228 if (ret >= 0)
924 lf->found = 1; 1229 if (!list_empty(&lf->lr->line_list))
1230 ret = lf->found = 1;
1231 else
1232 ret = 0; /* Lines are not found */
925 else { 1233 else {
926 free(lf->lr->path); 1234 free(lf->lr->path);
927 lf->lr->path = NULL; 1235 lf->lr->path = NULL;
928 } 1236 }
1237 return ret;
929} 1238}
930 1239
931static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1240static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
932{ 1241{
933 find_line_range_by_line(in_die, (struct line_finder *)data); 1242 struct dwarf_callback_param *param = data;
1243
1244 param->retval = find_line_range_by_line(in_die, param->data);
934 return DWARF_CB_ABORT; /* No need to find other instances */ 1245 return DWARF_CB_ABORT; /* No need to find other instances */
935} 1246}
936 1247
937/* Search function from function name */ 1248/* Search function from function name */
938static int line_range_search_cb(Dwarf_Die *sp_die, void *data) 1249static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
939{ 1250{
940 struct line_finder *lf = (struct line_finder *)data; 1251 struct dwarf_callback_param *param = data;
1252 struct line_finder *lf = param->data;
941 struct line_range *lr = lf->lr; 1253 struct line_range *lr = lf->lr;
942 1254
943 if (dwarf_tag(sp_die) == DW_TAG_subprogram && 1255 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
@@ -946,44 +1258,55 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
946 dwarf_decl_line(sp_die, &lr->offset); 1258 dwarf_decl_line(sp_die, &lr->offset);
947 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); 1259 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
948 lf->lno_s = lr->offset + lr->start; 1260 lf->lno_s = lr->offset + lr->start;
949 if (!lr->end) 1261 if (lf->lno_s < 0) /* Overflow */
1262 lf->lno_s = INT_MAX;
1263 lf->lno_e = lr->offset + lr->end;
1264 if (lf->lno_e < 0) /* Overflow */
950 lf->lno_e = INT_MAX; 1265 lf->lno_e = INT_MAX;
951 else 1266 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
952 lf->lno_e = lr->offset + lr->end;
953 lr->start = lf->lno_s; 1267 lr->start = lf->lno_s;
954 lr->end = lf->lno_e; 1268 lr->end = lf->lno_e;
955 if (dwarf_func_inline(sp_die)) 1269 if (dwarf_func_inline(sp_die)) {
1270 struct dwarf_callback_param _param;
1271 _param.data = (void *)lf;
1272 _param.retval = 0;
956 dwarf_func_inline_instances(sp_die, 1273 dwarf_func_inline_instances(sp_die,
957 line_range_inline_cb, lf); 1274 line_range_inline_cb,
958 else 1275 &_param);
959 find_line_range_by_line(sp_die, lf); 1276 param->retval = _param.retval;
960 return 1; 1277 } else
1278 param->retval = find_line_range_by_line(sp_die, lf);
1279 return DWARF_CB_ABORT;
961 } 1280 }
962 return 0; 1281 return DWARF_CB_OK;
963} 1282}
964 1283
965static void find_line_range_by_func(struct line_finder *lf) 1284static int find_line_range_by_func(struct line_finder *lf)
966{ 1285{
967 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, lf, 0); 1286 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1287 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
1288 return param.retval;
968} 1289}
969 1290
970int find_line_range(int fd, struct line_range *lr) 1291int find_line_range(int fd, struct line_range *lr)
971{ 1292{
972 struct line_finder lf = {.lr = lr, .found = 0}; 1293 struct line_finder lf = {.lr = lr, .found = 0};
973 int ret; 1294 int ret = 0;
974 Dwarf_Off off = 0, noff; 1295 Dwarf_Off off = 0, noff;
975 size_t cuhl; 1296 size_t cuhl;
976 Dwarf_Die *diep; 1297 Dwarf_Die *diep;
977 Dwarf *dbg; 1298 Dwarf *dbg;
978 1299
979 dbg = dwarf_begin(fd, DWARF_C_READ); 1300 dbg = dwarf_begin(fd, DWARF_C_READ);
980 if (!dbg) 1301 if (!dbg) {
981 return -ENOENT; 1302 pr_warning("No dwarf info found in the vmlinux - "
1303 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1304 return -EBADF;
1305 }
982 1306
983 /* Loop on CUs (Compilation Unit) */ 1307 /* Loop on CUs (Compilation Unit) */
984 while (!lf.found) { 1308 while (!lf.found && ret >= 0) {
985 ret = dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL); 1309 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
986 if (ret != 0)
987 break; 1310 break;
988 1311
989 /* Get the DIE(Debugging Information Entry) of this CU */ 1312 /* Get the DIE(Debugging Information Entry) of this CU */
@@ -999,20 +1322,18 @@ int find_line_range(int fd, struct line_range *lr)
999 1322
1000 if (!lr->file || lf.fname) { 1323 if (!lr->file || lf.fname) {
1001 if (lr->function) 1324 if (lr->function)
1002 find_line_range_by_func(&lf); 1325 ret = find_line_range_by_func(&lf);
1003 else { 1326 else {
1004 lf.lno_s = lr->start; 1327 lf.lno_s = lr->start;
1005 if (!lr->end) 1328 lf.lno_e = lr->end;
1006 lf.lno_e = INT_MAX; 1329 ret = find_line_range_by_line(NULL, &lf);
1007 else
1008 lf.lno_e = lr->end;
1009 find_line_range_by_line(NULL, &lf);
1010 } 1330 }
1011 } 1331 }
1012 off = noff; 1332 off = noff;
1013 } 1333 }
1014 pr_debug("path: %lx\n", (unsigned long)lr->path); 1334 pr_debug("path: %lx\n", (unsigned long)lr->path);
1015 dwarf_end(dbg); 1335 dwarf_end(dbg);
1016 return lf.found; 1336
1337 return (ret < 0) ? ret : lf.found;
1017} 1338}
1018 1339
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 2a271321944f..310ce897229c 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -42,6 +42,7 @@ struct probe_finder {
42 struct list_head lcache; /* Line cache for lazy match */ 42 struct list_head lcache; /* Line cache for lazy match */
43 43
44 /* For variable searching */ 44 /* For variable searching */
45 Dwarf_CFI *cfi; /* Call Frame Information */
45 Dwarf_Op *fb_ops; /* Frame base attribute */ 46 Dwarf_Op *fb_ops; /* Frame base attribute */
46 struct perf_probe_arg *pvar; /* Current target variable */ 47 struct perf_probe_arg *pvar; /* Current target variable */
47 struct kprobe_trace_arg *tvar; /* Current result variable */ 48 struct kprobe_trace_arg *tvar; /* Current result variable */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9d24d4b2c8fb..da30b305fba0 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,38 +30,38 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
30 size_t size, unsigned int width); 30 size_t size, unsigned int width);
31 31
32struct sort_entry sort_thread = { 32struct sort_entry sort_thread = {
33 .header = "Command: Pid", 33 .se_header = "Command: Pid",
34 .cmp = sort__thread_cmp, 34 .se_cmp = sort__thread_cmp,
35 .snprintf = hist_entry__thread_snprintf, 35 .se_snprintf = hist_entry__thread_snprintf,
36 .width = &threads__col_width, 36 .se_width = &threads__col_width,
37}; 37};
38 38
39struct sort_entry sort_comm = { 39struct sort_entry sort_comm = {
40 .header = "Command", 40 .se_header = "Command",
41 .cmp = sort__comm_cmp, 41 .se_cmp = sort__comm_cmp,
42 .collapse = sort__comm_collapse, 42 .se_collapse = sort__comm_collapse,
43 .snprintf = hist_entry__comm_snprintf, 43 .se_snprintf = hist_entry__comm_snprintf,
44 .width = &comms__col_width, 44 .se_width = &comms__col_width,
45}; 45};
46 46
47struct sort_entry sort_dso = { 47struct sort_entry sort_dso = {
48 .header = "Shared Object", 48 .se_header = "Shared Object",
49 .cmp = sort__dso_cmp, 49 .se_cmp = sort__dso_cmp,
50 .snprintf = hist_entry__dso_snprintf, 50 .se_snprintf = hist_entry__dso_snprintf,
51 .width = &dsos__col_width, 51 .se_width = &dsos__col_width,
52}; 52};
53 53
54struct sort_entry sort_sym = { 54struct sort_entry sort_sym = {
55 .header = "Symbol", 55 .se_header = "Symbol",
56 .cmp = sort__sym_cmp, 56 .se_cmp = sort__sym_cmp,
57 .snprintf = hist_entry__sym_snprintf, 57 .se_snprintf = hist_entry__sym_snprintf,
58}; 58};
59 59
60struct sort_entry sort_parent = { 60struct sort_entry sort_parent = {
61 .header = "Parent symbol", 61 .se_header = "Parent symbol",
62 .cmp = sort__parent_cmp, 62 .se_cmp = sort__parent_cmp,
63 .snprintf = hist_entry__parent_snprintf, 63 .se_snprintf = hist_entry__parent_snprintf,
64 .width = &parent_symbol__col_width, 64 .se_width = &parent_symbol__col_width,
65}; 65};
66 66
67struct sort_dimension { 67struct sort_dimension {
@@ -255,7 +255,7 @@ int sort_dimension__add(const char *tok)
255 if (strncasecmp(tok, sd->name, strlen(tok))) 255 if (strncasecmp(tok, sd->name, strlen(tok)))
256 continue; 256 continue;
257 257
258 if (sd->entry->collapse) 258 if (sd->entry->se_collapse)
259 sort__need_collapse = 1; 259 sort__need_collapse = 1;
260 260
261 if (sd->entry == &sort_parent) { 261 if (sd->entry == &sort_parent) {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 6d7b4be70609..1d857aa2c01f 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -78,13 +78,13 @@ enum sort_type {
78struct sort_entry { 78struct sort_entry {
79 struct list_head list; 79 struct list_head list;
80 80
81 const char *header; 81 const char *se_header;
82 82
83 int64_t (*cmp)(struct hist_entry *, struct hist_entry *); 83 int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
84 int64_t (*collapse)(struct hist_entry *, struct hist_entry *); 84 int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
85 int (*snprintf)(struct hist_entry *self, char *bf, size_t size, 85 int (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
86 unsigned int width); 86 unsigned int width);
87 unsigned int *width; 87 unsigned int *se_width;
88 bool elide; 88 bool elide;
89}; 89};
90 90