diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-10 14:48:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-10 14:48:51 -0400 |
commit | d00aa6695b67a31be2ce5f7464da32c20cb50699 (patch) | |
tree | 4e4a2bbd1ab710ddca3bd1a611a6c3e9a00f52f9 /tools/perf/util | |
parent | cec36911b5fa4ac342f6de856b12a9f71f84e6e5 (diff) | |
parent | 1853db0e02ae4088f102b0d8e59e83dc98f93f03 (diff) |
Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (27 commits)
perf_counter: Zero dead bytes from ftrace raw samples size alignment
perf_counter: Subtract the buffer size field from the event record size
perf_counter: Require CAP_SYS_ADMIN for raw tracepoint data
perf_counter: Correct PERF_SAMPLE_RAW output
perf tools: callchain: Fix bad rounding of minimum rate
perf_counter tools: Fix libbfd detection for systems with libz dependency
perf: "Longum est iter per praecepta, breve et efficax per exempla"
perf_counter: Fix a race on perf_counter_ctx
perf_counter: Fix tracepoint sampling to be part of generic sampling
perf_counter: Work around gcc warning by initializing tracepoint record unconditionally
perf tools: callchain: Fix sum of percentages to be 100% by displaying amount of ignored chains in fractal mode
perf tools: callchain: Fix 'perf report' display to be callchain by default
perf tools: callchain: Fix spurious 'perf report' warnings: ignore empty callchains
perf record: Fix the -A UI for empty or non-existent perf.data
perf util: Fix do_read() to fail on EOF instead of busy-looping
perf list: Fix the output to not include tracepoints without an id
perf_counter/powerpc: Fix oops on cpus without perf_counter hardware support
perf stat: Fix tool option consistency: rename -S/--scale to -c/--scale
perf report: Add debug help for the finding of symbol bugs - show the symtab origin (DSO, build-id, kernel, etc)
perf report: Fix per task mult-counter stat reporting
...
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/callchain.c | 32 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 8 | ||||
-rw-r--r-- | tools/perf/util/header.c | 5 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 26 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 1 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 57 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
7 files changed, 104 insertions, 27 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9d3c8141b8c1..011473411642 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <stdio.h> | 13 | #include <stdio.h> |
14 | #include <stdbool.h> | 14 | #include <stdbool.h> |
15 | #include <errno.h> | 15 | #include <errno.h> |
16 | #include <math.h> | ||
16 | 17 | ||
17 | #include "callchain.h" | 18 | #include "callchain.h" |
18 | 19 | ||
@@ -26,10 +27,14 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | |||
26 | struct rb_node **p = &root->rb_node; | 27 | struct rb_node **p = &root->rb_node; |
27 | struct rb_node *parent = NULL; | 28 | struct rb_node *parent = NULL; |
28 | struct callchain_node *rnode; | 29 | struct callchain_node *rnode; |
30 | u64 chain_cumul = cumul_hits(chain); | ||
29 | 31 | ||
30 | while (*p) { | 32 | while (*p) { |
33 | u64 rnode_cumul; | ||
34 | |||
31 | parent = *p; | 35 | parent = *p; |
32 | rnode = rb_entry(parent, struct callchain_node, rb_node); | 36 | rnode = rb_entry(parent, struct callchain_node, rb_node); |
37 | rnode_cumul = cumul_hits(rnode); | ||
33 | 38 | ||
34 | switch (mode) { | 39 | switch (mode) { |
35 | case CHAIN_FLAT: | 40 | case CHAIN_FLAT: |
@@ -40,7 +45,7 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | |||
40 | break; | 45 | break; |
41 | case CHAIN_GRAPH_ABS: /* Falldown */ | 46 | case CHAIN_GRAPH_ABS: /* Falldown */ |
42 | case CHAIN_GRAPH_REL: | 47 | case CHAIN_GRAPH_REL: |
43 | if (rnode->cumul_hit < chain->cumul_hit) | 48 | if (rnode_cumul < chain_cumul) |
44 | p = &(*p)->rb_left; | 49 | p = &(*p)->rb_left; |
45 | else | 50 | else |
46 | p = &(*p)->rb_right; | 51 | p = &(*p)->rb_right; |
@@ -87,7 +92,7 @@ static void __sort_chain_graph_abs(struct callchain_node *node, | |||
87 | 92 | ||
88 | chain_for_each_child(child, node) { | 93 | chain_for_each_child(child, node) { |
89 | __sort_chain_graph_abs(child, min_hit); | 94 | __sort_chain_graph_abs(child, min_hit); |
90 | if (child->cumul_hit >= min_hit) | 95 | if (cumul_hits(child) >= min_hit) |
91 | rb_insert_callchain(&node->rb_root, child, | 96 | rb_insert_callchain(&node->rb_root, child, |
92 | CHAIN_GRAPH_ABS); | 97 | CHAIN_GRAPH_ABS); |
93 | } | 98 | } |
@@ -108,11 +113,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node, | |||
108 | u64 min_hit; | 113 | u64 min_hit; |
109 | 114 | ||
110 | node->rb_root = RB_ROOT; | 115 | node->rb_root = RB_ROOT; |
111 | min_hit = node->cumul_hit * min_percent / 100.0; | 116 | min_hit = ceil(node->children_hit * min_percent); |
112 | 117 | ||
113 | chain_for_each_child(child, node) { | 118 | chain_for_each_child(child, node) { |
114 | __sort_chain_graph_rel(child, min_percent); | 119 | __sort_chain_graph_rel(child, min_percent); |
115 | if (child->cumul_hit >= min_hit) | 120 | if (cumul_hits(child) >= min_hit) |
116 | rb_insert_callchain(&node->rb_root, child, | 121 | rb_insert_callchain(&node->rb_root, child, |
117 | CHAIN_GRAPH_REL); | 122 | CHAIN_GRAPH_REL); |
118 | } | 123 | } |
@@ -122,7 +127,7 @@ static void | |||
122 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, | 127 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, |
123 | u64 min_hit __used, struct callchain_param *param) | 128 | u64 min_hit __used, struct callchain_param *param) |
124 | { | 129 | { |
125 | __sort_chain_graph_rel(chain_root, param->min_percent); | 130 | __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); |
126 | rb_root->rb_node = chain_root->rb_root.rb_node; | 131 | rb_root->rb_node = chain_root->rb_root.rb_node; |
127 | } | 132 | } |
128 | 133 | ||
@@ -211,7 +216,8 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
211 | new = create_child(parent, false); | 216 | new = create_child(parent, false); |
212 | fill_node(new, chain, start, syms); | 217 | fill_node(new, chain, start, syms); |
213 | 218 | ||
214 | new->cumul_hit = new->hit = 1; | 219 | new->children_hit = 0; |
220 | new->hit = 1; | ||
215 | } | 221 | } |
216 | 222 | ||
217 | /* | 223 | /* |
@@ -241,7 +247,8 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
241 | 247 | ||
242 | /* split the hits */ | 248 | /* split the hits */ |
243 | new->hit = parent->hit; | 249 | new->hit = parent->hit; |
244 | new->cumul_hit = parent->cumul_hit; | 250 | new->children_hit = parent->children_hit; |
251 | parent->children_hit = cumul_hits(new); | ||
245 | new->val_nr = parent->val_nr - idx_local; | 252 | new->val_nr = parent->val_nr - idx_local; |
246 | parent->val_nr = idx_local; | 253 | parent->val_nr = idx_local; |
247 | 254 | ||
@@ -249,6 +256,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
249 | if (idx_total < chain->nr) { | 256 | if (idx_total < chain->nr) { |
250 | parent->hit = 0; | 257 | parent->hit = 0; |
251 | add_child(parent, chain, idx_total, syms); | 258 | add_child(parent, chain, idx_total, syms); |
259 | parent->children_hit++; | ||
252 | } else { | 260 | } else { |
253 | parent->hit = 1; | 261 | parent->hit = 1; |
254 | } | 262 | } |
@@ -269,13 +277,13 @@ __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, | |||
269 | unsigned int ret = __append_chain(rnode, chain, start, syms); | 277 | unsigned int ret = __append_chain(rnode, chain, start, syms); |
270 | 278 | ||
271 | if (!ret) | 279 | if (!ret) |
272 | goto cumul; | 280 | goto inc_children_hit; |
273 | } | 281 | } |
274 | /* nothing in children, add to the current node */ | 282 | /* nothing in children, add to the current node */ |
275 | add_child(root, chain, start, syms); | 283 | add_child(root, chain, start, syms); |
276 | 284 | ||
277 | cumul: | 285 | inc_children_hit: |
278 | root->cumul_hit++; | 286 | root->children_hit++; |
279 | } | 287 | } |
280 | 288 | ||
281 | static int | 289 | static int |
@@ -317,8 +325,6 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
317 | /* we match 100% of the path, increment the hit */ | 325 | /* we match 100% of the path, increment the hit */ |
318 | if (i - start == root->val_nr && i == chain->nr) { | 326 | if (i - start == root->val_nr && i == chain->nr) { |
319 | root->hit++; | 327 | root->hit++; |
320 | root->cumul_hit++; | ||
321 | |||
322 | return 0; | 328 | return 0; |
323 | } | 329 | } |
324 | 330 | ||
@@ -331,5 +337,7 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
331 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, | 337 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, |
332 | struct symbol **syms) | 338 | struct symbol **syms) |
333 | { | 339 | { |
340 | if (!chain->nr) | ||
341 | return; | ||
334 | __append_chain_children(root, chain, syms, 0); | 342 | __append_chain_children(root, chain, syms, 0); |
335 | } | 343 | } |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 7812122bea1d..a926ae4f5a16 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "symbol.h" | 7 | #include "symbol.h" |
8 | 8 | ||
9 | enum chain_mode { | 9 | enum chain_mode { |
10 | CHAIN_NONE, | ||
10 | CHAIN_FLAT, | 11 | CHAIN_FLAT, |
11 | CHAIN_GRAPH_ABS, | 12 | CHAIN_GRAPH_ABS, |
12 | CHAIN_GRAPH_REL | 13 | CHAIN_GRAPH_REL |
@@ -21,7 +22,7 @@ struct callchain_node { | |||
21 | struct rb_root rb_root; /* sorted tree of children */ | 22 | struct rb_root rb_root; /* sorted tree of children */ |
22 | unsigned int val_nr; | 23 | unsigned int val_nr; |
23 | u64 hit; | 24 | u64 hit; |
24 | u64 cumul_hit; /* hit + hits of children */ | 25 | u64 children_hit; |
25 | }; | 26 | }; |
26 | 27 | ||
27 | struct callchain_param; | 28 | struct callchain_param; |
@@ -48,6 +49,11 @@ static inline void callchain_init(struct callchain_node *node) | |||
48 | INIT_LIST_HEAD(&node->val); | 49 | INIT_LIST_HEAD(&node->val); |
49 | } | 50 | } |
50 | 51 | ||
52 | static inline u64 cumul_hits(struct callchain_node *node) | ||
53 | { | ||
54 | return node->hit + node->children_hit; | ||
55 | } | ||
56 | |||
51 | int register_callchain_param(struct callchain_param *param); | 57 | int register_callchain_param(struct callchain_param *param); |
52 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, | 58 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, |
53 | struct symbol **syms); | 59 | struct symbol **syms); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 450384b3bbe5..b92a457ca32e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -185,6 +185,8 @@ static void do_read(int fd, void *buf, size_t size) | |||
185 | 185 | ||
186 | if (ret < 0) | 186 | if (ret < 0) |
187 | die("failed to read"); | 187 | die("failed to read"); |
188 | if (ret == 0) | ||
189 | die("failed to read: missing data"); | ||
188 | 190 | ||
189 | size -= ret; | 191 | size -= ret; |
190 | buf += ret; | 192 | buf += ret; |
@@ -213,9 +215,10 @@ struct perf_header *perf_header__read(int fd) | |||
213 | 215 | ||
214 | for (i = 0; i < nr_attrs; i++) { | 216 | for (i = 0; i < nr_attrs; i++) { |
215 | struct perf_header_attr *attr; | 217 | struct perf_header_attr *attr; |
216 | off_t tmp = lseek(fd, 0, SEEK_CUR); | 218 | off_t tmp; |
217 | 219 | ||
218 | do_read(fd, &f_attr, sizeof(f_attr)); | 220 | do_read(fd, &f_attr, sizeof(f_attr)); |
221 | tmp = lseek(fd, 0, SEEK_CUR); | ||
219 | 222 | ||
220 | attr = perf_header_attr__new(&f_attr.attr); | 223 | attr = perf_header_attr__new(&f_attr.attr); |
221 | 224 | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 7bdad8df22a6..4858d83b3b67 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -121,13 +121,29 @@ static unsigned long hw_cache_stat[C(MAX)] = { | |||
121 | (strcmp(sys_dirent.d_name, ".")) && \ | 121 | (strcmp(sys_dirent.d_name, ".")) && \ |
122 | (strcmp(sys_dirent.d_name, ".."))) | 122 | (strcmp(sys_dirent.d_name, ".."))) |
123 | 123 | ||
124 | static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) | ||
125 | { | ||
126 | char evt_path[MAXPATHLEN]; | ||
127 | int fd; | ||
128 | |||
129 | snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, | ||
130 | sys_dir->d_name, evt_dir->d_name); | ||
131 | fd = open(evt_path, O_RDONLY); | ||
132 | if (fd < 0) | ||
133 | return -EINVAL; | ||
134 | close(fd); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
124 | #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ | 139 | #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ |
125 | while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ | 140 | while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ |
126 | if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ | 141 | if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ |
127 | sys_dirent.d_name, evt_dirent.d_name) && \ | 142 | sys_dirent.d_name, evt_dirent.d_name) && \ |
128 | (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \ | 143 | (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \ |
129 | (strcmp(evt_dirent.d_name, ".")) && \ | 144 | (strcmp(evt_dirent.d_name, ".")) && \ |
130 | (strcmp(evt_dirent.d_name, ".."))) | 145 | (strcmp(evt_dirent.d_name, "..")) && \ |
146 | (!tp_event_has_id(&sys_dirent, &evt_dirent))) | ||
131 | 147 | ||
132 | #define MAX_EVENT_LENGTH 30 | 148 | #define MAX_EVENT_LENGTH 30 |
133 | 149 | ||
@@ -223,9 +239,15 @@ char *event_name(int counter) | |||
223 | { | 239 | { |
224 | u64 config = attrs[counter].config; | 240 | u64 config = attrs[counter].config; |
225 | int type = attrs[counter].type; | 241 | int type = attrs[counter].type; |
242 | |||
243 | return __event_name(type, config); | ||
244 | } | ||
245 | |||
246 | char *__event_name(int type, u64 config) | ||
247 | { | ||
226 | static char buf[32]; | 248 | static char buf[32]; |
227 | 249 | ||
228 | if (attrs[counter].type == PERF_TYPE_RAW) { | 250 | if (type == PERF_TYPE_RAW) { |
229 | sprintf(buf, "raw 0x%llx", config); | 251 | sprintf(buf, "raw 0x%llx", config); |
230 | return buf; | 252 | return buf; |
231 | } | 253 | } |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 1ea5d09b6eb1..192a962e3a0f 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -10,6 +10,7 @@ extern int nr_counters; | |||
10 | extern struct perf_counter_attr attrs[MAX_COUNTERS]; | 10 | extern struct perf_counter_attr attrs[MAX_COUNTERS]; |
11 | 11 | ||
12 | extern char *event_name(int ctr); | 12 | extern char *event_name(int ctr); |
13 | extern char *__event_name(int type, u64 config); | ||
13 | 14 | ||
14 | extern int parse_events(const struct option *opt, const char *str, int unset); | 15 | extern int parse_events(const struct option *opt, const char *str, int unset); |
15 | 16 | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 16ddca202948..f1dcede14307 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -24,6 +24,16 @@ const char *sym_hist_filter; | |||
24 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ | 24 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | enum dso_origin { | ||
28 | DSO__ORIG_KERNEL = 0, | ||
29 | DSO__ORIG_JAVA_JIT, | ||
30 | DSO__ORIG_FEDORA, | ||
31 | DSO__ORIG_UBUNTU, | ||
32 | DSO__ORIG_BUILDID, | ||
33 | DSO__ORIG_DSO, | ||
34 | DSO__ORIG_NOT_FOUND, | ||
35 | }; | ||
36 | |||
27 | static struct symbol *symbol__new(u64 start, u64 len, | 37 | static struct symbol *symbol__new(u64 start, u64 len, |
28 | const char *name, unsigned int priv_size, | 38 | const char *name, unsigned int priv_size, |
29 | u64 obj_start, int verbose) | 39 | u64 obj_start, int verbose) |
@@ -81,6 +91,7 @@ struct dso *dso__new(const char *name, unsigned int sym_priv_size) | |||
81 | self->sym_priv_size = sym_priv_size; | 91 | self->sym_priv_size = sym_priv_size; |
82 | self->find_symbol = dso__find_symbol; | 92 | self->find_symbol = dso__find_symbol; |
83 | self->slen_calculated = 0; | 93 | self->slen_calculated = 0; |
94 | self->origin = DSO__ORIG_NOT_FOUND; | ||
84 | } | 95 | } |
85 | 96 | ||
86 | return self; | 97 | return self; |
@@ -710,7 +721,7 @@ static char *dso__read_build_id(struct dso *self, int verbose) | |||
710 | ++raw; | 721 | ++raw; |
711 | bid += 2; | 722 | bid += 2; |
712 | } | 723 | } |
713 | if (verbose) | 724 | if (verbose >= 2) |
714 | printf("%s(%s): %s\n", __func__, self->name, build_id); | 725 | printf("%s(%s): %s\n", __func__, self->name, build_id); |
715 | out_elf_end: | 726 | out_elf_end: |
716 | elf_end(elf); | 727 | elf_end(elf); |
@@ -720,11 +731,26 @@ out: | |||
720 | return build_id; | 731 | return build_id; |
721 | } | 732 | } |
722 | 733 | ||
734 | char dso__symtab_origin(const struct dso *self) | ||
735 | { | ||
736 | static const char origin[] = { | ||
737 | [DSO__ORIG_KERNEL] = 'k', | ||
738 | [DSO__ORIG_JAVA_JIT] = 'j', | ||
739 | [DSO__ORIG_FEDORA] = 'f', | ||
740 | [DSO__ORIG_UBUNTU] = 'u', | ||
741 | [DSO__ORIG_BUILDID] = 'b', | ||
742 | [DSO__ORIG_DSO] = 'd', | ||
743 | }; | ||
744 | |||
745 | if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) | ||
746 | return '!'; | ||
747 | return origin[self->origin]; | ||
748 | } | ||
749 | |||
723 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose) | 750 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose) |
724 | { | 751 | { |
725 | int size = PATH_MAX; | 752 | int size = PATH_MAX; |
726 | char *name = malloc(size), *build_id = NULL; | 753 | char *name = malloc(size), *build_id = NULL; |
727 | int variant = 0; | ||
728 | int ret = -1; | 754 | int ret = -1; |
729 | int fd; | 755 | int fd; |
730 | 756 | ||
@@ -733,19 +759,26 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose) | |||
733 | 759 | ||
734 | self->adjust_symbols = 0; | 760 | self->adjust_symbols = 0; |
735 | 761 | ||
736 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) | 762 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) { |
737 | return dso__load_perf_map(self, filter, verbose); | 763 | ret = dso__load_perf_map(self, filter, verbose); |
764 | self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : | ||
765 | DSO__ORIG_NOT_FOUND; | ||
766 | return ret; | ||
767 | } | ||
768 | |||
769 | self->origin = DSO__ORIG_FEDORA - 1; | ||
738 | 770 | ||
739 | more: | 771 | more: |
740 | do { | 772 | do { |
741 | switch (variant) { | 773 | self->origin++; |
742 | case 0: /* Fedora */ | 774 | switch (self->origin) { |
775 | case DSO__ORIG_FEDORA: | ||
743 | snprintf(name, size, "/usr/lib/debug%s.debug", self->name); | 776 | snprintf(name, size, "/usr/lib/debug%s.debug", self->name); |
744 | break; | 777 | break; |
745 | case 1: /* Ubuntu */ | 778 | case DSO__ORIG_UBUNTU: |
746 | snprintf(name, size, "/usr/lib/debug%s", self->name); | 779 | snprintf(name, size, "/usr/lib/debug%s", self->name); |
747 | break; | 780 | break; |
748 | case 2: | 781 | case DSO__ORIG_BUILDID: |
749 | build_id = dso__read_build_id(self, verbose); | 782 | build_id = dso__read_build_id(self, verbose); |
750 | if (build_id != NULL) { | 783 | if (build_id != NULL) { |
751 | snprintf(name, size, | 784 | snprintf(name, size, |
@@ -754,16 +787,15 @@ more: | |||
754 | free(build_id); | 787 | free(build_id); |
755 | break; | 788 | break; |
756 | } | 789 | } |
757 | variant++; | 790 | self->origin++; |
758 | /* Fall thru */ | 791 | /* Fall thru */ |
759 | case 3: /* Sane people */ | 792 | case DSO__ORIG_DSO: |
760 | snprintf(name, size, "%s", self->name); | 793 | snprintf(name, size, "%s", self->name); |
761 | break; | 794 | break; |
762 | 795 | ||
763 | default: | 796 | default: |
764 | goto out; | 797 | goto out; |
765 | } | 798 | } |
766 | variant++; | ||
767 | 799 | ||
768 | fd = open(name, O_RDONLY); | 800 | fd = open(name, O_RDONLY); |
769 | } while (fd < 0); | 801 | } while (fd < 0); |
@@ -899,6 +931,9 @@ int dso__load_kernel(struct dso *self, const char *vmlinux, | |||
899 | if (err <= 0) | 931 | if (err <= 0) |
900 | err = dso__load_kallsyms(self, filter, verbose); | 932 | err = dso__load_kallsyms(self, filter, verbose); |
901 | 933 | ||
934 | if (err > 0) | ||
935 | self->origin = DSO__ORIG_KERNEL; | ||
936 | |||
902 | return err; | 937 | return err; |
903 | } | 938 | } |
904 | 939 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2f92b21c712d..1e003ec2f4b1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -26,6 +26,7 @@ struct dso { | |||
26 | unsigned int sym_priv_size; | 26 | unsigned int sym_priv_size; |
27 | unsigned char adjust_symbols; | 27 | unsigned char adjust_symbols; |
28 | unsigned char slen_calculated; | 28 | unsigned char slen_calculated; |
29 | unsigned char origin; | ||
29 | char name[0]; | 30 | char name[0]; |
30 | }; | 31 | }; |
31 | 32 | ||
@@ -49,6 +50,7 @@ int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose); | |||
49 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose); | 50 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose); |
50 | 51 | ||
51 | size_t dso__fprintf(struct dso *self, FILE *fp); | 52 | size_t dso__fprintf(struct dso *self, FILE *fp); |
53 | char dso__symtab_origin(const struct dso *self); | ||
52 | 54 | ||
53 | void symbol__init(void); | 55 | void symbol__init(void); |
54 | #endif /* _PERF_SYMBOL_ */ | 56 | #endif /* _PERF_SYMBOL_ */ |