summaryrefslogtreecommitdiff
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN5
-rw-r--r--tools/perf/util/annotate.c76
-rw-r--r--tools/perf/util/annotate.h26
-rw-r--r--tools/perf/util/build-id.c6
-rw-r--r--tools/perf/util/build-id.h3
-rw-r--r--tools/perf/util/cache.h3
-rw-r--r--tools/perf/util/callchain.c147
-rw-r--r--tools/perf/util/callchain.h11
-rw-r--r--tools/perf/util/color.c11
-rw-r--r--tools/perf/util/color.h2
-rw-r--r--tools/perf/util/comm.c121
-rw-r--r--tools/perf/util/comm.h21
-rw-r--r--tools/perf/util/cpumap.c6
-rw-r--r--tools/perf/util/data.c120
-rw-r--r--tools/perf/util/data.h48
-rw-r--r--tools/perf/util/dso.c50
-rw-r--r--tools/perf/util/dso.h3
-rw-r--r--tools/perf/util/event.c94
-rw-r--r--tools/perf/util/event.h18
-rw-r--r--tools/perf/util/evlist.c288
-rw-r--r--tools/perf/util/evlist.h24
-rw-r--r--tools/perf/util/evsel.c42
-rw-r--r--tools/perf/util/evsel.h34
-rw-r--r--tools/perf/util/fs.c119
-rw-r--r--tools/perf/util/fs.h7
-rwxr-xr-xtools/perf/util/generate-cmdlist.sh4
-rw-r--r--tools/perf/util/header.c32
-rw-r--r--tools/perf/util/hist.c95
-rw-r--r--tools/perf/util/hist.h75
-rw-r--r--tools/perf/util/include/dwarf-regs.h2
-rw-r--r--tools/perf/util/include/linux/compiler.h19
-rw-r--r--tools/perf/util/include/linux/magic.h4
-rw-r--r--tools/perf/util/intlist.c23
-rw-r--r--tools/perf/util/intlist.h2
-rw-r--r--tools/perf/util/machine.c180
-rw-r--r--tools/perf/util/machine.h41
-rw-r--r--tools/perf/util/map.c50
-rw-r--r--tools/perf/util/map.h7
-rw-r--r--tools/perf/util/parse-events.c10
-rw-r--r--tools/perf/util/parse-events.l63
-rw-r--r--tools/perf/util/parse-options.c218
-rw-r--r--tools/perf/util/parse-options.h4
-rw-r--r--tools/perf/util/path.c10
-rw-r--r--tools/perf/util/perf_regs.h4
-rw-r--r--tools/perf/util/pmu.c33
-rw-r--r--tools/perf/util/pmu.h1
-rw-r--r--tools/perf/util/probe-event.c5
-rw-r--r--tools/perf/util/probe-finder.c248
-rw-r--r--tools/perf/util/probe-finder.h15
-rw-r--r--tools/perf/util/pstack.h10
-rw-r--r--tools/perf/util/python-ext-sources2
-rw-r--r--tools/perf/util/python.c8
-rw-r--r--tools/perf/util/rblist.c27
-rw-r--r--tools/perf/util/rblist.h1
-rw-r--r--tools/perf/util/record.c71
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c4
-rw-r--r--tools/perf/util/session.c278
-rw-r--r--tools/perf/util/session.h38
-rw-r--r--tools/perf/util/sort.c331
-rw-r--r--tools/perf/util/sort.h8
-rw-r--r--tools/perf/util/srcline.c265
-rw-r--r--tools/perf/util/strfilter.c72
-rw-r--r--tools/perf/util/strfilter.h12
-rw-r--r--tools/perf/util/symbol-elf.c607
-rw-r--r--tools/perf/util/symbol-minimal.c15
-rw-r--r--tools/perf/util/symbol.c449
-rw-r--r--tools/perf/util/symbol.h29
-rw-r--r--tools/perf/util/sysfs.c60
-rw-r--r--tools/perf/util/sysfs.h6
-rw-r--r--tools/perf/util/target.c54
-rw-r--r--tools/perf/util/target.h45
-rw-r--r--tools/perf/util/thread.c136
-rw-r--r--tools/perf/util/thread.h20
-rw-r--r--tools/perf/util/top.c2
-rw-r--r--tools/perf/util/top.h1
-rw-r--r--tools/perf/util/trace-event-parse.c36
-rw-r--r--tools/perf/util/trace-event.h9
-rw-r--r--tools/perf/util/unwind.c84
-rw-r--r--tools/perf/util/unwind.h9
-rw-r--r--tools/perf/util/util.c66
-rw-r--r--tools/perf/util/util.h26
82 files changed, 1383 insertions, 3830 deletions
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 39f1750..15a77b7 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -19,9 +19,6 @@ if test -d ../../.git -o -f ../../.git
then
TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null )
CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID"
-elif test -f ../../PERF-VERSION-FILE
-then
- TAG=$(cut -d' ' -f3 ../../PERF-VERSION-FILE | sed -e 's/\"//g')
fi
if test -z "$TAG"
then
@@ -43,7 +40,7 @@ else
VC=unset
fi
test "$VN" = "$VC" || {
- echo >&2 " PERF_VERSION = $VN"
+ echo >&2 "PERF_VERSION = $VN"
echo "#define PERF_VERSION \"$VN\"" >$GVF
}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index cf6242c..7eae548 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -825,16 +825,20 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
dl->ops.target.offset = dl->ops.target.addr -
map__rip_2objdump(map, sym->start);
- /* kcore has no symbols, so add the call target name */
+ /*
+ * kcore has no symbols, so add the call target name if it is on the
+ * same map.
+ */
if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) {
- struct addr_map_symbol target = {
- .map = map,
- .addr = dl->ops.target.addr,
- };
-
- if (!map_groups__find_ams(&target, NULL) &&
- target.sym->start == target.al_addr)
- dl->ops.target.name = strdup(target.sym->name);
+ struct symbol *s;
+ u64 ip = dl->ops.target.addr;
+
+ if (ip >= map->start && ip <= map->end) {
+ ip = map->map_ip(map, ip);
+ s = map__find_symbol(map, ip, NULL);
+ if (s && s->start == ip)
+ dl->ops.target.name = strdup(s->name);
+ }
}
disasm__add(&notes->src->source, dl);
@@ -875,8 +879,6 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
FILE *file;
int err = 0;
char symfs_filename[PATH_MAX];
- struct kcore_extract kce;
- bool delete_extract = false;
if (filename) {
snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
@@ -938,23 +940,6 @@ fallback:
pr_debug("annotating [%p] %30s : [%p] %30s\n",
dso, dso->long_name, sym, sym->name);
- if (dso__is_kcore(dso)) {
- kce.kcore_filename = symfs_filename;
- kce.addr = map__rip_2objdump(map, sym->start);
- kce.offs = sym->start;
- kce.len = sym->end + 1 - sym->start;
- if (!kcore_extract__create(&kce)) {
- delete_extract = true;
- strlcpy(symfs_filename, kce.extract_filename,
- sizeof(symfs_filename));
- if (free_filename) {
- free(filename);
- free_filename = false;
- }
- filename = symfs_filename;
- }
- }
-
snprintf(command, sizeof(command),
"%s %s%s --start-address=0x%016" PRIx64
" --stop-address=0x%016" PRIx64
@@ -987,8 +972,6 @@ fallback:
pclose(file);
out_free_filename:
- if (delete_extract)
- kcore_extract__delete(&kce);
if (free_filename)
free(filename);
return err;
@@ -1087,7 +1070,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
(sizeof(src_line->p) * (src_line->nr_pcnt - 1));
for (i = 0; i < len; i++) {
- free_srcline(src_line->path);
+ free(src_line->path);
src_line = (void *)src_line + sizeof_src_line;
}
@@ -1098,11 +1081,13 @@ static void symbol__free_source_line(struct symbol *sym, int len)
/* Get the filename:line for the colored entries */
static int symbol__get_source_line(struct symbol *sym, struct map *map,
struct perf_evsel *evsel,
- struct rb_root *root, int len)
+ struct rb_root *root, int len,
+ const char *filename)
{
u64 start;
int i, k;
int evidx = evsel->idx;
+ char cmd[PATH_MAX * 2];
struct source_line *src_line;
struct annotation *notes = symbol__annotation(sym);
struct sym_hist *h = annotation__histogram(notes, evidx);
@@ -1130,7 +1115,10 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
start = map__rip_2objdump(map, sym->start);
for (i = 0; i < len; i++) {
+ char *path = NULL;
+ size_t line_len;
u64 offset;
+ FILE *fp;
double percent_max = 0.0;
src_line->nr_pcnt = nr_pcnt;
@@ -1147,9 +1135,23 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
goto next;
offset = start + i;
- src_line->path = get_srcline(map->dso, offset);
+ sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
+ fp = popen(cmd, "r");
+ if (!fp)
+ goto next;
+
+ if (getline(&path, &line_len, fp) < 0 || !line_len)
+ goto next_close;
+
+ src_line->path = malloc(sizeof(char) * line_len + 1);
+ if (!src_line->path)
+ goto next_close;
+
+ strcpy(src_line->path, path);
insert_source_line(&tmp_root, src_line);
+ next_close:
+ pclose(fp);
next:
src_line = (void *)src_line + sizeof_src_line;
}
@@ -1190,7 +1192,7 @@ static void print_summary(struct rb_root *root, const char *filename)
path = src_line->path;
color = get_percent_color(percent_max);
- color_fprintf(stdout, color, " %s\n", path);
+ color_fprintf(stdout, color, " %s", path);
node = rb_next(node);
}
@@ -1354,6 +1356,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
bool full_paths, int min_pcnt, int max_lines)
{
struct dso *dso = map->dso;
+ const char *filename = dso->long_name;
struct rb_root source_line = RB_ROOT;
u64 len;
@@ -1363,8 +1366,9 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
len = symbol__size(sym);
if (print_lines) {
- symbol__get_source_line(sym, map, evsel, &source_line, len);
- print_summary(&source_line, dso->long_name);
+ symbol__get_source_line(sym, map, evsel, &source_line,
+ len, filename);
+ print_summary(&source_line, filename);
}
symbol__annotate_printf(sym, map, evsel, full_paths,
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 834b7b5..af75515 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -150,7 +150,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel, bool print_lines,
bool full_paths, int min_pcnt, int max_lines);
-#ifdef HAVE_SLANG_SUPPORT
+#ifdef SLANG_SUPPORT
int symbol__tui_annotate(struct symbol *sym, struct map *map,
struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
@@ -165,6 +165,30 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
}
#endif
+#ifdef GTK2_SUPPORT
+int symbol__gtk_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt);
+
+static inline int hist_entry__gtk_annotate(struct hist_entry *he,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt)
+{
+ return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
+}
+
+void perf_gtk__show_annotations(void);
+#else
+static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
+ struct hist_browser_timer *hbt __maybe_unused)
+{
+ return 0;
+}
+
+static inline void perf_gtk__show_annotations(void) {}
+#endif
+
extern const char *disassembler_style;
#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a92770c..7ded71d 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -89,14 +89,14 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
return raw - build_id;
}
-char *dso__build_id_filename(struct dso *dso, char *bf, size_t size)
+char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
{
char build_id_hex[BUILD_ID_SIZE * 2 + 1];
- if (!dso->has_build_id)
+ if (!self->has_build_id)
return NULL;
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex);
+ build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex);
if (bf == NULL) {
if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
build_id_hex, build_id_hex + 2) < 0)
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 929f28a..a811f5c 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -10,9 +10,10 @@ extern struct perf_tool build_id__mark_dso_hit_ops;
struct dso;
int build_id__sprintf(const u8 *build_id, int len, char *bf);
-char *dso__build_id_filename(struct dso *dso, char *bf, size_t size);
+char *dso__build_id_filename(struct dso *self, char *bf, size_t size);
int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
struct perf_sample *sample, struct perf_evsel *evsel,
struct machine *machine);
+
#endif
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 7b176dd..26e3672 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -70,7 +70,8 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
extern char *perf_pathdup(const char *fmt, ...)
__attribute__((format (printf, 1, 2)));
-/* Matches the libc/libbsd function attribute so we declare this unconditionally: */
+#ifndef HAVE_STRLCPY
extern size_t strlcpy(char *dest, const char *src, size_t size);
+#endif
#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index e3970e3..482f680 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -21,6 +21,12 @@
__thread struct callchain_cursor callchain_cursor;
+#define chain_for_each_child(child, parent) \
+ list_for_each_entry(child, &parent->children, siblings)
+
+#define chain_for_each_child_safe(child, next, parent) \
+ list_for_each_entry_safe(child, next, &parent->children, siblings)
+
static void
rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
enum chain_mode mode)
@@ -65,16 +71,10 @@ static void
__sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
u64 min_hit)
{
- struct rb_node *n;
struct callchain_node *child;
- n = rb_first(&node->rb_root_in);
- while (n) {
- child = rb_entry(n, struct callchain_node, rb_node_in);
- n = rb_next(n);
-
+ chain_for_each_child(child, node)
__sort_chain_flat(rb_root, child, min_hit);
- }
if (node->hit && node->hit >= min_hit)
rb_insert_callchain(rb_root, node, CHAIN_FLAT);
@@ -94,16 +94,11 @@ sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root,
static void __sort_chain_graph_abs(struct callchain_node *node,
u64 min_hit)
{
- struct rb_node *n;
struct callchain_node *child;
node->rb_root = RB_ROOT;
- n = rb_first(&node->rb_root_in);
-
- while (n) {
- child = rb_entry(n, struct callchain_node, rb_node_in);
- n = rb_next(n);
+ chain_for_each_child(child, node) {
__sort_chain_graph_abs(child, min_hit);
if (callchain_cumul_hits(child) >= min_hit)
rb_insert_callchain(&node->rb_root, child,
@@ -122,18 +117,13 @@ sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root,
static void __sort_chain_graph_rel(struct callchain_node *node,
double min_percent)
{
- struct rb_node *n;
struct callchain_node *child;
u64 min_hit;
node->rb_root = RB_ROOT;
min_hit = ceil(node->children_hit * min_percent);
- n = rb_first(&node->rb_root_in);
- while (n) {
- child = rb_entry(n, struct callchain_node, rb_node_in);
- n = rb_next(n);
-
+ chain_for_each_child(child, node) {
__sort_chain_graph_rel(child, min_percent);
if (callchain_cumul_hits(child) >= min_hit)
rb_insert_callchain(&node->rb_root, child,
@@ -183,26 +173,19 @@ create_child(struct callchain_node *parent, bool inherit_children)
return NULL;
}
new->parent = parent;
+ INIT_LIST_HEAD(&new->children);
INIT_LIST_HEAD(&new->val);
if (inherit_children) {
- struct rb_node *n;
- struct callchain_node *child;
-
- new->rb_root_in = parent->rb_root_in;
- parent->rb_root_in = RB_ROOT;
+ struct callchain_node *next;
- n = rb_first(&new->rb_root_in);
- while (n) {
- child = rb_entry(n, struct callchain_node, rb_node_in);
- child->parent = new;
- n = rb_next(n);
- }
+ list_splice(&parent->children, &new->children);
+ INIT_LIST_HEAD(&parent->children);
- /* make it the first child */
- rb_link_node(&new->rb_node_in, NULL, &parent->rb_root_in.rb_node);
- rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
+ chain_for_each_child(next, new)
+ next->parent = new;
}
+ list_add_tail(&new->siblings, &parent->children);
return new;
}
@@ -240,7 +223,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
}
}
-static struct callchain_node *
+static void
add_child(struct callchain_node *parent,
struct callchain_cursor *cursor,
u64 period)
@@ -252,19 +235,6 @@ add_child(struct callchain_node *parent,
new->children_hit = 0;
new->hit = period;
- return new;
-}
-
-static s64 match_chain(struct callchain_cursor_node *node,
- struct callchain_list *cnode)
-{
- struct symbol *sym = node->sym;
-
- if (cnode->ms.sym && sym &&
- callchain_param.key == CCKEY_FUNCTION)
- return cnode->ms.sym->start - sym->start;
- else
- return cnode->ip - node->ip;
}
/*
@@ -302,33 +272,9 @@ split_add_child(struct callchain_node *parent,
/* create a new child for the new branch if any */
if (idx_total < cursor->nr) {
- struct callchain_node *first;
- struct callchain_list *cnode;
- struct callchain_cursor_node *node;
- struct rb_node *p, **pp;
-
parent->hit = 0;
+ add_child(parent, cursor, period);
parent->children_hit += period;
-
- node = callchain_cursor_current(cursor);
- new = add_child(parent, cursor, period);
-
- /*
- * This is second child since we moved parent's children
- * to new (first) child above.
- */
- p = parent->rb_root_in.rb_node;
- first = rb_entry(p, struct callchain_node, rb_node_in);
- cnode = list_first_entry(&first->val, struct callchain_list,
- list);
-
- if (match_chain(node, cnode) < 0)
- pp = &p->rb_left;
- else
- pp = &p->rb_right;
-
- rb_link_node(&new->rb_node_in, p, pp);
- rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
} else {
parent->hit = period;
}
@@ -345,40 +291,16 @@ append_chain_children(struct callchain_node *root,
u64 period)
{
struct callchain_node *rnode;
- struct callchain_cursor_node *node;
- struct rb_node **p = &root->rb_root_in.rb_node;
- struct rb_node *parent = NULL;
-
- node = callchain_cursor_current(cursor);
- if (!node)
- return;
/* lookup in childrens */
- while (*p) {
- s64 ret;
- struct callchain_list *cnode;
+ chain_for_each_child(rnode, root) {
+ unsigned int ret = append_chain(rnode, cursor, period);
- parent = *p;
- rnode = rb_entry(parent, struct callchain_node, rb_node_in);
- cnode = list_first_entry(&rnode->val, struct callchain_list,
- list);
-
- /* just check first entry */
- ret = match_chain(node, cnode);
- if (ret == 0) {
- append_chain(rnode, cursor, period);
+ if (!ret)
goto inc_children_hit;
- }
-
- if (ret < 0)
- p = &parent->rb_left;
- else
- p = &parent->rb_right;
}
/* nothing in children, add to the current node */
- rnode = add_child(root, cursor, period);
- rb_link_node(&rnode->rb_node_in, parent, p);
- rb_insert_color(&rnode->rb_node_in, &root->rb_root_in);
+ add_child(root, cursor, period);
inc_children_hit:
root->children_hit += period;
@@ -403,20 +325,28 @@ append_chain(struct callchain_node *root,
*/
list_for_each_entry(cnode, &root->val, list) {
struct callchain_cursor_node *node;
+ struct symbol *sym;
node = callchain_cursor_current(cursor);
if (!node)
break;
- if (match_chain(node, cnode) != 0)
+ sym = node->sym;
+
+ if (cnode->ms.sym && sym &&
+ callchain_param.key == CCKEY_FUNCTION) {
+ if (cnode->ms.sym->start != sym->start)
+ break;
+ } else if (cnode->ip != node->ip)
break;
- found = true;
+ if (!found)
+ found = true;
callchain_cursor_advance(cursor);
}
- /* matches not, relay no the parent */
+ /* matches not, relay on the parent */
if (!found) {
cursor->curr = curr_snap;
cursor->pos = start;
@@ -465,9 +395,8 @@ merge_chain_branch(struct callchain_cursor *cursor,
struct callchain_node *dst, struct callchain_node *src)
{
struct callchain_cursor_node **old_last = cursor->last;
- struct callchain_node *child;
+ struct callchain_node *child, *next_child;
struct callchain_list *list, *next_list;
- struct rb_node *n;
int old_pos = cursor->nr;
int err = 0;
@@ -483,16 +412,12 @@ merge_chain_branch(struct callchain_cursor *cursor,
append_chain_children(dst, cursor, src->hit);
}
- n = rb_first(&src->rb_root_in);
- while (n) {
- child = container_of(n, struct callchain_node, rb_node_in);
- n = rb_next(n);
- rb_erase(&child->rb_node_in, &src->rb_root_in);
-
+ chain_for_each_child_safe(child, next_child, src) {
err = merge_chain_branch(cursor, dst, child);
if (err)
break;
+ list_del(&child->siblings);
free(child);
}
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 4f7f989..9e99060 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -21,11 +21,11 @@ enum chain_order {
struct callchain_node {
struct callchain_node *parent;
+ struct list_head siblings;
+ struct list_head children;
struct list_head val;
- struct rb_node rb_node_in; /* to insert nodes in an rbtree */
- struct rb_node rb_node; /* to sort nodes in an output tree */
- struct rb_root rb_root_in; /* input tree of children */
- struct rb_root rb_root; /* sorted output tree of children */
+ struct rb_node rb_node; /* to sort nodes in an rbtree */
+ struct rb_root rb_root; /* sorted tree of children */
unsigned int val_nr;
u64 hit;
u64 children_hit;
@@ -86,12 +86,13 @@ extern __thread struct callchain_cursor callchain_cursor;
static inline void callchain_init(struct callchain_root *root)
{
+ INIT_LIST_HEAD(&root->node.siblings);
+ INIT_LIST_HEAD(&root->node.children);
INIT_LIST_HEAD(&root->node.val);
root->node.parent = NULL;
root->node.hit = 0;
root->node.children_hit = 0;
- root->node.rb_root_in = RB_ROOT;
root->max_depth = 0;
}
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 66e44a5..11e46da 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -318,15 +318,8 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
return r;
}
-int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
{
- va_list args;
- double percent;
- const char *color;
-
- va_start(args, fmt);
- percent = va_arg(args, double);
- va_end(args);
- color = get_percent_color(percent);
+ const char *color = get_percent_color(percent);
return color_snprintf(bf, size, color, fmt, percent);
}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index fced384..dea082b 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -39,7 +39,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
-int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...);
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
const char *get_percent_color(double percent);
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
deleted file mode 100644
index ee0df0e..0000000
--- a/tools/perf/util/comm.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "comm.h"
-#include "util.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-struct comm_str {
- char *str;
- struct rb_node rb_node;
- int ref;
-};
-
-/* Should perhaps be moved to struct machine */
-static struct rb_root comm_str_root;
-
-static void comm_str__get(struct comm_str *cs)
-{
- cs->ref++;
-}
-
-static void comm_str__put(struct comm_str *cs)
-{
- if (!--cs->ref) {
- rb_erase(&cs->rb_node, &comm_str_root);
- free(cs->str);
- free(cs);
- }
-}
-
-static struct comm_str *comm_str__alloc(const char *str)
-{
- struct comm_str *cs;
-
- cs = zalloc(sizeof(*cs));
- if (!cs)
- return NULL;
-
- cs->str = strdup(str);
- if (!cs->str) {
- free(cs);
- return NULL;
- }
-
- return cs;
-}
-
-static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct comm_str *iter, *new;
- int cmp;
-
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct comm_str, rb_node);
-
- cmp = strcmp(str, iter->str);
- if (!cmp)
- return iter;
-
- if (cmp < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- new = comm_str__alloc(str);
- if (!new)
- return NULL;
-
- rb_link_node(&new->rb_node, parent, p);
- rb_insert_color(&new->rb_node, root);
-
- return new;
-}
-
-struct comm *comm__new(const char *str, u64 timestamp)
-{
- struct comm *comm = zalloc(sizeof(*comm));
-
- if (!comm)
- return NULL;
-
- comm->start = timestamp;
-
- comm->comm_str = comm_str__findnew(str, &comm_str_root);
- if (!comm->comm_str) {
- free(comm);
- return NULL;
- }
-
- comm_str__get(comm->comm_str);
-
- return comm;
-}
-
-void comm__override(struct comm *comm, const char *str, u64 timestamp)
-{
- struct comm_str *old = comm->comm_str;
-
- comm->comm_str = comm_str__findnew(str, &comm_str_root);
- if (!comm->comm_str) {
- comm->comm_str = old;
- return;
- }
-
- comm->start = timestamp;
- comm_str__get(comm->comm_str);
- comm_str__put(old);
-}
-
-void comm__free(struct comm *comm)
-{
- comm_str__put(comm->comm_str);
- free(comm);
-}
-
-const char *comm__str(const struct comm *comm)
-{
- return comm->comm_str->str;
-}
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
deleted file mode 100644
index 7a86e56..0000000
--- a/tools/perf/util/comm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __PERF_COMM_H
-#define __PERF_COMM_H
-
-#include "../perf.h"
-#include <linux/rbtree.h>
-#include <linux/list.h>
-
-struct comm_str;
-
-struct comm {
- struct comm_str *comm_str;
- u64 start;
- struct list_head list;
-};
-
-void comm__free(struct comm *comm);
-struct comm *comm__new(const char *str, u64 timestamp);
-const char *comm__str(const struct comm *comm);
-void comm__override(struct comm *comm, const char *str, u64 timestamp);
-
-#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index a9b48c4..beb8cf9 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -1,5 +1,5 @@
#include "util.h"
-#include "fs.h"
+#include "sysfs.h"
#include "../perf.h"
#include "cpumap.h"
#include <assert.h>
@@ -216,7 +216,7 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)
cpu = map->map[idx];
- mnt = sysfs__mountpoint();
+ mnt = sysfs_find_mountpoint();
if (!mnt)
return -1;
@@ -279,7 +279,7 @@ int cpu_map__get_core(struct cpu_map *map, int idx)
cpu = map->map[idx];
- mnt = sysfs__mountpoint();
+ mnt = sysfs_find_mountpoint();
if (!mnt)
return -1;
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
deleted file mode 100644
index 7d09faf..0000000
--- a/tools/perf/util/data.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "data.h"
-#include "util.h"
-
-static bool check_pipe(struct perf_data_file *file)
-{
- struct stat st;
- bool is_pipe = false;
- int fd = perf_data_file__is_read(file) ?
- STDIN_FILENO : STDOUT_FILENO;
-
- if (!file->path) {
- if (!fstat(fd, &st) && S_ISFIFO(st.st_mode))
- is_pipe = true;
- } else {
- if (!strcmp(file->path, "-"))
- is_pipe = true;
- }
-
- if (is_pipe)
- file->fd = fd;
-
- return file->is_pipe = is_pipe;
-}
-
-static int check_backup(struct perf_data_file *file)
-{
- struct stat st;
-
- if (!stat(file->path, &st) && st.st_size) {
- /* TODO check errors properly */
- char oldname[PATH_MAX];
- snprintf(oldname, sizeof(oldname), "%s.old",
- file->path);
- unlink(oldname);
- rename(file->path, oldname);
- }
-
- return 0;
-}
-
-static int open_file_read(struct perf_data_file *file)
-{
- struct stat st;
- int fd;
-
- fd = open(file->path, O_RDONLY);
- if (fd < 0) {
- int err = errno;
-
- pr_err("failed to open %s: %s", file->path, strerror(err));
- if (err == ENOENT && !strcmp(file->path, "perf.data"))
- pr_err(" (try 'perf record' first)");
- pr_err("\n");
- return -err;
- }
-
- if (fstat(fd, &st) < 0)
- goto out_close;
-
- if (!file->force && st.st_uid && (st.st_uid != geteuid())) {
- pr_err("file %s not owned by current user or root\n",
- file->path);
- goto out_close;
- }
-
- if (!st.st_size) {
- pr_info("zero-sized file (%s), nothing to do!\n",
- file->path);
- goto out_close;
- }
-
- file->size = st.st_size;
- return fd;
-
- out_close:
- close(fd);
- return -1;
-}
-
-static int open_file_write(struct perf_data_file *file)
-{
- if (check_backup(file))
- return -1;
-
- return open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
-}
-
-static int open_file(struct perf_data_file *file)
-{
- int fd;
-
- fd = perf_data_file__is_read(file) ?
- open_file_read(file) : open_file_write(file);
-
- file->fd = fd;
- return fd < 0 ? -1 : 0;
-}
-
-int perf_data_file__open(struct perf_data_file *file)
-{
- if (check_pipe(file))
- return 0;
-
- if (!file->path)
- file->path = "perf.data";
-
- return open_file(file);
-}
-
-void perf_data_file__close(struct perf_data_file *file)
-{
- close(file->fd);
-}
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
deleted file mode 100644
index 8c2df80..0000000
--- a/tools/perf/util/data.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __PERF_DATA_H
-#define __PERF_DATA_H
-
-#include <stdbool.h>
-
-enum perf_data_mode {
- PERF_DATA_MODE_WRITE,
- PERF_DATA_MODE_READ,
-};
-
-struct perf_data_file {
- const char *path;
- int fd;
- bool is_pipe;
- bool force;
- unsigned long size;
- enum perf_data_mode mode;
-};
-
-static inline bool perf_data_file__is_read(struct perf_data_file *file)
-{
- return file->mode == PERF_DATA_MODE_READ;
-}
-
-static inline bool perf_data_file__is_write(struct perf_data_file *file)
-{
- return file->mode == PERF_DATA_MODE_WRITE;
-}
-
-static inline int perf_data_file__is_pipe(struct perf_data_file *file)
-{
- return file->is_pipe;
-}
-
-static inline int perf_data_file__fd(struct perf_data_file *file)
-{
- return file->fd;
-}
-
-static inline unsigned long perf_data_file__size(struct perf_data_file *file)
-{
- return file->size;
-}
-
-int perf_data_file__open(struct perf_data_file *file);
-void perf_data_file__close(struct perf_data_file *file);
-
-#endif /* __PERF_DATA_H */
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index af4c687c..e3c1ff8 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -7,20 +7,19 @@
char dso__symtab_origin(const struct dso *dso)
{
static const char origin[] = {
- [DSO_BINARY_TYPE__KALLSYMS] = 'k',
- [DSO_BINARY_TYPE__VMLINUX] = 'v',
- [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
- [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
- [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
- [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
- [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
- [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o',
- [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
- [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
- [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
- [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
- [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
- [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
+ [DSO_BINARY_TYPE__KALLSYMS] = 'k',
+ [DSO_BINARY_TYPE__VMLINUX] = 'v',
+ [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
+ [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
+ [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
+ [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
+ [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
+ [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
+ [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
+ [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
+ [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
+ [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
};
if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
@@ -65,28 +64,6 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
symbol_conf.symfs, dso->long_name);
break;
- case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
- {
- char *last_slash;
- size_t len;
- size_t dir_size;
-
- last_slash = dso->long_name + dso->long_name_len;
- while (last_slash != dso->long_name && *last_slash != '/')
- last_slash--;
-
- len = scnprintf(file, size, "%s", symbol_conf.symfs);
- dir_size = last_slash - dso->long_name + 2;
- if (dir_size > (size - len)) {
- ret = -1;
- break;
- }
- len += scnprintf(file + len, dir_size, "%s", dso->long_name);
- len += scnprintf(file + len , size - len, ".debug%s",
- last_slash);
- break;
- }
-
case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
if (!dso->has_build_id) {
ret = -1;
@@ -450,7 +427,6 @@ struct dso *dso__new(const char *name)
dso->rel = 0;
dso->sorted_by_name = 0;
dso->has_build_id = 0;
- dso->has_srcline = 1;
dso->kernel = DSO_TYPE_USER;
dso->needs_swap = DSO_SWAP__UNSET;
INIT_LIST_HEAD(&dso->node);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 9ac666a..b793053 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -6,7 +6,6 @@
#include <stdbool.h>
#include "types.h"
#include "map.h"
-#include "build-id.h"
enum dso_binary_type {
DSO_BINARY_TYPE__KALLSYMS = 0,
@@ -24,7 +23,6 @@ enum dso_binary_type {
DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
DSO_BINARY_TYPE__KCORE,
DSO_BINARY_TYPE__GUEST_KCORE,
- DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
DSO_BINARY_TYPE__NOT_FOUND,
};
@@ -83,7 +81,6 @@ struct dso {
enum dso_binary_type data_type;
u8 adjust_symbols:1;
u8 has_build_id:1;
- u8 has_srcline:1;
u8 hit:1;
u8 annotate_warned:1;
u8 sname_alloc:1;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bb788c1..49096ea 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -170,8 +170,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
union perf_event *event,
pid_t pid, pid_t tgid,
perf_event__handler_t process,
- struct machine *machine,
- bool mmap_data)
+ struct machine *machine)
{
char filename[PATH_MAX];
FILE *fp;
@@ -189,6 +188,10 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
}
event->header.type = PERF_RECORD_MMAP;
+ /*
+ * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
+ */
+ event->header.misc = PERF_RECORD_MISC_USER;
while (1) {
char bf[BUFSIZ];
@@ -209,22 +212,12 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
&event->mmap.start, &event->mmap.len, prot,
&event->mmap.pgoff,
execname);
- /*
- * Anon maps don't have the execname.
- */
- if (n < 4)
- continue;
- /*
- * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
- */
- event->header.misc = PERF_RECORD_MISC_USER;
- if (prot[2] != 'x') {
- if (!mmap_data || prot[0] != 'r')
- continue;
+ if (n != 5)
+ continue;
- event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
- }
+ if (prot[2] != 'x')
+ continue;
if (!strcmp(execname, ""))
strcpy(execname, anonstr);
@@ -311,21 +304,20 @@ static int __event__synthesize_thread(union perf_event *comm_event,
pid_t pid, int full,
perf_event__handler_t process,
struct perf_tool *tool,
- struct machine *machine, bool mmap_data)
+ struct machine *machine)
{
pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full,
process, machine);
if (tgid == -1)
return -1;
return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
- process, machine, mmap_data);
+ process, machine);
}
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine,
- bool mmap_data)
+ struct machine *machine)
{
union perf_event *comm_event, *mmap_event;
int err = -1, thread, j;
@@ -342,8 +334,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
for (thread = 0; thread < threads->nr; ++thread) {
if (__event__synthesize_thread(comm_event, mmap_event,
threads->map[thread], 0,
- process, tool, machine,
- mmap_data)) {
+ process, tool, machine)) {
err = -1;
break;
}
@@ -365,10 +356,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
/* if not, generate events for it */
if (need_leader &&
- __event__synthesize_thread(comm_event, mmap_event,
- comm_event->comm.pid, 0,
- process, tool, machine,
- mmap_data)) {
+ __event__synthesize_thread(comm_event,
+ mmap_event,
+ comm_event->comm.pid, 0,
+ process, tool, machine)) {
err = -1;
break;
}
@@ -383,7 +374,7 @@ out:
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine, bool mmap_data)
+ struct machine *machine)
{
DIR *proc;
struct dirent dirent, *next;
@@ -413,7 +404,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
* one thread couldn't be synthesized.
*/
__event__synthesize_thread(comm_event, mmap_event, pid, 1,
- process, tool, machine, mmap_data);
+ process, tool, machine);
}
err = 0;
@@ -521,55 +512,52 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_comm_event(machine, event, sample);
+ return machine__process_comm_event(machine, event);
}
int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_lost_event(machine, event, sample);
+ return machine__process_lost_event(machine, event);
}
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
- return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
+ return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n",
event->mmap.pid, event->mmap.tid, event->mmap.start,
- event->mmap.len, event->mmap.pgoff,
- (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
- event->mmap.filename);
+ event->mmap.len, event->mmap.pgoff, event->mmap.filename);
}
size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
{
return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
- " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n",
+ " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n",
event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
event->mmap2.min, event->mmap2.ino,
event->mmap2.ino_generation,
- (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
event->mmap2.filename);
}
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_mmap_event(machine, event, sample);
+ return machine__process_mmap_event(machine, event);
}
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_mmap2_event(machine, event, sample);
+ return machine__process_mmap2_event(machine, event);
}
size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
@@ -581,18 +569,18 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_fork_event(machine, event, sample);
+ return machine__process_fork_event(machine, event);
}
int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_exit_event(machine, event, sample);
+ return machine__process_exit_event(machine, event);
}
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
@@ -623,21 +611,21 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
int perf_event__process(struct perf_tool *tool __maybe_unused,
union perf_event *event,
- struct perf_sample *sample,
+ struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
- return machine__process_event(machine, event, sample);
+ return machine__process_event(machine, event);
}
-void thread__find_addr_map(struct thread *thread,
+void thread__find_addr_map(struct thread *self,
struct machine *machine, u8 cpumode,
enum map_type type, u64 addr,
struct addr_location *al)
{
- struct map_groups *mg = &thread->mg;
+ struct map_groups *mg = &self->mg;
bool load_map = false;
- al->thread = thread;
+ al->thread = self;
al->addr = addr;
al->cpumode = cpumode;
al->filtered = false;
@@ -733,10 +721,10 @@ int perf_event__preprocess_sample(const union perf_event *event,
return -1;
if (symbol_conf.comm_list &&
- !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread)))
+ !strlist__has_entry(symbol_conf.comm_list, thread->comm))
goto out_filtered;
- dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
+ dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid);
/*
* Have we already created the kernel maps for this machine?
*
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 30fec99..c67ecc4 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -61,12 +61,6 @@ struct read_event {
u64 id;
};
-struct throttle_event {
- struct perf_event_header header;
- u64 time;
- u64 id;
- u64 stream_id;
-};
#define PERF_SAMPLE_MASK \
(PERF_SAMPLE_IP | PERF_SAMPLE_TID | \
@@ -75,9 +69,6 @@ struct throttle_event {
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | \
PERF_SAMPLE_IDENTIFIER)
-/* perf sample has 16 bits size limit */
-#define PERF_SAMPLE_MAX_SIZE (1 << 16)
-
struct sample_event {
struct perf_event_header header;
u64 array[];
@@ -120,7 +111,6 @@ struct perf_sample {
u64 stream_id;
u64 period;
u64 weight;
- u64 transaction;
u32 cpu;
u32 raw_size;
u64 data_src;
@@ -187,7 +177,6 @@ union perf_event {
struct fork_event fork;
struct lost_event lost;
struct read_event read;
- struct throttle_event throttle;
struct sample_event sample;
struct attr_event attr;
struct event_type_event event_type;
@@ -208,10 +197,10 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool,
int perf_event__synthesize_thread_map(struct perf_tool *tool,
struct thread_map *threads,
perf_event__handler_t process,
- struct machine *machine, bool mmap_data);
+ struct machine *machine);
int perf_event__synthesize_threads(struct perf_tool *tool,
perf_event__handler_t process,
- struct machine *machine, bool mmap_data);
+ struct machine *machine);
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
perf_event__handler_t process,
struct machine *machine,
@@ -251,8 +240,7 @@ int perf_event__process(struct perf_tool *tool,
struct machine *machine);
struct addr_location;
-
-int perf_event__preprocess_sample(const union perf_event *event,
+int perf_event__preprocess_sample(const union perf_event *self,
struct machine *machine,
struct addr_location *al,
struct perf_sample *sample);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index bbc746a..e584cd3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -18,7 +18,6 @@
#include <unistd.h>
#include "parse-events.h"
-#include "parse-options.h"
#include <sys/mman.h>
@@ -50,18 +49,6 @@ struct perf_evlist *perf_evlist__new(void)
return evlist;
}
-struct perf_evlist *perf_evlist__new_default(void)
-{
- struct perf_evlist *evlist = perf_evlist__new();
-
- if (evlist && perf_evlist__add_default(evlist)) {
- perf_evlist__delete(evlist);
- evlist = NULL;
- }
-
- return evlist;
-}
-
/**
* perf_evlist__set_id_pos - set the positions of event ids.
* @evlist: selected event list
@@ -117,8 +104,6 @@ void perf_evlist__delete(struct perf_evlist *evlist)
void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
{
list_add_tail(&entry->node, &evlist->entries);
- entry->idx = evlist->nr_entries;
-
if (!evlist->nr_entries++)
perf_evlist__set_id_pos(evlist);
}
@@ -167,7 +152,7 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
event_attr_init(&attr);
- evsel = perf_evsel__new(&attr);
+ evsel = perf_evsel__new(&attr, 0);
if (evsel == NULL)
goto error;
@@ -192,7 +177,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
size_t i;
for (i = 0; i < nr_attrs; i++) {
- evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i);
+ evsel = perf_evsel__new(attrs + i, evlist->nr_entries + i);
if (evsel == NULL)
goto out_delete_partial_list;
list_add_tail(&evsel->node, &head);
@@ -251,12 +236,13 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
int perf_evlist__add_newtp(struct perf_evlist *evlist,
const char *sys, const char *name, void *handler)
{
- struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
+ struct perf_evsel *evsel;
+ evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
if (evsel == NULL)
return -1;
- evsel->handler = handler;
+ evsel->handler.func = handler;
perf_evlist__add(evlist, evsel);
return 0;
}
@@ -541,7 +527,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
if ((old & md->mask) + size != ((old + size) & md->mask)) {
unsigned int offset = old;
unsigned int len = min(sizeof(*event), size), cpy;
- void *dst = md->event_copy;
+ void *dst = &md->event_copy;
do {
cpy = min(md->mask + 1 - (offset & md->mask), len);
@@ -551,7 +537,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
len -= cpy;
} while (len);
- event = (union perf_event *) md->event_copy;
+ event = &md->event_copy;
}
old += size;
@@ -608,8 +594,6 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
MAP_SHARED, fd, 0);
if (evlist->mmap[idx].base == MAP_FAILED) {
- pr_debug2("failed to mmap perf event ring buffer, error %d\n",
- errno);
evlist->mmap[idx].base = NULL;
return -1;
}
@@ -618,36 +602,9 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist,
return 0;
}
-static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
- int prot, int mask, int cpu, int thread,
- int *output)
+static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
{
struct perf_evsel *evsel;
-
- list_for_each_entry(evsel, &evlist->entries, node) {
- int fd = FD(evsel, cpu, thread);
-
- if (*output == -1) {
- *output = fd;
- if (__perf_evlist__mmap(evlist, idx, prot, mask,
- *output) < 0)
- return -1;
- } else {
- if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
- return -1;
- }
-
- if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
- perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
- return -1;
- }
-
- return 0;
-}
-
-static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
- int mask)
-{
int cpu, thread;
int nr_cpus = cpu_map__nr(evlist->cpus);
int nr_threads = thread_map__nr(evlist->threads);
@@ -657,9 +614,23 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot,
int output = -1;
for (thread = 0; thread < nr_threads; thread++) {
- if (perf_evlist__mmap_per_evsel(evlist, cpu, prot, mask,
- cpu, thread, &output))
- goto out_unmap;
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ int fd = FD(evsel, cpu, thread);
+
+ if (output == -1) {
+ output = fd;
+ if (__perf_evlist__mmap(evlist, cpu,
+ prot, mask, output) < 0)
+ goto out_unmap;
+ } else {
+ if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
+ goto out_unmap;
+ }
+
+ if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
+ perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
+ goto out_unmap;
+ }
}
}
@@ -671,9 +642,9 @@ out_unmap:
return -1;
}
-static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
- int mask)
+static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
{
+ struct perf_evsel *evsel;
int thread;
int nr_threads = thread_map__nr(evlist->threads);
@@ -681,9 +652,23 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot,
for (thread = 0; thread < nr_threads; thread++) {
int output = -1;
- if (perf_evlist__mmap_per_evsel(evlist, thread, prot, mask, 0,
- thread, &output))
- goto out_unmap;
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ int fd = FD(evsel, 0, thread);
+
+ if (output == -1) {
+ output = fd;
+ if (__perf_evlist__mmap(evlist, thread,
+ prot, mask, output) < 0)
+ goto out_unmap;
+ } else {
+ if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
+ goto out_unmap;
+ }
+
+ if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
+ perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
+ goto out_unmap;
+ }
}
return 0;
@@ -694,90 +679,20 @@ out_unmap:
return -1;
}
-static size_t perf_evlist__mmap_size(unsigned long pages)
-{
- /* 512 kiB: default amount of unprivileged mlocked memory */
- if (pages == UINT_MAX)
- pages = (512 * 1024) / page_size;
- else if (!is_power_of_2(pages))
- return 0;
-
- return (pages + 1) * page_size;
-}
-
-static long parse_pages_arg(const char *str, unsigned long min,
- unsigned long max)
-{
- unsigned long pages, val;
- static struct parse_tag tags[] = {
- { .tag = 'B', .mult = 1 },
- { .tag = 'K', .mult = 1 << 10 },
- { .tag = 'M', .mult = 1 << 20 },
- { .tag = 'G', .mult = 1 << 30 },
- { .tag = 0 },
- };
-
- if (str == NULL)
- return -EINVAL;
-
- val = parse_tag_value(str, tags);
- if (val != (unsigned long) -1) {
- /* we got file size value */
- pages = PERF_ALIGN(val, page_size) / page_size;
- } else {
- /* we got pages count value */
- char *eptr;
- pages = strtoul(str, &eptr, 10);
- if (*eptr != '\0')
- return -EINVAL;
- }
-
- if ((pages == 0) && (min == 0)) {
- /* leave number of pages at 0 */
- } else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
- /* round pages up to next power of 2 */
- pages = next_pow2(pages);
- pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
- pages * page_size, pages);
- }
-
- if (pages > max)
- return -EINVAL;
-
- return pages;
-}
-
-int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
- int unset __maybe_unused)
-{
- unsigned int *mmap_pages = opt->value;
- unsigned long max = UINT_MAX;
- long pages;
-
- if (max < SIZE_MAX / page_size)
- max = SIZE_MAX / page_size;
-
- pages = parse_pages_arg(str, 1, max);
- if (pages < 0) {
- pr_err("Invalid argument for --mmap_pages/-m\n");
- return -1;
- }
-
- *mmap_pages = pages;
- return 0;
-}
-
-/**
- * perf_evlist__mmap - Create mmaps to receive events.
- * @evlist: list of events
- * @pages: map length in pages
- * @overwrite: overwrite older events?
+/** perf_evlist__mmap - Create per cpu maps to receive events
+ *
+ * @evlist - list of events
+ * @pages - map length in pages
+ * @overwrite - overwrite older events?
*
- * If @overwrite is %false the user needs to signal event consumption using
- * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this
- * automatically.
+ * If overwrite is false the user needs to signal event consuption using:
*
- * Return: %0 on success, negative error code otherwise.
+ * struct perf_mmap *m = &evlist->mmap[cpu];
+ * unsigned int head = perf_mmap__read_head(m);
+ *
+ * perf_mmap__write_tail(m, head)
+ *
+ * Using perf_evlist__read_on_cpu does this automatically.
*/
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
bool overwrite)
@@ -787,6 +702,14 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
const struct thread_map *threads = evlist->threads;
int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
+ /* 512 kiB: default amount of unprivileged mlocked memory */
+ if (pages == UINT_MAX)
+ pages = (512 * 1024) / page_size;
+ else if (!is_power_of_2(pages))
+ return -EINVAL;
+
+ mask = pages * page_size - 1;
+
if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
return -ENOMEM;
@@ -794,9 +717,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
return -ENOMEM;
evlist->overwrite = overwrite;
- evlist->mmap_len = perf_evlist__mmap_size(pages);
- pr_debug("mmap size %zuB\n", evlist->mmap_len);
- mask = evlist->mmap_len - page_size - 1;
+ evlist->mmap_len = (pages + 1) * page_size;
list_for_each_entry(evsel, &evlist->entries, node) {
if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
@@ -811,7 +732,8 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
return perf_evlist__mmap_per_cpu(evlist, prot, mask);
}
-int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
+int perf_evlist__create_maps(struct perf_evlist *evlist,
+ struct perf_target *target)
{
evlist->threads = thread_map__new_str(target->pid, target->tid,
target->uid);
@@ -819,11 +741,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
if (evlist->threads == NULL)
return -1;
- if (target->force_per_cpu)
- evlist->cpus = cpu_map__new(target->cpu_list);
- else if (target__has_task(target))
+ if (perf_target__has_task(target))
evlist->cpus = cpu_map__dummy_new();
- else if (!target__has_cpu(target) && !target->uses_mmap)
+ else if (!perf_target__has_cpu(target) && !target->uses_mmap)
evlist->cpus = cpu_map__dummy_new();
else
evlist->cpus = cpu_map__new(target->cpu_list);
@@ -1032,7 +952,8 @@ out_err:
return err;
}
-int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
+int perf_evlist__prepare_workload(struct perf_evlist *evlist,
+ struct perf_target *target,
const char *argv[], bool pipe_output,
bool want_signal)
{
@@ -1084,7 +1005,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar
exit(-1);
}
- if (target__none(target))
+ if (perf_target__none(target))
evlist->threads->map[0] = evlist->workload.pid;
close(child_ready_pipe[1]);
@@ -1150,68 +1071,5 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
perf_evsel__name(evsel));
}
- return printed + fprintf(fp, "\n");
-}
-
-int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
- int err, char *buf, size_t size)
-{
- char sbuf[128];
-
- switch (err) {
- case ENOENT:
- scnprintf(buf, size, "%s",
- "Error:\tUnable to find debugfs\n"
- "Hint:\tWas your kernel was compiled with debugfs support?\n"
- "Hint:\tIs the debugfs filesystem mounted?\n"
- "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
- break;
- case EACCES:
- scnprintf(buf, size,
- "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n"
- "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
- debugfs_mountpoint, debugfs_mountpoint);
- break;
- default:
- scnprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
- break;
- }
-
- return 0;
-}
-
-int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
- int err, char *buf, size_t size)
-{
- int printed, value;
- char sbuf[128], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
-
- switch (err) {
- case EACCES:
- case EPERM:
- printed = scnprintf(buf, size,
- "Error:\t%s.\n"
- "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
-
- if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value))
- break;
-
- printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
-
- if (value >= 2) {
- printed += scnprintf(buf + printed, size - printed,
- "For your workloads it needs to be <= 1\nHint:\t");
- }
- printed += scnprintf(buf + printed, size - printed,
- "For system wide tracing it needs to be set to -1");
-
- printed += scnprintf(buf + printed, size - printed,
- ".\nHint:\tThe current value is %d.", value);
- break;
- default:
- scnprintf(buf, size, "%s", emsg);
- break;
- }
-
- return 0;
+ return printed + fprintf(fp, "\n");;
}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 649d6ea..206d093 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -21,7 +21,7 @@ struct perf_mmap {
void *base;
int mask;
unsigned int prev;
- char event_copy[PERF_SAMPLE_MAX_SIZE];
+ union perf_event event_copy;
};
struct perf_evlist {
@@ -31,7 +31,7 @@ struct perf_evlist {
int nr_groups;
int nr_fds;
int nr_mmaps;
- size_t mmap_len;
+ int mmap_len;
int id_pos;
int is_pos;
u64 combined_sample_type;
@@ -53,7 +53,6 @@ struct perf_evsel_str_handler {
};
struct perf_evlist *perf_evlist__new(void);
-struct perf_evlist *perf_evlist__new_default(void);
void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
struct thread_map *threads);
void perf_evlist__exit(struct perf_evlist *evlist);
@@ -88,7 +87,7 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
-union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
+union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
@@ -99,18 +98,13 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist);
bool perf_can_sample_identifier(void);
void perf_evlist__config(struct perf_evlist *evlist,
struct perf_record_opts *opts);
-int perf_record_opts__config(struct perf_record_opts *opts);
int perf_evlist__prepare_workload(struct perf_evlist *evlist,
- struct target *target,
+ struct perf_target *target,
const char *argv[], bool pipe_output,
bool want_signal);
int perf_evlist__start_workload(struct perf_evlist *evlist);
-int perf_evlist__parse_mmap_pages(const struct option *opt,
- const char *str,
- int unset);
-
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
bool overwrite);
void perf_evlist__munmap(struct perf_evlist *evlist);
@@ -134,7 +128,8 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
evlist->threads = threads;
}
-int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target);
+int perf_evlist__create_maps(struct perf_evlist *evlist,
+ struct perf_target *target);
void perf_evlist__delete_maps(struct perf_evlist *evlist);
int perf_evlist__apply_filters(struct perf_evlist *evlist);
@@ -170,13 +165,10 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist)
size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp);
-int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size);
-int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size);
-
static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm)
{
struct perf_event_mmap_page *pc = mm->base;
- int head = ACCESS_ONCE(pc->data_head);
+ int head = pc->data_head;
rmb();
return head;
}
@@ -189,7 +181,7 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
/*
* ensure all reads are done before we write the tail out.
*/
- mb();
+ /* mb(); */
pc->data_tail = tail;
}
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 46dd4c2..9f1ef9b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -168,7 +168,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
perf_evsel__calc_id_pos(evsel);
}
-struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
+struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
{
struct perf_evsel *evsel = zalloc(sizeof(*evsel));
@@ -219,7 +219,7 @@ out:
return format;
}
-struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
+struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
{
struct perf_evsel *evsel = zalloc(sizeof(*evsel));
@@ -645,7 +645,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
}
}
- if (target__has_cpu(&opts->target) || opts->target.force_per_cpu)
+ if (perf_target__has_cpu(&opts->target))
perf_evsel__set_sample_bit(evsel, CPU);
if (opts->period)
@@ -653,7 +653,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
if (!perf_missing_features.sample_id_all &&
(opts->sample_time || !opts->no_inherit ||
- target__has_cpu(&opts->target) || opts->target.force_per_cpu))
+ perf_target__has_cpu(&opts->target)))
perf_evsel__set_sample_bit(evsel, TIME);
if (opts->raw_samples) {
@@ -663,7 +663,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
}
if (opts->sample_address)
- perf_evsel__set_sample_bit(evsel, DATA_SRC);
+ attr->sample_type |= PERF_SAMPLE_DATA_SRC;
if (opts->no_delay) {
attr->watermark = 0;
@@ -675,14 +675,11 @@ void perf_evsel__config(struct perf_evsel *evsel,
}
if (opts->sample_weight)
- perf_evsel__set_sample_bit(evsel, WEIGHT);
+ attr->sample_type |= PERF_SAMPLE_WEIGHT;
attr->mmap = track;
attr->comm = track;
- if (opts->sample_transaction)
- perf_evsel__set_sample_bit(evsel, TRANSACTION);
-
/*
* XXX see the function comment above
*
@@ -696,7 +693,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
* Setting enable_on_exec for independent events and
* group leaders for traced executed by perf.
*/
- if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
+ if (perf_target__none(&opts->target) && perf_evsel__is_group_leader(evsel))
attr->enable_on_exec = 1;
}
@@ -985,7 +982,6 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
ret += PRINT_ATTR2(exclude_host, exclude_guest);
ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
"excl.callchain_user", exclude_callchain_user);
- ret += PRINT_ATTR_U32(mmap2);
ret += PRINT_ATTR_U32(wakeup_events);
ret += PRINT_ATTR_U32(wakeup_watermark);
@@ -1051,8 +1047,6 @@ retry_open:
group_fd, flags);
if (FD(evsel, cpu, thread) < 0) {
err = -errno;
- pr_debug2("perf_event_open failed, error %d\n",
- err);
goto try_fallback;
}
set_rlimit = NO_CHANGE;
@@ -1219,7 +1213,6 @@ static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,
sample->pid = u.val32[0];
sample->tid = u.val32[1];
- array--;
}
return 0;
@@ -1459,9 +1452,6 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
array = (void *)array + sz;
OVERFLOW_CHECK_u64(array);
data->user_stack.size = *array++;
- if (WARN_ONCE(data->user_stack.size > sz,
- "user stack dump failure\n"))
- return -EFAULT;
}
}
@@ -1479,13 +1469,6 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
array++;
}
- data->transaction = 0;
- if (type & PERF_SAMPLE_TRANSACTION) {
- OVERFLOW_CHECK_u64(array);
- data->transaction = *array;
- array++;
- }
-
return 0;
}
@@ -1578,9 +1561,6 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
if (type & PERF_SAMPLE_DATA_SRC)
result += sizeof(u64);
- if (type & PERF_SAMPLE_TRANSACTION)
- result += sizeof(u64);
-
return result;
}
@@ -1754,11 +1734,6 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
array++;
}
- if (type & PERF_SAMPLE_TRANSACTION) {
- *array = sample->transaction;
- array++;
- }
-
return 0;
}
@@ -2006,7 +1981,8 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
return false;
}
-int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel,
+ struct perf_target *target,
int err, char *msg, size_t size)
{
switch (err) {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 1ea7c92..4a7bdc7 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -74,7 +74,10 @@ struct perf_evsel {
off_t id_offset;
};
struct cgroup_sel *cgrp;
- void *handler;
+ struct {
+ void *func;
+ void *data;
+ } handler;
struct cpu_map *cpus;
unsigned int sample_size;
int id_pos;
@@ -96,19 +99,8 @@ struct thread_map;
struct perf_evlist;
struct perf_record_opts;
-struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);
-
-static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
-{
- return perf_evsel__new_idx(attr, 0);
-}
-
-struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx);
-
-static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name)
-{
- return perf_evsel__newtp_idx(sys, name, 0);
-}
+struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
+struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx);
struct event_format *event_format__new(const char *sys, const char *name);
@@ -205,12 +197,6 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
(e1->attr.config == e2->attr.config);
}
-#define perf_evsel__cmp(a, b) \
- ((a) && \
- (b) && \
- (a)->attr.type == (b)->attr.type && \
- (a)->attr.config == (b)->attr.config)
-
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
int cpu, int thread, bool scale);
@@ -279,11 +265,6 @@ static inline struct perf_evsel *perf_evsel__next(struct perf_evsel *evsel)
return list_entry(evsel->node.next, struct perf_evsel, node);
}
-static inline struct perf_evsel *perf_evsel__prev(struct perf_evsel *evsel)
-{
- return list_entry(evsel->node.prev, struct perf_evsel, node);
-}
-
/**
* perf_evsel__is_group_leader - Return whether given evsel is a leader event
*
@@ -323,7 +304,8 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
char *msg, size_t msgsize);
-int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
+int perf_evsel__open_strerror(struct perf_evsel *evsel,
+ struct perf_target *target,
int err, char *msg, size_t size);
static inline int perf_evsel__group_idx(struct perf_evsel *evsel)
diff --git a/tools/perf/util/fs.c b/tools/perf/util/fs.c
deleted file mode 100644
index f5be1f2..0000000
--- a/tools/perf/util/fs.c
+++ /dev/null
@@ -1,119 +0,0 @@
-
-/* TODO merge/factor into tools/lib/lk/debugfs.c */
-
-#include "util.h"
-#include "util/fs.h"
-
-static const char * const sysfs__fs_known_mountpoints[] = {
- "/sys",
- 0,
-};
-
-static const char * const procfs__known_mountpoints[] = {
- "/proc",
- 0,
-};
-
-struct fs {
- const char *name;
- const char * const *mounts;
- char path[PATH_MAX + 1];
- bool found;
- long magic;
-};
-
-enum {
- FS__SYSFS = 0,
- FS__PROCFS = 1,
-};
-
-static struct fs fs__entries[] = {
- [FS__SYSFS] = {
- .name = "sysfs",
- .mounts = sysfs__fs_known_mountpoints,
- .magic = SYSFS_MAGIC,
- },
- [FS__PROCFS] = {
- .name = "proc",
- .mounts = procfs__known_mountpoints,
- .magic = PROC_SUPER_MAGIC,
- },
-};
-
-static bool fs__read_mounts(struct fs *fs)
-{
- bool found = false;
- char type[100];
- FILE *fp;
-
- fp = fopen("/proc/mounts", "r");
- if (fp == NULL)
- return NULL;
-
- while (!found &&
- fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
- fs->path, type) == 2) {
-
- if (strcmp(type, fs->name) == 0)
- found = true;
- }
-
- fclose(fp);
- return fs->found = found;
-}
-
-static int fs__valid_mount(const char *fs, long magic)
-{
- struct statfs st_fs;
-
- if (statfs(fs, &st_fs) < 0)
- return -ENOENT;
- else if (st_fs.f_type != magic)
- return -ENOENT;
-
- return 0;
-}
-
-static bool fs__check_mounts(struct fs *fs)
-{
- const char * const *ptr;
-
- ptr = fs->mounts;
- while (*ptr) {
- if (fs__valid_mount(*ptr, fs->magic) == 0) {
- fs->found = true;
- strcpy(fs->path, *ptr);
- return true;
- }
- ptr++;
- }
-
- return false;
-}
-
-static const char *fs__get_mountpoint(struct fs *fs)
-{
- if (fs__check_mounts(fs))
- return fs->path;
-
- return fs__read_mounts(fs) ? fs->path : NULL;
-}
-
-static const char *fs__mountpoint(int idx)
-{
- struct fs *fs = &fs__entries[idx];
-
- if (fs->found)
- return (const char *)fs->path;
-
- return fs__get_mountpoint(fs);
-}
-
-#define FS__MOUNTPOINT(name, idx) \
-const char *name##__mountpoint(void) \
-{ \
- return fs__mountpoint(idx); \
-}
-
-FS__MOUNTPOINT(sysfs, FS__SYSFS);
-FS__MOUNTPOINT(procfs, FS__PROCFS);
diff --git a/tools/perf/util/fs.h b/tools/perf/util/fs.h
deleted file mode 100644
index 5e09ce1..0000000
--- a/tools/perf/util/fs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __PERF_FS
-#define __PERF_FS
-
-const char *sysfs__mountpoint(void);
-const char *procfs__mountpoint(void);
-
-#endif /* __PERF_FS */
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 36a885d..3ac3803 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -22,7 +22,7 @@ do
}' "Documentation/perf-$cmd.txt"
done
-echo "#ifdef HAVE_LIBELF_SUPPORT"
+echo "#ifdef LIBELF_SUPPORT"
sed -n -e 's/^perf-\([^ ]*\)[ ].* full.*/\1/p' command-list.txt |
sort |
while read cmd
@@ -35,5 +35,5 @@ do
p
}' "Documentation/perf-$cmd.txt"
done
-echo "#endif /* HAVE_LIBELF_SUPPORT */"
+echo "#endif /* LIBELF_SUPPORT */"
echo "};"
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 1cd0357..c3e5a3b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -22,7 +22,6 @@
#include "vdso.h"
#include "strbuf.h"
#include "build-id.h"
-#include "data.h"
static bool no_buildid_cache = false;
@@ -2078,10 +2077,8 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
if (evsel->idx == (int) desc[i].leader_idx) {
evsel->leader = evsel;
/* {anon_group} is a dummy name */
- if (strcmp(desc[i].name, "{anon_group}")) {
+ if (strcmp(desc[i].name, "{anon_group}"))
evsel->group_name = desc[i].name;
- desc[i].name = NULL;
- }
evsel->nr_members = desc[i].nr_members;
if (i >= nr_groups || nr > 0) {
@@ -2107,7 +2104,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
ret = 0;
out_free:
- for (i = 0; i < nr_groups; i++)
+ while ((int) --i >= 0)
free(desc[i].name);
free(desc);
@@ -2192,7 +2189,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
{
struct header_print_data hd;
struct perf_header *header = &session->header;
- int fd = perf_data_file__fd(session->file);
+ int fd = session->fd;
hd.fp = fp;
hd.full = full;
@@ -2653,8 +2650,7 @@ static int perf_header__read_pipe(struct perf_session *session)
struct perf_header *header = &session->header;
struct perf_pipe_file_header f_header;
- if (perf_file_header__read_pipe(&f_header, header,
- perf_data_file__fd(session->file),
+ if (perf_file_header__read_pipe(&f_header, header, session->fd,
session->repipe) < 0) {
pr_debug("incompatible file format\n");
return -EINVAL;
@@ -2755,19 +2751,18 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
int perf_session__read_header(struct perf_session *session)
{
- struct perf_data_file *file = session->file;
struct perf_header *header = &session->header;
struct perf_file_header f_header;
struct perf_file_attr f_attr;
u64 f_id;
int nr_attrs, nr_ids, i, j;
- int fd = perf_data_file__fd(file);
+ int fd = session->fd;
session->evlist = perf_evlist__new();
if (session->evlist == NULL)
return -ENOMEM;
- if (perf_data_file__is_pipe(file))
+ if (session->fd_pipe)
return perf_header__read_pipe(session);
if (perf_file_header__read(&f_header, header, fd) < 0)
@@ -2782,7 +2777,7 @@ int perf_session__read_header(struct perf_session *session)
if (f_header.data.size == 0) {
pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
"Was the 'perf record' command properly terminated?\n",
- file->path);
+ session->filename);
}
nr_attrs = f_header.attrs.size / f_header.attr_size;
@@ -2799,7 +2794,7 @@ int perf_session__read_header(struct perf_session *session)
perf_event__attr_swap(&f_attr.attr);
tmp = lseek(fd, 0, SEEK_CUR);
- evsel = perf_evsel__new(&f_attr.attr);
+ evsel = perf_evsel__new(&f_attr.attr, i);
if (evsel == NULL)
goto out_delete_evlist;
@@ -2918,7 +2913,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
return -ENOMEM;
}
- evsel = perf_evsel__new(&event->attr.attr);
+ evsel = perf_evsel__new(&event->attr.attr, evlist->nr_entries);
if (evsel == NULL)
return -ENOMEM;
@@ -2995,19 +2990,18 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
struct perf_session *session)
{
ssize_t size_read, padding, size = event->tracing_data.size;
- int fd = perf_data_file__fd(session->file);
- off_t offset = lseek(fd, 0, SEEK_CUR);
+ off_t offset = lseek(session->fd, 0, SEEK_CUR);
char buf[BUFSIZ];
/* setup for reading amidst mmap */
- lseek(fd, offset + sizeof(struct tracing_data_event),
+ lseek(session->fd, offset + sizeof(struct tracing_data_event),
SEEK_SET);
- size_read = trace_report(fd, &session->pevent,
+ size_read = trace_report(session->fd, &session->pevent,
session->repipe);
padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
- if (readn(fd, buf, padding) < 0) {
+ if (readn(session->fd, buf, padding) < 0) {
pr_err("%s: reading input file", __func__);
return -1;
}
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 822903e..9ff6cf3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -160,10 +160,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
-
- if (h->transaction)
- hists__new_col_len(hists, HISTC_TRANSACTION,
- hist_entry__transaction_len());
}
void hists__output_recalc_col_len(struct hists *hists, int max_rows)
@@ -350,7 +346,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
struct rb_node **p;
struct rb_node *parent = NULL;
struct hist_entry *he;
- int64_t cmp;
+ int cmp;
p = &hists->entries_in->rb_node;
@@ -399,7 +395,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
if (!he)
return NULL;
- hists->nr_entries++;
rb_link_node(&he->rb_node_in, parent, p);
rb_insert_color(&he->rb_node_in, hists->entries_in);
out:
@@ -407,37 +402,94 @@ out:
return he;
}
-struct hist_entry *__hists__add_entry(struct hists *hists,
- struct addr_location *al,
- struct symbol *sym_parent,
- struct branch_info *bi,
- struct mem_info *mi,
- u64 period, u64 weight, u64 transaction)
+struct hist_entry *__hists__add_mem_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent,
+ struct mem_info *mi,
+ u64 period,
+ u64 weight)
{
struct hist_entry entry = {
.thread = al->thread,
- .comm = thread__comm(al->thread),
.ms = {
.map = al->map,
.sym = al->sym,
},
+ .stat = {
+ .period = period,
+ .weight = weight,
+ .nr_events = 1,
+ },
.cpu = al->cpu,
.ip = al->addr,
.level = al->level,
+ .parent = sym_parent,
+ .filtered = symbol__parent_filter(sym_parent),
+ .hists = self,
+ .mem_info = mi,
+ .branch_info = NULL,
+ };
+ return add_hist_entry(self, &entry, al, period, weight);
+}
+
+struct hist_entry *__hists__add_branch_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent,
+ struct branch_info *bi,
+ u64 period,
+ u64 weight)
+{
+ struct hist_entry entry = {
+ .thread = al->thread,
+ .ms = {
+ .map = bi->to.map,
+ .sym = bi->to.sym,
+ },
+ .cpu = al->cpu,
+ .ip = bi->to.addr,
+ .level = al->level,
.stat = {
- .nr_events = 1,
.period = period,
+ .nr_events = 1,
.weight = weight,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
- .hists = hists,
.branch_info = bi,
- .mem_info = mi,
- .transaction = transaction,
+ .hists = self,
+ .mem_info = NULL,
};
- return add_hist_entry(hists, &entry, al, period, weight);
+ return add_hist_entry(self, &entry, al, period, weight);
+}
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent, u64 period,
+ u64 weight)
+{
+ struct hist_entry entry = {
+ .thread = al->thread,
+ .ms = {
+ .map = al->map,
+ .sym = al->sym,
+ },
+ .cpu = al->cpu,
+ .ip = al->addr,
+ .level = al->level,
+ .stat = {
+ .period = period,
+ .nr_events = 1,
+ .weight = weight,
+ },
+ .parent = sym_parent,
+ .filtered = symbol__parent_filter(sym_parent),
+ .hists = self,
+ .branch_info = NULL,
+ .mem_info = NULL,
+ };
+
+ return add_hist_entry(self, &entry, al, period, weight);
}
int64_t
@@ -478,7 +530,6 @@ void hist_entry__free(struct hist_entry *he)
{
free(he->branch_info);
free(he->mem_info);
- free_srcline(he->srcline);
free(he);
}
@@ -547,7 +598,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
hists__filter_entry_by_symbol(hists, he);
}
-void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
+void hists__collapse_resort(struct hists *hists)
{
struct rb_root *root;
struct rb_node *next;
@@ -574,8 +625,6 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
*/
hists__apply_filters(hists, n);
}
- if (prog)
- ui_progress__update(prog, 1);
}
}
@@ -835,7 +884,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
struct rb_node **p;
struct rb_node *parent = NULL;
struct hist_entry *he;
- int64_t cmp;
+ int cmp;
if (sort__need_collapse)
root = &hists->entries_collapsed;
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index b621347a..ce8dc61 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -6,7 +6,6 @@
#include "callchain.h"
#include "header.h"
#include "color.h"
-#include "ui/progress.h"
extern struct callchain_param callchain_param;
@@ -47,8 +46,6 @@ enum hist_column {
HISTC_CPU,
HISTC_SRCLINE,
HISTC_MISPREDICT,
- HISTC_IN_TX,
- HISTC_ABORT,
HISTC_SYMBOL_FROM,
HISTC_SYMBOL_TO,
HISTC_DSO_FROM,
@@ -61,7 +58,6 @@ enum hist_column {
HISTC_MEM_TLB,
HISTC_MEM_LVL,
HISTC_MEM_SNOOP,
- HISTC_TRANSACTION,
HISTC_NR_COLS, /* Last entry */
};
@@ -84,43 +80,54 @@ struct hists {
u16 col_len[HISTC_NR_COLS];
};
-struct hist_entry *__hists__add_entry(struct hists *hists,
+struct hist_entry *__hists__add_entry(struct hists *self,
struct addr_location *al,
- struct symbol *parent,
- struct branch_info *bi,
- struct mem_info *mi, u64 period,
- u64 weight, u64 transaction);
+ struct symbol *parent, u64 period,
+ u64 weight);
int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
-int hist_entry__transaction_len(void);
-int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
+int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
struct hists *hists);
void hist_entry__free(struct hist_entry *);
-void hists__output_resort(struct hists *hists);
-void hists__collapse_resort(struct hists *hists, struct ui_progress *prog);
+struct hist_entry *__hists__add_branch_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent,
+ struct branch_info *bi,
+ u64 period,
+ u64 weight);
+
+struct hist_entry *__hists__add_mem_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent,
+ struct mem_info *mi,
+ u64 period,
+ u64 weight);
+
+void hists__output_resort(struct hists *self);
+void hists__collapse_resort(struct hists *self);
void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
void hists__output_recalc_col_len(struct hists *hists, int max_rows);
void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
-void hists__inc_nr_events(struct hists *hists, u32 type);
+void hists__inc_nr_events(struct hists *self, u32 type);
void events_stats__inc(struct events_stats *stats, u32 type);
size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
-size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
+size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
int max_cols, float min_pcnt, FILE *fp);
-int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);
-int hist_entry__annotate(struct hist_entry *he, size_t privsize);
+int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
+int hist_entry__annotate(struct hist_entry *self, size_t privsize);
void hists__filter_by_dso(struct hists *hists);
void hists__filter_by_thread(struct hists *hists);
void hists__filter_by_symbol(struct hists *hists);
-u16 hists__col_len(struct hists *hists, enum hist_column col);
-void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len);
-bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len);
+u16 hists__col_len(struct hists *self, enum hist_column col);
+void hists__set_col_len(struct hists *self, enum hist_column col, u16 len);
+bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
void hists__reset_col_len(struct hists *hists);
void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
@@ -189,7 +196,7 @@ struct hist_browser_timer {
int refresh;
};
-#ifdef HAVE_SLANG_SUPPORT
+#ifdef SLANG_SUPPORT
#include "../ui/keysyms.h"
int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
@@ -210,9 +217,12 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
return 0;
}
-static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused,
- struct perf_evsel *evsel __maybe_unused,
- struct hist_browser_timer *hbt __maybe_unused)
+static inline int hist_entry__tui_annotate(struct hist_entry *self
+ __maybe_unused,
+ struct perf_evsel *evsel
+ __maybe_unused,
+ struct hist_browser_timer *hbt
+ __maybe_unused)
{
return 0;
}
@@ -227,5 +237,20 @@ static inline int script_browse(const char *script_opt __maybe_unused)
#define K_SWITCH_INPUT_DATA -3000
#endif
-unsigned int hists__sort_list_width(struct hists *hists);
+#ifdef GTK2_SUPPORT
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+ struct hist_browser_timer *hbt __maybe_unused,
+ float min_pcnt);
+#else
+static inline
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
+ const char *help __maybe_unused,
+ struct hist_browser_timer *hbt __maybe_unused,
+ float min_pcnt __maybe_unused)
+{
+ return 0;
+}
+#endif
+
+unsigned int hists__sort_list_width(struct hists *self);
#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 8f14965..cf6727e 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -1,7 +1,7 @@
#ifndef _PERF_DWARF_REGS_H_
#define _PERF_DWARF_REGS_H_
-#ifdef HAVE_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
const char *get_arch_regstr(unsigned int n);
#endif
diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h
index b003ad7..96b919d 100644
--- a/tools/perf/util/include/linux/compiler.h
+++ b/tools/perf/util/include/linux/compiler.h
@@ -2,29 +2,20 @@
#define _PERF_LINUX_COMPILER_H_
#ifndef __always_inline
-# define __always_inline inline __attribute__((always_inline))
+#define __always_inline inline
#endif
-
#define __user
-
#ifndef __attribute_const__
-# define __attribute_const__
+#define __attribute_const__
#endif
#ifndef __maybe_unused
-# define __maybe_unused __attribute__((unused))
-#endif
-
-#ifndef __packed
-# define __packed __attribute__((__packed__))
+#define __maybe_unused __attribute__((unused))
#endif
+#define __packed __attribute__((__packed__))
#ifndef __force
-# define __force
-#endif
-
-#ifndef __weak
-# define __weak __attribute__((weak))
+#define __force
#endif
#endif
diff --git a/tools/perf/util/include/linux/magic.h b/tools/perf/util/include/linux/magic.h
index 07d63cf..58b64ed 100644
--- a/tools/perf/util/include/linux/magic.h
+++ b/tools/perf/util/include/linux/magic.h
@@ -9,8 +9,4 @@
#define SYSFS_MAGIC 0x62656572
#endif
-#ifndef PROC_SUPER_MAGIC
-#define PROC_SUPER_MAGIC 0x9fa0
-#endif
-
#endif
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index 89715b6..11a8d86 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -20,7 +20,6 @@ static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
if (node != NULL) {
node->i = i;
- node->priv = NULL;
rc = &node->rb_node;
}
@@ -58,36 +57,22 @@ void intlist__remove(struct intlist *ilist, struct int_node *node)
rblist__remove_node(&ilist->rblist, &node->rb_node);
}
-static struct int_node *__intlist__findnew(struct intlist *ilist,
- int i, bool create)
+struct int_node *intlist__find(struct intlist *ilist, int i)
{
- struct int_node *node = NULL;
+ struct int_node *node;
struct rb_node *rb_node;
if (ilist == NULL)
return NULL;
- if (create)
- rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
- else
- rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
-
+ node = NULL;
+ rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
if (rb_node)
node = container_of(rb_node, struct int_node, rb_node);
return node;
}
-struct int_node *intlist__find(struct intlist *ilist, int i)
-{
- return __intlist__findnew(ilist, i, false);
-}
-
-struct int_node *intlist__findnew(struct intlist *ilist, int i)
-{
- return __intlist__findnew(ilist, i, true);
-}
-
static int intlist__parse_list(struct intlist *ilist, const char *s)
{
char *sep;
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
index aa6877d..62351da 100644
--- a/tools/perf/util/intlist.h
+++ b/tools/perf/util/intlist.h
@@ -9,7 +9,6 @@
struct int_node {
struct rb_node rb_node;
int i;
- void *priv;
};
struct intlist {
@@ -24,7 +23,6 @@ int intlist__add(struct intlist *ilist, int i);
struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
struct int_node *intlist__find(struct intlist *ilist, int i);
-struct int_node *intlist__findnew(struct intlist *ilist, int i);
static inline bool intlist__has_entry(struct intlist *ilist, int i)
{
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 84cdb07..6188d28 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -40,29 +40,12 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
return -ENOMEM;
snprintf(comm, sizeof(comm), "[guest/%d]", pid);
- thread__set_comm(thread, comm, 0);
+ thread__set_comm(thread, comm);
}
return 0;
}
-struct machine *machine__new_host(void)
-{
- struct machine *machine = malloc(sizeof(*machine));
-
- if (machine != NULL) {
- machine__init(machine, "", HOST_KERNEL_ID);
-
- if (machine__create_kernel_maps(machine) < 0)
- goto out_delete;
- }
-
- return machine;
-out_delete:
- free(machine);
- return NULL;
-}
-
static void dsos__delete(struct list_head *dsos)
{
struct dso *pos, *n;
@@ -331,8 +314,7 @@ struct thread *machine__find_thread(struct machine *machine, pid_t tid)
return __machine__findnew_thread(machine, 0, tid, false);
}
-int machine__process_comm_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample)
+int machine__process_comm_event(struct machine *machine, union perf_event *event)
{
struct thread *thread = machine__findnew_thread(machine,
event->comm.pid,
@@ -341,7 +323,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
if (dump_trace)
perf_event__fprintf_comm(event, stdout);
- if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) {
+ if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
return -1;
}
@@ -350,7 +332,7 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event
}
int machine__process_lost_event(struct machine *machine __maybe_unused,
- union perf_event *event, struct perf_sample *sample __maybe_unused)
+ union perf_event *event)
{
dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
event->lost.id, event->lost.lost);
@@ -794,44 +776,75 @@ static int machine__set_modules_path(struct machine *machine)
return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
}
-static int machine__create_module(void *arg, const char *name, u64 start)
-{
- struct machine *machine = arg;
- struct map *map;
-
- map = machine__new_module(machine, start, name);
- if (map == NULL)
- return -1;
-
- dso__kernel_module_get_build_id(map->dso, machine->root_dir);
-
- return 0;
-}
-
static int machine__create_modules(struct machine *machine)
{
+ char *line = NULL;
+ size_t n;
+ FILE *file;
+ struct map *map;
const char *modules;
char path[PATH_MAX];
- if (machine__is_default_guest(machine)) {
+ if (machine__is_default_guest(machine))
modules = symbol_conf.default_guest_modules;
- } else {
- snprintf(path, PATH_MAX, "%s/proc/modules", machine->root_dir);
+ else {
+ sprintf(path, "%s/proc/modules", machine->root_dir);
modules = path;
}
if (symbol__restricted_filename(modules, "/proc/modules"))
return -1;
- if (modules__parse(modules, machine, machine__create_module))
+ file = fopen(modules, "r");
+ if (file == NULL)
return -1;
- if (!machine__set_modules_path(machine))
- return 0;
+ while (!feof(file)) {
+ char name[PATH_MAX];
+ u64 start;
+ char *sep;
+ int line_len;
+
+ line_len = getline(&line, &n, file);
+ if (line_len < 0)
+ break;
+
+ if (!line)
+ goto out_failure;
+
+ line[--line_len] = '\0'; /* \n */
+
+ sep = strrchr(line, 'x');
+ if (sep == NULL)
+ continue;
+
+ hex2u64(sep + 1, &start);
+
+ sep = strchr(line, ' ');
+ if (sep == NULL)
+ continue;
+
+ *sep = '\0';
+
+ snprintf(name, sizeof(name), "[%s]", line);
+ map = machine__new_module(machine, start, name);
+ if (map == NULL)
+ goto out_delete_line;
+ dso__kernel_module_get_build_id(map->dso, machine->root_dir);
+ }
- pr_debug("Problems setting modules path maps, continuing anyway...\n");
+ free(line);
+ fclose(file);
+ if (machine__set_modules_path(machine) < 0) {
+ pr_debug("Problems setting modules path maps, continuing anyway...\n");
+ }
return 0;
+
+out_delete_line:
+ free(line);
+out_failure:
+ return -1;
}
int machine__create_kernel_maps(struct machine *machine)
@@ -985,8 +998,7 @@ out_problem:
}
int machine__process_mmap2_event(struct machine *machine,
- union perf_event *event,
- struct perf_sample *sample __maybe_unused)
+ union perf_event *event)
{
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct thread *thread;
@@ -1033,8 +1045,7 @@ out_problem:
return 0;
}
-int machine__process_mmap_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample __maybe_unused)
+int machine__process_mmap_event(struct machine *machine, union perf_event *event)
{
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct thread *thread;
@@ -1091,8 +1102,7 @@ static void machine__remove_thread(struct machine *machine, struct thread *th)
list_add_tail(&th->node, &machine->dead_threads);
}
-int machine__process_fork_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample)
+int machine__process_fork_event(struct machine *machine, union perf_event *event)
{
struct thread *thread = machine__find_thread(machine, event->fork.tid);
struct thread *parent = machine__findnew_thread(machine,
@@ -1109,7 +1119,7 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
perf_event__fprintf_task(event, stdout);
if (thread == NULL || parent == NULL ||
- thread__fork(thread, parent, sample->time) < 0) {
+ thread__fork(thread, parent) < 0) {
dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
return -1;
}
@@ -1117,8 +1127,8 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
return 0;
}
-int machine__process_exit_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample __maybe_unused)
+int machine__process_exit_event(struct machine *machine __maybe_unused,
+ union perf_event *event)
{
struct thread *thread = machine__find_thread(machine, event->fork.tid);
@@ -1131,24 +1141,23 @@ int machine__process_exit_event(struct machine *machine, union perf_event *event
return 0;
}
-int machine__process_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample)
+int machine__process_event(struct machine *machine, union perf_event *event)
{
int ret;
switch (event->header.type) {
case PERF_RECORD_COMM:
- ret = machine__process_comm_event(machine, event, sample); break;
+ ret = machine__process_comm_event(machine, event); break;
case PERF_RECORD_MMAP:
- ret = machine__process_mmap_event(machine, event, sample); break;
+ ret = machine__process_mmap_event(machine, event); break;
case PERF_RECORD_MMAP2:
- ret = machine__process_mmap2_event(machine, event, sample); break;
+ ret = machine__process_mmap2_event(machine, event); break;
case PERF_RECORD_FORK:
- ret = machine__process_fork_event(machine, event, sample); break;
+ ret = machine__process_fork_event(machine, event); break;
case PERF_RECORD_EXIT:
- ret = machine__process_exit_event(machine, event, sample); break;
+ ret = machine__process_exit_event(machine, event); break;
case PERF_RECORD_LOST:
- ret = machine__process_lost_event(machine, event, sample); break;
+ ret = machine__process_lost_event(machine, event); break;
default:
ret = -1;
break;
@@ -1258,12 +1267,10 @@ static int machine__resolve_callchain_sample(struct machine *machine,
struct thread *thread,
struct ip_callchain *chain,
struct symbol **parent,
- struct addr_location *root_al,
- int max_stack)
+ struct addr_location *root_al)
{
u8 cpumode = PERF_RECORD_MISC_USER;
- int chain_nr = min(max_stack, (int)chain->nr);
- int i;
+ unsigned int i;
int err;
callchain_cursor_reset(&callchain_cursor);
@@ -1273,7 +1280,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,
return 0;
}
- for (i = 0; i < chain_nr; i++) {
+ for (i = 0; i < chain->nr; i++) {
u64 ip;
struct addr_location al;
@@ -1345,14 +1352,12 @@ int machine__resolve_callchain(struct machine *machine,
struct thread *thread,
struct perf_sample *sample,
struct symbol **parent,
- struct addr_location *root_al,
- int max_stack)
+ struct addr_location *root_al)
{
int ret;
ret = machine__resolve_callchain_sample(machine, thread,
- sample->callchain, parent,
- root_al, max_stack);
+ sample->callchain, parent, root_al);
if (ret)
return ret;
@@ -1368,41 +1373,6 @@ int machine__resolve_callchain(struct machine *machine,
return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
thread, evsel->attr.sample_regs_user,
- sample, max_stack);
+ sample);
}
-
-int machine__for_each_thread(struct machine *machine,
- int (*fn)(struct thread *thread, void *p),
- void *priv)
-{
- struct rb_node *nd;
- struct thread *thread;
- int rc = 0;
-
- for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
- thread = rb_entry(nd, struct thread, rb_node);
- rc = fn(thread, priv);
- if (rc != 0)
- return rc;
- }
-
- list_for_each_entry(thread, &machine->dead_threads, node) {
- rc = fn(thread, priv);
- if (rc != 0)
- return rc;
- }
- return rc;
-}
-
-int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
- struct target *target, struct thread_map *threads,
- perf_event__handler_t process, bool data_mmap)
-{
- if (target__has_task(target))
- return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
- else if (target__has_cpu(target))
- return perf_event__synthesize_threads(tool, process, machine, data_mmap);
- /* command specified */
- return 0;
-}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 4771330..58a6be1 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -4,7 +4,6 @@
#include <sys/types.h>
#include <linux/rbtree.h>
#include "map.h"
-#include "event.h"
struct addr_location;
struct branch_stack;
@@ -41,20 +40,13 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)
struct thread *machine__find_thread(struct machine *machine, pid_t tid);
-int machine__process_comm_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_exit_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_fork_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_lost_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_mmap_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
-int machine__process_event(struct machine *machine, union perf_event *event,
- struct perf_sample *sample);
+int machine__process_comm_event(struct machine *machine, union perf_event *event);
+int machine__process_exit_event(struct machine *machine, union perf_event *event);
+int machine__process_fork_event(struct machine *machine, union perf_event *event);
+int machine__process_lost_event(struct machine *machine, union perf_event *event);
+int machine__process_mmap_event(struct machine *machine, union perf_event *event);
+int machine__process_mmap2_event(struct machine *machine, union perf_event *event);
+int machine__process_event(struct machine *machine, union perf_event *event);
typedef void (*machine__process_t)(struct machine *machine, void *data);
@@ -82,7 +74,6 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
void machines__set_symbol_filter(struct machines *machines,
symbol_filter_t symbol_filter);
-struct machine *machine__new_host(void);
int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
void machine__exit(struct machine *machine);
void machine__delete_dead_threads(struct machine *machine);
@@ -100,8 +91,7 @@ int machine__resolve_callchain(struct machine *machine,
struct thread *thread,
struct perf_sample *sample,
struct symbol **parent,
- struct addr_location *root_al,
- int max_stack);
+ struct addr_location *root_al);
/*
* Default guest kernel is defined by parameter --guestkallsyms
@@ -175,19 +165,4 @@ void machines__destroy_kernel_maps(struct machines *machines);
size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
-int machine__for_each_thread(struct machine *machine,
- int (*fn)(struct thread *thread, void *p),
- void *priv);
-
-int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
- struct target *target, struct thread_map *threads,
- perf_event__handler_t process, bool data_mmap);
-static inline
-int machine__synthesize_threads(struct machine *machine, struct target *target,
- struct thread_map *threads, bool data_mmap)
-{
- return __machine__synthesize_threads(machine, NULL, target, threads,
- perf_event__process, data_mmap);
-}
-
#endif /* __PERF_MACHINE_H */
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index ef5bc91..4f6680d 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -172,7 +172,7 @@ int map__load(struct map *map, symbol_filter_t filter)
pr_warning(", continuing without symbols\n");
return -1;
} else if (nr == 0) {
-#ifdef HAVE_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
const size_t len = strlen(name);
const size_t real_len = len - sizeof(DSO__DELETED);
@@ -252,16 +252,10 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
return fprintf(fp, "%s", dsoname);
}
-/**
- * map__rip_2objdump - convert symbol start address to objdump address.
- * @map: memory map
- * @rip: symbol start address
- *
+/*
* objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
* map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
* relative to section start.
- *
- * Return: Address suitable for passing to "objdump --start-address="
*/
u64 map__rip_2objdump(struct map *map, u64 rip)
{
@@ -274,29 +268,6 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
return map->unmap_ip(map, rip);
}
-/**
- * map__objdump_2mem - convert objdump address to a memory address.
- * @map: memory map
- * @ip: objdump address
- *
- * Closely related to map__rip_2objdump(), this function takes an address from
- * objdump and converts it to a memory address. Note this assumes that @map
- * contains the address. To be sure the result is valid, check it forwards
- * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
- *
- * Return: Memory address.
- */
-u64 map__objdump_2mem(struct map *map, u64 ip)
-{
- if (!map->dso->adjust_symbols)
- return map->unmap_ip(map, ip);
-
- if (map->dso->rel)
- return map->unmap_ip(map, ip + map->pgoff);
-
- return ip;
-}
-
void map_groups__init(struct map_groups *mg)
{
int i;
@@ -400,23 +371,6 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
return NULL;
}
-int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
-{
- if (ams->addr < ams->map->start || ams->addr > ams->map->end) {
- if (ams->map->groups == NULL)
- return -1;
- ams->map = map_groups__find(ams->map->groups, ams->map->type,
- ams->addr);
- if (ams->map == NULL)
- return -1;
- }
-
- ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
- ams->sym = map__find_symbol(ams->map, ams->al_addr, filter);
-
- return ams->sym ? 0 : -1;
-}
-
size_t __map_groups__fprintf_maps(struct map_groups *mg,
enum map_type type, int verbose, FILE *fp)
{
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index e4e259c..4886ca2 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -84,9 +84,6 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
u64 map__rip_2objdump(struct map *map, u64 rip);
-/* objdump address -> memory address */
-u64 map__objdump_2mem(struct map *map, u64 ip);
-
struct symbol;
typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
@@ -170,10 +167,6 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
struct map **mapp,
symbol_filter_t filter);
-struct addr_map_symbol;
-
-int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter);
-
static inline
struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
const char *name, struct map **mapp,
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6de6f89..9812531 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -277,7 +277,7 @@ static int __add_event(struct list_head *list, int *idx,
event_attr_init(attr);
- evsel = perf_evsel__new_idx(attr, (*idx)++);
+ evsel = perf_evsel__new(attr, (*idx)++);
if (!evsel)
return -ENOMEM;
@@ -378,7 +378,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
{
struct perf_evsel *evsel;
- evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
+ evsel = perf_evsel__newtp(sys_name, evt_name, (*idx)++);
if (!evsel)
return -ENOMEM;
@@ -998,10 +998,8 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
char evt_path[MAXPATHLEN];
char dir_path[MAXPATHLEN];
- if (debugfs_valid_mountpoint(tracing_events_path)) {
- printf(" [ Tracepoints not available: %s ]\n", strerror(errno));
+ if (debugfs_valid_mountpoint(tracing_events_path))
return;
- }
sys_dir = opendir(tracing_events_path);
if (!sys_dir)
@@ -1097,7 +1095,7 @@ static bool is_event_supported(u8 type, unsigned config)
.threads = { 0 },
};
- evsel = perf_evsel__new(&attr);
+ evsel = perf_evsel__new(&attr, 0);
if (evsel) {
ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0;
perf_evsel__delete(evsel);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 3432995..91346b7 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -126,37 +126,6 @@ modifier_bp [rwx]{1,3}
}
-<config>{
-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
-config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
-config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
-name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
-period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
-branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
-, { return ','; }
-"/" { BEGIN(INITIAL); return '/'; }
-{name_minus} { return str(yyscanner, PE_NAME); }
-}
-
-<mem>{
-{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
-: { return ':'; }
-{num_dec} { return value(yyscanner, 10); }
-{num_hex} { return value(yyscanner, 16); }
- /*
- * We need to separate 'mem:' scanner part, in order to get specific
- * modifier bits parsed out. Otherwise we would need to handle PE_NAME
- * and we'd need to parse it manually. During the escape from <mem>
- * state we need to put the escaping char back, so we dont miss it.
- */
-. { unput(*yytext); BEGIN(INITIAL); }
- /*
- * We destroy the scanner after reaching EOF,
- * but anyway just to be sure get back to INIT state.
- */
-<<EOF>> { BEGIN(INITIAL); }
-}
-
cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
@@ -193,6 +162,18 @@ speculative-read|speculative-load |
refs|Reference|ops|access |
misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
+<config>{
+config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
+config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
+config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
+name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
+period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
+branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
+, { return ','; }
+"/" { BEGIN(INITIAL); return '/'; }
+{name_minus} { return str(yyscanner, PE_NAME); }
+}
+
mem: { BEGIN(mem); return PE_PREFIX_MEM; }
r{num_raw_hex} { return raw(yyscanner); }
{num_dec} { return value(yyscanner, 10); }
@@ -208,7 +189,25 @@ r{num_raw_hex} { return raw(yyscanner); }
"}" { return '}'; }
= { return '='; }
\n { }
-. { }
+
+<mem>{
+{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
+: { return ':'; }
+{num_dec} { return value(yyscanner, 10); }
+{num_hex} { return value(yyscanner, 16); }
+ /*
+ * We need to separate 'mem:' scanner part, in order to get specific
+ * modifier bits parsed out. Otherwise we would need to handle PE_NAME
+ * and we'd need to parse it manually. During the escape from <mem>
+ * state we need to put the escaping char back, so we dont miss it.
+ */
+. { unput(*yytext); BEGIN(INITIAL); }
+ /*
+ * We destroy the scanner after reaching EOF,
+ * but anyway just to be sure get back to INIT state.
+ */
+<<EOF>> { BEGIN(INITIAL); }
+}
%%
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 31f404a..2bc9e70 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -339,10 +339,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
if (arg[1] != '-') {
ctx->opt = arg + 1;
if (internal_help && *ctx->opt == 'h')
- return usage_with_options_internal(usagestr, options, 0);
+ return parse_options_usage(usagestr, options);
switch (parse_short_opt(ctx, options)) {
case -1:
- return parse_options_usage(usagestr, options, arg + 1, 1);
+ return parse_options_usage(usagestr, options);
case -2:
goto unknown;
default:
@@ -352,11 +352,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
check_typos(arg + 1, options);
while (ctx->opt) {
if (internal_help && *ctx->opt == 'h')
- return usage_with_options_internal(usagestr, options, 0);
- arg = ctx->opt;
+ return parse_options_usage(usagestr, options);
switch (parse_short_opt(ctx, options)) {
case -1:
- return parse_options_usage(usagestr, options, arg, 1);
+ return parse_options_usage(usagestr, options);
case -2:
/* fake a short option thing to hide the fact that we may have
* started to parse aggregated stuff
@@ -384,12 +383,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
if (internal_help && !strcmp(arg + 2, "help-all"))
return usage_with_options_internal(usagestr, options, 1);
if (internal_help && !strcmp(arg + 2, "help"))
- return usage_with_options_internal(usagestr, options, 0);
+ return parse_options_usage(usagestr, options);
if (!strcmp(arg + 2, "list-opts"))
return PARSE_OPT_LIST;
switch (parse_long_opt(ctx, arg + 2, options)) {
case -1:
- return parse_options_usage(usagestr, options, arg + 2, 0);
+ return parse_options_usage(usagestr, options);
case -2:
goto unknown;
default:
@@ -446,89 +445,6 @@ int parse_options(int argc, const char **argv, const struct option *options,
#define USAGE_OPTS_WIDTH 24
#define USAGE_GAP 2
-static void print_option_help(const struct option *opts, int full)
-{
- size_t pos;
- int pad;
-
- if (opts->type == OPTION_GROUP) {
- fputc('\n', stderr);
- if (*opts->help)
- fprintf(stderr, "%s\n", opts->help);
- return;
- }
- if (!full && (opts->flags & PARSE_OPT_HIDDEN))
- return;
-
- pos = fprintf(stderr, " ");
- if (opts->short_name)
- pos += fprintf(stderr, "-%c", opts->short_name);
- else
- pos += fprintf(stderr, " ");
-
- if (opts->long_name && opts->short_name)
- pos += fprintf(stderr, ", ");
- if (opts->long_name)
- pos += fprintf(stderr, "--%s", opts->long_name);
-
- switch (opts->type) {
- case OPTION_ARGUMENT:
- break;
- case OPTION_LONG:
- case OPTION_U64:
- case OPTION_INTEGER:
- case OPTION_UINTEGER:
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=<n>]");
- else
- pos += fprintf(stderr, "[<n>]");
- else
- pos += fprintf(stderr, " <n>");
- break;
- case OPTION_CALLBACK:
- if (opts->flags & PARSE_OPT_NOARG)
- break;
- /* FALLTHROUGH */
- case OPTION_STRING:
- if (opts->argh) {
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=<%s>]", opts->argh);
- else
- pos += fprintf(stderr, "[<%s>]", opts->argh);
- else
- pos += fprintf(stderr, " <%s>", opts->argh);
- } else {
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=...]");
- else
- pos += fprintf(stderr, "[...]");
- else
- pos += fprintf(stderr, " ...");
- }
- break;
- default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
- case OPTION_END:
- case OPTION_GROUP:
- case OPTION_BIT:
- case OPTION_BOOLEAN:
- case OPTION_INCR:
- case OPTION_SET_UINT:
- case OPTION_SET_PTR:
- break;
- }
-
- if (pos <= USAGE_OPTS_WIDTH)
- pad = USAGE_OPTS_WIDTH - pos;
- else {
- fputc('\n', stderr);
- pad = USAGE_OPTS_WIDTH;
- }
- fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
-}
-
int usage_with_options_internal(const char * const *usagestr,
const struct option *opts, int full)
{
@@ -548,9 +464,87 @@ int usage_with_options_internal(const char * const *usagestr,
if (opts->type != OPTION_GROUP)
fputc('\n', stderr);
- for ( ; opts->type != OPTION_END; opts++)
- print_option_help(opts, full);
+ for (; opts->type != OPTION_END; opts++) {
+ size_t pos;
+ int pad;
+
+ if (opts->type == OPTION_GROUP) {
+ fputc('\n', stderr);
+ if (*opts->help)
+ fprintf(stderr, "%s\n", opts->help);
+ continue;
+ }
+ if (!full && (opts->flags & PARSE_OPT_HIDDEN))
+ continue;
+
+ pos = fprintf(stderr, " ");
+ if (opts->short_name)
+ pos += fprintf(stderr, "-%c", opts->short_name);
+ else
+ pos += fprintf(stderr, " ");
+
+ if (opts->long_name && opts->short_name)
+ pos += fprintf(stderr, ", ");
+ if (opts->long_name)
+ pos += fprintf(stderr, "--%s", opts->long_name);
+
+ switch (opts->type) {
+ case OPTION_ARGUMENT:
+ break;
+ case OPTION_LONG:
+ case OPTION_U64:
+ case OPTION_INTEGER:
+ case OPTION_UINTEGER:
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=<n>]");
+ else
+ pos += fprintf(stderr, "[<n>]");
+ else
+ pos += fprintf(stderr, " <n>");
+ break;
+ case OPTION_CALLBACK:
+ if (opts->flags & PARSE_OPT_NOARG)
+ break;
+ /* FALLTHROUGH */
+ case OPTION_STRING:
+ if (opts->argh) {
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=<%s>]", opts->argh);
+ else
+ pos += fprintf(stderr, "[<%s>]", opts->argh);
+ else
+ pos += fprintf(stderr, " <%s>", opts->argh);
+ } else {
+ if (opts->flags & PARSE_OPT_OPTARG)
+ if (opts->long_name)
+ pos += fprintf(stderr, "[=...]");
+ else
+ pos += fprintf(stderr, "[...]");
+ else
+ pos += fprintf(stderr, " ...");
+ }
+ break;
+ default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
+ case OPTION_END:
+ case OPTION_GROUP:
+ case OPTION_BIT:
+ case OPTION_BOOLEAN:
+ case OPTION_INCR:
+ case OPTION_SET_UINT:
+ case OPTION_SET_PTR:
+ break;
+ }
+ if (pos <= USAGE_OPTS_WIDTH)
+ pad = USAGE_OPTS_WIDTH - pos;
+ else {
+ fputc('\n', stderr);
+ pad = USAGE_OPTS_WIDTH;
+ }
+ fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
+ }
fputc('\n', stderr);
return PARSE_OPT_HELP;
@@ -565,45 +559,9 @@ void usage_with_options(const char * const *usagestr,
}
int parse_options_usage(const char * const *usagestr,
- const struct option *opts,
- const char *optstr, bool short_opt)
+ const struct option *opts)
{
- if (!usagestr)
- goto opt;
-
- fprintf(stderr, "\n usage: %s\n", *usagestr++);
- while (*usagestr && **usagestr)
- fprintf(stderr, " or: %s\n", *usagestr++);
- while (*usagestr) {
- fprintf(stderr, "%s%s\n",
- **usagestr ? " " : "",
- *usagestr);
- usagestr++;
- }
- fputc('\n', stderr);
-
-opt:
- for ( ; opts->type != OPTION_END; opts++) {
- if (short_opt) {
- if (opts->short_name == *optstr)
- break;
- continue;
- }
-
- if (opts->long_name == NULL)
- continue;
-
- if (!prefixcmp(optstr, opts->long_name))
- break;
- if (!prefixcmp(optstr, "no-") &&
- !prefixcmp(optstr + 3, opts->long_name))
- break;
- }
-
- if (opts->type != OPTION_END)
- print_option_help(opts, 0);
-
- return PARSE_OPT_HELP;
+ return usage_with_options_internal(usagestr, opts, 0);
}
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index b0241e2..7bb5999 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -158,9 +158,7 @@ struct parse_opt_ctx_t {
};
extern int parse_options_usage(const char * const *usagestr,
- const struct option *opts,
- const char *optstr,
- bool short_opt);
+ const struct option *opts);
extern void parse_options_start(struct parse_opt_ctx_t *ctx,
int argc, const char **argv, int flags);
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index 5d13cb4..a8c4954 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -22,23 +22,19 @@ static const char *get_perf_dir(void)
return ".";
}
-/*
- * If libc has strlcpy() then that version will override this
- * implementation:
- */
-size_t __weak strlcpy(char *dest, const char *src, size_t size)
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
-
memcpy(dest, src, len);
dest[len] = '\0';
}
-
return ret;
}
+#endif
static char *get_pathname(void)
{
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index a3d42cd..5a4f2b6f 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -1,7 +1,7 @@
#ifndef __PERF_REGS_H
#define __PERF_REGS_H
-#ifdef HAVE_PERF_REGS_SUPPORT
+#ifdef HAVE_PERF_REGS
#include <perf_regs.h>
#else
#define PERF_REGS_MASK 0
@@ -10,5 +10,5 @@ static inline const char *perf_reg_name(int id __maybe_unused)
{
return NULL;
}
-#endif /* HAVE_PERF_REGS_SUPPORT */
+#endif /* HAVE_PERF_REGS */
#endif /* __PERF_REGS_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index c232d8d..bc9d806 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -4,7 +4,7 @@
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
-#include "fs.h"
+#include "sysfs.h"
#include "util.h"
#include "pmu.h"
#include "parse-events.h"
@@ -77,8 +77,9 @@ static int pmu_format(const char *name, struct list_head *format)
{
struct stat st;
char path[PATH_MAX];
- const char *sysfs = sysfs__mountpoint();
+ const char *sysfs;
+ sysfs = sysfs_find_mountpoint();
if (!sysfs)
return -1;
@@ -165,8 +166,9 @@ static int pmu_aliases(const char *name, struct list_head *head)
{
struct stat st;
char path[PATH_MAX];
- const char *sysfs = sysfs__mountpoint();
+ const char *sysfs;
+ sysfs = sysfs_find_mountpoint();
if (!sysfs)
return -1;
@@ -210,10 +212,11 @@ static int pmu_type(const char *name, __u32 *type)
{
struct stat st;
char path[PATH_MAX];
+ const char *sysfs;
FILE *file;
int ret = 0;
- const char *sysfs = sysfs__mountpoint();
+ sysfs = sysfs_find_mountpoint();
if (!sysfs)
return -1;
@@ -238,10 +241,11 @@ static int pmu_type(const char *name, __u32 *type)
static void pmu_read_sysfs(void)
{
char path[PATH_MAX];
+ const char *sysfs;
DIR *dir;
struct dirent *dent;
- const char *sysfs = sysfs__mountpoint();
+ sysfs = sysfs_find_mountpoint();
if (!sysfs)
return;
@@ -266,10 +270,11 @@ static struct cpu_map *pmu_cpumask(const char *name)
{
struct stat st;
char path[PATH_MAX];
+ const char *sysfs;
FILE *file;
struct cpu_map *cpus;
- const char *sysfs = sysfs__mountpoint();
+ sysfs = sysfs_find_mountpoint();
if (!sysfs)
return NULL;
@@ -632,19 +637,3 @@ void print_pmu_events(const char *event_glob, bool name_only)
printf("\n");
free(aliases);
}
-
-bool pmu_have_event(const char *pname, const char *name)
-{
- struct perf_pmu *pmu;
- struct perf_pmu_alias *alias;
-
- pmu = NULL;
- while ((pmu = perf_pmu__scan(pmu)) != NULL) {
- if (strcmp(pname, pmu->name))
- continue;
- list_for_each_entry(alias, &pmu->aliases, list)
- if (!strcmp(alias->name, name))
- return true;
- }
- return false;
-}
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 1179b26..6b2cbe2 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -42,7 +42,6 @@ int perf_pmu__format_parse(char *dir, struct list_head *head);
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
void print_pmu_events(const char *event_glob, bool name_only);
-bool pmu_have_event(const char *pname, const char *name);
int perf_pmu__test(void);
#endif /* __PMU_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9c6989c..aa04bf9 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -47,6 +47,7 @@
#include "session.h"
#define MAX_CMDLEN 256
+#define MAX_PROBE_ARGS 128
#define PERFPROBE_GROUP "probe"
bool probe_event_dry_run; /* Dry run flag */
@@ -200,7 +201,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
return 0;
}
-#ifdef HAVE_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
/* Open new debuginfo of given module */
static struct debuginfo *open_debuginfo(const char *module)
{
@@ -629,7 +630,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
return ret;
}
-#else /* !HAVE_DWARF_SUPPORT */
+#else /* !DWARF_SUPPORT */
static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
struct perf_probe_point *pp)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ffb657f..f069273 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -115,7 +115,7 @@ static const Dwfl_Callbacks offline_callbacks = {
};
/* Get a Dwarf from offline image */
-static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
+static int debuginfo__init_offline_dwarf(struct debuginfo *self,
const char *path)
{
int fd;
@@ -124,25 +124,25 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
if (fd < 0)
return fd;
- dbg->dwfl = dwfl_begin(&offline_callbacks);
- if (!dbg->dwfl)
+ self->dwfl = dwfl_begin(&offline_callbacks);
+ if (!self->dwfl)
goto error;
- dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
- if (!dbg->mod)
+ self->mod = dwfl_report_offline(self->dwfl, "", "", fd);
+ if (!self->mod)
goto error;
- dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
- if (!dbg->dbg)
+ self->dbg = dwfl_module_getdwarf(self->mod, &self->bias);
+ if (!self->dbg)
goto error;
return 0;
error:
- if (dbg->dwfl)
- dwfl_end(dbg->dwfl);
+ if (self->dwfl)
+ dwfl_end(self->dwfl);
else
close(fd);
- memset(dbg, 0, sizeof(*dbg));
+ memset(self, 0, sizeof(*self));
return -ENOENT;
}
@@ -180,24 +180,24 @@ static const Dwfl_Callbacks kernel_callbacks = {
};
/* Get a Dwarf from live kernel image */
-static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
+static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
Dwarf_Addr addr)
{
- dbg->dwfl = dwfl_begin(&kernel_callbacks);
- if (!dbg->dwfl)
+ self->dwfl = dwfl_begin(&kernel_callbacks);
+ if (!self->dwfl)
return -EINVAL;
/* Load the kernel dwarves: Don't care the result here */
- dwfl_linux_kernel_report_kernel(dbg->dwfl);
- dwfl_linux_kernel_report_modules(dbg->dwfl);
+ dwfl_linux_kernel_report_kernel(self->dwfl);
+ dwfl_linux_kernel_report_modules(self->dwfl);
- dbg->dbg = dwfl_addrdwarf(dbg->dwfl, addr, &dbg->bias);
+ self->dbg = dwfl_addrdwarf(self->dwfl, addr, &self->bias);
/* Here, check whether we could get a real dwarf */
- if (!dbg->dbg) {
+ if (!self->dbg) {
pr_debug("Failed to find kernel dwarf at %lx\n",
(unsigned long)addr);
- dwfl_end(dbg->dwfl);
- memset(dbg, 0, sizeof(*dbg));
+ dwfl_end(self->dwfl);
+ memset(self, 0, sizeof(*self));
return -ENOENT;
}
@@ -205,7 +205,7 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
}
#else
/* With older elfutils, this just support kernel module... */
-static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
+static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
Dwarf_Addr addr __maybe_unused)
{
const char *path = kernel_get_module_path("kernel");
@@ -216,45 +216,44 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
}
pr_debug2("Use file %s for debuginfo\n", path);
- return debuginfo__init_offline_dwarf(dbg, path);
+ return debuginfo__init_offline_dwarf(self, path);
}
#endif
struct debuginfo *debuginfo__new(const char *path)
{
- struct debuginfo *dbg = zalloc(sizeof(*dbg));
- if (!dbg)
+ struct debuginfo *self = zalloc(sizeof(struct debuginfo));
+ if (!self)
return NULL;
- if (debuginfo__init_offline_dwarf(dbg, path) < 0) {
- free(dbg);
- dbg = NULL;
+ if (debuginfo__init_offline_dwarf(self, path) < 0) {
+ free(self);
+ self = NULL;
}
- return dbg;
+ return self;
}
struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
{
- struct debuginfo *dbg = zalloc(sizeof(*dbg));
-
- if (!dbg)
+ struct debuginfo *self = zalloc(sizeof(struct debuginfo));
+ if (!self)
return NULL;
- if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) {
- free(dbg);
- dbg = NULL;
+ if (debuginfo__init_online_kernel_dwarf(self, (Dwarf_Addr)addr) < 0) {
+ free(self);
+ self = NULL;
}
- return dbg;
+ return self;
}
-void debuginfo__delete(struct debuginfo *dbg)
+void debuginfo__delete(struct debuginfo *self)
{
- if (dbg) {
- if (dbg->dwfl)
- dwfl_end(dbg->dwfl);
- free(dbg);
+ if (self) {
+ if (self->dwfl)
+ dwfl_end(self->dwfl);
+ free(self);
}
}
@@ -274,15 +273,12 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
/*
* Convert a location into trace_arg.
* If tvar == NULL, this just checks variable can be converted.
- * If fentry == true and vr_die is a parameter, do huristic search
- * for the location fuzzed by function entry mcount.
*/
static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
- Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
+ Dwarf_Op *fb_ops,
struct probe_trace_arg *tvar)
{
Dwarf_Attribute attr;
- Dwarf_Addr tmp = 0;
Dwarf_Op *op;
size_t nops;
unsigned int regn;
@@ -295,29 +291,12 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
goto static_var;
/* TODO: handle more than 1 exprs */
- if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
- return -EINVAL; /* Broken DIE ? */
- if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
- ret = dwarf_entrypc(sp_die, &tmp);
- if (ret || addr != tmp ||
- dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
- dwarf_highpc(sp_die, &tmp))
- return -ENOENT;
- /*
- * This is fuzzed by fentry mcount. We try to find the
- * parameter location at the earliest address.
- */
- for (addr += 1; addr <= tmp; addr++) {
- if (dwarf_getlocation_addr(&attr, addr, &op,
- &nops, 1) > 0)
- goto found;
- }
- return -ENOENT;
- }
-found:
- if (nops == 0)
+ if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
+ dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
+ nops == 0) {
/* TODO: Support const_value */
return -ENOENT;
+ }
if (op->atom == DW_OP_addr) {
static_var:
@@ -584,7 +563,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
}
if (die_find_member(&type, field->name, die_mem) == NULL) {
- pr_warning("%s(type:%s) has no member %s.\n", varname,
+ pr_warning("%s(tyep:%s) has no member %s.\n", varname,
dwarf_diename(&type), field->name);
return -EINVAL;
}
@@ -621,7 +600,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
dwarf_diename(vr_die));
ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
- &pf->sp_die, pf->tvar);
+ pf->tvar);
if (ret == -ENOENT)
pr_err("Failed to find the location of %s at this address.\n"
" Perhaps, it has been optimized out.\n", pf->pvar->var);
@@ -1084,7 +1063,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
}
/* Find probe points from debuginfo */
-static int debuginfo__find_probes(struct debuginfo *dbg,
+static int debuginfo__find_probes(struct debuginfo *self,
struct probe_finder *pf)
{
struct perf_probe_point *pp = &pf->pev->point;
@@ -1095,7 +1074,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
#if _ELFUTILS_PREREQ(0, 142)
/* Get the call frame information from this dwarf */
- pf->cfi = dwarf_getcfi(dbg->dbg);
+ pf->cfi = dwarf_getcfi(self->dbg);
#endif
off = 0;
@@ -1114,7 +1093,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
.data = pf,
};
- dwarf_getpubnames(dbg->dbg, pubname_search_cb,
+ dwarf_getpubnames(self->dbg, pubname_search_cb,
&pubname_param, 0);
if (pubname_param.found) {
ret = probe_point_search_cb(&pf->sp_die, &probe_param);
@@ -1124,9 +1103,9 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
}
/* Loop on CUs (Compilation Unit) */
- while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
+ while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
/* Get the DIE(Debugging Information Entry) of this CU */
- diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
+ diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die);
if (!diep)
continue;
@@ -1157,80 +1136,12 @@ found:
return ret;
}
-struct local_vars_finder {
- struct probe_finder *pf;
- struct perf_probe_arg *args;
- int max_args;
- int nargs;
- int ret;
-};
-
-/* Collect available variables in this scope */
-static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
-{
- struct local_vars_finder *vf = data;
- struct probe_finder *pf = vf->pf;
- int tag;
-
- tag = dwarf_tag(die_mem);
- if (tag == DW_TAG_formal_parameter ||
- tag == DW_TAG_variable) {
- if (convert_variable_location(die_mem, vf->pf->addr,
- vf->pf->fb_ops, &pf->sp_die,
- NULL) == 0) {
- vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
- if (vf->args[vf->nargs].var == NULL) {
- vf->ret = -ENOMEM;
- return DIE_FIND_CB_END;
- }
- pr_debug(" %s", vf->args[vf->nargs].var);
- vf->nargs++;
- }
- }
-
- if (dwarf_haspc(die_mem, vf->pf->addr))
- return DIE_FIND_CB_CONTINUE;
- else
- return DIE_FIND_CB_SIBLING;
-}
-
-static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
- struct perf_probe_arg *args)
-{
- Dwarf_Die die_mem;
- int i;
- int n = 0;
- struct local_vars_finder vf = {.pf = pf, .args = args,
- .max_args = MAX_PROBE_ARGS, .ret = 0};
-
- for (i = 0; i < pf->pev->nargs; i++) {
- /* var never be NULL */
- if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
- pr_debug("Expanding $vars into:");
- vf.nargs = n;
- /* Special local variables */
- die_find_child(sc_die, copy_variables_cb, (void *)&vf,
- &die_mem);
- pr_debug(" (%d)\n", vf.nargs - n);
- if (vf.ret < 0)
- return vf.ret;
- n = vf.nargs;
- } else {
- /* Copy normal argument */
- args[n] = pf->pev->args[i];
- n++;
- }
- }
- return n;
-}
-
/* Add a found probe point into trace event list */
static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
struct trace_event_finder *tf =
container_of(pf, struct trace_event_finder, pf);
struct probe_trace_event *tev;
- struct perf_probe_arg *args;
int ret, i;
/* Check number of tevs */
@@ -1250,45 +1161,31 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
tev->point.offset);
- /* Expand special probe argument if exist */
- args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
- if (args == NULL)
- return -ENOMEM;
-
- ret = expand_probe_args(sc_die, pf, args);
- if (ret < 0)
- goto end;
-
- tev->nargs = ret;
- tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
- if (tev->args == NULL) {
- ret = -ENOMEM;
- goto end;
- }
-
/* Find each argument */
- for (i = 0; i < tev->nargs; i++) {
- pf->pvar = &args[i];
+ tev->nargs = pf->pev->nargs;
+ tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
+ if (tev->args == NULL)
+ return -ENOMEM;
+ for (i = 0; i < pf->pev->nargs; i++) {
+ pf->pvar = &pf->pev->args[i];
pf->tvar = &tev->args[i];
/* Variable should be found from scope DIE */
ret = find_variable(sc_die, pf);
if (ret != 0)
- break;
+ return ret;
}
-end:
- free(args);
- return ret;
+ return 0;
}
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
-int debuginfo__find_trace_events(struct debuginfo *dbg,
+int debuginfo__find_trace_events(struct debuginfo *self,
struct perf_probe_event *pev,
struct probe_trace_event **tevs, int max_tevs)
{
struct trace_event_finder tf = {
.pf = {.pev = pev, .callback = add_probe_trace_event},
- .mod = dbg->mod, .max_tevs = max_tevs};
+ .mod = self->mod, .max_tevs = max_tevs};
int ret;
/* Allocate result tevs array */
@@ -1299,7 +1196,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
tf.tevs = *tevs;
tf.ntevs = 0;
- ret = debuginfo__find_probes(dbg, &tf.pf);
+ ret = debuginfo__find_probes(self, &tf.pf);
if (ret < 0) {
free(*tevs);
*tevs = NULL;
@@ -1325,8 +1222,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
if (tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) {
ret = convert_variable_location(die_mem, af->pf.addr,
- af->pf.fb_ops, &af->pf.sp_die,
- NULL);
+ af->pf.fb_ops, NULL);
if (ret == 0) {
ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
pr_debug2("Add new var: %s\n", buf);
@@ -1390,14 +1286,14 @@ out:
}
/* Find available variables at given probe point */
-int debuginfo__find_available_vars_at(struct debuginfo *dbg,
+int debuginfo__find_available_vars_at(struct debuginfo *self,
struct perf_probe_event *pev,
struct variable_list **vls,
int max_vls, bool externs)
{
struct available_var_finder af = {
.pf = {.pev = pev, .callback = add_available_vars},
- .mod = dbg->mod,
+ .mod = self->mod,
.max_vls = max_vls, .externs = externs};
int ret;
@@ -1409,7 +1305,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
af.vls = *vls;
af.nvls = 0;
- ret = debuginfo__find_probes(dbg, &af.pf);
+ ret = debuginfo__find_probes(self, &af.pf);
if (ret < 0) {
/* Free vlist for error */
while (af.nvls--) {
@@ -1427,7 +1323,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
}
/* Reverse search */
-int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
+int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
struct perf_probe_point *ppt)
{
Dwarf_Die cudie, spdie, indie;
@@ -1436,10 +1332,10 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
int baseline = 0, lineno = 0, ret = 0;
/* Adjust address with bias */
- addr += dbg->bias;
+ addr += self->bias;
/* Find cu die */
- if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr - dbg->bias, &cudie)) {
+ if (!dwarf_addrdie(self->dbg, (Dwarf_Addr)addr - self->bias, &cudie)) {
pr_warning("Failed to find debug information for address %lx\n",
addr);
ret = -EINVAL;
@@ -1640,7 +1536,7 @@ static int find_line_range_by_func(struct line_finder *lf)
return param.retval;
}
-int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
+int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
{
struct line_finder lf = {.lr = lr, .found = 0};
int ret = 0;
@@ -1657,7 +1553,7 @@ int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
struct dwarf_callback_param line_range_param = {
.data = (void *)&lf, .retval = 0};
- dwarf_getpubnames(dbg->dbg, pubname_search_cb,
+ dwarf_getpubnames(self->dbg, pubname_search_cb,
&pubname_param, 0);
if (pubname_param.found) {
line_range_search_cb(&lf.sp_die, &line_range_param);
@@ -1668,12 +1564,12 @@ int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
/* Loop on CUs (Compilation Unit) */
while (!lf.found && ret >= 0) {
- if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
+ if (dwarf_nextcu(self->dbg, off, &noff, &cuhl,
NULL, NULL, NULL) != 0)
break;
/* Get the DIE(Debugging Information Entry) of this CU */
- diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
+ diep = dwarf_offdie(self->dbg, off + cuhl, &lf.cu_die);
if (!diep)
continue;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index ffc33cd..3b7d630 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -7,7 +7,6 @@
#define MAX_PROBE_BUFFER 1024
#define MAX_PROBES 128
-#define MAX_PROBE_ARGS 128
static inline int is_c_varname(const char *name)
{
@@ -15,7 +14,7 @@ static inline int is_c_varname(const char *name)
return isalpha(name[0]) || name[0] == '_';
}
-#ifdef HAVE_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
#include "dwarf-aux.h"
@@ -31,25 +30,25 @@ struct debuginfo {
extern struct debuginfo *debuginfo__new(const char *path);
extern struct debuginfo *debuginfo__new_online_kernel(unsigned long addr);
-extern void debuginfo__delete(struct debuginfo *dbg);
+extern void debuginfo__delete(struct debuginfo *self);
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
-extern int debuginfo__find_trace_events(struct debuginfo *dbg,
+extern int debuginfo__find_trace_events(struct debuginfo *self,
struct perf_probe_event *pev,
struct probe_trace_event **tevs,
int max_tevs);
/* Find a perf_probe_point from debuginfo */
-extern int debuginfo__find_probe_point(struct debuginfo *dbg,
+extern int debuginfo__find_probe_point(struct debuginfo *self,
unsigned long addr,
struct perf_probe_point *ppt);
/* Find a line range */
-extern int debuginfo__find_line_range(struct debuginfo *dbg,
+extern int debuginfo__find_line_range(struct debuginfo *self,
struct line_range *lr);
/* Find available variables */
-extern int debuginfo__find_available_vars_at(struct debuginfo *dbg,
+extern int debuginfo__find_available_vars_at(struct debuginfo *self,
struct perf_probe_event *pev,
struct variable_list **vls,
int max_points, bool externs);
@@ -106,6 +105,6 @@ struct line_finder {
int found;
};
-#endif /* HAVE_DWARF_SUPPORT */
+#endif /* DWARF_SUPPORT */
#endif /*_PROBE_FINDER_H */
diff --git a/tools/perf/util/pstack.h b/tools/perf/util/pstack.h
index c3cb658..4cedea5 100644
--- a/tools/perf/util/pstack.h
+++ b/tools/perf/util/pstack.h
@@ -5,10 +5,10 @@
struct pstack;
struct pstack *pstack__new(unsigned short max_nr_entries);
-void pstack__delete(struct pstack *pstack);
-bool pstack__empty(const struct pstack *pstack);
-void pstack__remove(struct pstack *pstack, void *key);
-void pstack__push(struct pstack *pstack, void *key);
-void *pstack__pop(struct pstack *pstack);
+void pstack__delete(struct pstack *self);
+bool pstack__empty(const struct pstack *self);
+void pstack__remove(struct pstack *self, void *key);
+void pstack__push(struct pstack *self, void *key);
+void *pstack__pop(struct pstack *self);
#endif /* _PERF_PSTACK_ */
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 239036f..f75ae1b 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -17,5 +17,5 @@ util/xyarray.c
util/cgroup.c
util/rblist.c
util/strlist.c
-util/fs.c
+util/sysfs.c
../../lib/rbtree.c
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 4bf8ace..2ac4bc9 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -33,6 +33,13 @@ int eprintf(int level, const char *fmt, ...)
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
+struct throttle_event {
+ struct perf_event_header header;
+ u64 time;
+ u64 id;
+ u64 stream_id;
+};
+
PyMODINIT_FUNC initperf(void);
#define member_def(type, member, ptype, help) \
@@ -1031,7 +1038,6 @@ PyMODINIT_FUNC initperf(void)
pyrf_cpu_map__setup_types() < 0)
return;
- /* The page_size is placed in util object. */
page_size = sysconf(_SC_PAGE_SIZE);
Py_INCREF(&pyrf_evlist__type);
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
index 0dfe27d..a16cdd2 100644
--- a/tools/perf/util/rblist.c
+++ b/tools/perf/util/rblist.c
@@ -48,12 +48,10 @@ void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
rblist->node_delete(rblist, rb_node);
}
-static struct rb_node *__rblist__findnew(struct rblist *rblist,
- const void *entry,
- bool create)
+struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
{
struct rb_node **p = &rblist->entries.rb_node;
- struct rb_node *parent = NULL, *new_node = NULL;
+ struct rb_node *parent = NULL;
while (*p != NULL) {
int rc;
@@ -69,26 +67,7 @@ static struct rb_node *__rblist__findnew(struct rblist *rblist,
return parent;
}
- if (create) {
- new_node = rblist->node_new(rblist, entry);
- if (new_node) {
- rb_link_node(new_node, parent, p);
- rb_insert_color(new_node, &rblist->entries);
- ++rblist->nr_entries;
- }
- }
-
- return new_node;
-}
-
-struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
-{
- return __rblist__findnew(rblist, entry, false);
-}
-
-struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry)
-{
- return __rblist__findnew(rblist, entry, true);
+ return NULL;
}
void rblist__init(struct rblist *rblist)
diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h
index ff9913b..6d0cae5 100644
--- a/tools/perf/util/rblist.h
+++ b/tools/perf/util/rblist.h
@@ -32,7 +32,6 @@ void rblist__delete(struct rblist *rblist);
int rblist__add_node(struct rblist *rblist, const void *new_entry);
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node);
struct rb_node *rblist__find(struct rblist *rblist, const void *entry);
-struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry);
struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx);
static inline bool rblist__empty(const struct rblist *rblist)
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index c8845b1..18d73aa 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -2,8 +2,6 @@
#include "evsel.h"
#include "cpumap.h"
#include "parse-events.h"
-#include "fs.h"
-#include "util.h"
typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
@@ -108,72 +106,3 @@ void perf_evlist__config(struct perf_evlist *evlist,
perf_evlist__set_id_pos(evlist);
}
-
-static int get_max_rate(unsigned int *rate)
-{
- char path[PATH_MAX];
- const char *procfs = procfs__mountpoint();
-
- if (!procfs)
- return -1;
-
- snprintf(path, PATH_MAX,
- "%s/sys/kernel/perf_event_max_sample_rate", procfs);
-
- return filename__read_int(path, (int *) rate);
-}
-
-static int perf_record_opts__config_freq(struct perf_record_opts *opts)
-{
- bool user_freq = opts->user_freq != UINT_MAX;
- unsigned int max_rate;
-
- if (opts->user_interval != ULLONG_MAX)
- opts->default_interval = opts->user_interval;
- if (user_freq)
- opts->freq = opts->user_freq;
-
- /*
- * User specified count overrides default frequency.
- */
- if (opts->default_interval)
- opts->freq = 0;
- else if (opts->freq) {
- opts->default_interval = opts->freq;
- } else {
- pr_err("frequency and count are zero, aborting\n");
- return -1;
- }
-
- if (get_max_rate(&max_rate))
- return 0;
-
- /*
- * User specified frequency is over current maximum.
- */
- if (user_freq && (max_rate < opts->freq)) {
- pr_err("Maximum frequency rate (%u) reached.\n"
- "Please use -F freq option with lower value or consider\n"
- "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
- max_rate);
- return -1;
- }
-
- /*
- * Default frequency is over current maximum.
- */
- if (max_rate < opts->freq) {
- pr_warning("Lowering default frequency rate to %u.\n"
- "Please consider tweaking "
- "/proc/sys/kernel/perf_event_max_sample_rate.\n",
- max_rate);
- opts->freq = max_rate;
- }
-
- return 0;
-}
-
-int perf_record_opts__config(struct perf_record_opts *opts)
-{
- return perf_record_opts__config_freq(opts);
-}
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index d5e5969..c0c9795 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -273,7 +273,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- const char *comm = thread__comm_str(thread);
+ char *comm = thread->comm;
dSP;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 53c20e7..95d91a0 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -250,7 +250,7 @@ static void python_process_tracepoint(union perf_event *perf_event
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
- const char *comm = thread__comm_str(thread);
+ char *comm = thread->comm;
t = PyTuple_New(MAX_FIELDS);
if (!t)
@@ -389,7 +389,7 @@ static void python_process_general_event(union perf_event *perf_event
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
(const char *)sample->raw_data, sample->raw_size));
pydict_set_item_string_decref(dict, "comm",
- PyString_FromString(thread__comm_str(thread)));
+ PyString_FromString(thread->comm));
if (al->map) {
pydict_set_item_string_decref(dict, "dso",
PyString_FromString(al->map->dso->name));
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f36d24a..568b750 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -16,34 +16,73 @@
#include "perf_regs.h"
#include "vdso.h"
-static int perf_session__open(struct perf_session *session)
+static int perf_session__open(struct perf_session *self, bool force)
{
- struct perf_data_file *file = session->file;
+ struct stat input_stat;
- if (perf_session__read_header(session) < 0) {
- pr_err("incompatible file format (rerun with -v to learn more)");
- return -1;
- }
+ if (!strcmp(self->filename, "-")) {
+ self->fd_pipe = true;
+ self->fd = STDIN_FILENO;
+
+ if (perf_session__read_header(self) < 0)
+ pr_err("incompatible file format (rerun with -v to learn more)");
- if (perf_data_file__is_pipe(file))
return 0;
+ }
+
+ self->fd = open(self->filename, O_RDONLY);
+ if (self->fd < 0) {
+ int err = errno;
+
+ pr_err("failed to open %s: %s", self->filename, strerror(err));
+ if (err == ENOENT && !strcmp(self->filename, "perf.data"))
+ pr_err(" (try 'perf record' first)");
+ pr_err("\n");
+ return -errno;
+ }
+
+ if (fstat(self->fd, &input_stat) < 0)
+ goto out_close;
+
+ if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
+ pr_err("file %s not owned by current user or root\n",
+ self->filename);
+ goto out_close;
+ }
+
+ if (!input_stat.st_size) {
+ pr_info("zero-sized file (%s), nothing to do!\n",
+ self->filename);
+ goto out_close;
+ }
- if (!perf_evlist__valid_sample_type(session->evlist)) {
+ if (perf_session__read_header(self) < 0) {
+ pr_err("incompatible file format (rerun with -v to learn more)");
+ goto out_close;
+ }
+
+ if (!perf_evlist__valid_sample_type(self->evlist)) {
pr_err("non matching sample_type");
- return -1;
+ goto out_close;
}
- if (!perf_evlist__valid_sample_id_all(session->evlist)) {
+ if (!perf_evlist__valid_sample_id_all(self->evlist)) {
pr_err("non matching sample_id_all");
- return -1;
+ goto out_close;
}
- if (!perf_evlist__valid_read_format(session->evlist)) {
+ if (!perf_evlist__valid_read_format(self->evlist)) {
pr_err("non matching read_format");
- return -1;
+ goto out_close;
}
+ self->size = input_stat.st_size;
return 0;
+
+out_close:
+ close(self->fd);
+ self->fd = -1;
+ return -1;
}
void perf_session__set_id_hdr_size(struct perf_session *session)
@@ -53,70 +92,71 @@ void perf_session__set_id_hdr_size(struct perf_session *session)
machines__set_id_hdr_size(&session->machines, id_hdr_size);
}
-int perf_session__create_kernel_maps(struct perf_session *session)
+int perf_session__create_kernel_maps(struct perf_session *self)
{
- int ret = machine__create_kernel_maps(&session->machines.host);
+ int ret = machine__create_kernel_maps(&self->machines.host);
if (ret >= 0)
- ret = machines__create_guest_kernel_maps(&session->machines);
+ ret = machines__create_guest_kernel_maps(&self->machines);
return ret;
}
-static void perf_session__destroy_kernel_maps(struct perf_session *session)
+static void perf_session__destroy_kernel_maps(struct perf_session *self)
{
- machines__destroy_kernel_maps(&session->machines);
+ machines__destroy_kernel_maps(&self->machines);
}
-struct perf_session *perf_session__new(struct perf_data_file *file,
- bool repipe, struct perf_tool *tool)
+struct perf_session *perf_session__new(const char *filename, int mode,
+ bool force, bool repipe,
+ struct perf_tool *tool)
{
- struct perf_session *session = zalloc(sizeof(*session));
-
- if (!session)
- goto out;
-
- session->repipe = repipe;
- INIT_LIST_HEAD(&session->ordered_samples.samples);
- INIT_LIST_HEAD(&session->ordered_samples.sample_cache);
- INIT_LIST_HEAD(&session->ordered_samples.to_free);
- machines__init(&session->machines);
+ struct perf_session *self;
+ struct stat st;
+ size_t len;
- if (file) {
- if (perf_data_file__open(file))
- goto out_delete;
+ if (!filename || !strlen(filename)) {
+ if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
+ filename = "-";
+ else
+ filename = "perf.data";
+ }
- session->file = file;
+ len = strlen(filename);
+ self = zalloc(sizeof(*self) + len);
- if (perf_data_file__is_read(file)) {
- if (perf_session__open(session) < 0)
- goto out_close;
+ if (self == NULL)
+ goto out;
- perf_session__set_id_hdr_size(session);
- }
- }
+ memcpy(self->filename, filename, len);
+ self->repipe = repipe;
+ INIT_LIST_HEAD(&self->ordered_samples.samples);
+ INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
+ INIT_LIST_HEAD(&self->ordered_samples.to_free);
+ machines__init(&self->machines);
- if (!file || perf_data_file__is_write(file)) {
+ if (mode == O_RDONLY) {
+ if (perf_session__open(self, force) < 0)
+ goto out_delete;
+ perf_session__set_id_hdr_size(self);
+ } else if (mode == O_WRONLY) {
/*
* In O_RDONLY mode this will be performed when reading the
* kernel MMAP event, in perf_event__process_mmap().
*/
- if (perf_session__create_kernel_maps(session) < 0)
+ if (perf_session__create_kernel_maps(self) < 0)
goto out_delete;
}
if (tool && tool->ordering_requires_timestamps &&
- tool->ordered_samples && !perf_evlist__sample_id_all(session->evlist)) {
+ tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) {
dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
tool->ordered_samples = false;
}
- return session;
-
- out_close:
- perf_data_file__close(file);
- out_delete:
- perf_session__delete(session);
- out:
+out:
+ return self;
+out_delete:
+ perf_session__delete(self);
return NULL;
}
@@ -146,16 +186,15 @@ static void perf_session_env__delete(struct perf_session_env *env)
free(env->pmu_mappings);
}
-void perf_session__delete(struct perf_session *session)
+void perf_session__delete(struct perf_session *self)
{
- perf_session__destroy_kernel_maps(session);
- perf_session__delete_dead_threads(session);
- perf_session__delete_threads(session);
- perf_session_env__delete(&session->header.env);
- machines__exit(&session->machines);
- if (session->file)
- perf_data_file__close(session->file);
- free(session);
+ perf_session__destroy_kernel_maps(self);
+ perf_session__delete_dead_threads(self);
+ perf_session__delete_threads(self);
+ perf_session_env__delete(&self->header.env);
+ machines__exit(&self->machines);
+ close(self->fd);
+ free(self);
vdso__exit();
}
@@ -358,17 +397,6 @@ static void perf_event__read_swap(union perf_event *event, bool sample_id_all)
swap_sample_id_all(event, &event->read + 1);
}
-static void perf_event__throttle_swap(union perf_event *event,
- bool sample_id_all)
-{
- event->throttle.time = bswap_64(event->throttle.time);
- event->throttle.id = bswap_64(event->throttle.id);
- event->throttle.stream_id = bswap_64(event->throttle.stream_id);
-
- if (sample_id_all)
- swap_sample_id_all(event, &event->throttle + 1);
-}
-
static u8 revbyte(u8 b)
{
int rev = (b >> 4) | ((b & 0xf) << 4);
@@ -414,9 +442,6 @@ void perf_event__attr_swap(struct perf_event_attr *attr)
attr->bp_type = bswap_32(attr->bp_type);
attr->bp_addr = bswap_64(attr->bp_addr);
attr->bp_len = bswap_64(attr->bp_len);
- attr->branch_sample_type = bswap_64(attr->branch_sample_type);
- attr->sample_regs_user = bswap_64(attr->sample_regs_user);
- attr->sample_stack_user = bswap_32(attr->sample_stack_user);
swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64));
}
@@ -457,8 +482,6 @@ static perf_event__swap_op perf_event__swap_ops[] = {
[PERF_RECORD_EXIT] = perf_event__task_swap,
[PERF_RECORD_LOST] = perf_event__all64_swap,
[PERF_RECORD_READ] = perf_event__read_swap,
- [PERF_RECORD_THROTTLE] = perf_event__throttle_swap,
- [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap,
[PERF_RECORD_SAMPLE] = perf_event__all64_swap,
[PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
[PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
@@ -502,16 +525,13 @@ static int flush_sample_queue(struct perf_session *s,
struct perf_sample sample;
u64 limit = os->next_flush;
u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
+ unsigned idx = 0, progress_next = os->nr_samples / 16;
bool show_progress = limit == ULLONG_MAX;
- struct ui_progress prog;
int ret;
if (!tool->ordered_samples || !limit)
return 0;
- if (show_progress)
- ui_progress__init(&prog, os->nr_samples, "Processing time ordered events...");
-
list_for_each_entry_safe(iter, tmp, head, list) {
if (session_done())
return 0;
@@ -532,9 +552,11 @@ static int flush_sample_queue(struct perf_session *s,
os->last_flush = iter->timestamp;
list_del(&iter->list);
list_add(&iter->list, &os->sample_cache);
-
- if (show_progress)
- ui_progress__update(&prog, 1);
+ if (show_progress && (++idx >= progress_next)) {
+ progress_next += os->nr_samples / 16;
+ ui_progress__update(idx, os->nr_samples,
+ "Processing time ordered events...");
+ }
}
if (list_empty(head)) {
@@ -838,9 +860,6 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
if (sample_type & PERF_SAMPLE_DATA_SRC)
printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
- if (sample_type & PERF_SAMPLE_TRANSACTION)
- printf("... transaction: %" PRIx64 "\n", sample->transaction);
-
if (sample_type & PERF_SAMPLE_READ)
sample_read__printf(sample, evsel->attr.read_format);
}
@@ -1012,7 +1031,6 @@ static int perf_session_deliver_event(struct perf_session *session,
static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
struct perf_tool *tool, u64 file_offset)
{
- int fd = perf_data_file__fd(session->file);
int err;
dump_event(session, event, file_offset, NULL);
@@ -1026,7 +1044,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
return err;
case PERF_RECORD_HEADER_TRACING_DATA:
/* setup for reading amidst mmap */
- lseek(fd, file_offset, SEEK_SET);
+ lseek(session->fd, file_offset, SEEK_SET);
return tool->tracing_data(tool, event, session);
case PERF_RECORD_HEADER_BUILD_ID:
return tool->build_id(tool, event, session);
@@ -1083,11 +1101,11 @@ static int perf_session__process_event(struct perf_session *session,
file_offset);
}
-void perf_event_header__bswap(struct perf_event_header *hdr)
+void perf_event_header__bswap(struct perf_event_header *self)
{
- hdr->type = bswap_32(hdr->type);
- hdr->misc = bswap_16(hdr->misc);
- hdr->size = bswap_16(hdr->size);
+ self->type = bswap_32(self->type);
+ self->misc = bswap_16(self->misc);
+ self->size = bswap_16(self->size);
}
struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
@@ -1095,11 +1113,11 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
return machine__findnew_thread(&session->machines.host, 0, pid);
}
-static struct thread *perf_session__register_idle_thread(struct perf_session *session)
+static struct thread *perf_session__register_idle_thread(struct perf_session *self)
{
- struct thread *thread = perf_session__findnew(session, 0);
+ struct thread *thread = perf_session__findnew(self, 0);
- if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
+ if (thread == NULL || thread__set_comm(thread, "swapper")) {
pr_err("problem inserting idle task.\n");
thread = NULL;
}
@@ -1149,10 +1167,9 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
volatile int session_done;
-static int __perf_session__process_pipe_events(struct perf_session *session,
+static int __perf_session__process_pipe_events(struct perf_session *self,
struct perf_tool *tool)
{
- int fd = perf_data_file__fd(session->file);
union perf_event *event;
uint32_t size, cur_size = 0;
void *buf = NULL;
@@ -1171,7 +1188,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session,
return -errno;
more:
event = buf;
- err = readn(fd, event, sizeof(struct perf_event_header));
+ err = readn(self->fd, event, sizeof(struct perf_event_header));
if (err <= 0) {
if (err == 0)
goto done;
@@ -1180,7 +1197,7 @@ more:
goto out_err;
}
- if (session->header.needs_swap)
+ if (self->header.needs_swap)
perf_event_header__bswap(&event->header);
size = event->header.size;
@@ -1203,7 +1220,7 @@ more:
p += sizeof(struct perf_event_header);
if (size - sizeof(struct perf_event_header)) {
- err = readn(fd, p, size - sizeof(struct perf_event_header));
+ err = readn(self->fd, p, size - sizeof(struct perf_event_header));
if (err <= 0) {
if (err == 0) {
pr_err("unexpected end of event stream\n");
@@ -1215,7 +1232,7 @@ more:
}
}
- if ((skip = perf_session__process_event(session, event, tool, head)) < 0) {
+ if ((skip = perf_session__process_event(self, event, tool, head)) < 0) {
pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
head, event->header.size, event->header.type);
err = -EINVAL;
@@ -1230,13 +1247,11 @@ more:
if (!session_done())
goto more;
done:
- /* do the final flush for ordered samples */
- session->ordered_samples.next_flush = ULLONG_MAX;
- err = flush_sample_queue(session, tool);
+ err = 0;
out_err:
free(buf);
- perf_session__warn_about_errors(session, tool);
- perf_session_free_sample_buffers(session);
+ perf_session__warn_about_errors(self, tool);
+ perf_session_free_sample_buffers(self);
return err;
}
@@ -1284,14 +1299,12 @@ int __perf_session__process_events(struct perf_session *session,
u64 data_offset, u64 data_size,
u64 file_size, struct perf_tool *tool)
{
- int fd = perf_data_file__fd(session->file);
- u64 head, page_offset, file_offset, file_pos;
+ u64 head, page_offset, file_offset, file_pos, progress_next;
int err, mmap_prot, mmap_flags, map_idx = 0;
size_t mmap_size;
char *buf, *mmaps[NUM_MMAPS];
union perf_event *event;
uint32_t size;
- struct ui_progress prog;
perf_tool__fill_defaults(tool);
@@ -1302,7 +1315,7 @@ int __perf_session__process_events(struct perf_session *session,
if (data_size && (data_offset + data_size < file_size))
file_size = data_offset + data_size;
- ui_progress__init(&prog, file_size, "Processing events...");
+ progress_next = file_size / 16;
mmap_size = MMAP_SIZE;
if (mmap_size > file_size)
@@ -1318,7 +1331,7 @@ int __perf_session__process_events(struct perf_session *session,
mmap_flags = MAP_PRIVATE;
}
remap:
- buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, fd,
+ buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd,
file_offset);
if (buf == MAP_FAILED) {
pr_err("failed to mmap file\n");
@@ -1357,15 +1370,19 @@ more:
head += size;
file_pos += size;
- ui_progress__update(&prog, size);
+ if (file_pos >= progress_next) {
+ progress_next += file_size / 16;
+ ui_progress__update(file_pos, file_size,
+ "Processing events...");
+ }
+ err = 0;
if (session_done())
- goto out;
+ goto out_err;
if (file_pos < file_size)
goto more;
-out:
/* do the final flush for ordered samples */
session->ordered_samples.next_flush = ULLONG_MAX;
err = flush_sample_queue(session, tool);
@@ -1376,22 +1393,21 @@ out_err:
return err;
}
-int perf_session__process_events(struct perf_session *session,
+int perf_session__process_events(struct perf_session *self,
struct perf_tool *tool)
{
- u64 size = perf_data_file__size(session->file);
int err;
- if (perf_session__register_idle_thread(session) == NULL)
+ if (perf_session__register_idle_thread(self) == NULL)
return -ENOMEM;
- if (!perf_data_file__is_pipe(session->file))
- err = __perf_session__process_events(session,
- session->header.data_offset,
- session->header.data_size,
- size, tool);
+ if (!self->fd_pipe)
+ err = __perf_session__process_events(self,
+ self->header.data_offset,
+ self->header.data_size,
+ self->size, tool);
else
- err = __perf_session__process_pipe_events(session, tool);
+ err = __perf_session__process_pipe_events(self, tool);
return err;
}
@@ -1440,15 +1456,15 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
return 0;
}
-size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
{
- return machines__fprintf_dsos(&session->machines, fp);
+ return machines__fprintf_dsos(&self->machines, fp);
}
-size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
+size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
bool (skip)(struct dso *dso, int parm), int parm)
{
- return machines__fprintf_dsos_buildid(&session->machines, fp, skip, parm);
+ return machines__fprintf_dsos_buildid(&self->machines, fp, skip, parm);
}
size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
@@ -1509,8 +1525,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event,
if (symbol_conf.use_callchain && sample->callchain) {
if (machine__resolve_callchain(machine, evsel, al.thread,
- sample, NULL, NULL,
- PERF_MAX_STACK_DEPTH) != 0) {
+ sample, NULL, NULL) != 0) {
if (verbose)
error("Failed to resolve callchain. Skipping\n");
return;
@@ -1614,14 +1629,13 @@ int perf_session__cpu_bitmap(struct perf_session *session,
void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
bool full)
{
- int fd = perf_data_file__fd(session->file);
struct stat st;
int ret;
if (session == NULL || fp == NULL)
return;
- ret = fstat(fd, &st);
+ ret = fstat(session->fd, &st);
if (ret == -1)
return;
@@ -1650,9 +1664,9 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
continue;
err = -EEXIST;
- if (evsel->handler != NULL)
+ if (evsel->handler.func != NULL)
goto out;
- evsel->handler = assocs[i].handler;
+ evsel->handler.func = assocs[i].handler;
}
err = 0;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 50f6409..04bf737 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -7,7 +7,6 @@
#include "machine.h"
#include "symbol.h"
#include "thread.h"
-#include "data.h"
#include <linux/rbtree.h>
#include <linux/perf_event.h>
@@ -30,13 +29,16 @@ struct ordered_samples {
struct perf_session {
struct perf_header header;
+ unsigned long size;
struct machines machines;
struct perf_evlist *evlist;
struct pevent *pevent;
struct events_stats stats;
+ int fd;
+ bool fd_pipe;
bool repipe;
struct ordered_samples ordered_samples;
- struct perf_data_file *file;
+ char filename[1];
};
#define PRINT_IP_OPT_IP (1<<0)
@@ -47,16 +49,17 @@ struct perf_session {
struct perf_tool;
-struct perf_session *perf_session__new(struct perf_data_file *file,
- bool repipe, struct perf_tool *tool);
+struct perf_session *perf_session__new(const char *filename, int mode,
+ bool force, bool repipe,
+ struct perf_tool *tool);
void perf_session__delete(struct perf_session *session);
-void perf_event_header__bswap(struct perf_event_header *hdr);
+void perf_event_header__bswap(struct perf_event_header *self);
-int __perf_session__process_events(struct perf_session *session,
+int __perf_session__process_events(struct perf_session *self,
u64 data_offset, u64 data_size, u64 size,
struct perf_tool *tool);
-int perf_session__process_events(struct perf_session *session,
+int perf_session__process_events(struct perf_session *self,
struct perf_tool *tool);
int perf_session_queue_event(struct perf_session *s, union perf_event *event,
@@ -64,38 +67,37 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
void perf_tool__fill_defaults(struct perf_tool *tool);
-int perf_session__resolve_callchain(struct perf_session *session,
- struct perf_evsel *evsel,
+int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel *evsel,
struct thread *thread,
struct ip_callchain *chain,
struct symbol **parent);
-bool perf_session__has_traces(struct perf_session *session, const char *msg);
+bool perf_session__has_traces(struct perf_session *self, const char *msg);
void mem_bswap_64(void *src, int byte_size);
void mem_bswap_32(void *src, int byte_size);
void perf_event__attr_swap(struct perf_event_attr *attr);
-int perf_session__create_kernel_maps(struct perf_session *session);
+int perf_session__create_kernel_maps(struct perf_session *self);
void perf_session__set_id_hdr_size(struct perf_session *session);
static inline
-struct machine *perf_session__find_machine(struct perf_session *session, pid_t pid)
+struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
{
- return machines__find(&session->machines, pid);
+ return machines__find(&self->machines, pid);
}
static inline
-struct machine *perf_session__findnew_machine(struct perf_session *session, pid_t pid)
+struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
{
- return machines__findnew(&session->machines, pid);
+ return machines__findnew(&self->machines, pid);
}
-struct thread *perf_session__findnew(struct perf_session *session, pid_t pid);
-size_t perf_session__fprintf(struct perf_session *session, FILE *fp);
+struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
+size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
-size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp);
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
bool (fn)(struct dso *dso, int parm), int parm);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 8b0bb1f..5f118a0 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1,6 +1,5 @@
#include "sort.h"
#include "hist.h"
-#include "comm.h"
#include "symbol.h"
regex_t parent_regex;
@@ -43,7 +42,7 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
return n;
}
-static int64_t cmp_null(const void *l, const void *r)
+static int64_t cmp_null(void *l, void *r)
{
if (!l && !r)
return 0;
@@ -61,12 +60,11 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
return right->thread->tid - left->thread->tid;
}
-static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- const char *comm = thread__comm_str(he->thread);
return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
- comm ?: "", he->thread->tid);
+ self->thread->comm ?: "", self->thread->tid);
}
struct sort_entry sort_thread = {
@@ -81,21 +79,25 @@ struct sort_entry sort_thread = {
static int64_t
sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
{
- /* Compare the addr that should be unique among comm */
- return comm__str(right->comm) - comm__str(left->comm);
+ return right->thread->tid - left->thread->tid;
}
static int64_t
sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
{
- /* Compare the addr that should be unique among comm */
- return comm__str(right->comm) - comm__str(left->comm);
+ char *comm_l = left->thread->comm;
+ char *comm_r = right->thread->comm;
+
+ if (!comm_l || !comm_r)
+ return cmp_null(comm_l, comm_r);
+
+ return strcmp(comm_l, comm_r);
}
-static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm));
+ return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
}
struct sort_entry sort_comm = {
@@ -146,10 +148,10 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
}
-static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
+ return _hist_entry__dso_snprintf(self->ms.map, bf, size, width);
}
struct sort_entry sort_dso = {
@@ -180,19 +182,9 @@ static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
static int64_t
sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
{
- int64_t ret;
-
if (!left->ms.sym && !right->ms.sym)
return right->level - left->level;
- /*
- * comparing symbol address alone is not enough since it's a
- * relative address within a dso.
- */
- ret = sort__dso_cmp(left, right);
- if (ret != 0)
- return ret;
-
return _sort__sym_cmp(left->ms.sym, right->ms.sym);
}
@@ -232,11 +224,11 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
return ret;
}
-static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
- he->level, bf, size, width);
+ return _hist_entry__sym_snprintf(self->ms.map, self->ms.sym, self->ip,
+ self->level, bf, size, width);
}
struct sort_entry sort_sym = {
@@ -251,32 +243,50 @@ struct sort_entry sort_sym = {
static int64_t
sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
{
- if (!left->srcline) {
- if (!left->ms.map)
- left->srcline = SRCLINE_UNKNOWN;
- else {
- struct map *map = left->ms.map;
- left->srcline = get_srcline(map->dso,
- map__rip_2objdump(map, left->ip));
- }
- }
- if (!right->srcline) {
- if (!right->ms.map)
- right->srcline = SRCLINE_UNKNOWN;
- else {
- struct map *map = right->ms.map;
- right->srcline = get_srcline(map->dso,
- map__rip_2objdump(map, right->ip));
- }
- }
- return strcmp(left->srcline, right->srcline);
+ return (int64_t)(right->ip - left->ip);
}
-static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
size_t size,
unsigned int width __maybe_unused)
{
- return repsep_snprintf(bf, size, "%s", he->srcline);
+ FILE *fp = NULL;
+ char cmd[PATH_MAX + 2], *path = self->srcline, *nl;
+ size_t line_len;
+
+ if (path != NULL)
+ goto out_path;
+
+ if (!self->ms.map)
+ goto out_ip;
+
+ if (!strncmp(self->ms.map->dso->long_name, "/tmp/perf-", 10))
+ goto out_ip;
+
+ snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64,
+ self->ms.map->dso->long_name, self->ip);
+ fp = popen(cmd, "r");
+ if (!fp)
+ goto out_ip;
+
+ if (getline(&path, &line_len, fp) < 0 || !line_len)
+ goto out_ip;
+ self->srcline = strdup(path);
+ if (self->srcline == NULL)
+ goto out_ip;
+
+ nl = strchr(self->srcline, '\n');
+ if (nl != NULL)
+ *nl = '\0';
+ path = self->srcline;
+out_path:
+ if (fp)
+ pclose(fp);
+ return repsep_snprintf(bf, size, "%s", path);
+out_ip:
+ if (fp)
+ pclose(fp);
+ return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip);
}
struct sort_entry sort_srcline = {
@@ -300,11 +310,11 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(sym_l->name, sym_r->name);
}
-static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
return repsep_snprintf(bf, size, "%-*s", width,
- he->parent ? he->parent->name : "[other]");
+ self->parent ? self->parent->name : "[other]");
}
struct sort_entry sort_parent = {
@@ -322,10 +332,10 @@ sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
return right->cpu - left->cpu;
}
-static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
+static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%*d", width, he->cpu);
+ return repsep_snprintf(bf, size, "%*d", width, self->cpu);
}
struct sort_entry sort_cpu = {
@@ -344,10 +354,10 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->from.map);
}
-static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_from_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(he->branch_info->from.map,
+ return _hist_entry__dso_snprintf(self->branch_info->from.map,
bf, size, width);
}
@@ -358,10 +368,10 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
right->branch_info->to.map);
}
-static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_to_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return _hist_entry__dso_snprintf(he->branch_info->to.map,
+ return _hist_entry__dso_snprintf(self->branch_info->to.map,
bf, size, width);
}
@@ -389,21 +399,21 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
return _sort__sym_cmp(to_l->sym, to_r->sym);
}
-static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_from_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- struct addr_map_symbol *from = &he->branch_info->from;
+ struct addr_map_symbol *from = &self->branch_info->from;
return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
- he->level, bf, size, width);
+ self->level, bf, size, width);
}
-static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_to_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- struct addr_map_symbol *to = &he->branch_info->to;
+ struct addr_map_symbol *to = &self->branch_info->to;
return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
- he->level, bf, size, width);
+ self->level, bf, size, width);
}
@@ -446,13 +456,13 @@ sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
return mp || p;
}
-static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width){
static const char *out = "N/A";
- if (he->branch_info->flags.predicted)
+ if (self->branch_info->flags.predicted)
out = "N";
- else if (he->branch_info->flags.mispred)
+ else if (self->branch_info->flags.mispred)
out = "Y";
return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -472,19 +482,19 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
return (int64_t)(r - l);
}
-static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
uint64_t addr = 0;
struct map *map = NULL;
struct symbol *sym = NULL;
- if (he->mem_info) {
- addr = he->mem_info->daddr.addr;
- map = he->mem_info->daddr.map;
- sym = he->mem_info->daddr.sym;
+ if (self->mem_info) {
+ addr = self->mem_info->daddr.addr;
+ map = self->mem_info->daddr.map;
+ sym = self->mem_info->daddr.sym;
}
- return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
+ return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size,
width);
}
@@ -502,13 +512,13 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
return _sort__dso_cmp(map_l, map_r);
}
-static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
struct map *map = NULL;
- if (he->mem_info)
- map = he->mem_info->daddr.map;
+ if (self->mem_info)
+ map = self->mem_info->daddr.map;
return _hist_entry__dso_snprintf(map, bf, size, width);
}
@@ -532,14 +542,14 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
}
-static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
const char *out;
u64 mask = PERF_MEM_LOCK_NA;
- if (he->mem_info)
- mask = he->mem_info->data_src.mem_lock;
+ if (self->mem_info)
+ mask = self->mem_info->data_src.mem_lock;
if (mask & PERF_MEM_LOCK_NA)
out = "N/A";
@@ -581,7 +591,7 @@ static const char * const tlb_access[] = {
};
#define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
-static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -592,8 +602,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
out[0] = '\0';
- if (he->mem_info)
- m = he->mem_info->data_src.mem_dtlb;
+ if (self->mem_info)
+ m = self->mem_info->data_src.mem_dtlb;
hit = m & PERF_MEM_TLB_HIT;
miss = m & PERF_MEM_TLB_MISS;
@@ -658,7 +668,7 @@ static const char * const mem_lvl[] = {
};
#define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
-static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -667,8 +677,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
u64 m = PERF_MEM_LVL_NA;
u64 hit, miss;
- if (he->mem_info)
- m = he->mem_info->data_src.mem_lvl;
+ if (self->mem_info)
+ m = self->mem_info->data_src.mem_lvl;
out[0] = '\0';
@@ -726,7 +736,7 @@ static const char * const snoop_access[] = {
};
#define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
-static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
char out[64];
@@ -736,8 +746,8 @@ static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
out[0] = '\0';
- if (he->mem_info)
- m = he->mem_info->data_src.mem_snoop;
+ if (self->mem_info)
+ m = self->mem_info->data_src.mem_snoop;
for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) {
if (!(m & 0x1))
@@ -774,10 +784,10 @@ sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
return he_weight(left) - he_weight(right);
}
-static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
+ return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
}
struct sort_entry sort_local_weight = {
@@ -793,10 +803,10 @@ sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
return left->stat.weight - right->stat.weight;
}
-static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width)
{
- return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
+ return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
}
struct sort_entry sort_global_weight = {
@@ -848,127 +858,6 @@ struct sort_entry sort_mem_snoop = {
.se_width_idx = HISTC_MEM_SNOOP,
};
-static int64_t
-sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return left->branch_info->flags.abort !=
- right->branch_info->flags.abort;
-}
-
-static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
-{
- static const char *out = ".";
-
- if (he->branch_info->flags.abort)
- out = "A";
- return repsep_snprintf(bf, size, "%-*s", width, out);
-}
-
-struct sort_entry sort_abort = {
- .se_header = "Transaction abort",
- .se_cmp = sort__abort_cmp,
- .se_snprintf = hist_entry__abort_snprintf,
- .se_width_idx = HISTC_ABORT,
-};
-
-static int64_t
-sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return left->branch_info->flags.in_tx !=
- right->branch_info->flags.in_tx;
-}
-
-static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
-{
- static const char *out = ".";
-
- if (he->branch_info->flags.in_tx)
- out = "T";
-
- return repsep_snprintf(bf, size, "%-*s", width, out);
-}
-
-struct sort_entry sort_in_tx = {
- .se_header = "Branch in transaction",
- .se_cmp = sort__in_tx_cmp,
- .se_snprintf = hist_entry__in_tx_snprintf,
- .se_width_idx = HISTC_IN_TX,
-};
-
-static int64_t
-sort__transaction_cmp(struct hist_entry *left, struct hist_entry *right)
-{
- return left->transaction - right->transaction;
-}
-
-static inline char *add_str(char *p, const char *str)
-{
- strcpy(p, str);
- return p + strlen(str);
-}
-
-static struct txbit {
- unsigned flag;
- const char *name;
- int skip_for_len;
-} txbits[] = {
- { PERF_TXN_ELISION, "EL ", 0 },
- { PERF_TXN_TRANSACTION, "TX ", 1 },
- { PERF_TXN_SYNC, "SYNC ", 1 },
- { PERF_TXN_ASYNC, "ASYNC ", 0 },
- { PERF_TXN_RETRY, "RETRY ", 0 },
- { PERF_TXN_CONFLICT, "CON ", 0 },
- { PERF_TXN_CAPACITY_WRITE, "CAP-WRITE ", 1 },
- { PERF_TXN_CAPACITY_READ, "CAP-READ ", 0 },
- { 0, NULL, 0 }
-};
-
-int hist_entry__transaction_len(void)
-{
- int i;
- int len = 0;
-
- for (i = 0; txbits[i].name; i++) {
- if (!txbits[i].skip_for_len)
- len += strlen(txbits[i].name);
- }
- len += 4; /* :XX<space> */
- return len;
-}
-
-static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
-{
- u64 t = he->transaction;
- char buf[128];
- char *p = buf;
- int i;
-
- buf[0] = 0;
- for (i = 0; txbits[i].name; i++)
- if (txbits[i].flag & t)
- p = add_str(p, txbits[i].name);
- if (t && !(t & (PERF_TXN_SYNC|PERF_TXN_ASYNC)))
- p = add_str(p, "NEITHER ");
- if (t & PERF_TXN_ABORT_MASK) {
- sprintf(p, ":%" PRIx64,
- (t & PERF_TXN_ABORT_MASK) >>
- PERF_TXN_ABORT_SHIFT);
- p += strlen(p);
- }
-
- return repsep_snprintf(bf, size, "%-*s", width, buf);
-}
-
-struct sort_entry sort_transaction = {
- .se_header = "Transaction ",
- .se_cmp = sort__transaction_cmp,
- .se_snprintf = hist_entry__transaction_snprintf,
- .se_width_idx = HISTC_TRANSACTION,
-};
-
struct sort_dimension {
const char *name;
struct sort_entry *entry;
@@ -987,7 +876,6 @@ static struct sort_dimension common_sort_dimensions[] = {
DIM(SORT_SRCLINE, "srcline", sort_srcline),
DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
- DIM(SORT_TRANSACTION, "transaction", sort_transaction),
};
#undef DIM
@@ -1000,8 +888,6 @@ static struct sort_dimension bstack_sort_dimensions[] = {
DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),
DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
- DIM(SORT_IN_TX, "in_tx", sort_in_tx),
- DIM(SORT_ABORT, "abort", sort_abort),
};
#undef DIM
@@ -1123,7 +1009,7 @@ int setup_sorting(void)
return ret;
}
-static void sort_entry__setup_elide(struct sort_entry *se,
+static void sort_entry__setup_elide(struct sort_entry *self,
struct strlist *list,
const char *list_name, FILE *fp)
{
@@ -1131,14 +1017,12 @@ static void sort_entry__setup_elide(struct sort_entry *se,
if (fp != NULL)
fprintf(fp, "# %s: %s\n", list_name,
strlist__entry(list, 0)->s);
- se->elide = true;
+ self->elide = true;
}
}
void sort__setup_elide(FILE *output)
{
- struct sort_entry *se;
-
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"dso", output);
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
@@ -1174,15 +1058,4 @@ void sort__setup_elide(FILE *output)
"snoop", output);
}
- /*
- * It makes no sense to elide all of sort entries.
- * Just revert them to show up again.
- */
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- if (!se->elide)
- return;
- }
-
- list_for_each_entry(se, &hist_entry__sort_list, list)
- se->elide = false;
}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 43e5ff4..4e80dbd 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -22,6 +22,7 @@
#include "parse-events.h"
#include "thread.h"
+#include "sort.h"
extern regex_t parent_regex;
extern const char *sort_order;
@@ -83,9 +84,7 @@ struct hist_entry {
struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
- struct comm *comm;
u64 ip;
- u64 transaction;
s32 cpu;
struct hist_entry_diff diff;
@@ -146,7 +145,6 @@ enum sort_type {
SORT_SRCLINE,
SORT_LOCAL_WEIGHT,
SORT_GLOBAL_WEIGHT,
- SORT_TRANSACTION,
/* branch stack specific sort keys */
__SORT_BRANCH_STACK,
@@ -155,8 +153,6 @@ enum sort_type {
SORT_SYM_FROM,
SORT_SYM_TO,
SORT_MISPREDICT,
- SORT_ABORT,
- SORT_IN_TX,
/* memory mode specific sort keys */
__SORT_MEMORY_MODE,
@@ -179,7 +175,7 @@ struct sort_entry {
int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
- int (*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
+ int (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
unsigned int width);
u8 se_width_idx;
bool elide;
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
deleted file mode 100644
index d11aefb..0000000
--- a/tools/perf/util/srcline.c
+++ /dev/null
@@ -1,265 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <linux/kernel.h>
-
-#include "util/dso.h"
-#include "util/util.h"
-#include "util/debug.h"
-
-#ifdef HAVE_LIBBFD_SUPPORT
-
-/*
- * Implement addr2line using libbfd.
- */
-#define PACKAGE "perf"
-#include <bfd.h>
-
-struct a2l_data {
- const char *input;
- unsigned long addr;
-
- bool found;
- const char *filename;
- const char *funcname;
- unsigned line;
-
- bfd *abfd;
- asymbol **syms;
-};
-
-static int bfd_error(const char *string)
-{
- const char *errmsg;
-
- errmsg = bfd_errmsg(bfd_get_error());
- fflush(stdout);
-
- if (string)
- pr_debug("%s: %s\n", string, errmsg);
- else
- pr_debug("%s\n", errmsg);
-
- return -1;
-}
-
-static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
-{
- long storage;
- long symcount;
- asymbol **syms;
- bfd_boolean dynamic = FALSE;
-
- if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
- return bfd_error(bfd_get_filename(abfd));
-
- storage = bfd_get_symtab_upper_bound(abfd);
- if (storage == 0L) {
- storage = bfd_get_dynamic_symtab_upper_bound(abfd);
- dynamic = TRUE;
- }
- if (storage < 0L)
- return bfd_error(bfd_get_filename(abfd));
-
- syms = malloc(storage);
- if (dynamic)
- symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
- else
- symcount = bfd_canonicalize_symtab(abfd, syms);
-
- if (symcount < 0) {
- free(syms);
- return bfd_error(bfd_get_filename(abfd));
- }
-
- a2l->syms = syms;
- return 0;
-}
-
-static void find_address_in_section(bfd *abfd, asection *section, void *data)
-{
- bfd_vma pc, vma;
- bfd_size_type size;
- struct a2l_data *a2l = data;
-
- if (a2l->found)
- return;
-
- if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
- return;
-
- pc = a2l->addr;
- vma = bfd_get_section_vma(abfd, section);
- size = bfd_get_section_size(section);
-
- if (pc < vma || pc >= vma + size)
- return;
-
- a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
- &a2l->filename, &a2l->funcname,
- &a2l->line);
-}
-
-static struct a2l_data *addr2line_init(const char *path)
-{
- bfd *abfd;
- struct a2l_data *a2l = NULL;
-
- abfd = bfd_openr(path, NULL);
- if (abfd == NULL)
- return NULL;
-
- if (!bfd_check_format(abfd, bfd_object))
- goto out;
-
- a2l = zalloc(sizeof(*a2l));
- if (a2l == NULL)
- goto out;
-
- a2l->abfd = abfd;
- a2l->input = strdup(path);
- if (a2l->input == NULL)
- goto out;
-
- if (slurp_symtab(abfd, a2l))
- goto out;
-
- return a2l;
-
-out:
- if (a2l) {
- free((void *)a2l->input);
- free(a2l);
- }
- bfd_close(abfd);
- return NULL;
-}
-
-static void addr2line_cleanup(struct a2l_data *a2l)
-{
- if (a2l->abfd)
- bfd_close(a2l->abfd);
- free((void *)a2l->input);
- free(a2l->syms);
- free(a2l);
-}
-
-static int addr2line(const char *dso_name, unsigned long addr,
- char **file, unsigned int *line)
-{
- int ret = 0;
- struct a2l_data *a2l;
-
- a2l = addr2line_init(dso_name);
- if (a2l == NULL) {
- pr_warning("addr2line_init failed for %s\n", dso_name);
- return 0;
- }
-
- a2l->addr = addr;
- bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
-
- if (a2l->found && a2l->filename) {
- *file = strdup(a2l->filename);
- *line = a2l->line;
-
- if (*file)
- ret = 1;
- }
-
- addr2line_cleanup(a2l);
- return ret;
-}
-
-#else /* HAVE_LIBBFD_SUPPORT */
-
-static int addr2line(const char *dso_name, unsigned long addr,
- char **file, unsigned int *line_nr)
-{
- FILE *fp;
- char cmd[PATH_MAX];
- char *filename = NULL;
- size_t len;
- char *sep;
- int ret = 0;
-
- scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64,
- dso_name, addr);
-
- fp = popen(cmd, "r");
- if (fp == NULL) {
- pr_warning("popen failed for %s\n", dso_name);
- return 0;
- }
-
- if (getline(&filename, &len, fp) < 0 || !len) {
- pr_warning("addr2line has no output for %s\n", dso_name);
- goto out;
- }
-
- sep = strchr(filename, '\n');
- if (sep)
- *sep = '\0';
-
- if (!strcmp(filename, "??:0")) {
- pr_debug("no debugging info in %s\n", dso_name);
- free(filename);
- goto out;
- }
-
- sep = strchr(filename, ':');
- if (sep) {
- *sep++ = '\0';
- *file = filename;
- *line_nr = strtoul(sep, NULL, 0);
- ret = 1;
- }
-out:
- pclose(fp);
- return ret;
-}
-#endif /* HAVE_LIBBFD_SUPPORT */
-
-char *get_srcline(struct dso *dso, unsigned long addr)
-{
- char *file = NULL;
- unsigned line = 0;
- char *srcline;
- char *dso_name = dso->long_name;
- size_t size;
-
- if (!dso->has_srcline)
- return SRCLINE_UNKNOWN;
-
- if (dso_name[0] == '[')
- goto out;
-
- if (!strncmp(dso_name, "/tmp/perf-", 10))
- goto out;
-
- if (!addr2line(dso_name, addr, &file, &line))
- goto out;
-
- /* just calculate actual length */
- size = snprintf(NULL, 0, "%s:%u", file, line) + 1;
-
- srcline = malloc(size);
- if (srcline)
- snprintf(srcline, size, "%s:%u", file, line);
- else
- srcline = SRCLINE_UNKNOWN;
-
- free(file);
- return srcline;
-
-out:
- dso->has_srcline = 0;
- return SRCLINE_UNKNOWN;
-}
-
-void free_srcline(char *srcline)
-{
- if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
- free(srcline);
-}
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index 3edd053..834c8eb 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -10,22 +10,22 @@ static const char *OP_not = "!"; /* Logical NOT */
#define is_operator(c) ((c) == '|' || (c) == '&' || (c) == '!')
#define is_separator(c) (is_operator(c) || (c) == '(' || (c) == ')')
-static void strfilter_node__delete(struct strfilter_node *node)
+static void strfilter_node__delete(struct strfilter_node *self)
{
- if (node) {
- if (node->p && !is_operator(*node->p))
- free((char *)node->p);
- strfilter_node__delete(node->l);
- strfilter_node__delete(node->r);
- free(node);
+ if (self) {
+ if (self->p && !is_operator(*self->p))
+ free((char *)self->p);
+ strfilter_node__delete(self->l);
+ strfilter_node__delete(self->r);
+ free(self);
}
}
-void strfilter__delete(struct strfilter *filter)
+void strfilter__delete(struct strfilter *self)
{
- if (filter) {
- strfilter_node__delete(filter->root);
- free(filter);
+ if (self) {
+ strfilter_node__delete(self->root);
+ free(self);
}
}
@@ -62,15 +62,15 @@ static struct strfilter_node *strfilter_node__alloc(const char *op,
struct strfilter_node *l,
struct strfilter_node *r)
{
- struct strfilter_node *node = zalloc(sizeof(*node));
+ struct strfilter_node *ret = zalloc(sizeof(struct strfilter_node));
- if (node) {
- node->p = op;
- node->l = l;
- node->r = r;
+ if (ret) {
+ ret->p = op;
+ ret->l = l;
+ ret->r = r;
}
- return node;
+ return ret;
}
static struct strfilter_node *strfilter_node__new(const char *s,
@@ -154,46 +154,46 @@ error:
*/
struct strfilter *strfilter__new(const char *rules, const char **err)
{
- struct strfilter *filter = zalloc(sizeof(*filter));
+ struct strfilter *ret = zalloc(sizeof(struct strfilter));
const char *ep = NULL;
- if (filter)
- filter->root = strfilter_node__new(rules, &ep);
+ if (ret)
+ ret->root = strfilter_node__new(rules, &ep);
- if (!filter || !filter->root || *ep != '\0') {
+ if (!ret || !ret->root || *ep != '\0') {
if (err)
*err = ep;
- strfilter__delete(filter);
- filter = NULL;
+ strfilter__delete(ret);
+ ret = NULL;
}
- return filter;
+ return ret;
}
-static bool strfilter_node__compare(struct strfilter_node *node,
+static bool strfilter_node__compare(struct strfilter_node *self,
const char *str)
{
- if (!node || !node->p)
+ if (!self || !self->p)
return false;
- switch (*node->p) {
+ switch (*self->p) {
case '|': /* OR */
- return strfilter_node__compare(node->l, str) ||
- strfilter_node__compare(node->r, str);
+ return strfilter_node__compare(self->l, str) ||
+ strfilter_node__compare(self->r, str);
case '&': /* AND */
- return strfilter_node__compare(node->l, str) &&
- strfilter_node__compare(node->r, str);
+ return strfilter_node__compare(self->l, str) &&
+ strfilter_node__compare(self->r, str);
case '!': /* NOT */
- return !strfilter_node__compare(node->r, str);
+ return !strfilter_node__compare(self->r, str);
default:
- return strglobmatch(str, node->p);
+ return strglobmatch(str, self->p);
}
}
/* Return true if STR matches the filter rules */
-bool strfilter__compare(struct strfilter *filter, const char *str)
+bool strfilter__compare(struct strfilter *self, const char *str)
{
- if (!filter)
+ if (!self)
return false;
- return strfilter_node__compare(filter->root, str);
+ return strfilter_node__compare(self->root, str);
}
diff --git a/tools/perf/util/strfilter.h b/tools/perf/util/strfilter.h
index fe611f3..00f58a7 100644
--- a/tools/perf/util/strfilter.h
+++ b/tools/perf/util/strfilter.h
@@ -30,19 +30,19 @@ struct strfilter *strfilter__new(const char *rules, const char **err);
/**
* strfilter__compare - compare given string and a string filter
- * @filter: String filter
+ * @self: String filter
* @str: target string
*
- * Compare @str and @filter. Return true if the str match the rule
+ * Compare @str and @self. Return true if the str match the rule
*/
-bool strfilter__compare(struct strfilter *filter, const char *str);
+bool strfilter__compare(struct strfilter *self, const char *str);
/**
* strfilter__delete - delete a string filter
- * @filter: String filter to delete
+ * @self: String filter to delete
*
- * Delete @filter.
+ * Delete @self.
*/
-void strfilter__delete(struct strfilter *filter);
+void strfilter__delete(struct strfilter *self);
#endif
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index eed0b96..a9c829b 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -8,7 +8,7 @@
#include "symbol.h"
#include "debug.h"
-#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
+#ifndef HAVE_ELF_GETPHDRNUM
static int elf_getphdrnum(Elf *elf, size_t *dst)
{
GElf_Ehdr gehdr;
@@ -487,27 +487,27 @@ int filename__read_debuglink(const char *filename, char *debuglink,
ek = elf_kind(elf);
if (ek != ELF_K_ELF)
- goto out_elf_end;
+ goto out_close;
if (gelf_getehdr(elf, &ehdr) == NULL) {
pr_err("%s: cannot get elf header.\n", __func__);
- goto out_elf_end;
+ goto out_close;
}
sec = elf_section_by_name(elf, &ehdr, &shdr,
".gnu_debuglink", NULL);
if (sec == NULL)
- goto out_elf_end;
+ goto out_close;
data = elf_getdata(sec, NULL);
if (data == NULL)
- goto out_elf_end;
+ goto out_close;
/* the start of this section is a zero-terminated string */
strncpy(debuglink, data->d_buf, size);
-out_elf_end:
elf_end(elf);
+
out_close:
close(fd);
out:
@@ -1018,601 +1018,6 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
return err;
}
-static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)
-{
- ssize_t r;
- size_t n;
- int err = -1;
- char *buf = malloc(page_size);
-
- if (buf == NULL)
- return -1;
-
- if (lseek(to, to_offs, SEEK_SET) != to_offs)
- goto out;
-
- if (lseek(from, from_offs, SEEK_SET) != from_offs)
- goto out;
-
- while (len) {
- n = page_size;
- if (len < n)
- n = len;
- /* Use read because mmap won't work on proc files */
- r = read(from, buf, n);
- if (r < 0)
- goto out;
- if (!r)
- break;
- n = r;
- r = write(to, buf, n);
- if (r < 0)
- goto out;
- if ((size_t)r != n)
- goto out;
- len -= n;
- }
-
- err = 0;
-out:
- free(buf);
- return err;
-}
-
-struct kcore {
- int fd;
- int elfclass;
- Elf *elf;
- GElf_Ehdr ehdr;
-};
-
-static int kcore__open(struct kcore *kcore, const char *filename)
-{
- GElf_Ehdr *ehdr;
-
- kcore->fd = open(filename, O_RDONLY);
- if (kcore->fd == -1)
- return -1;
-
- kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL);
- if (!kcore->elf)
- goto out_close;
-
- kcore->elfclass = gelf_getclass(kcore->elf);
- if (kcore->elfclass == ELFCLASSNONE)
- goto out_end;
-
- ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
- if (!ehdr)
- goto out_end;
-
- return 0;
-
-out_end:
- elf_end(kcore->elf);
-out_close:
- close(kcore->fd);
- return -1;
-}
-
-static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
- bool temp)
-{
- GElf_Ehdr *ehdr;
-
- kcore->elfclass = elfclass;
-
- if (temp)
- kcore->fd = mkstemp(filename);
- else
- kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
- if (kcore->fd == -1)
- return -1;
-
- kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL);
- if (!kcore->elf)
- goto out_close;
-
- if (!gelf_newehdr(kcore->elf, elfclass))
- goto out_end;
-
- ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
- if (!ehdr)
- goto out_end;
-
- return 0;
-
-out_end:
- elf_end(kcore->elf);
-out_close:
- close(kcore->fd);
- unlink(filename);
- return -1;
-}
-
-static void kcore__close(struct kcore *kcore)
-{
- elf_end(kcore->elf);
- close(kcore->fd);
-}
-
-static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
-{
- GElf_Ehdr *ehdr = &to->ehdr;
- GElf_Ehdr *kehdr = &from->ehdr;
-
- memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT);
- ehdr->e_type = kehdr->e_type;
- ehdr->e_machine = kehdr->e_machine;
- ehdr->e_version = kehdr->e_version;
- ehdr->e_entry = 0;
- ehdr->e_shoff = 0;
- ehdr->e_flags = kehdr->e_flags;
- ehdr->e_phnum = count;
- ehdr->e_shentsize = 0;
- ehdr->e_shnum = 0;
- ehdr->e_shstrndx = 0;
-
- if (from->elfclass == ELFCLASS32) {
- ehdr->e_phoff = sizeof(Elf32_Ehdr);
- ehdr->e_ehsize = sizeof(Elf32_Ehdr);
- ehdr->e_phentsize = sizeof(Elf32_Phdr);
- } else {
- ehdr->e_phoff = sizeof(Elf64_Ehdr);
- ehdr->e_ehsize = sizeof(Elf64_Ehdr);
- ehdr->e_phentsize = sizeof(Elf64_Phdr);
- }
-
- if (!gelf_update_ehdr(to->elf, ehdr))
- return -1;
-
- if (!gelf_newphdr(to->elf, count))
- return -1;
-
- return 0;
-}
-
-static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
- u64 addr, u64 len)
-{
- GElf_Phdr gphdr;
- GElf_Phdr *phdr;
-
- phdr = gelf_getphdr(kcore->elf, idx, &gphdr);
- if (!phdr)
- return -1;
-
- phdr->p_type = PT_LOAD;
- phdr->p_flags = PF_R | PF_W | PF_X;
- phdr->p_offset = offset;
- phdr->p_vaddr = addr;
- phdr->p_paddr = 0;
- phdr->p_filesz = len;
- phdr->p_memsz = len;
- phdr->p_align = page_size;
-
- if (!gelf_update_phdr(kcore->elf, idx, phdr))
- return -1;
-
- return 0;
-}
-
-static off_t kcore__write(struct kcore *kcore)
-{
- return elf_update(kcore->elf, ELF_C_WRITE);
-}
-
-struct phdr_data {
- off_t offset;
- u64 addr;
- u64 len;
-};
-
-struct kcore_copy_info {
- u64 stext;
- u64 etext;
- u64 first_symbol;
- u64 last_symbol;
- u64 first_module;
- u64 last_module_symbol;
- struct phdr_data kernel_map;
- struct phdr_data modules_map;
-};
-
-static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
- u64 start)
-{
- struct kcore_copy_info *kci = arg;
-
- if (!symbol_type__is_a(type, MAP__FUNCTION))
- return 0;
-
- if (strchr(name, '[')) {
- if (start > kci->last_module_symbol)
- kci->last_module_symbol = start;
- return 0;
- }
-
- if (!kci->first_symbol || start < kci->first_symbol)
- kci->first_symbol = start;
-
- if (!kci->last_symbol || start > kci->last_symbol)
- kci->last_symbol = start;
-
- if (!strcmp(name, "_stext")) {
- kci->stext = start;
- return 0;
- }
-
- if (!strcmp(name, "_etext")) {
- kci->etext = start;
- return 0;
- }
-
- return 0;
-}
-
-static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci,
- const char *dir)
-{
- char kallsyms_filename[PATH_MAX];
-
- scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir);
-
- if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms"))
- return -1;
-
- if (kallsyms__parse(kallsyms_filename, kci,
- kcore_copy__process_kallsyms) < 0)
- return -1;
-
- return 0;
-}
-
-static int kcore_copy__process_modules(void *arg,
- const char *name __maybe_unused,
- u64 start)
-{
- struct kcore_copy_info *kci = arg;
-
- if (!kci->first_module || start < kci->first_module)
- kci->first_module = start;
-
- return 0;
-}
-
-static int kcore_copy__parse_modules(struct kcore_copy_info *kci,
- const char *dir)
-{
- char modules_filename[PATH_MAX];
-
- scnprintf(modules_filename, PATH_MAX, "%s/modules", dir);
-
- if (symbol__restricted_filename(modules_filename, "/proc/modules"))
- return -1;
-
- if (modules__parse(modules_filename, kci,
- kcore_copy__process_modules) < 0)
- return -1;
-
- return 0;
-}
-
-static void kcore_copy__map(struct phdr_data *p, u64 start, u64 end, u64 pgoff,
- u64 s, u64 e)
-{
- if (p->addr || s < start || s >= end)
- return;
-
- p->addr = s;
- p->offset = (s - start) + pgoff;
- p->len = e < end ? e - s : end - s;
-}
-
-static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data)
-{
- struct kcore_copy_info *kci = data;
- u64 end = start + len;
-
- kcore_copy__map(&kci->kernel_map, start, end, pgoff, kci->stext,
- kci->etext);
-
- kcore_copy__map(&kci->modules_map, start, end, pgoff, kci->first_module,
- kci->last_module_symbol);
-
- return 0;
-}
-
-static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf)
-{
- if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0)
- return -1;
-
- return 0;
-}
-
-static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir,
- Elf *elf)
-{
- if (kcore_copy__parse_kallsyms(kci, dir))
- return -1;
-
- if (kcore_copy__parse_modules(kci, dir))
- return -1;
-
- if (kci->stext)
- kci->stext = round_down(kci->stext, page_size);
- else
- kci->stext = round_down(kci->first_symbol, page_size);
-
- if (kci->etext) {
- kci->etext = round_up(kci->etext, page_size);
- } else if (kci->last_symbol) {
- kci->etext = round_up(kci->last_symbol, page_size);
- kci->etext += page_size;
- }
-
- kci->first_module = round_down(kci->first_module, page_size);
-
- if (kci->last_module_symbol) {
- kci->last_module_symbol = round_up(kci->last_module_symbol,
- page_size);
- kci->last_module_symbol += page_size;
- }
-
- if (!kci->stext || !kci->etext)
- return -1;
-
- if (kci->first_module && !kci->last_module_symbol)
- return -1;
-
- return kcore_copy__read_maps(kci, elf);
-}
-
-static int kcore_copy__copy_file(const char *from_dir, const char *to_dir,
- const char *name)
-{
- char from_filename[PATH_MAX];
- char to_filename[PATH_MAX];
-
- scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
- scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
-
- return copyfile_mode(from_filename, to_filename, 0400);
-}
-
-static int kcore_copy__unlink(const char *dir, const char *name)
-{
- char filename[PATH_MAX];
-
- scnprintf(filename, PATH_MAX, "%s/%s", dir, name);
-
- return unlink(filename);
-}
-
-static int kcore_copy__compare_fds(int from, int to)
-{
- char *buf_from;
- char *buf_to;
- ssize_t ret;
- size_t len;
- int err = -1;
-
- buf_from = malloc(page_size);
- buf_to = malloc(page_size);
- if (!buf_from || !buf_to)
- goto out;
-
- while (1) {
- /* Use read because mmap won't work on proc files */
- ret = read(from, buf_from, page_size);
- if (ret < 0)
- goto out;
-
- if (!ret)
- break;
-
- len = ret;
-
- if (readn(to, buf_to, len) != (int)len)
- goto out;
-
- if (memcmp(buf_from, buf_to, len))
- goto out;
- }
-
- err = 0;
-out:
- free(buf_to);
- free(buf_from);
- return err;
-}
-
-static int kcore_copy__compare_files(const char *from_filename,
- const char *to_filename)
-{
- int from, to, err = -1;
-
- from = open(from_filename, O_RDONLY);
- if (from < 0)
- return -1;
-
- to = open(to_filename, O_RDONLY);
- if (to < 0)
- goto out_close_from;
-
- err = kcore_copy__compare_fds(from, to);
-
- close(to);
-out_close_from:
- close(from);
- return err;
-}
-
-static int kcore_copy__compare_file(const char *from_dir, const char *to_dir,
- const char *name)
-{
- char from_filename[PATH_MAX];
- char to_filename[PATH_MAX];
-
- scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
- scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
-
- return kcore_copy__compare_files(from_filename, to_filename);
-}
-
-/**
- * kcore_copy - copy kallsyms, modules and kcore from one directory to another.
- * @from_dir: from directory
- * @to_dir: to directory
- *
- * This function copies kallsyms, modules and kcore files from one directory to
- * another. kallsyms and modules are copied entirely. Only code segments are
- * copied from kcore. It is assumed that two segments suffice: one for the
- * kernel proper and one for all the modules. The code segments are determined
- * from kallsyms and modules files. The kernel map starts at _stext or the
- * lowest function symbol, and ends at _etext or the highest function symbol.
- * The module map starts at the lowest module address and ends at the highest
- * module symbol. Start addresses are rounded down to the nearest page. End
- * addresses are rounded up to the nearest page. An extra page is added to the
- * highest kernel symbol and highest module symbol to, hopefully, encompass that
- * symbol too. Because it contains only code sections, the resulting kcore is
- * unusual. One significant peculiarity is that the mapping (start -> pgoff)
- * is not the same for the kernel map and the modules map. That happens because
- * the data is copied adjacently whereas the original kcore has gaps. Finally,
- * kallsyms and modules files are compared with their copies to check that
- * modules have not been loaded or unloaded while the copies were taking place.
- *
- * Return: %0 on success, %-1 on failure.
- */
-int kcore_copy(const char *from_dir, const char *to_dir)
-{
- struct kcore kcore;
- struct kcore extract;
- size_t count = 2;
- int idx = 0, err = -1;
- off_t offset = page_size, sz, modules_offset = 0;
- struct kcore_copy_info kci = { .stext = 0, };
- char kcore_filename[PATH_MAX];
- char extract_filename[PATH_MAX];
-
- if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms"))
- return -1;
-
- if (kcore_copy__copy_file(from_dir, to_dir, "modules"))
- goto out_unlink_kallsyms;
-
- scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir);
- scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir);
-
- if (kcore__open(&kcore, kcore_filename))
- goto out_unlink_modules;
-
- if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf))
- goto out_kcore_close;
-
- if (kcore__init(&extract, extract_filename, kcore.elfclass, false))
- goto out_kcore_close;
-
- if (!kci.modules_map.addr)
- count -= 1;
-
- if (kcore__copy_hdr(&kcore, &extract, count))
- goto out_extract_close;
-
- if (kcore__add_phdr(&extract, idx++, offset, kci.kernel_map.addr,
- kci.kernel_map.len))
- goto out_extract_close;
-
- if (kci.modules_map.addr) {
- modules_offset = offset + kci.kernel_map.len;
- if (kcore__add_phdr(&extract, idx, modules_offset,
- kci.modules_map.addr, kci.modules_map.len))
- goto out_extract_close;
- }
-
- sz = kcore__write(&extract);
- if (sz < 0 || sz > offset)
- goto out_extract_close;
-
- if (copy_bytes(kcore.fd, kci.kernel_map.offset, extract.fd, offset,
- kci.kernel_map.len))
- goto out_extract_close;
-
- if (modules_offset && copy_bytes(kcore.fd, kci.modules_map.offset,
- extract.fd, modules_offset,
- kci.modules_map.len))
- goto out_extract_close;
-
- if (kcore_copy__compare_file(from_dir, to_dir, "modules"))
- goto out_extract_close;
-
- if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
- goto out_extract_close;
-
- err = 0;
-
-out_extract_close:
- kcore__close(&extract);
- if (err)
- unlink(extract_filename);
-out_kcore_close:
- kcore__close(&kcore);
-out_unlink_modules:
- if (err)
- kcore_copy__unlink(to_dir, "modules");
-out_unlink_kallsyms:
- if (err)
- kcore_copy__unlink(to_dir, "kallsyms");
-
- return err;
-}
-
-int kcore_extract__create(struct kcore_extract *kce)
-{
- struct kcore kcore;
- struct kcore extract;
- size_t count = 1;
- int idx = 0, err = -1;
- off_t offset = page_size, sz;
-
- if (kcore__open(&kcore, kce->kcore_filename))
- return -1;
-
- strcpy(kce->extract_filename, PERF_KCORE_EXTRACT);
- if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true))
- goto out_kcore_close;
-
- if (kcore__copy_hdr(&kcore, &extract, count))
- goto out_extract_close;
-
- if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len))
- goto out_extract_close;
-
- sz = kcore__write(&extract);
- if (sz < 0 || sz > offset)
- goto out_extract_close;
-
- if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len))
- goto out_extract_close;
-
- err = 0;
-
-out_extract_close:
- kcore__close(&extract);
- if (err)
- unlink(kce->extract_filename);
-out_kcore_close:
- kcore__close(&kcore);
-
- return err;
-}
-
-void kcore_extract__delete(struct kcore_extract *kce)
-{
- unlink(kce->extract_filename);
-}
-
void symbol__elf_init(void)
{
elf_version(EV_CURRENT);
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 2d2dd05..3a802c3 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -308,21 +308,6 @@ int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,
return -1;
}
-int kcore_extract__create(struct kcore_extract *kce __maybe_unused)
-{
- return -1;
-}
-
-void kcore_extract__delete(struct kcore_extract *kce __maybe_unused)
-{
-}
-
-int kcore_copy(const char *from_dir __maybe_unused,
- const char *to_dir __maybe_unused)
-{
- return -1;
-}
-
void symbol__elf_init(void)
{
}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index c0c3696..7eb0362 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -51,7 +51,6 @@ static enum dso_binary_type binary_type_symtab[] = {
DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
DSO_BINARY_TYPE__GUEST_KMODULE,
DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
- DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
DSO_BINARY_TYPE__NOT_FOUND,
};
@@ -160,12 +159,10 @@ again:
if (choose_best_symbol(curr, next) == SYMBOL_A) {
rb_erase(&next->rb_node, symbols);
- symbol__delete(next);
goto again;
} else {
nd = rb_next(&curr->rb_node);
rb_erase(&curr->rb_node, symbols);
- symbol__delete(curr);
}
}
}
@@ -502,64 +499,6 @@ out_failure:
return -1;
}
-int modules__parse(const char *filename, void *arg,
- int (*process_module)(void *arg, const char *name,
- u64 start))
-{
- char *line = NULL;
- size_t n;
- FILE *file;
- int err = 0;
-
- file = fopen(filename, "r");
- if (file == NULL)
- return -1;
-
- while (1) {
- char name[PATH_MAX];
- u64 start;
- char *sep;
- ssize_t line_len;
-
- line_len = getline(&line, &n, file);
- if (line_len < 0) {
- if (feof(file))
- break;
- err = -1;
- goto out;
- }
-
- if (!line) {
- err = -1;
- goto out;
- }
-
- line[--line_len] = '\0'; /* \n */
-
- sep = strrchr(line, 'x');
- if (sep == NULL)
- continue;
-
- hex2u64(sep + 1, &start);
-
- sep = strchr(line, ' ');
- if (sep == NULL)
- continue;
-
- *sep = '\0';
-
- scnprintf(name, sizeof(name), "[%s]", line);
-
- err = process_module(arg, name, start);
- if (err)
- break;
- }
-out:
- free(line);
- fclose(file);
- return err;
-}
-
struct process_kallsyms_args {
struct map *map;
struct dso *dso;
@@ -800,242 +739,51 @@ bool symbol__restricted_filename(const char *filename,
return restricted;
}
-struct module_info {
- struct rb_node rb_node;
- char *name;
- u64 start;
+struct kcore_mapfn_data {
+ struct dso *dso;
+ enum map_type type;
+ struct list_head maps;
};
-static void add_module(struct module_info *mi, struct rb_root *modules)
-{
- struct rb_node **p = &modules->rb_node;
- struct rb_node *parent = NULL;
- struct module_info *m;
-
- while (*p != NULL) {
- parent = *p;
- m = rb_entry(parent, struct module_info, rb_node);
- if (strcmp(mi->name, m->name) < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
- rb_link_node(&mi->rb_node, parent, p);
- rb_insert_color(&mi->rb_node, modules);
-}
-
-static void delete_modules(struct rb_root *modules)
-{
- struct module_info *mi;
- struct rb_node *next = rb_first(modules);
-
- while (next) {
- mi = rb_entry(next, struct module_info, rb_node);
- next = rb_next(&mi->rb_node);
- rb_erase(&mi->rb_node, modules);
- free(mi->name);
- free(mi);
- }
-}
-
-static struct module_info *find_module(const char *name,
- struct rb_root *modules)
-{
- struct rb_node *n = modules->rb_node;
-
- while (n) {
- struct module_info *m;
- int cmp;
-
- m = rb_entry(n, struct module_info, rb_node);
- cmp = strcmp(name, m->name);
- if (cmp < 0)
- n = n->rb_left;
- else if (cmp > 0)
- n = n->rb_right;
- else
- return m;
- }
-
- return NULL;
-}
-
-static int __read_proc_modules(void *arg, const char *name, u64 start)
+static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
{
- struct rb_root *modules = arg;
- struct module_info *mi;
-
- mi = zalloc(sizeof(struct module_info));
- if (!mi)
- return -ENOMEM;
-
- mi->name = strdup(name);
- mi->start = start;
+ struct kcore_mapfn_data *md = data;
+ struct map *map;
- if (!mi->name) {
- free(mi);
+ map = map__new2(start, md->dso, md->type);
+ if (map == NULL)
return -ENOMEM;
- }
-
- add_module(mi, modules);
-
- return 0;
-}
-static int read_proc_modules(const char *filename, struct rb_root *modules)
-{
- if (symbol__restricted_filename(filename, "/proc/modules"))
- return -1;
+ map->end = map->start + len;
+ map->pgoff = pgoff;
- if (modules__parse(filename, modules, __read_proc_modules)) {
- delete_modules(modules);
- return -1;
- }
+ list_add(&map->node, &md->maps);
return 0;
}
-int compare_proc_modules(const char *from, const char *to)
-{
- struct rb_root from_modules = RB_ROOT;
- struct rb_root to_modules = RB_ROOT;
- struct rb_node *from_node, *to_node;
- struct module_info *from_m, *to_m;
- int ret = -1;
-
- if (read_proc_modules(from, &from_modules))
- return -1;
-
- if (read_proc_modules(to, &to_modules))
- goto out_delete_from;
-
- from_node = rb_first(&from_modules);
- to_node = rb_first(&to_modules);
- while (from_node) {
- if (!to_node)
- break;
-
- from_m = rb_entry(from_node, struct module_info, rb_node);
- to_m = rb_entry(to_node, struct module_info, rb_node);
-
- if (from_m->start != to_m->start ||
- strcmp(from_m->name, to_m->name))
- break;
-
- from_node = rb_next(from_node);
- to_node = rb_next(to_node);
- }
-
- if (!from_node && !to_node)
- ret = 0;
-
- delete_modules(&to_modules);
-out_delete_from:
- delete_modules(&from_modules);
-
- return ret;
-}
-
-static int do_validate_kcore_modules(const char *filename, struct map *map,
- struct map_groups *kmaps)
-{
- struct rb_root modules = RB_ROOT;
- struct map *old_map;
- int err;
-
- err = read_proc_modules(filename, &modules);
- if (err)
- return err;
-
- old_map = map_groups__first(kmaps, map->type);
- while (old_map) {
- struct map *next = map_groups__next(old_map);
- struct module_info *mi;
-
- if (old_map == map || old_map->start == map->start) {
- /* The kernel map */
- old_map = next;
- continue;
- }
-
- /* Module must be in memory at the same address */
- mi = find_module(old_map->dso->short_name, &modules);
- if (!mi || mi->start != old_map->start) {
- err = -EINVAL;
- goto out;
- }
-
- old_map = next;
- }
-out:
- delete_modules(&modules);
- return err;
-}
-
/*
- * If kallsyms is referenced by name then we look for filename in the same
+ * If kallsyms is referenced by name then we look for kcore in the same
* directory.
*/
-static bool filename_from_kallsyms_filename(char *filename,
- const char *base_name,
- const char *kallsyms_filename)
+static bool kcore_filename_from_kallsyms_filename(char *kcore_filename,
+ const char *kallsyms_filename)
{
char *name;
- strcpy(filename, kallsyms_filename);
- name = strrchr(filename, '/');
+ strcpy(kcore_filename, kallsyms_filename);
+ name = strrchr(kcore_filename, '/');
if (!name)
return false;
- name += 1;
-
- if (!strcmp(name, "kallsyms")) {
- strcpy(name, base_name);
+ if (!strcmp(name, "/kallsyms")) {
+ strcpy(name, "/kcore");
return true;
}
return false;
}
-static int validate_kcore_modules(const char *kallsyms_filename,
- struct map *map)
-{
- struct map_groups *kmaps = map__kmap(map)->kmaps;
- char modules_filename[PATH_MAX];
-
- if (!filename_from_kallsyms_filename(modules_filename, "modules",
- kallsyms_filename))
- return -EINVAL;
-
- if (do_validate_kcore_modules(modules_filename, map, kmaps))
- return -EINVAL;
-
- return 0;
-}
-
-struct kcore_mapfn_data {
- struct dso *dso;
- enum map_type type;
- struct list_head maps;
-};
-
-static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
-{
- struct kcore_mapfn_data *md = data;
- struct map *map;
-
- map = map__new2(start, md->dso, md->type);
- if (map == NULL)
- return -ENOMEM;
-
- map->end = map->start + len;
- map->pgoff = pgoff;
-
- list_add(&map->node, &md->maps);
-
- return 0;
-}
-
static int dso__load_kcore(struct dso *dso, struct map *map,
const char *kallsyms_filename)
{
@@ -1052,12 +800,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
if (map != machine->vmlinux_maps[map->type])
return -EINVAL;
- if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
- kallsyms_filename))
- return -EINVAL;
-
- /* All modules must be present at their original addresses */
- if (validate_kcore_modules(kallsyms_filename, map))
+ if (!kcore_filename_from_kallsyms_filename(kcore_filename,
+ kallsyms_filename))
return -EINVAL;
md.dso = dso;
@@ -1444,105 +1188,6 @@ out:
return err;
}
-static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
-{
- char kallsyms_filename[PATH_MAX];
- struct dirent *dent;
- int ret = -1;
- DIR *d;
-
- d = opendir(dir);
- if (!d)
- return -1;
-
- while (1) {
- dent = readdir(d);
- if (!dent)
- break;
- if (dent->d_type != DT_DIR)
- continue;
- scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
- "%s/%s/kallsyms", dir, dent->d_name);
- if (!validate_kcore_modules(kallsyms_filename, map)) {
- strlcpy(dir, kallsyms_filename, dir_sz);
- ret = 0;
- break;
- }
- }
-
- closedir(d);
-
- return ret;
-}
-
-static char *dso__find_kallsyms(struct dso *dso, struct map *map)
-{
- u8 host_build_id[BUILD_ID_SIZE];
- char sbuild_id[BUILD_ID_SIZE * 2 + 1];
- bool is_host = false;
- char path[PATH_MAX];
-
- if (!dso->has_build_id) {
- /*
- * Last resort, if we don't have a build-id and couldn't find
- * any vmlinux file, try the running kernel kallsyms table.
- */
- goto proc_kallsyms;
- }
-
- if (sysfs__read_build_id("/sys/kernel/notes", host_build_id,
- sizeof(host_build_id)) == 0)
- is_host = dso__build_id_equal(dso, host_build_id);
-
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
-
- /* Use /proc/kallsyms if possible */
- if (is_host) {
- DIR *d;
- int fd;
-
- /* If no cached kcore go with /proc/kallsyms */
- scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s",
- buildid_dir, sbuild_id);
- d = opendir(path);
- if (!d)
- goto proc_kallsyms;
- closedir(d);
-
- /*
- * Do not check the build-id cache, until we know we cannot use
- * /proc/kcore.
- */
- fd = open("/proc/kcore", O_RDONLY);
- if (fd != -1) {
- close(fd);
- /* If module maps match go with /proc/kallsyms */
- if (!validate_kcore_modules("/proc/kallsyms", map))
- goto proc_kallsyms;
- }
-
- /* Find kallsyms in build-id cache with kcore */
- if (!find_matching_kcore(map, path, sizeof(path)))
- return strdup(path);
-
- goto proc_kallsyms;
- }
-
- scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
- buildid_dir, sbuild_id);
-
- if (access(path, F_OK)) {
- pr_err("No kallsyms or vmlinux with build-id %s was found\n",
- sbuild_id);
- return NULL;
- }
-
- return strdup(path);
-
-proc_kallsyms:
- return strdup("/proc/kallsyms");
-}
-
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
symbol_filter_t filter)
{
@@ -1569,7 +1214,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
goto do_kallsyms;
}
- if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
+ if (symbol_conf.vmlinux_name != NULL) {
err = dso__load_vmlinux(dso, map,
symbol_conf.vmlinux_name, filter);
if (err > 0) {
@@ -1581,7 +1226,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
return err;
}
- if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
+ if (vmlinux_path != NULL) {
err = dso__load_vmlinux_path(dso, map, filter);
if (err > 0)
return err;
@@ -1591,11 +1236,51 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map,
if (symbol_conf.symfs[0] != 0)
return -1;
- kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
- if (!kallsyms_allocated_filename)
- return -1;
+ /*
+ * Say the kernel DSO was created when processing the build-id header table,
+ * we have a build-id, so check if it is the same as the running kernel,
+ * using it if it is.
+ */
+ if (dso->has_build_id) {
+ u8 kallsyms_build_id[BUILD_ID_SIZE];
+ char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+ if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
+ sizeof(kallsyms_build_id)) == 0) {
+ if (dso__build_id_equal(dso, kallsyms_build_id)) {
+ kallsyms_filename = "/proc/kallsyms";
+ goto do_kallsyms;
+ }
+ }
+ /*
+ * Now look if we have it on the build-id cache in
+ * $HOME/.debug/[kernel.kallsyms].
+ */
+ build_id__sprintf(dso->build_id, sizeof(dso->build_id),
+ sbuild_id);
- kallsyms_filename = kallsyms_allocated_filename;
+ if (asprintf(&kallsyms_allocated_filename,
+ "%s/.debug/[kernel.kallsyms]/%s",
+ getenv("HOME"), sbuild_id) == -1) {
+ pr_err("Not enough memory for kallsyms file lookup\n");
+ return -1;
+ }
+
+ kallsyms_filename = kallsyms_allocated_filename;
+
+ if (access(kallsyms_filename, F_OK)) {
+ pr_err("No kallsyms or vmlinux with build-id %s "
+ "was found\n", sbuild_id);
+ free(kallsyms_allocated_filename);
+ return -1;
+ }
+ } else {
+ /*
+ * Last resort, if we don't have a build-id and couldn't find
+ * any vmlinux file, try the running kernel kallsyms table.
+ */
+ kallsyms_filename = "/proc/kallsyms";
+ }
do_kallsyms:
err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 07de8fe..fd5b70e 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -13,7 +13,7 @@
#include <libgen.h>
#include "build-id.h"
-#ifdef HAVE_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
#include <libelf.h>
#include <gelf.h>
#endif
@@ -21,7 +21,7 @@
#include "dso.h"
-#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
+#ifdef HAVE_CPLUS_DEMANGLE
extern char *cplus_demangle(const char *, int);
static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i)
@@ -46,7 +46,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
*/
-#ifdef HAVE_LIBELF_MMAP_SUPPORT
+#ifdef LIBELF_MMAP
# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
#else
# define PERF_ELF_C_READ_MMAP ELF_C_READ
@@ -85,7 +85,6 @@ struct symbol_conf {
unsigned short priv_size;
unsigned short nr_events;
bool try_vmlinux_path,
- ignore_vmlinux,
show_kernel_path,
use_modules,
sort_by_name,
@@ -179,7 +178,7 @@ struct symsrc {
int fd;
enum dso_binary_type type;
-#ifdef HAVE_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
Elf *elf;
GElf_Ehdr ehdr;
@@ -223,9 +222,6 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
-int modules__parse(const char *filename, void *arg,
- int (*process_module)(void *arg, const char *name,
- u64 start));
int filename__read_debuglink(const char *filename, char *debuglink,
size_t size);
@@ -256,21 +252,4 @@ typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
bool *is_64_bit);
-#define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
-
-struct kcore_extract {
- char *kcore_filename;
- u64 addr;
- u64 offs;
- u64 len;
- char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
- int fd;
-};
-
-int kcore_extract__create(struct kcore_extract *kce);
-void kcore_extract__delete(struct kcore_extract *kce);
-
-int kcore_copy(const char *from_dir, const char *to_dir);
-int compare_proc_modules(const char *from, const char *to);
-
#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/sysfs.c b/tools/perf/util/sysfs.c
new file mode 100644
index 0000000..f71e9ea
--- /dev/null
+++ b/tools/perf/util/sysfs.c
@@ -0,0 +1,60 @@
+
+#include "util.h"
+#include "sysfs.h"
+
+static const char * const sysfs_known_mountpoints[] = {
+ "/sys",
+ 0,
+};
+
+static int sysfs_found;
+char sysfs_mountpoint[PATH_MAX + 1];
+
+static int sysfs_valid_mountpoint(const char *sysfs)
+{
+ struct statfs st_fs;
+
+ if (statfs(sysfs, &st_fs) < 0)
+ return -ENOENT;
+ else if (st_fs.f_type != (long) SYSFS_MAGIC)
+ return -ENOENT;
+
+ return 0;
+}
+
+const char *sysfs_find_mountpoint(void)
+{
+ const char * const *ptr;
+ char type[100];
+ FILE *fp;
+
+ if (sysfs_found)
+ return (const char *) sysfs_mountpoint;
+
+ ptr = sysfs_known_mountpoints;
+ while (*ptr) {
+ if (sysfs_valid_mountpoint(*ptr) == 0) {
+ sysfs_found = 1;
+ strcpy(sysfs_mountpoint, *ptr);
+ return sysfs_mountpoint;
+ }
+ ptr++;
+ }
+
+ /* give up and parse /proc/mounts */
+ fp = fopen("/proc/mounts", "r");
+ if (fp == NULL)
+ return NULL;
+
+ while (!sysfs_found &&
+ fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
+ sysfs_mountpoint, type) == 2) {
+
+ if (strcmp(type, "sysfs") == 0)
+ sysfs_found = 1;
+ }
+
+ fclose(fp);
+
+ return sysfs_found ? sysfs_mountpoint : NULL;
+}
diff --git a/tools/perf/util/sysfs.h b/tools/perf/util/sysfs.h
new file mode 100644
index 0000000..a813b72
--- /dev/null
+++ b/tools/perf/util/sysfs.h
@@ -0,0 +1,6 @@
+#ifndef __SYSFS_H__
+#define __SYSFS_H__
+
+const char *sysfs_find_mountpoint(void);
+
+#endif /* __DEBUGFS_H__ */
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 3c778a0..065528b 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -13,9 +13,9 @@
#include <string.h>
-enum target_errno target__validate(struct target *target)
+enum perf_target_errno perf_target__validate(struct perf_target *target)
{
- enum target_errno ret = TARGET_ERRNO__SUCCESS;
+ enum perf_target_errno ret = PERF_ERRNO_TARGET__SUCCESS;
if (target->pid)
target->tid = target->pid;
@@ -23,42 +23,42 @@ enum target_errno target__validate(struct target *target)
/* CPU and PID are mutually exclusive */
if (target->tid && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == TARGET_ERRNO__SUCCESS)
- ret = TARGET_ERRNO__PID_OVERRIDE_CPU;
+ if (ret == PERF_ERRNO_TARGET__SUCCESS)
+ ret = PERF_ERRNO_TARGET__PID_OVERRIDE_CPU;
}
/* UID and PID are mutually exclusive */
if (target->tid && target->uid_str) {
target->uid_str = NULL;
- if (ret == TARGET_ERRNO__SUCCESS)
- ret = TARGET_ERRNO__PID_OVERRIDE_UID;
+ if (ret == PERF_ERRNO_TARGET__SUCCESS)
+ ret = PERF_ERRNO_TARGET__PID_OVERRIDE_UID;
}
/* UID and CPU are mutually exclusive */
if (target->uid_str && target->cpu_list) {
target->cpu_list = NULL;
- if (ret == TARGET_ERRNO__SUCCESS)
- ret = TARGET_ERRNO__UID_OVERRIDE_CPU;
+ if (ret == PERF_ERRNO_TARGET__SUCCESS)
+ ret = PERF_ERRNO_TARGET__UID_OVERRIDE_CPU;
}
/* PID and SYSTEM are mutually exclusive */
if (target->tid && target->system_wide) {
target->system_wide = false;
- if (ret == TARGET_ERRNO__SUCCESS)
- ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM;
+ if (ret == PERF_ERRNO_TARGET__SUCCESS)
+ ret = PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM;
}
/* UID and SYSTEM are mutually exclusive */
if (target->uid_str && target->system_wide) {
target->system_wide = false;
- if (ret == TARGET_ERRNO__SUCCESS)
- ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM;
+ if (ret == PERF_ERRNO_TARGET__SUCCESS)
+ ret = PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM;
}
return ret;
}
-enum target_errno target__parse_uid(struct target *target)
+enum perf_target_errno perf_target__parse_uid(struct perf_target *target)
{
struct passwd pwd, *result;
char buf[1024];
@@ -66,7 +66,7 @@ enum target_errno target__parse_uid(struct target *target)
target->uid = UINT_MAX;
if (str == NULL)
- return TARGET_ERRNO__SUCCESS;
+ return PERF_ERRNO_TARGET__SUCCESS;
/* Try user name first */
getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
@@ -79,22 +79,22 @@ enum target_errno target__parse_uid(struct target *target)
int uid = strtol(str, &endptr, 10);
if (*endptr != '\0')
- return TARGET_ERRNO__INVALID_UID;
+ return PERF_ERRNO_TARGET__INVALID_UID;
getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
if (result == NULL)
- return TARGET_ERRNO__USER_NOT_FOUND;
+ return PERF_ERRNO_TARGET__USER_NOT_FOUND;
}
target->uid = result->pw_uid;
- return TARGET_ERRNO__SUCCESS;
+ return PERF_ERRNO_TARGET__SUCCESS;
}
/*
- * This must have a same ordering as the enum target_errno.
+ * This must have a same ordering as the enum perf_target_errno.
*/
-static const char *target__error_str[] = {
+static const char *perf_target__error_str[] = {
"PID/TID switch overriding CPU",
"PID/TID switch overriding UID",
"UID switch overriding CPU",
@@ -104,7 +104,7 @@ static const char *target__error_str[] = {
"Problems obtaining information for user %s",
};
-int target__strerror(struct target *target, int errnum,
+int perf_target__strerror(struct perf_target *target, int errnum,
char *buf, size_t buflen)
{
int idx;
@@ -124,19 +124,21 @@ int target__strerror(struct target *target, int errnum,
return 0;
}
- if (errnum < __TARGET_ERRNO__START || errnum >= __TARGET_ERRNO__END)
+ if (errnum < __PERF_ERRNO_TARGET__START ||
+ errnum >= __PERF_ERRNO_TARGET__END)
return -1;
- idx = errnum - __TARGET_ERRNO__START;
- msg = target__error_str[idx];
+ idx = errnum - __PERF_ERRNO_TARGET__START;
+ msg = perf_target__error_str[idx];
switch (errnum) {
- case TARGET_ERRNO__PID_OVERRIDE_CPU ... TARGET_ERRNO__UID_OVERRIDE_SYSTEM:
+ case PERF_ERRNO_TARGET__PID_OVERRIDE_CPU
+ ... PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM:
snprintf(buf, buflen, "%s", msg);
break;
- case TARGET_ERRNO__INVALID_UID:
- case TARGET_ERRNO__USER_NOT_FOUND:
+ case PERF_ERRNO_TARGET__INVALID_UID:
+ case PERF_ERRNO_TARGET__USER_NOT_FOUND:
snprintf(buf, buflen, msg, target->uid_str);
break;
diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h
index 2d0c506..a4be857 100644
--- a/tools/perf/util/target.h
+++ b/tools/perf/util/target.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include <sys/types.h>
-struct target {
+struct perf_target {
const char *pid;
const char *tid;
const char *cpu_list;
@@ -12,11 +12,10 @@ struct target {
uid_t uid;
bool system_wide;
bool uses_mmap;
- bool force_per_cpu;
};
-enum target_errno {
- TARGET_ERRNO__SUCCESS = 0,
+enum perf_target_errno {
+ PERF_ERRNO_TARGET__SUCCESS = 0,
/*
* Choose an arbitrary negative big number not to clash with standard
@@ -25,40 +24,42 @@ enum target_errno {
*
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
*/
- __TARGET_ERRNO__START = -10000,
+ __PERF_ERRNO_TARGET__START = -10000,
- /* for target__validate() */
- TARGET_ERRNO__PID_OVERRIDE_CPU = __TARGET_ERRNO__START,
- TARGET_ERRNO__PID_OVERRIDE_UID,
- TARGET_ERRNO__UID_OVERRIDE_CPU,
- TARGET_ERRNO__PID_OVERRIDE_SYSTEM,
- TARGET_ERRNO__UID_OVERRIDE_SYSTEM,
- /* for target__parse_uid() */
- TARGET_ERRNO__INVALID_UID,
- TARGET_ERRNO__USER_NOT_FOUND,
+ /* for perf_target__validate() */
+ PERF_ERRNO_TARGET__PID_OVERRIDE_CPU = __PERF_ERRNO_TARGET__START,
+ PERF_ERRNO_TARGET__PID_OVERRIDE_UID,
+ PERF_ERRNO_TARGET__UID_OVERRIDE_CPU,
+ PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM,
+ PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM,
- __TARGET_ERRNO__END,
+ /* for perf_target__parse_uid() */
+ PERF_ERRNO_TARGET__INVALID_UID,
+ PERF_ERRNO_TARGET__USER_NOT_FOUND,
+
+ __PERF_ERRNO_TARGET__END,
};
-enum target_errno target__validate(struct target *target);
-enum target_errno target__parse_uid(struct target *target);
+enum perf_target_errno perf_target__validate(struct perf_target *target);
+enum perf_target_errno perf_target__parse_uid(struct perf_target *target);
-int target__strerror(struct target *target, int errnum, char *buf, size_t buflen);
+int perf_target__strerror(struct perf_target *target, int errnum, char *buf,
+ size_t buflen);
-static inline bool target__has_task(struct target *target)
+static inline bool perf_target__has_task(struct perf_target *target)
{
return target->tid || target->pid || target->uid_str;
}
-static inline bool target__has_cpu(struct target *target)
+static inline bool perf_target__has_cpu(struct perf_target *target)
{
return target->system_wide || target->cpu_list;
}
-static inline bool target__none(struct target *target)
+static inline bool perf_target__none(struct perf_target *target)
{
- return !target__has_task(target) && !target__has_cpu(target);
+ return !perf_target__has_task(target) && !perf_target__has_cpu(target);
}
#endif /* _PERF_TARGET_H */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 49eaf1d..e3d4a55 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -6,136 +6,86 @@
#include "thread.h"
#include "util.h"
#include "debug.h"
-#include "comm.h"
struct thread *thread__new(pid_t pid, pid_t tid)
{
- char *comm_str;
- struct comm *comm;
- struct thread *thread = zalloc(sizeof(*thread));
-
- if (thread != NULL) {
- map_groups__init(&thread->mg);
- thread->pid_ = pid;
- thread->tid = tid;
- thread->ppid = -1;
- INIT_LIST_HEAD(&thread->comm_list);
-
- comm_str = malloc(32);
- if (!comm_str)
- goto err_thread;
-
- snprintf(comm_str, 32, ":%d", tid);
- comm = comm__new(comm_str, 0);
- free(comm_str);
- if (!comm)
- goto err_thread;
-
- list_add(&comm->list, &thread->comm_list);
- }
-
- return thread;
-
-err_thread:
- free(thread);
- return NULL;
-}
-
-void thread__delete(struct thread *thread)
-{
- struct comm *comm, *tmp;
-
- map_groups__exit(&thread->mg);
- list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
- list_del(&comm->list);
- comm__free(comm);
+ struct thread *self = zalloc(sizeof(*self));
+
+ if (self != NULL) {
+ map_groups__init(&self->mg);
+ self->pid_ = pid;
+ self->tid = tid;
+ self->ppid = -1;
+ self->comm = malloc(32);
+ if (self->comm)
+ snprintf(self->comm, 32, ":%d", self->tid);
}
- free(thread);
+ return self;
}
-struct comm *thread__comm(const struct thread *thread)
+void thread__delete(struct thread *self)
{
- if (list_empty(&thread->comm_list))
- return NULL;
-
- return list_first_entry(&thread->comm_list, struct comm, list);
+ map_groups__exit(&self->mg);
+ free(self->comm);
+ free(self);
}
-/* CHECKME: time should always be 0 if event aren't ordered */
-int thread__set_comm(struct thread *thread, const char *str, u64 timestamp)
+int thread__set_comm(struct thread *self, const char *comm)
{
- struct comm *new, *curr = thread__comm(thread);
-
- /* Override latest entry if it had no specific time coverage */
- if (!curr->start) {
- comm__override(curr, str, timestamp);
- } else {
- new = comm__new(str, timestamp);
- if (!new)
- return -ENOMEM;
- list_add(&new->list, &thread->comm_list);
+ int err;
+
+ if (self->comm)
+ free(self->comm);
+ self->comm = strdup(comm);
+ err = self->comm == NULL ? -ENOMEM : 0;
+ if (!err) {
+ self->comm_set = true;
}
-
- thread->comm_set = true;
-
- return 0;
-}
-
-const char *thread__comm_str(const struct thread *thread)
-{
- const struct comm *comm = thread__comm(thread);
-
- if (!comm)
- return NULL;
-
- return comm__str(comm);
+ return err;
}
-/* CHECKME: it should probably better return the max comm len from its comm list */
-int thread__comm_len(struct thread *thread)
+int thread__comm_len(struct thread *self)
{
- if (!thread->comm_len) {
- const char *comm = thread__comm_str(thread);
- if (!comm)
+ if (!self->comm_len) {
+ if (!self->comm)
return 0;
- thread->comm_len = strlen(comm);
+ self->comm_len = strlen(self->comm);
}
- return thread->comm_len;
+ return self->comm_len;
}
size_t thread__fprintf(struct thread *thread, FILE *fp)
{
- return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
+ return fprintf(fp, "Thread %d %s\n", thread->tid, thread->comm) +
map_groups__fprintf(&thread->mg, verbose, fp);
}
-void thread__insert_map(struct thread *thread, struct map *map)
+void thread__insert_map(struct thread *self, struct map *map)
{
- map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr);
- map_groups__insert(&thread->mg, map);
+ map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
+ map_groups__insert(&self->mg, map);
}
-int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
+int thread__fork(struct thread *self, struct thread *parent)
{
- int i, err;
+ int i;
if (parent->comm_set) {
- const char *comm = thread__comm_str(parent);
- if (!comm)
+ if (self->comm)
+ free(self->comm);
+ self->comm = strdup(parent->comm);
+ if (!self->comm)
return -ENOMEM;
- err = thread__set_comm(thread, comm, timestamp);
- if (!err)
- return err;
- thread->comm_set = true;
+ self->comm_set = true;
}
for (i = 0; i < MAP__NR_TYPES; ++i)
- if (map_groups__clone(&thread->mg, &parent->mg, i) < 0)
+ if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
return -ENOMEM;
- thread->ppid = parent->tid;
+ self->ppid = parent->tid;
return 0;
}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 897c1b2..4ebbb40 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -2,7 +2,6 @@
#define __PERF_THREAD_H
#include <linux/rbtree.h>
-#include <linux/list.h>
#include <unistd.h>
#include <sys/types.h>
#include "symbol.h"
@@ -19,34 +18,31 @@ struct thread {
char shortname[3];
bool comm_set;
bool dead; /* if set thread has exited */
- struct list_head comm_list;
+ char *comm;
int comm_len;
void *priv;
};
struct machine;
-struct comm;
struct thread *thread__new(pid_t pid, pid_t tid);
-void thread__delete(struct thread *thread);
+void thread__delete(struct thread *self);
static inline void thread__exited(struct thread *thread)
{
thread->dead = true;
}
-int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp);
-int thread__comm_len(struct thread *thread);
-struct comm *thread__comm(const struct thread *thread);
-const char *thread__comm_str(const struct thread *thread);
-void thread__insert_map(struct thread *thread, struct map *map);
-int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
+int thread__set_comm(struct thread *self, const char *comm);
+int thread__comm_len(struct thread *self);
+void thread__insert_map(struct thread *self, struct map *map);
+int thread__fork(struct thread *self, struct thread *parent);
size_t thread__fprintf(struct thread *thread, FILE *fp);
-static inline struct map *thread__find_map(struct thread *thread,
+static inline struct map *thread__find_map(struct thread *self,
enum map_type type, u64 addr)
{
- return thread ? map_groups__find(&thread->mg, type, addr) : NULL;
+ return self ? map_groups__find(&self->mg, type, addr) : NULL;
}
void thread__find_addr_map(struct thread *thread, struct machine *machine,
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index ce793c7..f857b51 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -27,7 +27,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
float ksamples_per_sec;
float esamples_percent;
struct perf_record_opts *opts = &top->record_opts;
- struct target *target = &opts->target;
+ struct perf_target *target = &opts->target;
size_t ret = 0;
if (top->samples) {
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 88cfeaf..b554ffc 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -24,7 +24,6 @@ struct perf_top {
u64 exact_samples;
u64 guest_us_samples, guest_kernel_samples;
int print_entries, count_filter, delay_secs;
- int max_stack;
bool hide_kernel_symbols, hide_user_symbols, zero;
bool use_tui, use_stdio;
bool kptr_restrict_warned;
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 6681f71..e9e1c03 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -120,6 +120,42 @@ raw_field_value(struct event_format *event, const char *name, void *data)
return val;
}
+void *raw_field_ptr(struct event_format *event, const char *name, void *data)
+{
+ struct format_field *field;
+
+ field = pevent_find_any_field(event, name);
+ if (!field)
+ return NULL;
+
+ if (field->flags & FIELD_IS_DYNAMIC) {
+ int offset;
+
+ offset = *(int *)(data + field->offset);
+ offset &= 0xffff;
+
+ return data + offset;
+ }
+
+ return data + field->offset;
+}
+
+int trace_parse_common_type(struct pevent *pevent, void *data)
+{
+ struct pevent_record record;
+
+ record.data = data;
+ return pevent_data_type(pevent, &record);
+}
+
+int trace_parse_common_pid(struct pevent *pevent, void *data)
+{
+ struct pevent_record record;
+
+ record.data = data;
+ return pevent_data_pid(pevent, &record);
+}
+
unsigned long long read_size(struct event_format *event, void *ptr, int size)
{
return pevent_read_number(event->pevent, ptr, size);
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 04df631..fafe1a4 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -11,6 +11,8 @@ union perf_event;
struct perf_tool;
struct thread;
+extern struct pevent *perf_pevent;
+
int bigendian(void);
struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
@@ -21,19 +23,26 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
int parse_event_file(struct pevent *pevent,
char *buf, unsigned long size, char *sys);
+struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu);
+
unsigned long long
raw_field_value(struct event_format *event, const char *name, void *data);
+void *raw_field_ptr(struct event_format *event, const char *name, void *data);
void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
+int trace_parse_common_type(struct pevent *pevent, void *data);
+int trace_parse_common_pid(struct pevent *pevent, void *data);
+
struct event_format *trace_find_next_event(struct pevent *pevent,
struct event_format *event);
unsigned long long read_size(struct event_format *event, void *ptr, int size);
unsigned long long eval_flag(const char *flag);
+struct pevent_record *trace_read_data(struct pevent *pevent, int cpu);
int read_tracing_data(int fd, struct list_head *pattrs);
struct tracing_data {
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 0efd539..2f891f7 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,15 +39,6 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
-extern int
-UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
- unw_word_t ip,
- unw_word_t segbase,
- const char *obj_name, unw_word_t start,
- unw_word_t end);
-
-#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
-
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
@@ -254,9 +245,8 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
return 0;
}
-static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
- u64 *table_data, u64 *segbase,
- u64 *fde_count)
+static int read_unwind_spec(struct dso *dso, struct machine *machine,
+ u64 *table_data, u64 *segbase, u64 *fde_count)
{
int ret = -EINVAL, fd;
u64 offset;
@@ -265,7 +255,6 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
if (fd < 0)
return -EINVAL;
- /* Check the .eh_frame section for unwinding info */
offset = elf_section_offset(fd, ".eh_frame_hdr");
close(fd);
@@ -274,29 +263,10 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
table_data, segbase,
fde_count);
+ /* TODO .debug_frame check if eh_frame_hdr fails */
return ret;
}
-#ifndef NO_LIBUNWIND_DEBUG_FRAME
-static int read_unwind_spec_debug_frame(struct dso *dso,
- struct machine *machine, u64 *offset)
-{
- int fd = dso__data_fd(dso, machine);
-
- if (fd < 0)
- return -EINVAL;
-
- /* Check the .debug_frame section for unwinding info */
- *offset = elf_section_offset(fd, ".debug_frame");
- close(fd);
-
- if (*offset)
- return 0;
-
- return -EINVAL;
-}
-#endif
-
static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
{
struct addr_location al;
@@ -321,33 +291,20 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
- /* Check the .eh_frame section for unwinding info */
- if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
- &table_data, &segbase, &fde_count)) {
- memset(&di, 0, sizeof(di));
- di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
- di.start_ip = map->start;
- di.end_ip = map->end;
- di.u.rti.segbase = map->start + segbase;
- di.u.rti.table_data = map->start + table_data;
- di.u.rti.table_len = fde_count * sizeof(struct table_entry)
- / sizeof(unw_word_t);
- return dwarf_search_unwind_table(as, ip, &di, pi,
- need_unwind_info, arg);
- }
-
-#ifndef NO_LIBUNWIND_DEBUG_FRAME
- /* Check the .debug_frame section for unwinding info */
- if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
- memset(&di, 0, sizeof(di));
- dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
- map->start, map->end);
- return dwarf_search_unwind_table(as, ip, &di, pi,
- need_unwind_info, arg);
- }
-#endif
+ if (read_unwind_spec(map->dso, ui->machine,
+ &table_data, &segbase, &fde_count))
+ return -EINVAL;
- return -EINVAL;
+ memset(&di, 0, sizeof(di));
+ di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
+ di.start_ip = map->start;
+ di.end_ip = map->end;
+ di.u.rti.segbase = map->start + segbase;
+ di.u.rti.table_data = map->start + table_data;
+ di.u.rti.table_len = fde_count * sizeof(struct table_entry)
+ / sizeof(unw_word_t);
+ return dwarf_search_unwind_table(as, ip, &di, pi,
+ need_unwind_info, arg);
}
static int access_fpreg(unw_addr_space_t __maybe_unused as,
@@ -559,7 +516,7 @@ static unw_accessors_t accessors = {
};
static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
- void *arg, int max_stack)
+ void *arg)
{
unw_addr_space_t addr_space;
unw_cursor_t c;
@@ -575,7 +532,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
if (ret)
display_error(ret);
- while (!ret && (unw_step(&c) > 0) && max_stack--) {
+ while (!ret && (unw_step(&c) > 0)) {
unw_word_t ip;
unw_get_reg(&c, UNW_REG_IP, &ip);
@@ -588,8 +545,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
struct machine *machine, struct thread *thread,
- u64 sample_uregs, struct perf_sample *data,
- int max_stack)
+ u64 sample_uregs, struct perf_sample *data)
{
unw_word_t ip;
struct unwind_info ui = {
@@ -611,5 +567,5 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
if (ret)
return -ENOMEM;
- return get_entries(&ui, cb, arg, max_stack);
+ return get_entries(&ui, cb, arg);
}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index d5966f49..cb6bc50 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -13,12 +13,12 @@ struct unwind_entry {
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
-#ifdef HAVE_LIBUNWIND_SUPPORT
+#ifdef LIBUNWIND_SUPPORT
int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
struct machine *machine,
struct thread *thread,
u64 sample_uregs,
- struct perf_sample *data, int max_stack);
+ struct perf_sample *data);
int unwind__arch_reg_id(int regnum);
#else
static inline int
@@ -27,10 +27,9 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
struct machine *machine __maybe_unused,
struct thread *thread __maybe_unused,
u64 sample_uregs __maybe_unused,
- struct perf_sample *data __maybe_unused,
- int max_stack __maybe_unused)
+ struct perf_sample *data __maybe_unused)
{
return 0;
}
-#endif /* HAVE_LIBUNWIND_SUPPORT */
+#endif /* LIBUNWIND_SUPPORT */
#endif /* __UNWIND_H */
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 28a0a89..6d17b18 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -1,7 +1,7 @@
#include "../perf.h"
#include "util.h"
#include <sys/mman.h>
-#ifdef HAVE_BACKTRACE_SUPPORT
+#ifdef BACKTRACE_SUPPORT
#include <execinfo.h>
#endif
#include <stdio.h>
@@ -55,20 +55,17 @@ int mkdir_p(char *path, mode_t mode)
return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
}
-static int slow_copyfile(const char *from, const char *to, mode_t mode)
+static int slow_copyfile(const char *from, const char *to)
{
- int err = -1;
+ int err = 0;
char *line = NULL;
size_t n;
FILE *from_fp = fopen(from, "r"), *to_fp;
- mode_t old_umask;
if (from_fp == NULL)
goto out;
- old_umask = umask(mode ^ 0777);
to_fp = fopen(to, "w");
- umask(old_umask);
if (to_fp == NULL)
goto out_fclose_from;
@@ -85,7 +82,7 @@ out:
return err;
}
-int copyfile_mode(const char *from, const char *to, mode_t mode)
+int copyfile(const char *from, const char *to)
{
int fromfd, tofd;
struct stat st;
@@ -96,13 +93,13 @@ int copyfile_mode(const char *from, const char *to, mode_t mode)
goto out;
if (st.st_size == 0) /* /proc? do it slowly... */
- return slow_copyfile(from, to, mode);
+ return slow_copyfile(from, to);
fromfd = open(from, O_RDONLY);
if (fromfd < 0)
goto out;
- tofd = creat(to, mode);
+ tofd = creat(to, 0755);
if (tofd < 0)
goto out_close_from;
@@ -124,11 +121,6 @@ out:
return err;
}
-int copyfile(const char *from, const char *to)
-{
- return copyfile_mode(from, to, 0755);
-}
-
unsigned long convert_unit(unsigned long value, char *unit)
{
*unit = ' ';
@@ -212,7 +204,7 @@ int hex2u64(const char *ptr, u64 *long_val)
}
/* Obtain a backtrace and print it to stdout. */
-#ifdef HAVE_BACKTRACE_SUPPORT
+#ifdef BACKTRACE_SUPPORT
void dump_stack(void)
{
void *array[16];
@@ -369,47 +361,3 @@ int parse_nsec_time(const char *str, u64 *ptime)
*ptime = time_sec * NSEC_PER_SEC + time_nsec;
return 0;
}
-
-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 filename__read_int(const char *filename, int *value)
-{
- char line[64];
- int fd = open(filename, O_RDONLY), err = -1;
-
- if (fd < 0)
- return -1;
-
- if (read(fd, line, sizeof(line)) > 0) {
- *value = atoi(line);
- err = 0;
- }
-
- close(fd);
- return err;
-}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index c8f362d..a535359 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -128,8 +128,6 @@ void put_tracing_file(char *file);
#endif
#endif
-#define PERF_GTK_DSO "libperf-gtk.so"
-
/* General helper functions */
extern void usage(const char *err) NORETURN;
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
@@ -243,7 +241,6 @@ static inline int sane_case(int x, int high)
int mkdir_p(char *path, mode_t mode);
int copyfile(const char *from, const char *to);
-int copyfile_mode(const char *from, const char *to, mode_t mode);
s64 perf_atoll(const char *str);
char **argv_split(const char *str, int *argcp);
@@ -273,13 +270,6 @@ bool is_power_of_2(unsigned long n)
return (n != 0 && ((n & (n - 1)) == 0));
}
-static inline unsigned next_pow2(unsigned x)
-{
- if (!x)
- return 1;
- return 1ULL << (32 - __builtin_clz(x - 1));
-}
-
size_t hex_width(u64 v);
int hex2u64(const char *ptr, u64 *val);
@@ -291,20 +281,4 @@ void dump_stack(void);
extern unsigned int page_size;
void get_term_dimensions(struct winsize *ws);
-
-struct parse_tag {
- char tag;
- int mult;
-};
-
-unsigned long parse_tag_value(const char *str, struct parse_tag *tags);
-
-#define SRCLINE_UNKNOWN ((char *) "??:0")
-
-struct dso;
-
-char *get_srcline(struct dso *dso, unsigned long addr);
-void free_srcline(char *srcline);
-
-int filename__read_int(const char *filename, int *value);
#endif /* GIT_COMPAT_UTIL_H */