diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/scripts/perl/Perf-Trace-Util/Context.c | 5 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 18 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 2 | ||||
-rw-r--r-- | tools/perf/util/map.h | 16 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 34 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 31 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
7 files changed, 80 insertions, 27 deletions
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c index 790ceba6ad3f..28431d1bbcf5 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c | |||
@@ -5,7 +5,10 @@ | |||
5 | * ANY CHANGES MADE HERE WILL BE LOST! | 5 | * ANY CHANGES MADE HERE WILL BE LOST! |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | 8 | #include <stdbool.h> | |
9 | #ifndef HAS_BOOL | ||
10 | # define HAS_BOOL 1 | ||
11 | #endif | ||
9 | #line 1 "Context.xs" | 12 | #line 1 "Context.xs" |
10 | /* | 13 | /* |
11 | * Context.xs. XS interfaces for perf script. | 14 | * Context.xs. XS interfaces for perf script. |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 79999ceaf2be..01bc4e23a2cf 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -177,14 +177,17 @@ static int lock__parse(struct ins_operands *ops) | |||
177 | goto out_free_ops; | 177 | goto out_free_ops; |
178 | 178 | ||
179 | ops->locked.ins = ins__find(name); | 179 | ops->locked.ins = ins__find(name); |
180 | free(name); | ||
181 | |||
180 | if (ops->locked.ins == NULL) | 182 | if (ops->locked.ins == NULL) |
181 | goto out_free_ops; | 183 | goto out_free_ops; |
182 | 184 | ||
183 | if (!ops->locked.ins->ops) | 185 | if (!ops->locked.ins->ops) |
184 | return 0; | 186 | return 0; |
185 | 187 | ||
186 | if (ops->locked.ins->ops->parse) | 188 | if (ops->locked.ins->ops->parse && |
187 | ops->locked.ins->ops->parse(ops->locked.ops); | 189 | ops->locked.ins->ops->parse(ops->locked.ops) < 0) |
190 | goto out_free_ops; | ||
188 | 191 | ||
189 | return 0; | 192 | return 0; |
190 | 193 | ||
@@ -208,6 +211,13 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, | |||
208 | 211 | ||
209 | static void lock__delete(struct ins_operands *ops) | 212 | static void lock__delete(struct ins_operands *ops) |
210 | { | 213 | { |
214 | struct ins *ins = ops->locked.ins; | ||
215 | |||
216 | if (ins && ins->ops->free) | ||
217 | ins->ops->free(ops->locked.ops); | ||
218 | else | ||
219 | ins__delete(ops->locked.ops); | ||
220 | |||
211 | zfree(&ops->locked.ops); | 221 | zfree(&ops->locked.ops); |
212 | zfree(&ops->target.raw); | 222 | zfree(&ops->target.raw); |
213 | zfree(&ops->target.name); | 223 | zfree(&ops->target.name); |
@@ -531,8 +541,8 @@ static void disasm_line__init_ins(struct disasm_line *dl) | |||
531 | if (!dl->ins->ops) | 541 | if (!dl->ins->ops) |
532 | return; | 542 | return; |
533 | 543 | ||
534 | if (dl->ins->ops->parse) | 544 | if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0) |
535 | dl->ins->ops->parse(&dl->ops); | 545 | dl->ins = NULL; |
536 | } | 546 | } |
537 | 547 | ||
538 | static int disasm_line__parse(char *line, char **namep, char **rawp) | 548 | static int disasm_line__parse(char *line, char **namep, char **rawp) |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index cbab1fb77b1d..2e507b5025a3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -1445,7 +1445,7 @@ int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused, | |||
1445 | case ENOENT: | 1445 | case ENOENT: |
1446 | scnprintf(buf, size, "%s", | 1446 | scnprintf(buf, size, "%s", |
1447 | "Error:\tUnable to find debugfs\n" | 1447 | "Error:\tUnable to find debugfs\n" |
1448 | "Hint:\tWas your kernel was compiled with debugfs support?\n" | 1448 | "Hint:\tWas your kernel compiled with debugfs support?\n" |
1449 | "Hint:\tIs the debugfs filesystem mounted?\n" | 1449 | "Hint:\tIs the debugfs filesystem mounted?\n" |
1450 | "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); | 1450 | "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); |
1451 | break; | 1451 | break; |
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 6951a9d42339..0e42438b1e59 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -116,6 +116,22 @@ struct thread; | |||
116 | #define map__for_each_symbol(map, pos, n) \ | 116 | #define map__for_each_symbol(map, pos, n) \ |
117 | dso__for_each_symbol(map->dso, pos, n, map->type) | 117 | dso__for_each_symbol(map->dso, pos, n, map->type) |
118 | 118 | ||
119 | /* map__for_each_symbol_with_name - iterate over the symbols in the given map | ||
120 | * that have the given name | ||
121 | * | ||
122 | * @map: the 'struct map *' in which symbols itereated | ||
123 | * @sym_name: the symbol name | ||
124 | * @pos: the 'struct symbol *' to use as a loop cursor | ||
125 | * @filter: to use when loading the DSO | ||
126 | */ | ||
127 | #define __map__for_each_symbol_by_name(map, sym_name, pos, filter) \ | ||
128 | for (pos = map__find_symbol_by_name(map, sym_name, filter); \ | ||
129 | pos && strcmp(pos->name, sym_name) == 0; \ | ||
130 | pos = symbol__next_by_name(pos)) | ||
131 | |||
132 | #define map__for_each_symbol_by_name(map, sym_name, pos) \ | ||
133 | __map__for_each_symbol_by_name(map, sym_name, (pos), NULL) | ||
134 | |||
119 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); | 135 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); |
120 | 136 | ||
121 | void map__init(struct map *map, enum map_type type, | 137 | void map__init(struct map *map, enum map_type type, |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 94a717bf007d..919937eb0be2 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -446,7 +446,7 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, | |||
446 | } | 446 | } |
447 | 447 | ||
448 | for (i = 0; i < ntevs; i++) { | 448 | for (i = 0; i < ntevs; i++) { |
449 | if (tevs[i].point.address) { | 449 | if (tevs[i].point.address && !tevs[i].point.retprobe) { |
450 | tmp = strdup(reloc_sym->name); | 450 | tmp = strdup(reloc_sym->name); |
451 | if (!tmp) | 451 | if (!tmp) |
452 | return -ENOMEM; | 452 | return -ENOMEM; |
@@ -2193,18 +2193,17 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, | |||
2193 | return ret; | 2193 | return ret; |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | static char *looking_function_name; | 2196 | static int find_probe_functions(struct map *map, char *name) |
2197 | static int num_matched_functions; | ||
2198 | |||
2199 | static int probe_function_filter(struct map *map __maybe_unused, | ||
2200 | struct symbol *sym) | ||
2201 | { | 2197 | { |
2202 | if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) && | 2198 | int found = 0; |
2203 | strcmp(looking_function_name, sym->name) == 0) { | 2199 | struct symbol *sym; |
2204 | num_matched_functions++; | 2200 | |
2205 | return 0; | 2201 | map__for_each_symbol_by_name(map, name, sym) { |
2202 | if (sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) | ||
2203 | found++; | ||
2206 | } | 2204 | } |
2207 | return 1; | 2205 | |
2206 | return found; | ||
2208 | } | 2207 | } |
2209 | 2208 | ||
2210 | #define strdup_or_goto(str, label) \ | 2209 | #define strdup_or_goto(str, label) \ |
@@ -2222,10 +2221,10 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, | |||
2222 | struct kmap *kmap = NULL; | 2221 | struct kmap *kmap = NULL; |
2223 | struct ref_reloc_sym *reloc_sym = NULL; | 2222 | struct ref_reloc_sym *reloc_sym = NULL; |
2224 | struct symbol *sym; | 2223 | struct symbol *sym; |
2225 | struct rb_node *nd; | ||
2226 | struct probe_trace_event *tev; | 2224 | struct probe_trace_event *tev; |
2227 | struct perf_probe_point *pp = &pev->point; | 2225 | struct perf_probe_point *pp = &pev->point; |
2228 | struct probe_trace_point *tp; | 2226 | struct probe_trace_point *tp; |
2227 | int num_matched_functions; | ||
2229 | int ret, i; | 2228 | int ret, i; |
2230 | 2229 | ||
2231 | /* Init maps of given executable or kernel */ | 2230 | /* Init maps of given executable or kernel */ |
@@ -2242,10 +2241,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, | |||
2242 | * Load matched symbols: Since the different local symbols may have | 2241 | * Load matched symbols: Since the different local symbols may have |
2243 | * same name but different addresses, this lists all the symbols. | 2242 | * same name but different addresses, this lists all the symbols. |
2244 | */ | 2243 | */ |
2245 | num_matched_functions = 0; | 2244 | num_matched_functions = find_probe_functions(map, pp->function); |
2246 | looking_function_name = pp->function; | 2245 | if (num_matched_functions == 0) { |
2247 | ret = map__load(map, probe_function_filter); | ||
2248 | if (ret || num_matched_functions == 0) { | ||
2249 | pr_err("Failed to find symbol %s in %s\n", pp->function, | 2246 | pr_err("Failed to find symbol %s in %s\n", pp->function, |
2250 | target ? : "kernel"); | 2247 | target ? : "kernel"); |
2251 | ret = -ENOENT; | 2248 | ret = -ENOENT; |
@@ -2257,7 +2254,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, | |||
2257 | goto out; | 2254 | goto out; |
2258 | } | 2255 | } |
2259 | 2256 | ||
2260 | if (!pev->uprobes) { | 2257 | if (!pev->uprobes && !pp->retprobe) { |
2261 | kmap = map__kmap(map); | 2258 | kmap = map__kmap(map); |
2262 | reloc_sym = kmap->ref_reloc_sym; | 2259 | reloc_sym = kmap->ref_reloc_sym; |
2263 | if (!reloc_sym) { | 2260 | if (!reloc_sym) { |
@@ -2275,7 +2272,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, | |||
2275 | } | 2272 | } |
2276 | 2273 | ||
2277 | ret = 0; | 2274 | ret = 0; |
2278 | map__for_each_symbol(map, sym, nd) { | 2275 | |
2276 | map__for_each_symbol_by_name(map, pp->function, sym) { | ||
2279 | tev = (*tevs) + ret; | 2277 | tev = (*tevs) + ret; |
2280 | tp = &tev->point; | 2278 | tp = &tev->point; |
2281 | if (ret == num_matched_functions) { | 2279 | if (ret == num_matched_functions) { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c24c5b83156c..a194702a0a2f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -396,6 +396,7 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, | |||
396 | const char *name) | 396 | const char *name) |
397 | { | 397 | { |
398 | struct rb_node *n; | 398 | struct rb_node *n; |
399 | struct symbol_name_rb_node *s; | ||
399 | 400 | ||
400 | if (symbols == NULL) | 401 | if (symbols == NULL) |
401 | return NULL; | 402 | return NULL; |
@@ -403,7 +404,6 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, | |||
403 | n = symbols->rb_node; | 404 | n = symbols->rb_node; |
404 | 405 | ||
405 | while (n) { | 406 | while (n) { |
406 | struct symbol_name_rb_node *s; | ||
407 | int cmp; | 407 | int cmp; |
408 | 408 | ||
409 | s = rb_entry(n, struct symbol_name_rb_node, rb_node); | 409 | s = rb_entry(n, struct symbol_name_rb_node, rb_node); |
@@ -414,10 +414,24 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, | |||
414 | else if (cmp > 0) | 414 | else if (cmp > 0) |
415 | n = n->rb_right; | 415 | n = n->rb_right; |
416 | else | 416 | else |
417 | return &s->sym; | 417 | break; |
418 | } | 418 | } |
419 | 419 | ||
420 | return NULL; | 420 | if (n == NULL) |
421 | return NULL; | ||
422 | |||
423 | /* return first symbol that has same name (if any) */ | ||
424 | for (n = rb_prev(n); n; n = rb_prev(n)) { | ||
425 | struct symbol_name_rb_node *tmp; | ||
426 | |||
427 | tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); | ||
428 | if (strcmp(tmp->sym.name, s->sym.name)) | ||
429 | break; | ||
430 | |||
431 | s = tmp; | ||
432 | } | ||
433 | |||
434 | return &s->sym; | ||
421 | } | 435 | } |
422 | 436 | ||
423 | struct symbol *dso__find_symbol(struct dso *dso, | 437 | struct symbol *dso__find_symbol(struct dso *dso, |
@@ -436,6 +450,17 @@ struct symbol *dso__next_symbol(struct symbol *sym) | |||
436 | return symbols__next(sym); | 450 | return symbols__next(sym); |
437 | } | 451 | } |
438 | 452 | ||
453 | struct symbol *symbol__next_by_name(struct symbol *sym) | ||
454 | { | ||
455 | struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym); | ||
456 | struct rb_node *n = rb_next(&s->rb_node); | ||
457 | |||
458 | return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL; | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * Teturns first symbol that matched with @name. | ||
463 | */ | ||
439 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, | 464 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, |
440 | const char *name) | 465 | const char *name) |
441 | { | 466 | { |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 9d602e9c6f59..1650dcb3a67b 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -231,6 +231,7 @@ struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, | |||
231 | u64 addr); | 231 | u64 addr); |
232 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, | 232 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, |
233 | const char *name); | 233 | const char *name); |
234 | struct symbol *symbol__next_by_name(struct symbol *sym); | ||
234 | 235 | ||
235 | struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); | 236 | struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); |
236 | struct symbol *dso__next_symbol(struct symbol *sym); | 237 | struct symbol *dso__next_symbol(struct symbol *sym); |