aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /tools/perf/util/symbol.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c1561
1 files changed, 1245 insertions, 316 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 226f44a2357d..c458c4a371d1 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,111 +1,234 @@
1#include "util.h" 1#include "util.h"
2#include "../perf.h" 2#include "../perf.h"
3#include "sort.h"
3#include "string.h" 4#include "string.h"
4#include "symbol.h" 5#include "symbol.h"
6#include "thread.h"
5 7
6#include "debug.h" 8#include "debug.h"
7 9
10#include <asm/bug.h>
8#include <libelf.h> 11#include <libelf.h>
9#include <gelf.h> 12#include <gelf.h>
10#include <elf.h> 13#include <elf.h>
14#include <limits.h>
15#include <sys/utsname.h>
11 16
12const char *sym_hist_filter; 17#ifndef NT_GNU_BUILD_ID
18#define NT_GNU_BUILD_ID 3
19#endif
13 20
14enum dso_origin { 21enum dso_origin {
15 DSO__ORIG_KERNEL = 0, 22 DSO__ORIG_KERNEL = 0,
16 DSO__ORIG_JAVA_JIT, 23 DSO__ORIG_JAVA_JIT,
24 DSO__ORIG_BUILD_ID_CACHE,
17 DSO__ORIG_FEDORA, 25 DSO__ORIG_FEDORA,
18 DSO__ORIG_UBUNTU, 26 DSO__ORIG_UBUNTU,
19 DSO__ORIG_BUILDID, 27 DSO__ORIG_BUILDID,
20 DSO__ORIG_DSO, 28 DSO__ORIG_DSO,
29 DSO__ORIG_KMODULE,
21 DSO__ORIG_NOT_FOUND, 30 DSO__ORIG_NOT_FOUND,
22}; 31};
23 32
24static struct symbol *symbol__new(u64 start, u64 len, 33static void dsos__add(struct list_head *head, struct dso *dso);
25 const char *name, unsigned int priv_size, 34static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
26 u64 obj_start, int v) 35static int dso__load_kernel_sym(struct dso *self, struct map *map,
36 symbol_filter_t filter);
37static int vmlinux_path__nr_entries;
38static char **vmlinux_path;
39
40struct symbol_conf symbol_conf = {
41 .exclude_other = true,
42 .use_modules = true,
43 .try_vmlinux_path = true,
44};
45
46bool dso__loaded(const struct dso *self, enum map_type type)
27{ 47{
28 size_t namelen = strlen(name) + 1; 48 return self->loaded & (1 << type);
29 struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen); 49}
30 50
31 if (!self) 51bool dso__sorted_by_name(const struct dso *self, enum map_type type)
32 return NULL; 52{
53 return self->sorted_by_name & (1 << type);
54}
55
56static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
57{
58 self->sorted_by_name |= (1 << type);
59}
60
61bool symbol_type__is_a(char symbol_type, enum map_type map_type)
62{
63 switch (map_type) {
64 case MAP__FUNCTION:
65 return symbol_type == 'T' || symbol_type == 'W';
66 case MAP__VARIABLE:
67 return symbol_type == 'D' || symbol_type == 'd';
68 default:
69 return false;
70 }
71}
33 72
34 if (v >= 2) 73static void symbols__fixup_end(struct rb_root *self)
35 printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n", 74{
36 (u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start); 75 struct rb_node *nd, *prevnd = rb_first(self);
76 struct symbol *curr, *prev;
37 77
38 self->obj_start= obj_start; 78 if (prevnd == NULL)
39 self->hist = NULL; 79 return;
40 self->hist_sum = 0;
41 80
42 if (sym_hist_filter && !strcmp(name, sym_hist_filter)) 81 curr = rb_entry(prevnd, struct symbol, rb_node);
43 self->hist = calloc(sizeof(u64), len);
44 82
45 if (priv_size) { 83 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
46 memset(self, 0, priv_size); 84 prev = curr;
47 self = ((void *)self) + priv_size; 85 curr = rb_entry(nd, struct symbol, rb_node);
86
87 if (prev->end == prev->start)
88 prev->end = curr->start - 1;
48 } 89 }
90
91 /* Last entry */
92 if (curr->end == curr->start)
93 curr->end = roundup(curr->start, 4096);
94}
95
96static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
97{
98 struct map *prev, *curr;
99 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
100
101 if (prevnd == NULL)
102 return;
103
104 curr = rb_entry(prevnd, struct map, rb_node);
105
106 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
107 prev = curr;
108 curr = rb_entry(nd, struct map, rb_node);
109 prev->end = curr->start - 1;
110 }
111
112 /*
113 * We still haven't the actual symbols, so guess the
114 * last map final address.
115 */
116 curr->end = ~0UL;
117}
118
119static void map_groups__fixup_end(struct map_groups *self)
120{
121 int i;
122 for (i = 0; i < MAP__NR_TYPES; ++i)
123 __map_groups__fixup_end(self, i);
124}
125
126static struct symbol *symbol__new(u64 start, u64 len, const char *name)
127{
128 size_t namelen = strlen(name) + 1;
129 struct symbol *self = zalloc(symbol_conf.priv_size +
130 sizeof(*self) + namelen);
131 if (self == NULL)
132 return NULL;
133
134 if (symbol_conf.priv_size)
135 self = ((void *)self) + symbol_conf.priv_size;
136
49 self->start = start; 137 self->start = start;
50 self->end = len ? start + len - 1 : start; 138 self->end = len ? start + len - 1 : start;
139
140 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
141
51 memcpy(self->name, name, namelen); 142 memcpy(self->name, name, namelen);
52 143
53 return self; 144 return self;
54} 145}
55 146
56static void symbol__delete(struct symbol *self, unsigned int priv_size) 147void symbol__delete(struct symbol *self)
57{ 148{
58 free(((void *)self) - priv_size); 149 free(((void *)self) - symbol_conf.priv_size);
59} 150}
60 151
61static size_t symbol__fprintf(struct symbol *self, FILE *fp) 152static size_t symbol__fprintf(struct symbol *self, FILE *fp)
62{ 153{
63 if (!self->module) 154 return fprintf(fp, " %llx-%llx %s\n",
64 return fprintf(fp, " %llx-%llx %s\n",
65 self->start, self->end, self->name); 155 self->start, self->end, self->name);
66 else
67 return fprintf(fp, " %llx-%llx %s \t[%s]\n",
68 self->start, self->end, self->name, self->module->name);
69} 156}
70 157
71struct dso *dso__new(const char *name, unsigned int sym_priv_size) 158void dso__set_long_name(struct dso *self, char *name)
72{ 159{
73 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); 160 if (name == NULL)
161 return;
162 self->long_name = name;
163 self->long_name_len = strlen(name);
164}
165
166static void dso__set_short_name(struct dso *self, const char *name)
167{
168 if (name == NULL)
169 return;
170 self->short_name = name;
171 self->short_name_len = strlen(name);
172}
173
174static void dso__set_basename(struct dso *self)
175{
176 dso__set_short_name(self, basename(self->long_name));
177}
178
179struct dso *dso__new(const char *name)
180{
181 struct dso *self = zalloc(sizeof(*self) + strlen(name) + 1);
74 182
75 if (self != NULL) { 183 if (self != NULL) {
184 int i;
76 strcpy(self->name, name); 185 strcpy(self->name, name);
77 self->syms = RB_ROOT; 186 dso__set_long_name(self, self->name);
78 self->sym_priv_size = sym_priv_size; 187 dso__set_short_name(self, self->name);
79 self->find_symbol = dso__find_symbol; 188 for (i = 0; i < MAP__NR_TYPES; ++i)
189 self->symbols[i] = self->symbol_names[i] = RB_ROOT;
80 self->slen_calculated = 0; 190 self->slen_calculated = 0;
81 self->origin = DSO__ORIG_NOT_FOUND; 191 self->origin = DSO__ORIG_NOT_FOUND;
192 self->loaded = 0;
193 self->sorted_by_name = 0;
194 self->has_build_id = 0;
82 } 195 }
83 196
84 return self; 197 return self;
85} 198}
86 199
87static void dso__delete_symbols(struct dso *self) 200static void symbols__delete(struct rb_root *self)
88{ 201{
89 struct symbol *pos; 202 struct symbol *pos;
90 struct rb_node *next = rb_first(&self->syms); 203 struct rb_node *next = rb_first(self);
91 204
92 while (next) { 205 while (next) {
93 pos = rb_entry(next, struct symbol, rb_node); 206 pos = rb_entry(next, struct symbol, rb_node);
94 next = rb_next(&pos->rb_node); 207 next = rb_next(&pos->rb_node);
95 rb_erase(&pos->rb_node, &self->syms); 208 rb_erase(&pos->rb_node, self);
96 symbol__delete(pos, self->sym_priv_size); 209 symbol__delete(pos);
97 } 210 }
98} 211}
99 212
100void dso__delete(struct dso *self) 213void dso__delete(struct dso *self)
101{ 214{
102 dso__delete_symbols(self); 215 int i;
216 for (i = 0; i < MAP__NR_TYPES; ++i)
217 symbols__delete(&self->symbols[i]);
218 if (self->long_name != self->name)
219 free(self->long_name);
103 free(self); 220 free(self);
104} 221}
105 222
106static void dso__insert_symbol(struct dso *self, struct symbol *sym) 223void dso__set_build_id(struct dso *self, void *build_id)
107{ 224{
108 struct rb_node **p = &self->syms.rb_node; 225 memcpy(self->build_id, build_id, sizeof(self->build_id));
226 self->has_build_id = 1;
227}
228
229static void symbols__insert(struct rb_root *self, struct symbol *sym)
230{
231 struct rb_node **p = &self->rb_node;
109 struct rb_node *parent = NULL; 232 struct rb_node *parent = NULL;
110 const u64 ip = sym->start; 233 const u64 ip = sym->start;
111 struct symbol *s; 234 struct symbol *s;
@@ -119,17 +242,17 @@ static void dso__insert_symbol(struct dso *self, struct symbol *sym)
119 p = &(*p)->rb_right; 242 p = &(*p)->rb_right;
120 } 243 }
121 rb_link_node(&sym->rb_node, parent, p); 244 rb_link_node(&sym->rb_node, parent, p);
122 rb_insert_color(&sym->rb_node, &self->syms); 245 rb_insert_color(&sym->rb_node, self);
123} 246}
124 247
125struct symbol *dso__find_symbol(struct dso *self, u64 ip) 248static struct symbol *symbols__find(struct rb_root *self, u64 ip)
126{ 249{
127 struct rb_node *n; 250 struct rb_node *n;
128 251
129 if (self == NULL) 252 if (self == NULL)
130 return NULL; 253 return NULL;
131 254
132 n = self->syms.rb_node; 255 n = self->rb_node;
133 256
134 while (n) { 257 while (n) {
135 struct symbol *s = rb_entry(n, struct symbol, rb_node); 258 struct symbol *s = rb_entry(n, struct symbol, rb_node);
@@ -145,12 +268,120 @@ struct symbol *dso__find_symbol(struct dso *self, u64 ip)
145 return NULL; 268 return NULL;
146} 269}
147 270
148size_t dso__fprintf(struct dso *self, FILE *fp) 271struct symbol_name_rb_node {
272 struct rb_node rb_node;
273 struct symbol sym;
274};
275
276static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
277{
278 struct rb_node **p = &self->rb_node;
279 struct rb_node *parent = NULL;
280 struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;
281
282 while (*p != NULL) {
283 parent = *p;
284 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
285 if (strcmp(sym->name, s->sym.name) < 0)
286 p = &(*p)->rb_left;
287 else
288 p = &(*p)->rb_right;
289 }
290 rb_link_node(&symn->rb_node, parent, p);
291 rb_insert_color(&symn->rb_node, self);
292}
293
294static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source)
295{
296 struct rb_node *nd;
297
298 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
299 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
300 symbols__insert_by_name(self, pos);
301 }
302}
303
304static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name)
305{
306 struct rb_node *n;
307
308 if (self == NULL)
309 return NULL;
310
311 n = self->rb_node;
312
313 while (n) {
314 struct symbol_name_rb_node *s;
315 int cmp;
316
317 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
318 cmp = strcmp(name, s->sym.name);
319
320 if (cmp < 0)
321 n = n->rb_left;
322 else if (cmp > 0)
323 n = n->rb_right;
324 else
325 return &s->sym;
326 }
327
328 return NULL;
329}
330
331struct symbol *dso__find_symbol(struct dso *self,
332 enum map_type type, u64 addr)
333{
334 return symbols__find(&self->symbols[type], addr);
335}
336
337struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
338 const char *name)
339{
340 return symbols__find_by_name(&self->symbol_names[type], name);
341}
342
343void dso__sort_by_name(struct dso *self, enum map_type type)
344{
345 dso__set_sorted_by_name(self, type);
346 return symbols__sort_by_name(&self->symbol_names[type],
347 &self->symbols[type]);
348}
349
350int build_id__sprintf(const u8 *self, int len, char *bf)
351{
352 char *bid = bf;
353 const u8 *raw = self;
354 int i;
355
356 for (i = 0; i < len; ++i) {
357 sprintf(bid, "%02x", *raw);
358 ++raw;
359 bid += 2;
360 }
361
362 return raw - self;
363}
364
365size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
149{ 366{
150 size_t ret = fprintf(fp, "dso: %s\n", self->name); 367 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
368
369 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
370 return fprintf(fp, "%s", sbuild_id);
371}
151 372
373size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
374{
152 struct rb_node *nd; 375 struct rb_node *nd;
153 for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { 376 size_t ret = fprintf(fp, "dso: %s (", self->short_name);
377
378 if (self->short_name != self->long_name)
379 ret += fprintf(fp, "%s, ", self->long_name);
380 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
381 self->loaded ? "" : "NOT ");
382 ret += dso__fprintf_buildid(self, fp);
383 ret += fprintf(fp, ")\n");
384 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
154 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 385 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
155 ret += symbol__fprintf(pos, fp); 386 ret += symbol__fprintf(pos, fp);
156 } 387 }
@@ -158,22 +389,23 @@ size_t dso__fprintf(struct dso *self, FILE *fp)
158 return ret; 389 return ret;
159} 390}
160 391
161static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v) 392int kallsyms__parse(const char *filename, void *arg,
393 int (*process_symbol)(void *arg, const char *name,
394 char type, u64 start))
162{ 395{
163 struct rb_node *nd, *prevnd;
164 char *line = NULL; 396 char *line = NULL;
165 size_t n; 397 size_t n;
166 FILE *file = fopen("/proc/kallsyms", "r"); 398 int err = 0;
167 int count = 0; 399 FILE *file = fopen(filename, "r");
168 400
169 if (file == NULL) 401 if (file == NULL)
170 goto out_failure; 402 goto out_failure;
171 403
172 while (!feof(file)) { 404 while (!feof(file)) {
173 u64 start; 405 u64 start;
174 struct symbol *sym;
175 int line_len, len; 406 int line_len, len;
176 char symbol_type; 407 char symbol_type;
408 char *symbol_name;
177 409
178 line_len = getline(&line, &n, file); 410 line_len = getline(&line, &n, file);
179 if (line_len < 0) 411 if (line_len < 0)
@@ -191,64 +423,168 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v)
191 continue; 423 continue;
192 424
193 symbol_type = toupper(line[len]); 425 symbol_type = toupper(line[len]);
194 /* 426 symbol_name = line + len + 2;
195 * We're interested only in code ('T'ext)
196 */
197 if (symbol_type != 'T' && symbol_type != 'W')
198 continue;
199 /*
200 * Well fix up the end later, when we have all sorted.
201 */
202 sym = symbol__new(start, 0xdead, line + len + 2,
203 self->sym_priv_size, 0, v);
204 427
205 if (sym == NULL) 428 err = process_symbol(arg, symbol_name, symbol_type, start);
206 goto out_delete_line; 429 if (err)
207 430 break;
208 if (filter && filter(self, sym))
209 symbol__delete(sym, self->sym_priv_size);
210 else {
211 dso__insert_symbol(self, sym);
212 count++;
213 }
214 } 431 }
215 432
433 free(line);
434 fclose(file);
435 return err;
436
437out_failure:
438 return -1;
439}
440
441struct process_kallsyms_args {
442 struct map *map;
443 struct dso *dso;
444};
445
446static int map__process_kallsym_symbol(void *arg, const char *name,
447 char type, u64 start)
448{
449 struct symbol *sym;
450 struct process_kallsyms_args *a = arg;
451 struct rb_root *root = &a->dso->symbols[a->map->type];
452
453 if (!symbol_type__is_a(type, a->map->type))
454 return 0;
455
216 /* 456 /*
217 * Now that we have all sorted out, just set the ->end of all 457 * Will fix up the end later, when we have all symbols sorted.
218 * symbols
219 */ 458 */
220 prevnd = rb_first(&self->syms); 459 sym = symbol__new(start, 0, name);
221 460
222 if (prevnd == NULL) 461 if (sym == NULL)
223 goto out_delete_line; 462 return -ENOMEM;
463 /*
464 * We will pass the symbols to the filter later, in
465 * map__split_kallsyms, when we have split the maps per module
466 */
467 symbols__insert(root, sym);
468 return 0;
469}
224 470
225 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 471/*
226 struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node), 472 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
227 *curr = rb_entry(nd, struct symbol, rb_node); 473 * so that we can in the next step set the symbol ->end address and then
474 * call kernel_maps__split_kallsyms.
475 */
476static int dso__load_all_kallsyms(struct dso *self, const char *filename,
477 struct map *map)
478{
479 struct process_kallsyms_args args = { .map = map, .dso = self, };
480 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
481}
228 482
229 prev->end = curr->start - 1; 483/*
230 prevnd = nd; 484 * Split the symbols into maps, making sure there are no overlaps, i.e. the
231 } 485 * kernel range is broken in several maps, named [kernel].N, as we don't have
486 * the original ELF section names vmlinux have.
487 */
488static int dso__split_kallsyms(struct dso *self, struct map *map,
489 symbol_filter_t filter)
490{
491 struct map_groups *kmaps = map__kmap(map)->kmaps;
492 struct map *curr_map = map;
493 struct symbol *pos;
494 int count = 0;
495 struct rb_root *root = &self->symbols[map->type];
496 struct rb_node *next = rb_first(root);
497 int kernel_range = 0;
232 498
233 free(line); 499 while (next) {
234 fclose(file); 500 char *module;
501
502 pos = rb_entry(next, struct symbol, rb_node);
503 next = rb_next(&pos->rb_node);
504
505 module = strchr(pos->name, '\t');
506 if (module) {
507 if (!symbol_conf.use_modules)
508 goto discard_symbol;
509
510 *module++ = '\0';
511
512 if (strcmp(curr_map->dso->short_name, module)) {
513 curr_map = map_groups__find_by_name(kmaps, map->type, module);
514 if (curr_map == NULL) {
515 pr_debug("/proc/{kallsyms,modules} "
516 "inconsistency while looking "
517 "for \"%s\" module!\n", module);
518 return -1;
519 }
520
521 if (curr_map->dso->loaded)
522 goto discard_symbol;
523 }
524 /*
525 * So that we look just like we get from .ko files,
526 * i.e. not prelinked, relative to map->start.
527 */
528 pos->start = curr_map->map_ip(curr_map, pos->start);
529 pos->end = curr_map->map_ip(curr_map, pos->end);
530 } else if (curr_map != map) {
531 char dso_name[PATH_MAX];
532 struct dso *dso;
533
534 snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
535 kernel_range++);
536
537 dso = dso__new(dso_name);
538 if (dso == NULL)
539 return -1;
540
541 curr_map = map__new2(pos->start, dso, map->type);
542 if (curr_map == NULL) {
543 dso__delete(dso);
544 return -1;
545 }
546
547 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
548 map_groups__insert(kmaps, curr_map);
549 ++kernel_range;
550 }
551
552 if (filter && filter(curr_map, pos)) {
553discard_symbol: rb_erase(&pos->rb_node, root);
554 symbol__delete(pos);
555 } else {
556 if (curr_map != map) {
557 rb_erase(&pos->rb_node, root);
558 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
559 }
560 count++;
561 }
562 }
235 563
236 return count; 564 return count;
565}
237 566
238out_delete_line: 567int dso__load_kallsyms(struct dso *self, const char *filename,
239 free(line); 568 struct map *map, symbol_filter_t filter)
240out_failure: 569{
241 return -1; 570 if (dso__load_all_kallsyms(self, filename, map) < 0)
571 return -1;
572
573 symbols__fixup_end(&self->symbols[map->type]);
574 self->origin = DSO__ORIG_KERNEL;
575
576 return dso__split_kallsyms(self, map, filter);
242} 577}
243 578
244static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v) 579static int dso__load_perf_map(struct dso *self, struct map *map,
580 symbol_filter_t filter)
245{ 581{
246 char *line = NULL; 582 char *line = NULL;
247 size_t n; 583 size_t n;
248 FILE *file; 584 FILE *file;
249 int nr_syms = 0; 585 int nr_syms = 0;
250 586
251 file = fopen(self->name, "r"); 587 file = fopen(self->long_name, "r");
252 if (file == NULL) 588 if (file == NULL)
253 goto out_failure; 589 goto out_failure;
254 590
@@ -278,16 +614,15 @@ static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v)
278 if (len + 2 >= line_len) 614 if (len + 2 >= line_len)
279 continue; 615 continue;
280 616
281 sym = symbol__new(start, size, line + len, 617 sym = symbol__new(start, size, line + len);
282 self->sym_priv_size, start, v);
283 618
284 if (sym == NULL) 619 if (sym == NULL)
285 goto out_delete_line; 620 goto out_delete_line;
286 621
287 if (filter && filter(self, sym)) 622 if (filter && filter(map, sym))
288 symbol__delete(sym, self->sym_priv_size); 623 symbol__delete(sym);
289 else { 624 else {
290 dso__insert_symbol(self, sym); 625 symbols__insert(&self->symbols[map->type], sym);
291 nr_syms++; 626 nr_syms++;
292 } 627 }
293 } 628 }
@@ -327,6 +662,13 @@ static inline int elf_sym__is_function(const GElf_Sym *sym)
327 sym->st_shndx != SHN_UNDEF; 662 sym->st_shndx != SHN_UNDEF;
328} 663}
329 664
665static inline bool elf_sym__is_object(const GElf_Sym *sym)
666{
667 return elf_sym__type(sym) == STT_OBJECT &&
668 sym->st_name != 0 &&
669 sym->st_shndx != SHN_UNDEF;
670}
671
330static inline int elf_sym__is_label(const GElf_Sym *sym) 672static inline int elf_sym__is_label(const GElf_Sym *sym)
331{ 673{
332 return elf_sym__type(sym) == STT_NOTYPE && 674 return elf_sym__type(sym) == STT_NOTYPE &&
@@ -347,6 +689,12 @@ static inline int elf_sec__is_text(const GElf_Shdr *shdr,
347 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; 689 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
348} 690}
349 691
692static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
693 const Elf_Data *secstrs)
694{
695 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
696}
697
350static inline const char *elf_sym__name(const GElf_Sym *sym, 698static inline const char *elf_sym__name(const GElf_Sym *sym,
351 const Elf_Data *symstrs) 699 const Elf_Data *symstrs)
352{ 700{
@@ -393,7 +741,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
393 * And always look at the original dso, not at debuginfo packages, that 741 * And always look at the original dso, not at debuginfo packages, that
394 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 742 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
395 */ 743 */
396static int dso__synthesize_plt_symbols(struct dso *self, int v) 744static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
745 symbol_filter_t filter)
397{ 746{
398 uint32_t nr_rel_entries, idx; 747 uint32_t nr_rel_entries, idx;
399 GElf_Sym sym; 748 GElf_Sym sym;
@@ -409,7 +758,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
409 Elf *elf; 758 Elf *elf;
410 int nr = 0, symidx, fd, err = 0; 759 int nr = 0, symidx, fd, err = 0;
411 760
412 fd = open(self->name, O_RDONLY); 761 fd = open(self->long_name, O_RDONLY);
413 if (fd < 0) 762 if (fd < 0)
414 goto out; 763 goto out;
415 764
@@ -477,12 +826,16 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
477 "%s@plt", elf_sym__name(&sym, symstrs)); 826 "%s@plt", elf_sym__name(&sym, symstrs));
478 827
479 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 828 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
480 sympltname, self->sym_priv_size, 0, v); 829 sympltname);
481 if (!f) 830 if (!f)
482 goto out_elf_end; 831 goto out_elf_end;
483 832
484 dso__insert_symbol(self, f); 833 if (filter && filter(map, f))
485 ++nr; 834 symbol__delete(f);
835 else {
836 symbols__insert(&self->symbols[map->type], f);
837 ++nr;
838 }
486 } 839 }
487 } else if (shdr_rel_plt.sh_type == SHT_REL) { 840 } else if (shdr_rel_plt.sh_type == SHT_REL) {
488 GElf_Rel pos_mem, *pos; 841 GElf_Rel pos_mem, *pos;
@@ -495,12 +848,16 @@ static int dso__synthesize_plt_symbols(struct dso *self, int v)
495 "%s@plt", elf_sym__name(&sym, symstrs)); 848 "%s@plt", elf_sym__name(&sym, symstrs));
496 849
497 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 850 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
498 sympltname, self->sym_priv_size, 0, v); 851 sympltname);
499 if (!f) 852 if (!f)
500 goto out_elf_end; 853 goto out_elf_end;
501 854
502 dso__insert_symbol(self, f); 855 if (filter && filter(map, f))
503 ++nr; 856 symbol__delete(f);
857 else {
858 symbols__insert(&self->symbols[map->type], f);
859 ++nr;
860 }
504 } 861 }
505 } 862 }
506 863
@@ -513,14 +870,41 @@ out_close:
513 if (err == 0) 870 if (err == 0)
514 return nr; 871 return nr;
515out: 872out:
516 fprintf(stderr, "%s: problems reading %s PLT info.\n", 873 pr_warning("%s: problems reading %s PLT info.\n",
517 __func__, self->name); 874 __func__, self->long_name);
518 return 0; 875 return 0;
519} 876}
520 877
521static int dso__load_sym(struct dso *self, int fd, const char *name, 878static bool elf_sym__is_a(GElf_Sym *self, enum map_type type)
522 symbol_filter_t filter, int v, struct module *mod)
523{ 879{
880 switch (type) {
881 case MAP__FUNCTION:
882 return elf_sym__is_function(self);
883 case MAP__VARIABLE:
884 return elf_sym__is_object(self);
885 default:
886 return false;
887 }
888}
889
890static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type)
891{
892 switch (type) {
893 case MAP__FUNCTION:
894 return elf_sec__is_text(self, secstrs);
895 case MAP__VARIABLE:
896 return elf_sec__is_data(self, secstrs);
897 default:
898 return false;
899 }
900}
901
902static int dso__load_sym(struct dso *self, struct map *map, const char *name,
903 int fd, symbol_filter_t filter, int kmodule)
904{
905 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
906 struct map *curr_map = map;
907 struct dso *curr_dso = self;
524 Elf_Data *symstrs, *secstrs; 908 Elf_Data *symstrs, *secstrs;
525 uint32_t nr_syms; 909 uint32_t nr_syms;
526 int err = -1; 910 int err = -1;
@@ -531,19 +915,16 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
531 GElf_Sym sym; 915 GElf_Sym sym;
532 Elf_Scn *sec, *sec_strndx; 916 Elf_Scn *sec, *sec_strndx;
533 Elf *elf; 917 Elf *elf;
534 int nr = 0, kernel = !strcmp("[kernel]", self->name); 918 int nr = 0;
535 919
536 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 920 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
537 if (elf == NULL) { 921 if (elf == NULL) {
538 if (v) 922 pr_err("%s: cannot read %s ELF file.\n", __func__, name);
539 fprintf(stderr, "%s: cannot read %s ELF file.\n",
540 __func__, name);
541 goto out_close; 923 goto out_close;
542 } 924 }
543 925
544 if (gelf_getehdr(elf, &ehdr) == NULL) { 926 if (gelf_getehdr(elf, &ehdr) == NULL) {
545 if (v) 927 pr_err("%s: cannot get elf header.\n", __func__);
546 fprintf(stderr, "%s: cannot get elf header.\n", __func__);
547 goto out_elf_end; 928 goto out_elf_end;
548 } 929 }
549 930
@@ -577,7 +958,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
577 nr_syms = shdr.sh_size / shdr.sh_entsize; 958 nr_syms = shdr.sh_size / shdr.sh_entsize;
578 959
579 memset(&sym, 0, sizeof(sym)); 960 memset(&sym, 0, sizeof(sym));
580 if (!kernel) { 961 if (!self->kernel) {
581 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 962 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
582 elf_section_by_name(elf, &ehdr, &shdr, 963 elf_section_by_name(elf, &ehdr, &shdr,
583 ".gnu.prelink_undo", 964 ".gnu.prelink_undo",
@@ -586,14 +967,16 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
586 967
587 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 968 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
588 struct symbol *f; 969 struct symbol *f;
589 const char *elf_name; 970 const char *elf_name = elf_sym__name(&sym, symstrs);
590 char *demangled; 971 char *demangled = NULL;
591 u64 obj_start;
592 struct section *section = NULL;
593 int is_label = elf_sym__is_label(&sym); 972 int is_label = elf_sym__is_label(&sym);
594 const char *section_name; 973 const char *section_name;
595 974
596 if (!is_label && !elf_sym__is_function(&sym)) 975 if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
976 strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
977 kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
978
979 if (!is_label && !elf_sym__is_a(&sym, map->type))
597 continue; 980 continue;
598 981
599 sec = elf_getscn(elf, sym.st_shndx); 982 sec = elf_getscn(elf, sym.st_shndx);
@@ -602,55 +985,98 @@ static int dso__load_sym(struct dso *self, int fd, const char *name,
602 985
603 gelf_getshdr(sec, &shdr); 986 gelf_getshdr(sec, &shdr);
604 987
605 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 988 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
606 continue; 989 continue;
607 990
608 section_name = elf_sec__name(&shdr, secstrs); 991 section_name = elf_sec__name(&shdr, secstrs);
609 obj_start = sym.st_value;
610 992
611 if (self->adjust_symbols) { 993 if (self->kernel || kmodule) {
612 if (v >= 2) 994 char dso_name[PATH_MAX];
613 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
614 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
615 995
616 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 996 if (strcmp(section_name,
617 } 997 (curr_dso->short_name +
998 self->short_name_len)) == 0)
999 goto new_symbol;
618 1000
619 if (mod) { 1001 if (strcmp(section_name, ".text") == 0) {
620 section = mod->sections->find_section(mod->sections, section_name); 1002 curr_map = map;
621 if (section) 1003 curr_dso = self;
622 sym.st_value += section->vma; 1004 goto new_symbol;
623 else {
624 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
625 mod->name, section_name);
626 goto out_elf_end;
627 } 1005 }
1006
1007 snprintf(dso_name, sizeof(dso_name),
1008 "%s%s", self->short_name, section_name);
1009
1010 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1011 if (curr_map == NULL) {
1012 u64 start = sym.st_value;
1013
1014 if (kmodule)
1015 start += map->start + shdr.sh_offset;
1016
1017 curr_dso = dso__new(dso_name);
1018 if (curr_dso == NULL)
1019 goto out_elf_end;
1020 curr_map = map__new2(start, curr_dso,
1021 map->type);
1022 if (curr_map == NULL) {
1023 dso__delete(curr_dso);
1024 goto out_elf_end;
1025 }
1026 curr_map->map_ip = identity__map_ip;
1027 curr_map->unmap_ip = identity__map_ip;
1028 curr_dso->origin = DSO__ORIG_KERNEL;
1029 map_groups__insert(kmap->kmaps, curr_map);
1030 dsos__add(&dsos__kernel, curr_dso);
1031 dso__set_loaded(curr_dso, map->type);
1032 } else
1033 curr_dso = curr_map->dso;
1034
1035 goto new_symbol;
1036 }
1037
1038 if (curr_dso->adjust_symbols) {
1039 pr_debug4("%s: adjusting symbol: st_value: %#Lx "
1040 "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
1041 (u64)sym.st_value, (u64)shdr.sh_addr,
1042 (u64)shdr.sh_offset);
1043 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
628 } 1044 }
629 /* 1045 /*
630 * We need to figure out if the object was created from C++ sources 1046 * We need to figure out if the object was created from C++ sources
631 * DWARF DW_compile_unit has this, but we don't always have access 1047 * DWARF DW_compile_unit has this, but we don't always have access
632 * to it... 1048 * to it...
633 */ 1049 */
634 elf_name = elf_sym__name(&sym, symstrs);
635 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 1050 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
636 if (demangled != NULL) 1051 if (demangled != NULL)
637 elf_name = demangled; 1052 elf_name = demangled;
638 1053new_symbol:
639 f = symbol__new(sym.st_value, sym.st_size, elf_name, 1054 f = symbol__new(sym.st_value, sym.st_size, elf_name);
640 self->sym_priv_size, obj_start, v);
641 free(demangled); 1055 free(demangled);
642 if (!f) 1056 if (!f)
643 goto out_elf_end; 1057 goto out_elf_end;
644 1058
645 if (filter && filter(self, f)) 1059 if (filter && filter(curr_map, f))
646 symbol__delete(f, self->sym_priv_size); 1060 symbol__delete(f);
647 else { 1061 else {
648 f->module = mod; 1062 symbols__insert(&curr_dso->symbols[curr_map->type], f);
649 dso__insert_symbol(self, f);
650 nr++; 1063 nr++;
651 } 1064 }
652 } 1065 }
653 1066
1067 /*
1068 * For misannotated, zeroed, ASM function sizes.
1069 */
1070 if (nr > 0) {
1071 symbols__fixup_end(&self->symbols[map->type]);
1072 if (kmap) {
1073 /*
1074 * We need to fixup this here too because we create new
1075 * maps here, for things like vsyscall sections.
1076 */
1077 __map_groups__fixup_end(kmap->kmaps, map->type);
1078 }
1079 }
654 err = nr; 1080 err = nr;
655out_elf_end: 1081out_elf_end:
656 elf_end(elf); 1082 elf_end(elf);
@@ -658,63 +1084,157 @@ out_close:
658 return err; 1084 return err;
659} 1085}
660 1086
661#define BUILD_ID_SIZE 128 1087static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1088{
1089 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1090}
662 1091
663static char *dso__read_build_id(struct dso *self, int v) 1092static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
664{ 1093{
665 int i; 1094 bool have_build_id = false;
1095 struct dso *pos;
1096
1097 list_for_each_entry(pos, head, node) {
1098 if (with_hits && !pos->hit)
1099 continue;
1100 if (filename__read_build_id(pos->long_name, pos->build_id,
1101 sizeof(pos->build_id)) > 0) {
1102 have_build_id = true;
1103 pos->has_build_id = true;
1104 }
1105 }
1106
1107 return have_build_id;
1108}
1109
1110bool dsos__read_build_ids(bool with_hits)
1111{
1112 bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
1113 ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
1114 return kbuildids || ubuildids;
1115}
1116
1117/*
1118 * Align offset to 4 bytes as needed for note name and descriptor data.
1119 */
1120#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1121
1122int filename__read_build_id(const char *filename, void *bf, size_t size)
1123{
1124 int fd, err = -1;
666 GElf_Ehdr ehdr; 1125 GElf_Ehdr ehdr;
667 GElf_Shdr shdr; 1126 GElf_Shdr shdr;
668 Elf_Data *build_id_data; 1127 Elf_Data *data;
669 Elf_Scn *sec; 1128 Elf_Scn *sec;
670 char *build_id = NULL, *bid; 1129 Elf_Kind ek;
671 unsigned char *raw; 1130 void *ptr;
672 Elf *elf; 1131 Elf *elf;
673 int fd = open(self->name, O_RDONLY);
674 1132
1133 if (size < BUILD_ID_SIZE)
1134 goto out;
1135
1136 fd = open(filename, O_RDONLY);
675 if (fd < 0) 1137 if (fd < 0)
676 goto out; 1138 goto out;
677 1139
678 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 1140 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
679 if (elf == NULL) { 1141 if (elf == NULL) {
680 if (v) 1142 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
681 fprintf(stderr, "%s: cannot read %s ELF file.\n",
682 __func__, self->name);
683 goto out_close; 1143 goto out_close;
684 } 1144 }
685 1145
1146 ek = elf_kind(elf);
1147 if (ek != ELF_K_ELF)
1148 goto out_elf_end;
1149
686 if (gelf_getehdr(elf, &ehdr) == NULL) { 1150 if (gelf_getehdr(elf, &ehdr) == NULL) {
687 if (v) 1151 pr_err("%s: cannot get elf header.\n", __func__);
688 fprintf(stderr, "%s: cannot get elf header.\n", __func__);
689 goto out_elf_end; 1152 goto out_elf_end;
690 } 1153 }
691 1154
692 sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL); 1155 sec = elf_section_by_name(elf, &ehdr, &shdr,
693 if (sec == NULL) 1156 ".note.gnu.build-id", NULL);
694 goto out_elf_end; 1157 if (sec == NULL) {
1158 sec = elf_section_by_name(elf, &ehdr, &shdr,
1159 ".notes", NULL);
1160 if (sec == NULL)
1161 goto out_elf_end;
1162 }
695 1163
696 build_id_data = elf_getdata(sec, NULL); 1164 data = elf_getdata(sec, NULL);
697 if (build_id_data == NULL) 1165 if (data == NULL)
698 goto out_elf_end; 1166 goto out_elf_end;
699 build_id = malloc(BUILD_ID_SIZE);
700 if (build_id == NULL)
701 goto out_elf_end;
702 raw = build_id_data->d_buf + 16;
703 bid = build_id;
704 1167
705 for (i = 0; i < 20; ++i) { 1168 ptr = data->d_buf;
706 sprintf(bid, "%02x", *raw); 1169 while (ptr < (data->d_buf + data->d_size)) {
707 ++raw; 1170 GElf_Nhdr *nhdr = ptr;
708 bid += 2; 1171 int namesz = NOTE_ALIGN(nhdr->n_namesz),
1172 descsz = NOTE_ALIGN(nhdr->n_descsz);
1173 const char *name;
1174
1175 ptr += sizeof(*nhdr);
1176 name = ptr;
1177 ptr += namesz;
1178 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1179 nhdr->n_namesz == sizeof("GNU")) {
1180 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1181 memcpy(bf, ptr, BUILD_ID_SIZE);
1182 err = BUILD_ID_SIZE;
1183 break;
1184 }
1185 }
1186 ptr += descsz;
709 } 1187 }
710 if (v >= 2)
711 printf("%s(%s): %s\n", __func__, self->name, build_id);
712out_elf_end: 1188out_elf_end:
713 elf_end(elf); 1189 elf_end(elf);
714out_close: 1190out_close:
715 close(fd); 1191 close(fd);
716out: 1192out:
717 return build_id; 1193 return err;
1194}
1195
1196int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1197{
1198 int fd, err = -1;
1199
1200 if (size < BUILD_ID_SIZE)
1201 goto out;
1202
1203 fd = open(filename, O_RDONLY);
1204 if (fd < 0)
1205 goto out;
1206
1207 while (1) {
1208 char bf[BUFSIZ];
1209 GElf_Nhdr nhdr;
1210 int namesz, descsz;
1211
1212 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1213 break;
1214
1215 namesz = NOTE_ALIGN(nhdr.n_namesz);
1216 descsz = NOTE_ALIGN(nhdr.n_descsz);
1217 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1218 nhdr.n_namesz == sizeof("GNU")) {
1219 if (read(fd, bf, namesz) != namesz)
1220 break;
1221 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1222 if (read(fd, build_id,
1223 BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1224 err = 0;
1225 break;
1226 }
1227 } else if (read(fd, bf, descsz) != descsz)
1228 break;
1229 } else {
1230 int n = namesz + descsz;
1231 if (read(fd, bf, n) != n)
1232 break;
1233 }
1234 }
1235 close(fd);
1236out:
1237 return err;
718} 1238}
719 1239
720char dso__symtab_origin(const struct dso *self) 1240char dso__symtab_origin(const struct dso *self)
@@ -722,10 +1242,12 @@ char dso__symtab_origin(const struct dso *self)
722 static const char origin[] = { 1242 static const char origin[] = {
723 [DSO__ORIG_KERNEL] = 'k', 1243 [DSO__ORIG_KERNEL] = 'k',
724 [DSO__ORIG_JAVA_JIT] = 'j', 1244 [DSO__ORIG_JAVA_JIT] = 'j',
1245 [DSO__ORIG_BUILD_ID_CACHE] = 'B',
725 [DSO__ORIG_FEDORA] = 'f', 1246 [DSO__ORIG_FEDORA] = 'f',
726 [DSO__ORIG_UBUNTU] = 'u', 1247 [DSO__ORIG_UBUNTU] = 'u',
727 [DSO__ORIG_BUILDID] = 'b', 1248 [DSO__ORIG_BUILDID] = 'b',
728 [DSO__ORIG_DSO] = 'd', 1249 [DSO__ORIG_DSO] = 'd',
1250 [DSO__ORIG_KMODULE] = 'K',
729 }; 1251 };
730 1252
731 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 1253 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
@@ -733,60 +1255,90 @@ char dso__symtab_origin(const struct dso *self)
733 return origin[self->origin]; 1255 return origin[self->origin];
734} 1256}
735 1257
736int dso__load(struct dso *self, symbol_filter_t filter, int v) 1258int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
737{ 1259{
738 int size = PATH_MAX; 1260 int size = PATH_MAX;
739 char *name = malloc(size), *build_id = NULL; 1261 char *name;
1262 u8 build_id[BUILD_ID_SIZE];
1263 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
740 int ret = -1; 1264 int ret = -1;
741 int fd; 1265 int fd;
742 1266
1267 dso__set_loaded(self, map->type);
1268
1269 if (self->kernel)
1270 return dso__load_kernel_sym(self, map, filter);
1271
1272 name = malloc(size);
743 if (!name) 1273 if (!name)
744 return -1; 1274 return -1;
745 1275
746 self->adjust_symbols = 0; 1276 self->adjust_symbols = 0;
747 1277
748 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1278 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
749 ret = dso__load_perf_map(self, filter, v); 1279 ret = dso__load_perf_map(self, map, filter);
750 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 1280 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
751 DSO__ORIG_NOT_FOUND; 1281 DSO__ORIG_NOT_FOUND;
752 return ret; 1282 return ret;
753 } 1283 }
754 1284
755 self->origin = DSO__ORIG_FEDORA - 1; 1285 self->origin = DSO__ORIG_BUILD_ID_CACHE;
756 1286
1287 if (self->has_build_id) {
1288 build_id__sprintf(self->build_id, sizeof(self->build_id),
1289 build_id_hex);
1290 snprintf(name, size, "%s/%s/.build-id/%.2s/%s",
1291 getenv("HOME"), DEBUG_CACHE_DIR,
1292 build_id_hex, build_id_hex + 2);
1293 goto open_file;
1294 }
757more: 1295more:
758 do { 1296 do {
759 self->origin++; 1297 self->origin++;
760 switch (self->origin) { 1298 switch (self->origin) {
761 case DSO__ORIG_FEDORA: 1299 case DSO__ORIG_FEDORA:
762 snprintf(name, size, "/usr/lib/debug%s.debug", self->name); 1300 snprintf(name, size, "/usr/lib/debug%s.debug",
1301 self->long_name);
763 break; 1302 break;
764 case DSO__ORIG_UBUNTU: 1303 case DSO__ORIG_UBUNTU:
765 snprintf(name, size, "/usr/lib/debug%s", self->name); 1304 snprintf(name, size, "/usr/lib/debug%s",
1305 self->long_name);
766 break; 1306 break;
767 case DSO__ORIG_BUILDID: 1307 case DSO__ORIG_BUILDID:
768 build_id = dso__read_build_id(self, v); 1308 if (filename__read_build_id(self->long_name, build_id,
769 if (build_id != NULL) { 1309 sizeof(build_id))) {
1310 build_id__sprintf(build_id, sizeof(build_id),
1311 build_id_hex);
770 snprintf(name, size, 1312 snprintf(name, size,
771 "/usr/lib/debug/.build-id/%.2s/%s.debug", 1313 "/usr/lib/debug/.build-id/%.2s/%s.debug",
772 build_id, build_id + 2); 1314 build_id_hex, build_id_hex + 2);
773 free(build_id); 1315 if (self->has_build_id)
1316 goto compare_build_id;
774 break; 1317 break;
775 } 1318 }
776 self->origin++; 1319 self->origin++;
777 /* Fall thru */ 1320 /* Fall thru */
778 case DSO__ORIG_DSO: 1321 case DSO__ORIG_DSO:
779 snprintf(name, size, "%s", self->name); 1322 snprintf(name, size, "%s", self->long_name);
780 break; 1323 break;
781 1324
782 default: 1325 default:
783 goto out; 1326 goto out;
784 } 1327 }
785 1328
1329 if (self->has_build_id) {
1330 if (filename__read_build_id(name, build_id,
1331 sizeof(build_id)) < 0)
1332 goto more;
1333compare_build_id:
1334 if (!dso__build_id_equal(self, build_id))
1335 goto more;
1336 }
1337open_file:
786 fd = open(name, O_RDONLY); 1338 fd = open(name, O_RDONLY);
787 } while (fd < 0); 1339 } while (fd < 0);
788 1340
789 ret = dso__load_sym(self, fd, name, filter, v, NULL); 1341 ret = dso__load_sym(self, map, name, fd, filter, 0);
790 close(fd); 1342 close(fd);
791 1343
792 /* 1344 /*
@@ -796,7 +1348,7 @@ more:
796 goto more; 1348 goto more;
797 1349
798 if (ret > 0) { 1350 if (ret > 0) {
799 int nr_plt = dso__synthesize_plt_symbols(self, v); 1351 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
800 if (nr_plt > 0) 1352 if (nr_plt > 0)
801 ret += nr_plt; 1353 ret += nr_plt;
802 } 1354 }
@@ -807,231 +1359,608 @@ out:
807 return ret; 1359 return ret;
808} 1360}
809 1361
810static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, 1362struct map *map_groups__find_by_name(struct map_groups *self,
811 symbol_filter_t filter, int v) 1363 enum map_type type, const char *name)
812{ 1364{
813 struct module *mod = mod_dso__find_module(mods, name); 1365 struct rb_node *nd;
814 int err = 0, fd;
815 1366
816 if (mod == NULL || !mod->active) 1367 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
817 return err; 1368 struct map *map = rb_entry(nd, struct map, rb_node);
818 1369
819 fd = open(mod->path, O_RDONLY); 1370 if (map->dso && strcmp(map->dso->short_name, name) == 0)
1371 return map;
1372 }
820 1373
821 if (fd < 0) 1374 return NULL;
822 return err; 1375}
823 1376
824 err = dso__load_sym(self, fd, name, filter, v, mod); 1377static int dso__kernel_module_get_build_id(struct dso *self)
825 close(fd); 1378{
1379 char filename[PATH_MAX];
1380 /*
1381 * kernel module short names are of the form "[module]" and
1382 * we need just "module" here.
1383 */
1384 const char *name = self->short_name + 1;
826 1385
827 return err; 1386 snprintf(filename, sizeof(filename),
1387 "/sys/module/%.*s/notes/.note.gnu.build-id",
1388 (int)strlen(name - 1), name);
1389
1390 if (sysfs__read_build_id(filename, self->build_id,
1391 sizeof(self->build_id)) == 0)
1392 self->has_build_id = true;
1393
1394 return 0;
828} 1395}
829 1396
830int dso__load_modules(struct dso *self, symbol_filter_t filter, int v) 1397static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname)
831{ 1398{
832 struct mod_dso *mods = mod_dso__new_dso("modules"); 1399 struct dirent *dent;
833 struct module *pos; 1400 DIR *dir = opendir(dirname);
834 struct rb_node *next;
835 int err, count = 0;
836 1401
837 err = mod_dso__load_modules(mods); 1402 if (!dir) {
1403 pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1404 return -1;
1405 }
838 1406
839 if (err <= 0) 1407 while ((dent = readdir(dir)) != NULL) {
840 return err; 1408 char path[PATH_MAX];
1409
1410 if (dent->d_type == DT_DIR) {
1411 if (!strcmp(dent->d_name, ".") ||
1412 !strcmp(dent->d_name, ".."))
1413 continue;
1414
1415 snprintf(path, sizeof(path), "%s/%s",
1416 dirname, dent->d_name);
1417 if (map_groups__set_modules_path_dir(self, path) < 0)
1418 goto failure;
1419 } else {
1420 char *dot = strrchr(dent->d_name, '.'),
1421 dso_name[PATH_MAX];
1422 struct map *map;
1423 char *long_name;
1424
1425 if (dot == NULL || strcmp(dot, ".ko"))
1426 continue;
1427 snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1428 (int)(dot - dent->d_name), dent->d_name);
1429
1430 strxfrchar(dso_name, '-', '_');
1431 map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
1432 if (map == NULL)
1433 continue;
1434
1435 snprintf(path, sizeof(path), "%s/%s",
1436 dirname, dent->d_name);
1437
1438 long_name = strdup(path);
1439 if (long_name == NULL)
1440 goto failure;
1441 dso__set_long_name(map->dso, long_name);
1442 dso__kernel_module_get_build_id(map->dso);
1443 }
1444 }
841 1445
842 /* 1446 return 0;
843 * Iterate over modules, and load active symbols. 1447failure:
844 */ 1448 closedir(dir);
845 next = rb_first(&mods->mods); 1449 return -1;
846 while (next) { 1450}
847 pos = rb_entry(next, struct module, rb_node);
848 err = dso__load_module(self, mods, pos->name, filter, v);
849 1451
850 if (err < 0) 1452static int map_groups__set_modules_path(struct map_groups *self)
851 break; 1453{
1454 struct utsname uts;
1455 char modules_path[PATH_MAX];
852 1456
853 next = rb_next(&pos->rb_node); 1457 if (uname(&uts) < 0)
854 count += err; 1458 return -1;
855 } 1459
1460 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
1461 uts.release);
1462
1463 return map_groups__set_modules_path_dir(self, modules_path);
1464}
856 1465
857 if (err < 0) { 1466/*
858 mod_dso__delete_modules(mods); 1467 * Constructor variant for modules (where we know from /proc/modules where
859 mod_dso__delete_self(mods); 1468 * they are loaded) and for vmlinux, where only after we load all the
860 return err; 1469 * symbols we'll know where it starts and ends.
1470 */
1471static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1472{
1473 struct map *self = zalloc(sizeof(*self) +
1474 (dso->kernel ? sizeof(struct kmap) : 0));
1475 if (self != NULL) {
1476 /*
1477 * ->end will be filled after we load all the symbols
1478 */
1479 map__init(self, type, start, 0, 0, dso);
861 } 1480 }
862 1481
863 return count; 1482 return self;
864} 1483}
865 1484
866static inline void dso__fill_symbol_holes(struct dso *self) 1485struct map *map_groups__new_module(struct map_groups *self, u64 start,
1486 const char *filename)
867{ 1487{
868 struct symbol *prev = NULL; 1488 struct map *map;
869 struct rb_node *nd; 1489 struct dso *dso = __dsos__findnew(&dsos__kernel, filename);
870 1490
871 for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { 1491 if (dso == NULL)
872 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 1492 return NULL;
873 1493
874 if (prev) { 1494 map = map__new2(start, dso, MAP__FUNCTION);
875 u64 hole = 0; 1495 if (map == NULL)
876 int alias = pos->start == prev->start; 1496 return NULL;
877 1497
878 if (!alias) 1498 dso->origin = DSO__ORIG_KMODULE;
879 hole = prev->start - pos->end - 1; 1499 map_groups__insert(self, map);
1500 return map;
1501}
880 1502
881 if (hole || alias) { 1503static int map_groups__create_modules(struct map_groups *self)
882 if (alias) 1504{
883 pos->end = prev->end; 1505 char *line = NULL;
884 else if (hole) 1506 size_t n;
885 pos->end = prev->start - 1; 1507 FILE *file = fopen("/proc/modules", "r");
886 } 1508 struct map *map;
887 } 1509
888 prev = pos; 1510 if (file == NULL)
1511 return -1;
1512
1513 while (!feof(file)) {
1514 char name[PATH_MAX];
1515 u64 start;
1516 char *sep;
1517 int line_len;
1518
1519 line_len = getline(&line, &n, file);
1520 if (line_len < 0)
1521 break;
1522
1523 if (!line)
1524 goto out_failure;
1525
1526 line[--line_len] = '\0'; /* \n */
1527
1528 sep = strrchr(line, 'x');
1529 if (sep == NULL)
1530 continue;
1531
1532 hex2u64(sep + 1, &start);
1533
1534 sep = strchr(line, ' ');
1535 if (sep == NULL)
1536 continue;
1537
1538 *sep = '\0';
1539
1540 snprintf(name, sizeof(name), "[%s]", line);
1541 map = map_groups__new_module(self, start, name);
1542 if (map == NULL)
1543 goto out_delete_line;
1544 dso__kernel_module_get_build_id(map->dso);
889 } 1545 }
1546
1547 free(line);
1548 fclose(file);
1549
1550 return map_groups__set_modules_path(self);
1551
1552out_delete_line:
1553 free(line);
1554out_failure:
1555 return -1;
890} 1556}
891 1557
892static int dso__load_vmlinux(struct dso *self, const char *vmlinux, 1558static int dso__load_vmlinux(struct dso *self, struct map *map,
893 symbol_filter_t filter, int v) 1559 const char *vmlinux, symbol_filter_t filter)
894{ 1560{
895 int err, fd = open(vmlinux, O_RDONLY); 1561 int err = -1, fd;
1562
1563 if (self->has_build_id) {
1564 u8 build_id[BUILD_ID_SIZE];
1565
1566 if (filename__read_build_id(vmlinux, build_id,
1567 sizeof(build_id)) < 0) {
1568 pr_debug("No build_id in %s, ignoring it\n", vmlinux);
1569 return -1;
1570 }
1571 if (!dso__build_id_equal(self, build_id)) {
1572 char expected_build_id[BUILD_ID_SIZE * 2 + 1],
1573 vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];
1574
1575 build_id__sprintf(self->build_id,
1576 sizeof(self->build_id),
1577 expected_build_id);
1578 build_id__sprintf(build_id, sizeof(build_id),
1579 vmlinux_build_id);
1580 pr_debug("build_id in %s is %s while expected is %s, "
1581 "ignoring it\n", vmlinux, vmlinux_build_id,
1582 expected_build_id);
1583 return -1;
1584 }
1585 }
896 1586
1587 fd = open(vmlinux, O_RDONLY);
897 if (fd < 0) 1588 if (fd < 0)
898 return -1; 1589 return -1;
899 1590
900 err = dso__load_sym(self, fd, vmlinux, filter, v, NULL); 1591 dso__set_loaded(self, map->type);
1592 err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
1593 close(fd);
901 1594
902 if (err > 0) 1595 if (err > 0)
903 dso__fill_symbol_holes(self); 1596 pr_debug("Using %s for symbols\n", vmlinux);
904 1597
905 close(fd); 1598 return err;
1599}
1600
1601int dso__load_vmlinux_path(struct dso *self, struct map *map,
1602 symbol_filter_t filter)
1603{
1604 int i, err = 0;
1605
1606 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1607 vmlinux_path__nr_entries);
1608
1609 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1610 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1611 if (err > 0) {
1612 dso__set_long_name(self, strdup(vmlinux_path[i]));
1613 break;
1614 }
1615 }
906 1616
907 return err; 1617 return err;
908} 1618}
909 1619
910int dso__load_kernel(struct dso *self, const char *vmlinux, 1620static int dso__load_kernel_sym(struct dso *self, struct map *map,
911 symbol_filter_t filter, int v, int use_modules) 1621 symbol_filter_t filter)
912{ 1622{
913 int err = -1; 1623 int err;
1624 const char *kallsyms_filename = NULL;
1625 char *kallsyms_allocated_filename = NULL;
1626 /*
1627 * Step 1: if the user specified a vmlinux filename, use it and only
1628 * it, reporting errors to the user if it cannot be used.
1629 *
1630 * For instance, try to analyse an ARM perf.data file _without_ a
1631 * build-id, or if the user specifies the wrong path to the right
1632 * vmlinux file, obviously we can't fallback to another vmlinux (a
1633 * x86_86 one, on the machine where analysis is being performed, say),
1634 * or worse, /proc/kallsyms.
1635 *
1636 * If the specified file _has_ a build-id and there is a build-id
1637 * section in the perf.data file, we will still do the expected
1638 * validation in dso__load_vmlinux and will bail out if they don't
1639 * match.
1640 */
1641 if (symbol_conf.vmlinux_name != NULL) {
1642 err = dso__load_vmlinux(self, map,
1643 symbol_conf.vmlinux_name, filter);
1644 goto out_try_fixup;
1645 }
914 1646
915 if (vmlinux) { 1647 if (vmlinux_path != NULL) {
916 err = dso__load_vmlinux(self, vmlinux, filter, v); 1648 err = dso__load_vmlinux_path(self, map, filter);
917 if (err > 0 && use_modules) { 1649 if (err > 0)
918 int syms = dso__load_modules(self, filter, v); 1650 goto out_fixup;
1651 }
919 1652
920 if (syms < 0) { 1653 /*
921 fprintf(stderr, "dso__load_modules failed!\n"); 1654 * Say the kernel DSO was created when processing the build-id header table,
922 return syms; 1655 * we have a build-id, so check if it is the same as the running kernel,
1656 * using it if it is.
1657 */
1658 if (self->has_build_id) {
1659 u8 kallsyms_build_id[BUILD_ID_SIZE];
1660 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1661
1662 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1663 sizeof(kallsyms_build_id)) == 0) {
1664 if (dso__build_id_equal(self, kallsyms_build_id)) {
1665 kallsyms_filename = "/proc/kallsyms";
1666 goto do_kallsyms;
923 } 1667 }
924 err += syms;
925 } 1668 }
926 } 1669 /*
1670 * Now look if we have it on the build-id cache in
1671 * $HOME/.debug/[kernel.kallsyms].
1672 */
1673 build_id__sprintf(self->build_id, sizeof(self->build_id),
1674 sbuild_id);
1675
1676 if (asprintf(&kallsyms_allocated_filename,
1677 "%s/.debug/[kernel.kallsyms]/%s",
1678 getenv("HOME"), sbuild_id) == -1) {
1679 pr_err("Not enough memory for kallsyms file lookup\n");
1680 return -1;
1681 }
927 1682
928 if (err <= 0) 1683 kallsyms_filename = kallsyms_allocated_filename;
929 err = dso__load_kallsyms(self, filter, v);
930 1684
1685 if (access(kallsyms_filename, F_OK)) {
1686 pr_err("No kallsyms or vmlinux with build-id %s "
1687 "was found\n", sbuild_id);
1688 free(kallsyms_allocated_filename);
1689 return -1;
1690 }
1691 } else {
1692 /*
1693 * Last resort, if we don't have a build-id and couldn't find
1694 * any vmlinux file, try the running kernel kallsyms table.
1695 */
1696 kallsyms_filename = "/proc/kallsyms";
1697 }
1698
1699do_kallsyms:
1700 err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
931 if (err > 0) 1701 if (err > 0)
932 self->origin = DSO__ORIG_KERNEL; 1702 pr_debug("Using %s for symbols\n", kallsyms_filename);
1703 free(kallsyms_allocated_filename);
1704
1705out_try_fixup:
1706 if (err > 0) {
1707out_fixup:
1708 if (kallsyms_filename != NULL)
1709 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1710 map__fixup_start(map);
1711 map__fixup_end(map);
1712 }
933 1713
934 return err; 1714 return err;
935} 1715}
936 1716
937LIST_HEAD(dsos); 1717LIST_HEAD(dsos__user);
938struct dso *kernel_dso; 1718LIST_HEAD(dsos__kernel);
939struct dso *vdso;
940struct dso *hypervisor_dso;
941
942const char *vmlinux_name = "vmlinux";
943int modules;
944 1719
945static void dsos__add(struct dso *dso) 1720static void dsos__add(struct list_head *head, struct dso *dso)
946{ 1721{
947 list_add_tail(&dso->node, &dsos); 1722 list_add_tail(&dso->node, head);
948} 1723}
949 1724
950static struct dso *dsos__find(const char *name) 1725static struct dso *dsos__find(struct list_head *head, const char *name)
951{ 1726{
952 struct dso *pos; 1727 struct dso *pos;
953 1728
954 list_for_each_entry(pos, &dsos, node) 1729 list_for_each_entry(pos, head, node)
955 if (strcmp(pos->name, name) == 0) 1730 if (strcmp(pos->long_name, name) == 0)
956 return pos; 1731 return pos;
957 return NULL; 1732 return NULL;
958} 1733}
959 1734
960struct dso *dsos__findnew(const char *name) 1735struct dso *__dsos__findnew(struct list_head *head, const char *name)
961{ 1736{
962 struct dso *dso = dsos__find(name); 1737 struct dso *dso = dsos__find(head, name);
963 int nr;
964
965 if (dso)
966 return dso;
967
968 dso = dso__new(name, 0);
969 if (!dso)
970 goto out_delete_dso;
971 1738
972 nr = dso__load(dso, NULL, verbose); 1739 if (!dso) {
973 if (nr < 0) { 1740 dso = dso__new(name);
974 eprintf("Failed to open: %s\n", name); 1741 if (dso != NULL) {
975 goto out_delete_dso; 1742 dsos__add(head, dso);
1743 dso__set_basename(dso);
1744 }
976 } 1745 }
977 if (!nr)
978 eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
979
980 dsos__add(dso);
981 1746
982 return dso; 1747 return dso;
1748}
983 1749
984out_delete_dso: 1750static void __dsos__fprintf(struct list_head *head, FILE *fp)
985 dso__delete(dso); 1751{
986 return NULL; 1752 struct dso *pos;
1753
1754 list_for_each_entry(pos, head, node) {
1755 int i;
1756 for (i = 0; i < MAP__NR_TYPES; ++i)
1757 dso__fprintf(pos, i, fp);
1758 }
987} 1759}
988 1760
989void dsos__fprintf(FILE *fp) 1761void dsos__fprintf(FILE *fp)
990{ 1762{
1763 __dsos__fprintf(&dsos__kernel, fp);
1764 __dsos__fprintf(&dsos__user, fp);
1765}
1766
1767static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1768 bool with_hits)
1769{
991 struct dso *pos; 1770 struct dso *pos;
1771 size_t ret = 0;
992 1772
993 list_for_each_entry(pos, &dsos, node) 1773 list_for_each_entry(pos, head, node) {
994 dso__fprintf(pos, fp); 1774 if (with_hits && !pos->hit)
1775 continue;
1776 ret += dso__fprintf_buildid(pos, fp);
1777 ret += fprintf(fp, " %s\n", pos->long_name);
1778 }
1779 return ret;
995} 1780}
996 1781
997static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) 1782size_t dsos__fprintf_buildid(FILE *fp, bool with_hits)
998{ 1783{
999 return dso__find_symbol(dso, ip); 1784 return (__dsos__fprintf_buildid(&dsos__kernel, fp, with_hits) +
1785 __dsos__fprintf_buildid(&dsos__user, fp, with_hits));
1000} 1786}
1001 1787
1002int load_kernel(void) 1788struct dso *dso__new_kernel(const char *name)
1003{ 1789{
1004 int err; 1790 struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
1005 1791
1006 kernel_dso = dso__new("[kernel]", 0); 1792 if (self != NULL) {
1007 if (!kernel_dso) 1793 dso__set_short_name(self, "[kernel]");
1008 return -1; 1794 self->kernel = 1;
1795 }
1009 1796
1010 err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules); 1797 return self;
1011 if (err <= 0) { 1798}
1012 dso__delete(kernel_dso);
1013 kernel_dso = NULL;
1014 } else
1015 dsos__add(kernel_dso);
1016 1799
1017 vdso = dso__new("[vdso]", 0); 1800void dso__read_running_kernel_build_id(struct dso *self)
1018 if (!vdso) 1801{
1019 return -1; 1802 if (sysfs__read_build_id("/sys/kernel/notes", self->build_id,
1803 sizeof(self->build_id)) == 0)
1804 self->has_build_id = true;
1805}
1806
1807static struct dso *dsos__create_kernel(const char *vmlinux)
1808{
1809 struct dso *kernel = dso__new_kernel(vmlinux);
1810
1811 if (kernel != NULL) {
1812 dso__read_running_kernel_build_id(kernel);
1813 dsos__add(&dsos__kernel, kernel);
1814 }
1815
1816 return kernel;
1817}
1818
1819int __map_groups__create_kernel_maps(struct map_groups *self,
1820 struct map *vmlinux_maps[MAP__NR_TYPES],
1821 struct dso *kernel)
1822{
1823 enum map_type type;
1824
1825 for (type = 0; type < MAP__NR_TYPES; ++type) {
1826 struct kmap *kmap;
1827
1828 vmlinux_maps[type] = map__new2(0, kernel, type);
1829 if (vmlinux_maps[type] == NULL)
1830 return -1;
1831
1832 vmlinux_maps[type]->map_ip =
1833 vmlinux_maps[type]->unmap_ip = identity__map_ip;
1834
1835 kmap = map__kmap(vmlinux_maps[type]);
1836 kmap->kmaps = self;
1837 map_groups__insert(self, vmlinux_maps[type]);
1838 }
1839
1840 return 0;
1841}
1842
1843static void vmlinux_path__exit(void)
1844{
1845 while (--vmlinux_path__nr_entries >= 0) {
1846 free(vmlinux_path[vmlinux_path__nr_entries]);
1847 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1848 }
1020 1849
1021 vdso->find_symbol = vdso__find_symbol; 1850 free(vmlinux_path);
1851 vmlinux_path = NULL;
1852}
1022 1853
1023 dsos__add(vdso); 1854static int vmlinux_path__init(void)
1855{
1856 struct utsname uts;
1857 char bf[PATH_MAX];
1024 1858
1025 hypervisor_dso = dso__new("[hypervisor]", 0); 1859 if (uname(&uts) < 0)
1026 if (!hypervisor_dso)
1027 return -1; 1860 return -1;
1028 dsos__add(hypervisor_dso);
1029 1861
1030 return err; 1862 vmlinux_path = malloc(sizeof(char *) * 5);
1863 if (vmlinux_path == NULL)
1864 return -1;
1865
1866 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1867 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1868 goto out_fail;
1869 ++vmlinux_path__nr_entries;
1870 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1871 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1872 goto out_fail;
1873 ++vmlinux_path__nr_entries;
1874 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1875 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1876 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1877 goto out_fail;
1878 ++vmlinux_path__nr_entries;
1879 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1880 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1881 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1882 goto out_fail;
1883 ++vmlinux_path__nr_entries;
1884 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1885 uts.release);
1886 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1887 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1888 goto out_fail;
1889 ++vmlinux_path__nr_entries;
1890
1891 return 0;
1892
1893out_fail:
1894 vmlinux_path__exit();
1895 return -1;
1031} 1896}
1032 1897
1898static int setup_list(struct strlist **list, const char *list_str,
1899 const char *list_name)
1900{
1901 if (list_str == NULL)
1902 return 0;
1903
1904 *list = strlist__new(true, list_str);
1905 if (!*list) {
1906 pr_err("problems parsing %s list\n", list_name);
1907 return -1;
1908 }
1909 return 0;
1910}
1033 1911
1034void symbol__init(void) 1912int symbol__init(void)
1035{ 1913{
1036 elf_version(EV_CURRENT); 1914 elf_version(EV_CURRENT);
1915 if (symbol_conf.sort_by_name)
1916 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1917 sizeof(struct symbol));
1918
1919 if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
1920 return -1;
1921
1922 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1923 pr_err("'.' is the only non valid --field-separator argument\n");
1924 return -1;
1925 }
1926
1927 if (setup_list(&symbol_conf.dso_list,
1928 symbol_conf.dso_list_str, "dso") < 0)
1929 return -1;
1930
1931 if (setup_list(&symbol_conf.comm_list,
1932 symbol_conf.comm_list_str, "comm") < 0)
1933 goto out_free_dso_list;
1934
1935 if (setup_list(&symbol_conf.sym_list,
1936 symbol_conf.sym_list_str, "symbol") < 0)
1937 goto out_free_comm_list;
1938
1939 return 0;
1940
1941out_free_dso_list:
1942 strlist__delete(symbol_conf.dso_list);
1943out_free_comm_list:
1944 strlist__delete(symbol_conf.comm_list);
1945 return -1;
1946}
1947
1948int map_groups__create_kernel_maps(struct map_groups *self,
1949 struct map *vmlinux_maps[MAP__NR_TYPES])
1950{
1951 struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name);
1952
1953 if (kernel == NULL)
1954 return -1;
1955
1956 if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0)
1957 return -1;
1958
1959 if (symbol_conf.use_modules && map_groups__create_modules(self) < 0)
1960 pr_debug("Problems creating module maps, continuing anyway...\n");
1961 /*
1962 * Now that we have all the maps created, just set the ->end of them:
1963 */
1964 map_groups__fixup_end(self);
1965 return 0;
1037} 1966}