diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/Build | 1 | ||||
-rw-r--r-- | tools/perf/util/build-id.h | 4 | ||||
-rw-r--r-- | tools/perf/util/event.c | 10 | ||||
-rw-r--r-- | tools/perf/util/event.h | 14 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 1 | ||||
-rw-r--r-- | tools/perf/util/header.c | 1 | ||||
-rw-r--r-- | tools/perf/util/intel-pt.c | 1 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 28 | ||||
-rw-r--r-- | tools/perf/util/map.c | 5 | ||||
-rw-r--r-- | tools/perf/util/map.h | 5 | ||||
-rw-r--r-- | tools/perf/util/memswap.c | 24 | ||||
-rw-r--r-- | tools/perf/util/memswap.h | 7 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-perl.c | 4 | ||||
-rw-r--r-- | tools/perf/util/session.c | 1 | ||||
-rw-r--r-- | tools/perf/util/strbuf.c | 9 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 72 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 11 | ||||
-rw-r--r-- | tools/perf/util/units.c | 29 | ||||
-rw-r--r-- | tools/perf/util/units.h | 7 | ||||
-rw-r--r-- | tools/perf/util/util.c | 49 | ||||
-rw-r--r-- | tools/perf/util/util.h | 26 |
21 files changed, 180 insertions, 129 deletions
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 069583bdc670..79dea95a7f68 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -13,6 +13,7 @@ libperf-y += find_bit.o libperf-y += kallsyms.o libperf-y += levenshtein.o libperf-y += llvm-utils.o +libperf-y += memswap.o libperf-y += parse-events.o libperf-y += perf_regs.o libperf-y += path.o diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index a96081121179..8a89b195c1fc 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -44,6 +44,10 @@ bool build_id_cache__cached(const char *sbuild_id); int build_id_cache__add_s(const char *sbuild_id, const char *name, bool is_kallsyms, bool is_vdso); int build_id_cache__remove_s(const char *sbuild_id); + +extern char buildid_dir[]; + +void set_buildid_dir(const char *dir); void disable_buildid_cache(void); #endif diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 142835c0ca0a..dc5c3bb69d73 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -8,6 +8,7 @@ #include <unistd.h> #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ #include <api/fs/fs.h> +#include <linux/perf_event.h> #include "event.h" #include "debug.h" #include "hist.h" @@ -767,15 +768,16 @@ static int find_symbol_cb(void *arg, const char *name, char type, return 1; } -u64 kallsyms__get_function_start(const char *kallsyms_filename, - const char *symbol_name) +int kallsyms__get_function_start(const char *kallsyms_filename, + const char *symbol_name, u64 *addr) { struct process_symbol_args args = { .name = symbol_name, }; if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) - return 0; + return -1; - return args.start; + *addr = args.start; + return 0; } int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index db2de6413518..7c3fa1c8cbcd 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -229,7 +229,7 @@ struct build_id_event { enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, - PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */ + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ PERF_RECORD_HEADER_TRACING_DATA = 66, PERF_RECORD_HEADER_BUILD_ID = 67, PERF_RECORD_FINISHED_ROUND = 68, @@ -675,10 +675,18 @@ size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp); size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp); size_t perf_event__fprintf(union perf_event *event, FILE *fp); -u64 kallsyms__get_function_start(const char *kallsyms_filename, - const char *symbol_name); +int kallsyms__get_function_start(const char *kallsyms_filename, + const char *symbol_name, u64 *addr); void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max); void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map, u16 type, int max); + +void event_attr_init(struct perf_event_attr *attr); + +int perf_event_paranoid(void); + +extern int sysctl_perf_event_max_stack; +extern int sysctl_perf_event_max_contexts_per_stack; + #endif /* __PERF_RECORD_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0e879097adfb..e4f7902d5afa 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -21,6 +21,7 @@ #include "asm/bug.h" #include "callchain.h" #include "cgroup.h" +#include "event.h" #include "evsel.h" #include "evlist.h" #include "util.h" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 948b2c5efb65..314a07151fb7 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -19,6 +19,7 @@ #include "evlist.h" #include "evsel.h" #include "header.h" +#include "memswap.h" #include "../perf.h" #include "trace-event.h" #include "session.h" diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index bdd4a28c6cee..4c7718f87a08 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -23,6 +23,7 @@ #include "../perf.h" #include "session.h" #include "machine.h" +#include "memswap.h" #include "sort.h" #include "tool.h" #include "event.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7a47f52ccfcc..d97e014c3df3 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -796,11 +796,11 @@ const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; * Returns the name of the start symbol in *symbol_name. Pass in NULL as * symbol_name if it's not that important. */ -static u64 machine__get_running_kernel_start(struct machine *machine, - const char **symbol_name) +static int machine__get_running_kernel_start(struct machine *machine, + const char **symbol_name, u64 *start) { char filename[PATH_MAX]; - int i; + int i, err = -1; const char *name; u64 addr = 0; @@ -810,21 +810,28 @@ static u64 machine__get_running_kernel_start(struct machine *machine, return 0; for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { - addr = kallsyms__get_function_start(filename, name); - if (addr) + err = kallsyms__get_function_start(filename, name, &addr); + if (!err) break; } + if (err) + return -1; + if (symbol_name) *symbol_name = name; - return addr; + *start = addr; + return 0; } int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) { int type; - u64 start = machine__get_running_kernel_start(machine, NULL); + u64 start = 0; + + if (machine__get_running_kernel_start(machine, NULL, &start)) + return -1; /* In case of renewal the kernel map, destroy previous one */ machine__destroy_kernel_maps(machine); @@ -1185,8 +1192,8 @@ static int machine__create_modules(struct machine *machine) int machine__create_kernel_maps(struct machine *machine) { struct dso *kernel = machine__get_kernel(machine); - const char *name; - u64 addr; + const char *name = NULL; + u64 addr = 0; int ret; if (kernel == NULL) @@ -1211,8 +1218,7 @@ int machine__create_kernel_maps(struct machine *machine) */ map_groups__fixup_end(&machine->kmaps); - addr = machine__get_running_kernel_start(machine, &name); - if (!addr) { + if (machine__get_running_kernel_start(machine, &name, &addr)) { } else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { machine__destroy_kernel_maps(machine); return -1; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index ebfa5d92358a..2179b2deb730 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -325,11 +325,6 @@ int map__load(struct map *map) return 0; } -int __weak arch__compare_symbol_names(const char *namea, const char *nameb) -{ - return strcmp(namea, nameb); -} - struct symbol *map__find_symbol(struct map *map, u64 addr) { if (map__load(map) < 0) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index c8a5a644c0a9..f9e8ac8a52cd 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -130,13 +130,14 @@ struct thread; */ #define __map__for_each_symbol_by_name(map, sym_name, pos) \ for (pos = map__find_symbol_by_name(map, sym_name); \ - pos && arch__compare_symbol_names(pos->name, sym_name) == 0; \ + pos && \ + !symbol__match_symbol_name(pos->name, sym_name, \ + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \ pos = symbol__next_by_name(pos)) #define map__for_each_symbol_by_name(map, sym_name, pos) \ __map__for_each_symbol_by_name(map, sym_name, (pos)) -int arch__compare_symbol_names(const char *namea, const char *nameb); void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso); struct map *map__new(struct machine *machine, u64 start, u64 len, diff --git a/tools/perf/util/memswap.c b/tools/perf/util/memswap.c new file mode 100644 index 000000000000..55f7faa8d9ec --- /dev/null +++ b/tools/perf/util/memswap.c @@ -0,0 +1,24 @@ +#include <byteswap.h> +#include "memswap.h" +#include <linux/types.h> + +void mem_bswap_32(void *src, int byte_size) +{ + u32 *m = src; + while (byte_size > 0) { + *m = bswap_32(*m); + byte_size -= sizeof(u32); + ++m; + } +} + +void mem_bswap_64(void *src, int byte_size) +{ + u64 *m = src; + + while (byte_size > 0) { + *m = bswap_64(*m); + byte_size -= sizeof(u64); + ++m; + } +} diff --git a/tools/perf/util/memswap.h b/tools/perf/util/memswap.h new file mode 100644 index 000000000000..7d1b1c34bb57 --- /dev/null +++ b/tools/perf/util/memswap.h @@ -0,0 +1,7 @@ +#ifndef PERF_MEMSWAP_H_ +#define PERF_MEMSWAP_H_ + +void mem_bswap_64(void *src, int byte_size); +void mem_bswap_32(void *src, int byte_size); + +#endif /* PERF_MEMSWAP_H_ */ diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 2b12bdb3ce33..7b79c413486b 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -28,7 +28,9 @@ #include <linux/bitmap.h> #include <linux/time64.h> -#include "../util.h" +#include <stdbool.h> +/* perl needs the following define, right after including stdbool.h */ +#define HAS_BOOL #include <EXTERN.h> #include <perl.h> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 3041c6b98191..7dc1096264c5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -11,6 +11,7 @@ #include "evlist.h" #include "evsel.h" +#include "memswap.h" #include "session.h" #include "tool.h" #include "sort.h" diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index e91b5e86f027..aafe908b82b5 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -3,15 +3,6 @@ #include <linux/kernel.h> #include <errno.h> -int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} - /* * Used as the default ->buf value, so that people can always assume * buf is non NULL and ->buf is NUL terminated even for a freshly diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 2cb7665e9973..8f2b068ff756 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -90,6 +90,17 @@ static int prefix_underscores_count(const char *str) return tail - str; } +int __weak arch__compare_symbol_names(const char *namea, const char *nameb) +{ + return strcmp(namea, nameb); +} + +int __weak arch__compare_symbol_names_n(const char *namea, const char *nameb, + unsigned int n) +{ + return strncmp(namea, nameb, n); +} + int __weak arch__choose_best_symbol(struct symbol *syma, struct symbol *symb __maybe_unused) { @@ -399,8 +410,26 @@ static void symbols__sort_by_name(struct rb_root *symbols, } } +int symbol__match_symbol_name(const char *name, const char *str, + enum symbol_tag_include includes) +{ + const char *versioning; + + if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY && + (versioning = strstr(name, "@@"))) { + int len = strlen(str); + + if (len < versioning - name) + len = versioning - name; + + return arch__compare_symbol_names_n(name, str, len); + } else + return arch__compare_symbol_names(name, str); +} + static struct symbol *symbols__find_by_name(struct rb_root *symbols, - const char *name) + const char *name, + enum symbol_tag_include includes) { struct rb_node *n; struct symbol_name_rb_node *s = NULL; @@ -414,11 +443,11 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, int cmp; s = rb_entry(n, struct symbol_name_rb_node, rb_node); - cmp = arch__compare_symbol_names(name, s->sym.name); + cmp = symbol__match_symbol_name(s->sym.name, name, includes); - if (cmp < 0) + if (cmp > 0) n = n->rb_left; - else if (cmp > 0) + else if (cmp < 0) n = n->rb_right; else break; @@ -427,16 +456,17 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, if (n == NULL) return NULL; - /* return first symbol that has same name (if any) */ - for (n = rb_prev(n); n; n = rb_prev(n)) { - struct symbol_name_rb_node *tmp; + if (includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY) + /* return first symbol that has same name (if any) */ + for (n = rb_prev(n); n; n = rb_prev(n)) { + struct symbol_name_rb_node *tmp; - tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); - if (arch__compare_symbol_names(tmp->sym.name, s->sym.name)) - break; + tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); + if (arch__compare_symbol_names(tmp->sym.name, s->sym.name)) + break; - s = tmp; - } + s = tmp; + } return &s->sym; } @@ -466,7 +496,7 @@ void dso__insert_symbol(struct dso *dso, enum map_type type, struct symbol *sym) struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, u64 addr) { - if (dso->last_find_result[type].addr != addr) { + if (dso->last_find_result[type].addr != addr || dso->last_find_result[type].symbol == NULL) { dso->last_find_result[type].addr = addr; dso->last_find_result[type].symbol = symbols__find(&dso->symbols[type], addr); } @@ -503,7 +533,12 @@ struct symbol *symbol__next_by_name(struct symbol *sym) struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, const char *name) { - return symbols__find_by_name(&dso->symbol_names[type], name); + struct symbol *s = symbols__find_by_name(&dso->symbol_names[type], name, + SYMBOL_TAG_INCLUDE__NONE); + if (!s) + s = symbols__find_by_name(&dso->symbol_names[type], name, + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); + return s; } void dso__sort_by_name(struct dso *dso, enum map_type type) @@ -1075,8 +1110,9 @@ static int validate_kcore_addresses(const char *kallsyms_filename, if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { u64 start; - start = kallsyms__get_function_start(kallsyms_filename, - kmap->ref_reloc_sym->name); + if (kallsyms__get_function_start(kallsyms_filename, + kmap->ref_reloc_sym->name, &start)) + return -ENOENT; if (start != kmap->ref_reloc_sym->addr) return -EINVAL; } @@ -1248,9 +1284,7 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) return 0; - addr = kallsyms__get_function_start(filename, - kmap->ref_reloc_sym->name); - if (!addr) + if (kallsyms__get_function_start(filename, kmap->ref_reloc_sym->name, &addr)) return -1; *delta = addr - kmap->ref_reloc_sym->addr; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 7acd70fce68e..41ebba9a2eb2 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -348,8 +348,19 @@ void arch__sym_update(struct symbol *s, GElf_Sym *sym); #define SYMBOL_A 0 #define SYMBOL_B 1 +int arch__compare_symbol_names(const char *namea, const char *nameb); +int arch__compare_symbol_names_n(const char *namea, const char *nameb, + unsigned int n); int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); +enum symbol_tag_include { + SYMBOL_TAG_INCLUDE__NONE = 0, + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY +}; + +int symbol__match_symbol_name(const char *namea, const char *nameb, + enum symbol_tag_include includes); + /* structure containing an SDT note's info */ struct sdt_note { char *name; /* name of the note*/ diff --git a/tools/perf/util/units.c b/tools/perf/util/units.c index f6a2a3d117d5..4767ec2c5ef6 100644 --- a/tools/perf/util/units.c +++ b/tools/perf/util/units.c @@ -1,8 +1,37 @@ #include "units.h" #include <inttypes.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> #include <linux/kernel.h> #include <linux/time64.h> +unsigned long parse_tag_value(const char *str, struct parse_tag *tags) +{ + struct parse_tag *i = tags; + + while (i->tag) { + char *s = strchr(str, i->tag); + + if (s) { + unsigned long int value; + char *endptr; + + value = strtoul(str, &endptr, 10); + if (s != endptr) + break; + + if (value > ULONG_MAX / i->mult) + break; + value *= i->mult; + return value; + } + i++; + } + + return (unsigned long) -1; +} + unsigned long convert_unit(unsigned long value, char *unit) { *unit = ' '; diff --git a/tools/perf/util/units.h b/tools/perf/util/units.h index 3ed7774afaa9..f02c87317150 100644 --- a/tools/perf/util/units.h +++ b/tools/perf/util/units.h @@ -4,6 +4,13 @@ #include <stddef.h> #include <linux/types.h> +struct parse_tag { + char tag; + int mult; +}; + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags); + unsigned long convert_unit(unsigned long value, char *unit); int unit_number__scnprintf(char *buf, size_t size, u64 n); diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6450c75a6f5b..28c9f335006c 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -13,7 +13,6 @@ #include <string.h> #include <errno.h> #include <limits.h> -#include <byteswap.h> #include <linux/kernel.h> #include <linux/log2.h> #include <linux/time64.h> @@ -335,33 +334,6 @@ int hex2u64(const char *ptr, u64 *long_val) return p - ptr; } -unsigned long parse_tag_value(const char *str, struct parse_tag *tags) -{ - struct parse_tag *i = tags; - - while (i->tag) { - char *s; - - s = strchr(str, i->tag); - if (s) { - unsigned long int value; - char *endptr; - - value = strtoul(str, &endptr, 10); - if (s != endptr) - break; - - if (value > ULONG_MAX / i->mult) - break; - value *= i->mult; - return value; - } - i++; - } - - return (unsigned long) -1; -} - int perf_event_paranoid(void) { int value; @@ -372,27 +344,6 @@ int perf_event_paranoid(void) return value; } -void mem_bswap_32(void *src, int byte_size) -{ - u32 *m = src; - while (byte_size > 0) { - *m = bswap_32(*m); - byte_size -= sizeof(u32); - ++m; - } -} - -void mem_bswap_64(void *src, int byte_size) -{ - u64 *m = src; - - while (byte_size > 0) { - *m = bswap_64(*m); - byte_size -= sizeof(u64); - ++m; - } -} - bool find_process(const char *name) { size_t len = strlen(name); diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 3852b6d3270a..5dfb9bb6482d 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -5,7 +5,6 @@ #define _BSD_SOURCE 1 /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ #define _DEFAULT_SOURCE 1 -#define HAS_BOOL #include <fcntl.h> #include <stdbool.h> @@ -14,8 +13,6 @@ #include <stdarg.h> #include <linux/types.h> -extern char buildid_dir[]; - #ifdef __GNUC__ #define NORETURN __attribute__((__noreturn__)) #else @@ -25,8 +22,6 @@ extern char buildid_dir[]; #endif #endif -#define PERF_GTK_DSO "libperf-gtk.so" - /* General helper functions */ void usage(const char *err) NORETURN; void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); @@ -35,9 +30,6 @@ void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); void set_warning_routine(void (*routine)(const char *err, va_list params)); -int prefixcmp(const char *str, const char *prefix); -void set_buildid_dir(const char *dir); - static inline void *zalloc(size_t size) { return calloc(1, size); @@ -59,29 +51,11 @@ int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 si ssize_t readn(int fd, void *buf, size_t n); ssize_t writen(int fd, void *buf, size_t n); -struct perf_event_attr; - -void event_attr_init(struct perf_event_attr *attr); - size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); extern unsigned int page_size; extern int cacheline_size; -extern int sysctl_perf_event_max_stack; -extern int sysctl_perf_event_max_contexts_per_stack; - -struct parse_tag { - char tag; - int mult; -}; - -unsigned long parse_tag_value(const char *str, struct parse_tag *tags); - -int perf_event_paranoid(void); - -void mem_bswap_64(void *src, int byte_size); -void mem_bswap_32(void *src, int byte_size); bool find_process(const char *name); |