Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[deliverable/linux.git] / tools / perf / util / symbol.c
CommitLineData
5aab621b
ACM
1#define _GNU_SOURCE
2#include <ctype.h>
3#include <dirent.h>
4#include <errno.h>
5#include <libgen.h>
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <sys/param.h>
12#include <fcntl.h>
13#include <unistd.h>
b36f19d5 14#include "build-id.h"
8a6c5b26 15#include "debug.h"
a2928c42 16#include "symbol.h"
5aab621b 17#include "strlist.h"
a2928c42
ACM
18
19#include <libelf.h>
20#include <gelf.h>
21#include <elf.h>
f1617b40 22#include <limits.h>
439d473b 23#include <sys/utsname.h>
2cdbc46d 24
c12e15e7
ACM
25#ifndef NT_GNU_BUILD_ID
26#define NT_GNU_BUILD_ID 3
27#endif
28
21916c38
DM
29static bool dso__build_id_equal(const struct dso *self, u8 *build_id);
30static int elf_read_build_id(Elf *elf, void *bf, size_t size);
b0da954a 31static void dsos__add(struct list_head *head, struct dso *dso);
3610583c 32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
c338aee8 33static int dso__load_kernel_sym(struct dso *self, struct map *map,
9de89fe7 34 symbol_filter_t filter);
a1645ce1
ZY
35static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
36 symbol_filter_t filter);
cc612d81
ACM
37static int vmlinux_path__nr_entries;
38static char **vmlinux_path;
439d473b 39
75be6cf4 40struct symbol_conf symbol_conf = {
d599db3f 41 .exclude_other = true,
b32d133a
ACM
42 .use_modules = true,
43 .try_vmlinux_path = true,
ec5761ea 44 .symfs = "",
b32d133a
ACM
45};
46
8a6c5b26
ACM
47int dso__name_len(const struct dso *self)
48{
49 if (verbose)
50 return self->long_name_len;
51
52 return self->short_name_len;
53}
54
3610583c
ACM
55bool dso__loaded(const struct dso *self, enum map_type type)
56{
57 return self->loaded & (1 << type);
58}
59
79406cd7
ACM
60bool dso__sorted_by_name(const struct dso *self, enum map_type type)
61{
62 return self->sorted_by_name & (1 << type);
63}
64
79406cd7
ACM
65static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
66{
67 self->sorted_by_name |= (1 << type);
68}
69
36a3e646 70bool symbol_type__is_a(char symbol_type, enum map_type map_type)
6893d4ee
ACM
71{
72 switch (map_type) {
73 case MAP__FUNCTION:
74 return symbol_type == 'T' || symbol_type == 'W';
f1dfa0b1
ACM
75 case MAP__VARIABLE:
76 return symbol_type == 'D' || symbol_type == 'd';
6893d4ee
ACM
77 default:
78 return false;
79 }
80}
81
fcf1203a 82static void symbols__fixup_end(struct rb_root *self)
af427bf5 83{
fcf1203a 84 struct rb_node *nd, *prevnd = rb_first(self);
2e538c4a 85 struct symbol *curr, *prev;
af427bf5
ACM
86
87 if (prevnd == NULL)
88 return;
89
2e538c4a
ACM
90 curr = rb_entry(prevnd, struct symbol, rb_node);
91
af427bf5 92 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
2e538c4a
ACM
93 prev = curr;
94 curr = rb_entry(nd, struct symbol, rb_node);
af427bf5
ACM
95
96 if (prev->end == prev->start)
97 prev->end = curr->start - 1;
af427bf5 98 }
2e538c4a
ACM
99
100 /* Last entry */
101 if (curr->end == curr->start)
102 curr->end = roundup(curr->start, 4096);
af427bf5
ACM
103}
104
9958e1f0 105static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
af427bf5
ACM
106{
107 struct map *prev, *curr;
95011c60 108 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
af427bf5
ACM
109
110 if (prevnd == NULL)
111 return;
112
113 curr = rb_entry(prevnd, struct map, rb_node);
af427bf5
ACM
114
115 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
116 prev = curr;
117 curr = rb_entry(nd, struct map, rb_node);
118 prev->end = curr->start - 1;
2e538c4a 119 }
90c83218
ACM
120
121 /*
122 * We still haven't the actual symbols, so guess the
123 * last map final address.
124 */
9d1faba5 125 curr->end = ~0ULL;
af427bf5
ACM
126}
127
9958e1f0 128static void map_groups__fixup_end(struct map_groups *self)
23ea4a3f
ACM
129{
130 int i;
131 for (i = 0; i < MAP__NR_TYPES; ++i)
9958e1f0 132 __map_groups__fixup_end(self, i);
23ea4a3f
ACM
133}
134
c408fedf
ACM
135static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
136 const char *name)
a2928c42 137{
0085c954 138 size_t namelen = strlen(name) + 1;
5aab621b
ACM
139 struct symbol *self = calloc(1, (symbol_conf.priv_size +
140 sizeof(*self) + namelen));
36479484 141 if (self == NULL)
0b73da3f
IM
142 return NULL;
143
75be6cf4
ACM
144 if (symbol_conf.priv_size)
145 self = ((void *)self) + symbol_conf.priv_size;
36479484 146
fefb0b94
ACM
147 self->start = start;
148 self->end = len ? start + len - 1 : start;
c408fedf 149 self->binding = binding;
fefb0b94 150 self->namelen = namelen - 1;
e4204992 151
29a9f66d 152 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
e4204992 153
0b73da3f 154 memcpy(self->name, name, namelen);
a2928c42
ACM
155
156 return self;
157}
158
628ada0c 159void symbol__delete(struct symbol *self)
a2928c42 160{
75be6cf4 161 free(((void *)self) - symbol_conf.priv_size);
a2928c42
ACM
162}
163
164static size_t symbol__fprintf(struct symbol *self, FILE *fp)
165{
c408fedf
ACM
166 return fprintf(fp, " %llx-%llx %c %s\n",
167 self->start, self->end,
168 self->binding == STB_GLOBAL ? 'g' :
169 self->binding == STB_LOCAL ? 'l' : 'w',
170 self->name);
a2928c42
ACM
171}
172
b7cece76 173void dso__set_long_name(struct dso *self, char *name)
cfc10d3b 174{
ef6ae724
ACM
175 if (name == NULL)
176 return;
cfc10d3b
ACM
177 self->long_name = name;
178 self->long_name_len = strlen(name);
179}
180
b63be8d7
ACM
181static void dso__set_short_name(struct dso *self, const char *name)
182{
183 if (name == NULL)
184 return;
185 self->short_name = name;
186 self->short_name_len = strlen(name);
187}
188
cfc10d3b
ACM
189static void dso__set_basename(struct dso *self)
190{
b63be8d7 191 dso__set_short_name(self, basename(self->long_name));
cfc10d3b
ACM
192}
193
00a192b3 194struct dso *dso__new(const char *name)
a2928c42 195{
5aab621b 196 struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
a2928c42
ACM
197
198 if (self != NULL) {
6a4694a4 199 int i;
a2928c42 200 strcpy(self->name, name);
cfc10d3b 201 dso__set_long_name(self, self->name);
b63be8d7 202 dso__set_short_name(self, self->name);
6a4694a4 203 for (i = 0; i < MAP__NR_TYPES; ++i)
79406cd7 204 self->symbols[i] = self->symbol_names[i] = RB_ROOT;
52d422de 205 self->slen_calculated = 0;
94cb9e38 206 self->origin = DSO__ORIG_NOT_FOUND;
8d06367f 207 self->loaded = 0;
79406cd7 208 self->sorted_by_name = 0;
8d06367f 209 self->has_build_id = 0;
a1645ce1 210 self->kernel = DSO_TYPE_USER;
0ab061cd 211 INIT_LIST_HEAD(&self->node);
a2928c42
ACM
212 }
213
214 return self;
215}
216
fcf1203a 217static void symbols__delete(struct rb_root *self)
a2928c42
ACM
218{
219 struct symbol *pos;
fcf1203a 220 struct rb_node *next = rb_first(self);
a2928c42
ACM
221
222 while (next) {
223 pos = rb_entry(next, struct symbol, rb_node);
224 next = rb_next(&pos->rb_node);
fcf1203a 225 rb_erase(&pos->rb_node, self);
00a192b3 226 symbol__delete(pos);
a2928c42
ACM
227 }
228}
229
230void dso__delete(struct dso *self)
231{
6a4694a4
ACM
232 int i;
233 for (i = 0; i < MAP__NR_TYPES; ++i)
234 symbols__delete(&self->symbols[i]);
6e406257
ACM
235 if (self->sname_alloc)
236 free((char *)self->short_name);
237 if (self->lname_alloc)
439d473b 238 free(self->long_name);
a2928c42
ACM
239 free(self);
240}
241
8d06367f
ACM
242void dso__set_build_id(struct dso *self, void *build_id)
243{
244 memcpy(self->build_id, build_id, sizeof(self->build_id));
245 self->has_build_id = 1;
246}
247
fcf1203a 248static void symbols__insert(struct rb_root *self, struct symbol *sym)
a2928c42 249{
fcf1203a 250 struct rb_node **p = &self->rb_node;
a2928c42 251 struct rb_node *parent = NULL;
9cffa8d5 252 const u64 ip = sym->start;
a2928c42
ACM
253 struct symbol *s;
254
255 while (*p != NULL) {
256 parent = *p;
257 s = rb_entry(parent, struct symbol, rb_node);
258 if (ip < s->start)
259 p = &(*p)->rb_left;
260 else
261 p = &(*p)->rb_right;
262 }
263 rb_link_node(&sym->rb_node, parent, p);
fcf1203a 264 rb_insert_color(&sym->rb_node, self);
a2928c42
ACM
265}
266
fcf1203a 267static struct symbol *symbols__find(struct rb_root *self, u64 ip)
a2928c42
ACM
268{
269 struct rb_node *n;
270
271 if (self == NULL)
272 return NULL;
273
fcf1203a 274 n = self->rb_node;
a2928c42
ACM
275
276 while (n) {
277 struct symbol *s = rb_entry(n, struct symbol, rb_node);
278
279 if (ip < s->start)
280 n = n->rb_left;
281 else if (ip > s->end)
282 n = n->rb_right;
283 else
284 return s;
285 }
286
287 return NULL;
288}
289
79406cd7
ACM
290struct symbol_name_rb_node {
291 struct rb_node rb_node;
292 struct symbol sym;
293};
294
295static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
296{
297 struct rb_node **p = &self->rb_node;
298 struct rb_node *parent = NULL;
02a9d037
RV
299 struct symbol_name_rb_node *symn, *s;
300
301 symn = container_of(sym, struct symbol_name_rb_node, sym);
79406cd7
ACM
302
303 while (*p != NULL) {
304 parent = *p;
305 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
306 if (strcmp(sym->name, s->sym.name) < 0)
307 p = &(*p)->rb_left;
308 else
309 p = &(*p)->rb_right;
310 }
311 rb_link_node(&symn->rb_node, parent, p);
312 rb_insert_color(&symn->rb_node, self);
313}
314
315static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source)
316{
317 struct rb_node *nd;
318
319 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
320 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
321 symbols__insert_by_name(self, pos);
322 }
323}
324
325static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name)
326{
327 struct rb_node *n;
328
329 if (self == NULL)
330 return NULL;
331
332 n = self->rb_node;
333
334 while (n) {
335 struct symbol_name_rb_node *s;
336 int cmp;
337
338 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
339 cmp = strcmp(name, s->sym.name);
340
341 if (cmp < 0)
342 n = n->rb_left;
343 else if (cmp > 0)
344 n = n->rb_right;
345 else
346 return &s->sym;
347 }
348
349 return NULL;
350}
351
352struct symbol *dso__find_symbol(struct dso *self,
353 enum map_type type, u64 addr)
fcf1203a 354{
6a4694a4 355 return symbols__find(&self->symbols[type], addr);
fcf1203a
ACM
356}
357
79406cd7
ACM
358struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
359 const char *name)
360{
361 return symbols__find_by_name(&self->symbol_names[type], name);
362}
363
364void dso__sort_by_name(struct dso *self, enum map_type type)
365{
366 dso__set_sorted_by_name(self, type);
367 return symbols__sort_by_name(&self->symbol_names[type],
368 &self->symbols[type]);
369}
370
ef12a141 371int build_id__sprintf(const u8 *self, int len, char *bf)
a2928c42 372{
8d06367f 373 char *bid = bf;
ef12a141 374 const u8 *raw = self;
8d06367f 375 int i;
a2928c42 376
8d06367f
ACM
377 for (i = 0; i < len; ++i) {
378 sprintf(bid, "%02x", *raw);
379 ++raw;
380 bid += 2;
381 }
382
383 return raw - self;
384}
385
9e03eb2d 386size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
8d06367f
ACM
387{
388 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
8d06367f
ACM
389
390 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
9e03eb2d
ACM
391 return fprintf(fp, "%s", sbuild_id);
392}
393
90f18e63
SD
394size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp)
395{
396 size_t ret = 0;
397 struct rb_node *nd;
398 struct symbol_name_rb_node *pos;
399
400 for (nd = rb_first(&self->symbol_names[type]); nd; nd = rb_next(nd)) {
401 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
402 fprintf(fp, "%s\n", pos->sym.name);
403 }
404
405 return ret;
406}
407
95011c60 408size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
9e03eb2d
ACM
409{
410 struct rb_node *nd;
411 size_t ret = fprintf(fp, "dso: %s (", self->short_name);
412
3846df2e
ACM
413 if (self->short_name != self->long_name)
414 ret += fprintf(fp, "%s, ", self->long_name);
415 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
416 self->loaded ? "" : "NOT ");
9e03eb2d 417 ret += dso__fprintf_buildid(self, fp);
6a4694a4 418 ret += fprintf(fp, ")\n");
95011c60
ACM
419 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
420 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
421 ret += symbol__fprintf(pos, fp);
a2928c42
ACM
422 }
423
424 return ret;
425}
426
9e201442
ACM
427int kallsyms__parse(const char *filename, void *arg,
428 int (*process_symbol)(void *arg, const char *name,
682b335a 429 char type, u64 start))
a2928c42 430{
a2928c42
ACM
431 char *line = NULL;
432 size_t n;
682b335a 433 int err = 0;
9e201442 434 FILE *file = fopen(filename, "r");
a2928c42
ACM
435
436 if (file == NULL)
437 goto out_failure;
438
439 while (!feof(file)) {
9cffa8d5 440 u64 start;
a2928c42
ACM
441 int line_len, len;
442 char symbol_type;
2e538c4a 443 char *symbol_name;
a2928c42
ACM
444
445 line_len = getline(&line, &n, file);
a1645ce1 446 if (line_len < 0 || !line)
a2928c42
ACM
447 break;
448
a2928c42
ACM
449 line[--line_len] = '\0'; /* \n */
450
a0055ae2 451 len = hex2u64(line, &start);
a2928c42
ACM
452
453 len++;
454 if (len + 2 >= line_len)
455 continue;
456
457 symbol_type = toupper(line[len]);
af427bf5 458 symbol_name = line + len + 2;
682b335a
ACM
459
460 err = process_symbol(arg, symbol_name, symbol_type, start);
461 if (err)
462 break;
2e538c4a
ACM
463 }
464
465 free(line);
466 fclose(file);
682b335a 467 return err;
2e538c4a 468
2e538c4a
ACM
469out_failure:
470 return -1;
471}
472
682b335a
ACM
473struct process_kallsyms_args {
474 struct map *map;
475 struct dso *dso;
476};
477
c408fedf
ACM
478static u8 kallsyms2elf_type(char type)
479{
480 if (type == 'W')
481 return STB_WEAK;
482
483 return isupper(type) ? STB_GLOBAL : STB_LOCAL;
484}
485
682b335a
ACM
486static int map__process_kallsym_symbol(void *arg, const char *name,
487 char type, u64 start)
488{
489 struct symbol *sym;
490 struct process_kallsyms_args *a = arg;
491 struct rb_root *root = &a->dso->symbols[a->map->type];
492
493 if (!symbol_type__is_a(type, a->map->type))
494 return 0;
495
496 /*
497 * Will fix up the end later, when we have all symbols sorted.
498 */
c408fedf 499 sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
682b335a
ACM
500
501 if (sym == NULL)
502 return -ENOMEM;
503 /*
504 * We will pass the symbols to the filter later, in
505 * map__split_kallsyms, when we have split the maps per module
506 */
507 symbols__insert(root, sym);
a1645ce1 508
682b335a
ACM
509 return 0;
510}
511
512/*
513 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
514 * so that we can in the next step set the symbol ->end address and then
515 * call kernel_maps__split_kallsyms.
516 */
9e201442
ACM
517static int dso__load_all_kallsyms(struct dso *self, const char *filename,
518 struct map *map)
682b335a
ACM
519{
520 struct process_kallsyms_args args = { .map = map, .dso = self, };
9e201442 521 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
682b335a
ACM
522}
523
2e538c4a
ACM
524/*
525 * Split the symbols into maps, making sure there are no overlaps, i.e. the
526 * kernel range is broken in several maps, named [kernel].N, as we don't have
527 * the original ELF section names vmlinux have.
528 */
9958e1f0 529static int dso__split_kallsyms(struct dso *self, struct map *map,
9de89fe7 530 symbol_filter_t filter)
2e538c4a 531{
9de89fe7 532 struct map_groups *kmaps = map__kmap(map)->kmaps;
23346f21 533 struct machine *machine = kmaps->machine;
4e06255f 534 struct map *curr_map = map;
2e538c4a 535 struct symbol *pos;
8a953312 536 int count = 0, moved = 0;
4e06255f
ACM
537 struct rb_root *root = &self->symbols[map->type];
538 struct rb_node *next = rb_first(root);
2e538c4a
ACM
539 int kernel_range = 0;
540
541 while (next) {
542 char *module;
543
544 pos = rb_entry(next, struct symbol, rb_node);
545 next = rb_next(&pos->rb_node);
546
547 module = strchr(pos->name, '\t');
548 if (module) {
75be6cf4 549 if (!symbol_conf.use_modules)
1de8e245
ACM
550 goto discard_symbol;
551
2e538c4a
ACM
552 *module++ = '\0';
553
b7cece76 554 if (strcmp(curr_map->dso->short_name, module)) {
a1645ce1 555 if (curr_map != map &&
23346f21
ACM
556 self->kernel == DSO_TYPE_GUEST_KERNEL &&
557 machine__is_default_guest(machine)) {
a1645ce1
ZY
558 /*
559 * We assume all symbols of a module are
560 * continuous in * kallsyms, so curr_map
561 * points to a module and all its
562 * symbols are in its kmap. Mark it as
563 * loaded.
564 */
565 dso__set_loaded(curr_map->dso,
566 curr_map->type);
567 }
568
569 curr_map = map_groups__find_by_name(kmaps,
570 map->type, module);
4e06255f 571 if (curr_map == NULL) {
2f51903b 572 pr_debug("%s/proc/{kallsyms,modules} "
b7cece76 573 "inconsistency while looking "
a1645ce1 574 "for \"%s\" module!\n",
23346f21 575 machine->root_dir, module);
a1645ce1
ZY
576 curr_map = map;
577 goto discard_symbol;
af427bf5 578 }
b7cece76 579
a1645ce1 580 if (curr_map->dso->loaded &&
23346f21 581 !machine__is_default_guest(machine))
b7cece76 582 goto discard_symbol;
af427bf5 583 }
2e538c4a
ACM
584 /*
585 * So that we look just like we get from .ko files,
586 * i.e. not prelinked, relative to map->start.
587 */
4e06255f
ACM
588 pos->start = curr_map->map_ip(curr_map, pos->start);
589 pos->end = curr_map->map_ip(curr_map, pos->end);
590 } else if (curr_map != map) {
2e538c4a
ACM
591 char dso_name[PATH_MAX];
592 struct dso *dso;
593
8a953312
ACM
594 if (count == 0) {
595 curr_map = map;
596 goto filter_symbol;
597 }
598
a1645ce1
ZY
599 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
600 snprintf(dso_name, sizeof(dso_name),
601 "[guest.kernel].%d",
602 kernel_range++);
603 else
604 snprintf(dso_name, sizeof(dso_name),
605 "[kernel].%d",
606 kernel_range++);
2e538c4a 607
00a192b3 608 dso = dso__new(dso_name);
2e538c4a
ACM
609 if (dso == NULL)
610 return -1;
611
a1645ce1
ZY
612 dso->kernel = self->kernel;
613
4e06255f 614 curr_map = map__new2(pos->start, dso, map->type);
37fe5fcb 615 if (curr_map == NULL) {
2e538c4a
ACM
616 dso__delete(dso);
617 return -1;
618 }
a2928c42 619
4e06255f 620 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
9de89fe7 621 map_groups__insert(kmaps, curr_map);
2e538c4a
ACM
622 ++kernel_range;
623 }
8a953312 624filter_symbol:
4e06255f 625 if (filter && filter(curr_map, pos)) {
1de8e245 626discard_symbol: rb_erase(&pos->rb_node, root);
00a192b3 627 symbol__delete(pos);
2e538c4a 628 } else {
4e06255f
ACM
629 if (curr_map != map) {
630 rb_erase(&pos->rb_node, root);
631 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
8a953312
ACM
632 ++moved;
633 } else
634 ++count;
9974f496 635 }
a2928c42
ACM
636 }
637
a1645ce1
ZY
638 if (curr_map != map &&
639 self->kernel == DSO_TYPE_GUEST_KERNEL &&
23346f21 640 machine__is_default_guest(kmaps->machine)) {
a1645ce1
ZY
641 dso__set_loaded(curr_map->dso, curr_map->type);
642 }
643
8a953312 644 return count + moved;
2e538c4a 645}
a2928c42 646
9de89fe7
ACM
647int dso__load_kallsyms(struct dso *self, const char *filename,
648 struct map *map, symbol_filter_t filter)
2e538c4a 649{
9e201442 650 if (dso__load_all_kallsyms(self, filename, map) < 0)
2e538c4a
ACM
651 return -1;
652
4e06255f 653 symbols__fixup_end(&self->symbols[map->type]);
a1645ce1
ZY
654 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
655 self->origin = DSO__ORIG_GUEST_KERNEL;
656 else
657 self->origin = DSO__ORIG_KERNEL;
2e538c4a 658
9de89fe7 659 return dso__split_kallsyms(self, map, filter);
af427bf5
ACM
660}
661
439d473b 662static int dso__load_perf_map(struct dso *self, struct map *map,
6beba7ad 663 symbol_filter_t filter)
80d496be
PE
664{
665 char *line = NULL;
666 size_t n;
667 FILE *file;
668 int nr_syms = 0;
669
439d473b 670 file = fopen(self->long_name, "r");
80d496be
PE
671 if (file == NULL)
672 goto out_failure;
673
674 while (!feof(file)) {
9cffa8d5 675 u64 start, size;
80d496be
PE
676 struct symbol *sym;
677 int line_len, len;
678
679 line_len = getline(&line, &n, file);
680 if (line_len < 0)
681 break;
682
683 if (!line)
684 goto out_failure;
685
686 line[--line_len] = '\0'; /* \n */
687
688 len = hex2u64(line, &start);
689
690 len++;
691 if (len + 2 >= line_len)
692 continue;
693
694 len += hex2u64(line + len, &size);
695
696 len++;
697 if (len + 2 >= line_len)
698 continue;
699
c408fedf 700 sym = symbol__new(start, size, STB_GLOBAL, line + len);
80d496be
PE
701
702 if (sym == NULL)
703 goto out_delete_line;
704
439d473b 705 if (filter && filter(map, sym))
00a192b3 706 symbol__delete(sym);
80d496be 707 else {
6a4694a4 708 symbols__insert(&self->symbols[map->type], sym);
80d496be
PE
709 nr_syms++;
710 }
711 }
712
713 free(line);
714 fclose(file);
715
716 return nr_syms;
717
718out_delete_line:
719 free(line);
720out_failure:
721 return -1;
722}
723
a2928c42
ACM
724/**
725 * elf_symtab__for_each_symbol - iterate thru all the symbols
726 *
727 * @self: struct elf_symtab instance to iterate
83a0944f 728 * @idx: uint32_t idx
a2928c42
ACM
729 * @sym: GElf_Sym iterator
730 */
83a0944f
IM
731#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
732 for (idx = 0, gelf_getsym(syms, idx, &sym);\
733 idx < nr_syms; \
734 idx++, gelf_getsym(syms, idx, &sym))
a2928c42
ACM
735
736static inline uint8_t elf_sym__type(const GElf_Sym *sym)
737{
738 return GELF_ST_TYPE(sym->st_info);
739}
740
741static inline int elf_sym__is_function(const GElf_Sym *sym)
742{
743 return elf_sym__type(sym) == STT_FUNC &&
744 sym->st_name != 0 &&
81833130 745 sym->st_shndx != SHN_UNDEF;
a2928c42
ACM
746}
747
f1dfa0b1
ACM
748static inline bool elf_sym__is_object(const GElf_Sym *sym)
749{
750 return elf_sym__type(sym) == STT_OBJECT &&
751 sym->st_name != 0 &&
752 sym->st_shndx != SHN_UNDEF;
753}
754
6cfcc53e
MG
755static inline int elf_sym__is_label(const GElf_Sym *sym)
756{
757 return elf_sym__type(sym) == STT_NOTYPE &&
758 sym->st_name != 0 &&
759 sym->st_shndx != SHN_UNDEF &&
760 sym->st_shndx != SHN_ABS;
761}
762
763static inline const char *elf_sec__name(const GElf_Shdr *shdr,
764 const Elf_Data *secstrs)
765{
766 return secstrs->d_buf + shdr->sh_name;
767}
768
769static inline int elf_sec__is_text(const GElf_Shdr *shdr,
770 const Elf_Data *secstrs)
771{
772 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
773}
774
f1dfa0b1
ACM
775static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
776 const Elf_Data *secstrs)
777{
778 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
779}
780
a2928c42
ACM
781static inline const char *elf_sym__name(const GElf_Sym *sym,
782 const Elf_Data *symstrs)
783{
784 return symstrs->d_buf + sym->st_name;
785}
786
787static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
788 GElf_Shdr *shp, const char *name,
83a0944f 789 size_t *idx)
a2928c42
ACM
790{
791 Elf_Scn *sec = NULL;
792 size_t cnt = 1;
793
794 while ((sec = elf_nextscn(elf, sec)) != NULL) {
795 char *str;
796
797 gelf_getshdr(sec, shp);
798 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
799 if (!strcmp(name, str)) {
83a0944f
IM
800 if (idx)
801 *idx = cnt;
a2928c42
ACM
802 break;
803 }
804 ++cnt;
805 }
806
807 return sec;
808}
809
8ce998d6
ACM
810#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
811 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
812 idx < nr_entries; \
813 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
814
815#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
816 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
817 idx < nr_entries; \
818 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
819
a25e46c4
ACM
820/*
821 * We need to check if we have a .dynsym, so that we can handle the
822 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
823 * .dynsym or .symtab).
824 * And always look at the original dso, not at debuginfo packages, that
825 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
826 */
82164161
ACM
827static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
828 symbol_filter_t filter)
8ce998d6
ACM
829{
830 uint32_t nr_rel_entries, idx;
831 GElf_Sym sym;
9cffa8d5 832 u64 plt_offset;
8ce998d6
ACM
833 GElf_Shdr shdr_plt;
834 struct symbol *f;
a25e46c4 835 GElf_Shdr shdr_rel_plt, shdr_dynsym;
8ce998d6 836 Elf_Data *reldata, *syms, *symstrs;
a25e46c4
ACM
837 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
838 size_t dynsym_idx;
839 GElf_Ehdr ehdr;
8ce998d6 840 char sympltname[1024];
a25e46c4
ACM
841 Elf *elf;
842 int nr = 0, symidx, fd, err = 0;
ec5761ea 843 char name[PATH_MAX];
a25e46c4 844
ec5761ea
DA
845 snprintf(name, sizeof(name), "%s%s",
846 symbol_conf.symfs, self->long_name);
847 fd = open(name, O_RDONLY);
a25e46c4
ACM
848 if (fd < 0)
849 goto out;
850
84087126 851 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
a25e46c4
ACM
852 if (elf == NULL)
853 goto out_close;
854
855 if (gelf_getehdr(elf, &ehdr) == NULL)
856 goto out_elf_end;
857
858 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
859 ".dynsym", &dynsym_idx);
860 if (scn_dynsym == NULL)
861 goto out_elf_end;
8ce998d6 862
a25e46c4 863 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
8ce998d6
ACM
864 ".rela.plt", NULL);
865 if (scn_plt_rel == NULL) {
a25e46c4 866 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
8ce998d6
ACM
867 ".rel.plt", NULL);
868 if (scn_plt_rel == NULL)
a25e46c4 869 goto out_elf_end;
8ce998d6
ACM
870 }
871
a25e46c4
ACM
872 err = -1;
873
8ce998d6 874 if (shdr_rel_plt.sh_link != dynsym_idx)
a25e46c4 875 goto out_elf_end;
8ce998d6 876
a25e46c4
ACM
877 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
878 goto out_elf_end;
8ce998d6
ACM
879
880 /*
83a0944f 881 * Fetch the relocation section to find the idxes to the GOT
8ce998d6
ACM
882 * and the symbols in the .dynsym they refer to.
883 */
884 reldata = elf_getdata(scn_plt_rel, NULL);
885 if (reldata == NULL)
a25e46c4 886 goto out_elf_end;
8ce998d6
ACM
887
888 syms = elf_getdata(scn_dynsym, NULL);
889 if (syms == NULL)
a25e46c4 890 goto out_elf_end;
8ce998d6 891
a25e46c4 892 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
8ce998d6 893 if (scn_symstrs == NULL)
a25e46c4 894 goto out_elf_end;
8ce998d6
ACM
895
896 symstrs = elf_getdata(scn_symstrs, NULL);
897 if (symstrs == NULL)
a25e46c4 898 goto out_elf_end;
8ce998d6
ACM
899
900 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
901 plt_offset = shdr_plt.sh_offset;
902
903 if (shdr_rel_plt.sh_type == SHT_RELA) {
904 GElf_Rela pos_mem, *pos;
905
906 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
907 nr_rel_entries) {
908 symidx = GELF_R_SYM(pos->r_info);
909 plt_offset += shdr_plt.sh_entsize;
910 gelf_getsym(syms, symidx, &sym);
911 snprintf(sympltname, sizeof(sympltname),
912 "%s@plt", elf_sym__name(&sym, symstrs));
913
914 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
c408fedf 915 STB_GLOBAL, sympltname);
8ce998d6 916 if (!f)
a25e46c4 917 goto out_elf_end;
8ce998d6 918
82164161
ACM
919 if (filter && filter(map, f))
920 symbol__delete(f);
921 else {
6a4694a4 922 symbols__insert(&self->symbols[map->type], f);
82164161
ACM
923 ++nr;
924 }
8ce998d6
ACM
925 }
926 } else if (shdr_rel_plt.sh_type == SHT_REL) {
927 GElf_Rel pos_mem, *pos;
928 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
929 nr_rel_entries) {
930 symidx = GELF_R_SYM(pos->r_info);
931 plt_offset += shdr_plt.sh_entsize;
932 gelf_getsym(syms, symidx, &sym);
933 snprintf(sympltname, sizeof(sympltname),
934 "%s@plt", elf_sym__name(&sym, symstrs));
935
936 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
c408fedf 937 STB_GLOBAL, sympltname);
8ce998d6 938 if (!f)
a25e46c4 939 goto out_elf_end;
8ce998d6 940
82164161
ACM
941 if (filter && filter(map, f))
942 symbol__delete(f);
943 else {
6a4694a4 944 symbols__insert(&self->symbols[map->type], f);
82164161
ACM
945 ++nr;
946 }
8ce998d6 947 }
8ce998d6
ACM
948 }
949
a25e46c4
ACM
950 err = 0;
951out_elf_end:
952 elf_end(elf);
953out_close:
954 close(fd);
955
956 if (err == 0)
957 return nr;
958out:
fe2197b8
ACM
959 pr_debug("%s: problems reading %s PLT info.\n",
960 __func__, self->long_name);
a25e46c4 961 return 0;
8ce998d6
ACM
962}
963
d45868d3
ACM
964static bool elf_sym__is_a(GElf_Sym *self, enum map_type type)
965{
966 switch (type) {
967 case MAP__FUNCTION:
968 return elf_sym__is_function(self);
f1dfa0b1
ACM
969 case MAP__VARIABLE:
970 return elf_sym__is_object(self);
d45868d3
ACM
971 default:
972 return false;
973 }
974}
975
976static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type)
977{
978 switch (type) {
979 case MAP__FUNCTION:
980 return elf_sec__is_text(self, secstrs);
f1dfa0b1
ACM
981 case MAP__VARIABLE:
982 return elf_sec__is_data(self, secstrs);
d45868d3
ACM
983 default:
984 return false;
985 }
986}
987
70c3856b
EM
988static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
989{
990 Elf_Scn *sec = NULL;
991 GElf_Shdr shdr;
992 size_t cnt = 1;
993
994 while ((sec = elf_nextscn(elf, sec)) != NULL) {
995 gelf_getshdr(sec, &shdr);
996
997 if ((addr >= shdr.sh_addr) &&
998 (addr < (shdr.sh_addr + shdr.sh_size)))
999 return cnt;
1000
1001 ++cnt;
1002 }
1003
1004 return -1;
1005}
1006
9de89fe7 1007static int dso__load_sym(struct dso *self, struct map *map, const char *name,
6da80ce8
DM
1008 int fd, symbol_filter_t filter, int kmodule,
1009 int want_symtab)
a2928c42 1010{
9de89fe7 1011 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
2e538c4a
ACM
1012 struct map *curr_map = map;
1013 struct dso *curr_dso = self;
6cfcc53e 1014 Elf_Data *symstrs, *secstrs;
a2928c42
ACM
1015 uint32_t nr_syms;
1016 int err = -1;
83a0944f 1017 uint32_t idx;
a2928c42 1018 GElf_Ehdr ehdr;
70c3856b
EM
1019 GElf_Shdr shdr, opdshdr;
1020 Elf_Data *syms, *opddata = NULL;
a2928c42 1021 GElf_Sym sym;
70c3856b 1022 Elf_Scn *sec, *sec_strndx, *opdsec;
a2928c42 1023 Elf *elf;
439d473b 1024 int nr = 0;
70c3856b 1025 size_t opdidx = 0;
a2928c42 1026
84087126 1027 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
a2928c42 1028 if (elf == NULL) {
8b1389ef 1029 pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
a2928c42
ACM
1030 goto out_close;
1031 }
1032
1033 if (gelf_getehdr(elf, &ehdr) == NULL) {
8b1389ef 1034 pr_debug("%s: cannot get elf header.\n", __func__);
a2928c42
ACM
1035 goto out_elf_end;
1036 }
1037
6da80ce8 1038 /* Always reject images with a mismatched build-id: */
21916c38
DM
1039 if (self->has_build_id) {
1040 u8 build_id[BUILD_ID_SIZE];
1041
1042 if (elf_read_build_id(elf, build_id,
1043 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1044 goto out_elf_end;
1045
1046 if (!dso__build_id_equal(self, build_id))
1047 goto out_elf_end;
1048 }
1049
a2928c42 1050 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
8ce998d6 1051 if (sec == NULL) {
6da80ce8
DM
1052 if (want_symtab)
1053 goto out_elf_end;
1054
a25e46c4
ACM
1055 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
1056 if (sec == NULL)
8ce998d6 1057 goto out_elf_end;
8ce998d6 1058 }
a2928c42 1059
70c3856b
EM
1060 opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
1061 if (opdsec)
1062 opddata = elf_rawdata(opdsec, NULL);
1063
a2928c42
ACM
1064 syms = elf_getdata(sec, NULL);
1065 if (syms == NULL)
1066 goto out_elf_end;
1067
1068 sec = elf_getscn(elf, shdr.sh_link);
1069 if (sec == NULL)
1070 goto out_elf_end;
1071
1072 symstrs = elf_getdata(sec, NULL);
1073 if (symstrs == NULL)
1074 goto out_elf_end;
1075
6cfcc53e
MG
1076 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
1077 if (sec_strndx == NULL)
1078 goto out_elf_end;
1079
1080 secstrs = elf_getdata(sec_strndx, NULL);
9b30a26b 1081 if (secstrs == NULL)
6cfcc53e
MG
1082 goto out_elf_end;
1083
a2928c42
ACM
1084 nr_syms = shdr.sh_size / shdr.sh_entsize;
1085
e9fbc9dc 1086 memset(&sym, 0, sizeof(sym));
a1645ce1 1087 if (self->kernel == DSO_TYPE_USER) {
d20ff6bd 1088 self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
30d7a77d
ACM
1089 elf_section_by_name(elf, &ehdr, &shdr,
1090 ".gnu.prelink_undo",
1091 NULL) != NULL);
d20ff6bd
MG
1092 } else self->adjust_symbols = 0;
1093
83a0944f 1094 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
a2928c42 1095 struct symbol *f;
56b03f3c 1096 const char *elf_name = elf_sym__name(&sym, symstrs);
2e538c4a 1097 char *demangled = NULL;
6cfcc53e
MG
1098 int is_label = elf_sym__is_label(&sym);
1099 const char *section_name;
a2928c42 1100
9de89fe7
ACM
1101 if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
1102 strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
1103 kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
56b03f3c 1104
d45868d3 1105 if (!is_label && !elf_sym__is_a(&sym, map->type))
a2928c42
ACM
1106 continue;
1107
696b97a5
DM
1108 /* Reject ARM ELF "mapping symbols": these aren't unique and
1109 * don't identify functions, so will confuse the profile
1110 * output: */
1111 if (ehdr.e_machine == EM_ARM) {
1112 if (!strcmp(elf_name, "$a") ||
1113 !strcmp(elf_name, "$d") ||
1114 !strcmp(elf_name, "$t"))
1115 continue;
1116 }
1117
70c3856b
EM
1118 if (opdsec && sym.st_shndx == opdidx) {
1119 u32 offset = sym.st_value - opdshdr.sh_addr;
1120 u64 *opd = opddata->d_buf + offset;
1121 sym.st_value = *opd;
1122 sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
1123 }
1124
a2928c42
ACM
1125 sec = elf_getscn(elf, sym.st_shndx);
1126 if (!sec)
1127 goto out_elf_end;
1128
1129 gelf_getshdr(sec, &shdr);
6cfcc53e 1130
d45868d3 1131 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
6cfcc53e
MG
1132 continue;
1133
1134 section_name = elf_sec__name(&shdr, secstrs);
0b73da3f 1135
a1645ce1 1136 if (self->kernel != DSO_TYPE_USER || kmodule) {
2e538c4a
ACM
1137 char dso_name[PATH_MAX];
1138
1139 if (strcmp(section_name,
b63be8d7
ACM
1140 (curr_dso->short_name +
1141 self->short_name_len)) == 0)
2e538c4a
ACM
1142 goto new_symbol;
1143
1144 if (strcmp(section_name, ".text") == 0) {
1145 curr_map = map;
1146 curr_dso = self;
1147 goto new_symbol;
1148 }
1149
1150 snprintf(dso_name, sizeof(dso_name),
1151 "%s%s", self->short_name, section_name);
1152
9de89fe7 1153 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
2e538c4a
ACM
1154 if (curr_map == NULL) {
1155 u64 start = sym.st_value;
1156
1157 if (kmodule)
1158 start += map->start + shdr.sh_offset;
1159
00a192b3 1160 curr_dso = dso__new(dso_name);
2e538c4a
ACM
1161 if (curr_dso == NULL)
1162 goto out_elf_end;
a1645ce1 1163 curr_dso->kernel = self->kernel;
3610583c 1164 curr_map = map__new2(start, curr_dso,
6275ce2d 1165 map->type);
2e538c4a
ACM
1166 if (curr_map == NULL) {
1167 dso__delete(curr_dso);
1168 goto out_elf_end;
1169 }
ed52ce2e
ACM
1170 curr_map->map_ip = identity__map_ip;
1171 curr_map->unmap_ip = identity__map_ip;
b0a9ab62 1172 curr_dso->origin = self->origin;
9de89fe7 1173 map_groups__insert(kmap->kmaps, curr_map);
a1645ce1 1174 dsos__add(&self->node, curr_dso);
6275ce2d 1175 dso__set_loaded(curr_dso, map->type);
2e538c4a
ACM
1176 } else
1177 curr_dso = curr_map->dso;
1178
1179 goto new_symbol;
af427bf5
ACM
1180 }
1181
2e538c4a 1182 if (curr_dso->adjust_symbols) {
29a9f66d
ACM
1183 pr_debug4("%s: adjusting symbol: st_value: %#Lx "
1184 "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
1185 (u64)sym.st_value, (u64)shdr.sh_addr,
1186 (u64)shdr.sh_offset);
f5812a7a 1187 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
af427bf5 1188 }
28ac909b
ACM
1189 /*
1190 * We need to figure out if the object was created from C++ sources
1191 * DWARF DW_compile_unit has this, but we don't always have access
1192 * to it...
1193 */
83a0944f 1194 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
28ac909b 1195 if (demangled != NULL)
83a0944f 1196 elf_name = demangled;
2e538c4a 1197new_symbol:
c408fedf
ACM
1198 f = symbol__new(sym.st_value, sym.st_size,
1199 GELF_ST_BIND(sym.st_info), elf_name);
28ac909b 1200 free(demangled);
a2928c42
ACM
1201 if (!f)
1202 goto out_elf_end;
1203
2e538c4a 1204 if (filter && filter(curr_map, f))
00a192b3 1205 symbol__delete(f);
69ee69f6 1206 else {
6a4694a4 1207 symbols__insert(&curr_dso->symbols[curr_map->type], f);
69ee69f6
ACM
1208 nr++;
1209 }
a2928c42
ACM
1210 }
1211
2e538c4a
ACM
1212 /*
1213 * For misannotated, zeroed, ASM function sizes.
1214 */
6275ce2d 1215 if (nr > 0) {
6a4694a4 1216 symbols__fixup_end(&self->symbols[map->type]);
6275ce2d
ACM
1217 if (kmap) {
1218 /*
1219 * We need to fixup this here too because we create new
1220 * maps here, for things like vsyscall sections.
1221 */
1222 __map_groups__fixup_end(kmap->kmaps, map->type);
1223 }
1224 }
a2928c42
ACM
1225 err = nr;
1226out_elf_end:
1227 elf_end(elf);
1228out_close:
1229 return err;
1230}
1231
78075caa
ACM
1232static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1233{
1234 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1235}
1236
a1645ce1 1237bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
57f395a7 1238{
e30a3d12 1239 bool have_build_id = false;
57f395a7
FW
1240 struct dso *pos;
1241
6122e4e4
ACM
1242 list_for_each_entry(pos, head, node) {
1243 if (with_hits && !pos->hit)
1244 continue;
f6e1467d
ACM
1245 if (pos->has_build_id) {
1246 have_build_id = true;
1247 continue;
1248 }
e30a3d12
ACM
1249 if (filename__read_build_id(pos->long_name, pos->build_id,
1250 sizeof(pos->build_id)) > 0) {
1251 have_build_id = true;
1252 pos->has_build_id = true;
1253 }
6122e4e4 1254 }
57f395a7 1255
e30a3d12 1256 return have_build_id;
57f395a7
FW
1257}
1258
fd7a346e
ACM
1259/*
1260 * Align offset to 4 bytes as needed for note name and descriptor data.
1261 */
1262#define NOTE_ALIGN(n) (((n) + 3) & -4U)
1263
21916c38 1264static int elf_read_build_id(Elf *elf, void *bf, size_t size)
4d1e00a8 1265{
21916c38 1266 int err = -1;
4d1e00a8
ACM
1267 GElf_Ehdr ehdr;
1268 GElf_Shdr shdr;
fd7a346e 1269 Elf_Data *data;
4d1e00a8 1270 Elf_Scn *sec;
e57cfcda 1271 Elf_Kind ek;
fd7a346e 1272 void *ptr;
4d1e00a8 1273
2643ce11
ACM
1274 if (size < BUILD_ID_SIZE)
1275 goto out;
1276
e57cfcda
PE
1277 ek = elf_kind(elf);
1278 if (ek != ELF_K_ELF)
21916c38 1279 goto out;
e57cfcda 1280
4d1e00a8 1281 if (gelf_getehdr(elf, &ehdr) == NULL) {
6beba7ad 1282 pr_err("%s: cannot get elf header.\n", __func__);
21916c38 1283 goto out;
4d1e00a8
ACM
1284 }
1285
2643ce11
ACM
1286 sec = elf_section_by_name(elf, &ehdr, &shdr,
1287 ".note.gnu.build-id", NULL);
fd7a346e
ACM
1288 if (sec == NULL) {
1289 sec = elf_section_by_name(elf, &ehdr, &shdr,
1290 ".notes", NULL);
1291 if (sec == NULL)
21916c38 1292 goto out;
fd7a346e 1293 }
4d1e00a8 1294
fd7a346e
ACM
1295 data = elf_getdata(sec, NULL);
1296 if (data == NULL)
21916c38 1297 goto out;
fd7a346e
ACM
1298
1299 ptr = data->d_buf;
1300 while (ptr < (data->d_buf + data->d_size)) {
1301 GElf_Nhdr *nhdr = ptr;
1302 int namesz = NOTE_ALIGN(nhdr->n_namesz),
1303 descsz = NOTE_ALIGN(nhdr->n_descsz);
1304 const char *name;
1305
1306 ptr += sizeof(*nhdr);
1307 name = ptr;
1308 ptr += namesz;
1309 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1310 nhdr->n_namesz == sizeof("GNU")) {
1311 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1312 memcpy(bf, ptr, BUILD_ID_SIZE);
1313 err = BUILD_ID_SIZE;
1314 break;
1315 }
1316 }
1317 ptr += descsz;
1318 }
21916c38
DM
1319
1320out:
1321 return err;
1322}
1323
1324int filename__read_build_id(const char *filename, void *bf, size_t size)
1325{
1326 int fd, err = -1;
1327 Elf *elf;
1328
1329 if (size < BUILD_ID_SIZE)
1330 goto out;
1331
1332 fd = open(filename, O_RDONLY);
1333 if (fd < 0)
1334 goto out;
1335
1336 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1337 if (elf == NULL) {
1338 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1339 goto out_close;
1340 }
1341
1342 err = elf_read_build_id(elf, bf, size);
1343
2643ce11
ACM
1344 elf_end(elf);
1345out_close:
1346 close(fd);
1347out:
1348 return err;
1349}
1350
f1617b40
ACM
1351int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1352{
1353 int fd, err = -1;
1354
1355 if (size < BUILD_ID_SIZE)
1356 goto out;
1357
1358 fd = open(filename, O_RDONLY);
1359 if (fd < 0)
1360 goto out;
1361
1362 while (1) {
1363 char bf[BUFSIZ];
1364 GElf_Nhdr nhdr;
1365 int namesz, descsz;
1366
1367 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1368 break;
1369
fd7a346e
ACM
1370 namesz = NOTE_ALIGN(nhdr.n_namesz);
1371 descsz = NOTE_ALIGN(nhdr.n_descsz);
f1617b40
ACM
1372 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1373 nhdr.n_namesz == sizeof("GNU")) {
1374 if (read(fd, bf, namesz) != namesz)
1375 break;
1376 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1377 if (read(fd, build_id,
1378 BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1379 err = 0;
1380 break;
1381 }
1382 } else if (read(fd, bf, descsz) != descsz)
1383 break;
1384 } else {
1385 int n = namesz + descsz;
1386 if (read(fd, bf, n) != n)
1387 break;
1388 }
1389 }
1390 close(fd);
1391out:
1392 return err;
1393}
1394
94cb9e38
ACM
1395char dso__symtab_origin(const struct dso *self)
1396{
1397 static const char origin[] = {
1398 [DSO__ORIG_KERNEL] = 'k',
1399 [DSO__ORIG_JAVA_JIT] = 'j',
4cf40131 1400 [DSO__ORIG_BUILD_ID_CACHE] = 'B',
94cb9e38
ACM
1401 [DSO__ORIG_FEDORA] = 'f',
1402 [DSO__ORIG_UBUNTU] = 'u',
1403 [DSO__ORIG_BUILDID] = 'b',
1404 [DSO__ORIG_DSO] = 'd',
439d473b 1405 [DSO__ORIG_KMODULE] = 'K',
a1645ce1
ZY
1406 [DSO__ORIG_GUEST_KERNEL] = 'g',
1407 [DSO__ORIG_GUEST_KMODULE] = 'G',
94cb9e38
ACM
1408 };
1409
1410 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
1411 return '!';
1412 return origin[self->origin];
1413}
1414
9de89fe7 1415int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
a2928c42 1416{
4d1e00a8 1417 int size = PATH_MAX;
c338aee8 1418 char *name;
a2928c42
ACM
1419 int ret = -1;
1420 int fd;
23346f21 1421 struct machine *machine;
a1645ce1 1422 const char *root_dir;
6da80ce8 1423 int want_symtab;
a2928c42 1424
3610583c 1425 dso__set_loaded(self, map->type);
66bd8424 1426
a1645ce1 1427 if (self->kernel == DSO_TYPE_KERNEL)
9de89fe7 1428 return dso__load_kernel_sym(self, map, filter);
a1645ce1
ZY
1429 else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
1430 return dso__load_guest_kernel_sym(self, map, filter);
1431
23346f21
ACM
1432 if (map->groups && map->groups->machine)
1433 machine = map->groups->machine;
a1645ce1 1434 else
23346f21 1435 machine = NULL;
c338aee8
ACM
1436
1437 name = malloc(size);
a2928c42
ACM
1438 if (!name)
1439 return -1;
1440
30d7a77d 1441 self->adjust_symbols = 0;
f5812a7a 1442
94cb9e38 1443 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
6beba7ad 1444 ret = dso__load_perf_map(self, map, filter);
94cb9e38
ACM
1445 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
1446 DSO__ORIG_NOT_FOUND;
1447 return ret;
1448 }
1449
6da80ce8
DM
1450 /* Iterate over candidate debug images.
1451 * On the first pass, only load images if they have a full symtab.
1452 * Failing that, do a second pass where we accept .dynsym also
1453 */
1454 for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1;
1455 self->origin != DSO__ORIG_NOT_FOUND;
1456 self->origin++) {
94cb9e38 1457 switch (self->origin) {
6da80ce8 1458 case DSO__ORIG_BUILD_ID_CACHE:
ec5761ea
DA
1459 /* skip the locally configured cache if a symfs is given */
1460 if (symbol_conf.symfs[0] ||
1461 (dso__build_id_filename(self, name, size) == NULL)) {
6da80ce8 1462 continue;
ec5761ea 1463 }
6da80ce8 1464 break;
94cb9e38 1465 case DSO__ORIG_FEDORA:
ec5761ea
DA
1466 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1467 symbol_conf.symfs, self->long_name);
a2928c42 1468 break;
94cb9e38 1469 case DSO__ORIG_UBUNTU:
ec5761ea
DA
1470 snprintf(name, size, "%s/usr/lib/debug%s",
1471 symbol_conf.symfs, self->long_name);
a2928c42 1472 break;
6da80ce8
DM
1473 case DSO__ORIG_BUILDID: {
1474 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1475
1476 if (!self->has_build_id)
1477 continue;
1478
1479 build_id__sprintf(self->build_id,
1480 sizeof(self->build_id),
1481 build_id_hex);
1482 snprintf(name, size,
ec5761ea
DA
1483 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
1484 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
4d1e00a8 1485 }
6da80ce8 1486 break;
94cb9e38 1487 case DSO__ORIG_DSO:
ec5761ea
DA
1488 snprintf(name, size, "%s%s",
1489 symbol_conf.symfs, self->long_name);
a2928c42 1490 break;
a1645ce1 1491 case DSO__ORIG_GUEST_KMODULE:
23346f21
ACM
1492 if (map->groups && map->groups->machine)
1493 root_dir = map->groups->machine->root_dir;
a1645ce1
ZY
1494 else
1495 root_dir = "";
ec5761ea
DA
1496 snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1497 root_dir, self->long_name);
1498 break;
1499
1500 case DSO__ORIG_KMODULE:
1501 snprintf(name, size, "%s%s", symbol_conf.symfs,
1502 self->long_name);
a1645ce1 1503 break;
a2928c42
ACM
1504
1505 default:
6da80ce8
DM
1506 /*
1507 * If we wanted a full symtab but no image had one,
1508 * relax our requirements and repeat the search.
1509 */
1510 if (want_symtab) {
1511 want_symtab = 0;
1512 self->origin = DSO__ORIG_BUILD_ID_CACHE;
1513 } else
1514 continue;
a2928c42 1515 }
6da80ce8
DM
1516
1517 /* Name is now the name of the next image to try */
a2928c42 1518 fd = open(name, O_RDONLY);
6da80ce8
DM
1519 if (fd < 0)
1520 continue;
a2928c42 1521
6da80ce8
DM
1522 ret = dso__load_sym(self, map, name, fd, filter, 0,
1523 want_symtab);
1524 close(fd);
a2928c42 1525
6da80ce8
DM
1526 /*
1527 * Some people seem to have debuginfo files _WITHOUT_ debug
1528 * info!?!?
1529 */
1530 if (!ret)
1531 continue;
a2928c42 1532
6da80ce8
DM
1533 if (ret > 0) {
1534 int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1535 if (nr_plt > 0)
1536 ret += nr_plt;
1537 break;
1538 }
a25e46c4 1539 }
6da80ce8 1540
a2928c42 1541 free(name);
1340e6bb
ACM
1542 if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
1543 return 0;
a2928c42
ACM
1544 return ret;
1545}
1546
79406cd7
ACM
1547struct map *map_groups__find_by_name(struct map_groups *self,
1548 enum map_type type, const char *name)
439d473b
ACM
1549{
1550 struct rb_node *nd;
1551
79406cd7 1552 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
439d473b
ACM
1553 struct map *map = rb_entry(nd, struct map, rb_node);
1554
b7cece76 1555 if (map->dso && strcmp(map->dso->short_name, name) == 0)
439d473b
ACM
1556 return map;
1557 }
1558
1559 return NULL;
1560}
1561
a1645ce1
ZY
1562static int dso__kernel_module_get_build_id(struct dso *self,
1563 const char *root_dir)
b7cece76
ACM
1564{
1565 char filename[PATH_MAX];
1566 /*
1567 * kernel module short names are of the form "[module]" and
1568 * we need just "module" here.
1569 */
1570 const char *name = self->short_name + 1;
1571
1572 snprintf(filename, sizeof(filename),
a1645ce1
ZY
1573 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1574 root_dir, (int)strlen(name) - 1, name);
b7cece76
ACM
1575
1576 if (sysfs__read_build_id(filename, self->build_id,
1577 sizeof(self->build_id)) == 0)
1578 self->has_build_id = true;
1579
1580 return 0;
1581}
1582
a1645ce1
ZY
1583static int map_groups__set_modules_path_dir(struct map_groups *self,
1584 const char *dir_name)
6cfcc53e 1585{
439d473b 1586 struct dirent *dent;
5aab621b 1587 DIR *dir = opendir(dir_name);
74534341 1588 int ret = 0;
6cfcc53e 1589
439d473b 1590 if (!dir) {
5aab621b 1591 pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
439d473b
ACM
1592 return -1;
1593 }
6cfcc53e 1594
439d473b
ACM
1595 while ((dent = readdir(dir)) != NULL) {
1596 char path[PATH_MAX];
a1645ce1
ZY
1597 struct stat st;
1598
1599 /*sshfs might return bad dent->d_type, so we have to stat*/
1600 sprintf(path, "%s/%s", dir_name, dent->d_name);
1601 if (stat(path, &st))
1602 continue;
439d473b 1603
a1645ce1 1604 if (S_ISDIR(st.st_mode)) {
439d473b
ACM
1605 if (!strcmp(dent->d_name, ".") ||
1606 !strcmp(dent->d_name, ".."))
1607 continue;
1608
1609 snprintf(path, sizeof(path), "%s/%s",
5aab621b 1610 dir_name, dent->d_name);
74534341
GJ
1611 ret = map_groups__set_modules_path_dir(self, path);
1612 if (ret < 0)
1613 goto out;
439d473b
ACM
1614 } else {
1615 char *dot = strrchr(dent->d_name, '.'),
1616 dso_name[PATH_MAX];
1617 struct map *map;
cfc10d3b 1618 char *long_name;
439d473b
ACM
1619
1620 if (dot == NULL || strcmp(dot, ".ko"))
1621 continue;
1622 snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1623 (int)(dot - dent->d_name), dent->d_name);
1624
a2a99e8e 1625 strxfrchar(dso_name, '-', '_');
9de89fe7 1626 map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
439d473b
ACM
1627 if (map == NULL)
1628 continue;
1629
1630 snprintf(path, sizeof(path), "%s/%s",
5aab621b 1631 dir_name, dent->d_name);
439d473b 1632
cfc10d3b 1633 long_name = strdup(path);
74534341
GJ
1634 if (long_name == NULL) {
1635 ret = -1;
1636 goto out;
1637 }
cfc10d3b 1638 dso__set_long_name(map->dso, long_name);
6e406257 1639 map->dso->lname_alloc = 1;
a1645ce1 1640 dso__kernel_module_get_build_id(map->dso, "");
439d473b 1641 }
439d473b 1642 }
6cfcc53e 1643
74534341 1644out:
439d473b 1645 closedir(dir);
74534341 1646 return ret;
439d473b 1647}
6cfcc53e 1648
a1645ce1 1649static char *get_kernel_version(const char *root_dir)
439d473b 1650{
a1645ce1
ZY
1651 char version[PATH_MAX];
1652 FILE *file;
1653 char *name, *tmp;
1654 const char *prefix = "Linux version ";
1655
1656 sprintf(version, "%s/proc/version", root_dir);
1657 file = fopen(version, "r");
1658 if (!file)
1659 return NULL;
1660
1661 version[0] = '\0';
1662 tmp = fgets(version, sizeof(version), file);
1663 fclose(file);
1664
1665 name = strstr(version, prefix);
1666 if (!name)
1667 return NULL;
1668 name += strlen(prefix);
1669 tmp = strchr(name, ' ');
1670 if (tmp)
1671 *tmp = '\0';
1672
1673 return strdup(name);
1674}
1675
d28c6223 1676static int machine__set_modules_path(struct machine *self)
a1645ce1
ZY
1677{
1678 char *version;
439d473b 1679 char modules_path[PATH_MAX];
6cfcc53e 1680
d28c6223 1681 version = get_kernel_version(self->root_dir);
a1645ce1 1682 if (!version)
439d473b 1683 return -1;
6cfcc53e 1684
a1645ce1 1685 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
d28c6223 1686 self->root_dir, version);
a1645ce1 1687 free(version);
6cfcc53e 1688
d28c6223 1689 return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
6cfcc53e
MG
1690}
1691
439d473b
ACM
1692/*
1693 * Constructor variant for modules (where we know from /proc/modules where
1694 * they are loaded) and for vmlinux, where only after we load all the
1695 * symbols we'll know where it starts and ends.
1696 */
3610583c 1697static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
6cfcc53e 1698{
5aab621b
ACM
1699 struct map *self = calloc(1, (sizeof(*self) +
1700 (dso->kernel ? sizeof(struct kmap) : 0)));
439d473b 1701 if (self != NULL) {
439d473b 1702 /*
afb7b4f0 1703 * ->end will be filled after we load all the symbols
439d473b 1704 */
3610583c 1705 map__init(self, type, start, 0, 0, dso);
439d473b 1706 }
afb7b4f0 1707
439d473b
ACM
1708 return self;
1709}
1710
d28c6223
ACM
1711struct map *machine__new_module(struct machine *self, u64 start,
1712 const char *filename)
b7cece76
ACM
1713{
1714 struct map *map;
d28c6223 1715 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
b7cece76
ACM
1716
1717 if (dso == NULL)
1718 return NULL;
1719
1720 map = map__new2(start, dso, MAP__FUNCTION);
1721 if (map == NULL)
1722 return NULL;
1723
d28c6223 1724 if (machine__is_host(self))
a1645ce1
ZY
1725 dso->origin = DSO__ORIG_KMODULE;
1726 else
1727 dso->origin = DSO__ORIG_GUEST_KMODULE;
d28c6223 1728 map_groups__insert(&self->kmaps, map);
b7cece76
ACM
1729 return map;
1730}
1731
d28c6223 1732static int machine__create_modules(struct machine *self)
439d473b
ACM
1733{
1734 char *line = NULL;
1735 size_t n;
a1645ce1 1736 FILE *file;
439d473b 1737 struct map *map;
a1645ce1
ZY
1738 const char *modules;
1739 char path[PATH_MAX];
1740
d28c6223 1741 if (machine__is_default_guest(self))
a1645ce1
ZY
1742 modules = symbol_conf.default_guest_modules;
1743 else {
d28c6223 1744 sprintf(path, "%s/proc/modules", self->root_dir);
a1645ce1
ZY
1745 modules = path;
1746 }
6cfcc53e 1747
a1645ce1 1748 file = fopen(modules, "r");
439d473b
ACM
1749 if (file == NULL)
1750 return -1;
6cfcc53e 1751
439d473b
ACM
1752 while (!feof(file)) {
1753 char name[PATH_MAX];
1754 u64 start;
439d473b
ACM
1755 char *sep;
1756 int line_len;
6cfcc53e 1757
439d473b
ACM
1758 line_len = getline(&line, &n, file);
1759 if (line_len < 0)
1760 break;
1761
1762 if (!line)
1763 goto out_failure;
1764
1765 line[--line_len] = '\0'; /* \n */
1766
1767 sep = strrchr(line, 'x');
1768 if (sep == NULL)
1769 continue;
1770
1771 hex2u64(sep + 1, &start);
1772
1773 sep = strchr(line, ' ');
1774 if (sep == NULL)
1775 continue;
1776
1777 *sep = '\0';
1778
1779 snprintf(name, sizeof(name), "[%s]", line);
d28c6223 1780 map = machine__new_module(self, start, name);
b7cece76 1781 if (map == NULL)
439d473b 1782 goto out_delete_line;
d28c6223 1783 dso__kernel_module_get_build_id(map->dso, self->root_dir);
6cfcc53e 1784 }
439d473b
ACM
1785
1786 free(line);
1787 fclose(file);
1788
d28c6223 1789 return machine__set_modules_path(self);
439d473b
ACM
1790
1791out_delete_line:
1792 free(line);
1793out_failure:
1794 return -1;
6cfcc53e
MG
1795}
1796
9958e1f0 1797static int dso__load_vmlinux(struct dso *self, struct map *map,
6beba7ad 1798 const char *vmlinux, symbol_filter_t filter)
a2928c42 1799{
fbd733b8 1800 int err = -1, fd;
ec5761ea 1801 char symfs_vmlinux[PATH_MAX];
a2928c42 1802
ec5761ea
DA
1803 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s",
1804 symbol_conf.symfs, vmlinux);
1805 fd = open(symfs_vmlinux, O_RDONLY);
a2928c42
ACM
1806 if (fd < 0)
1807 return -1;
1808
3610583c 1809 dso__set_loaded(self, map->type);
ec5761ea 1810 err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
a2928c42
ACM
1811 close(fd);
1812
3846df2e 1813 if (err > 0)
ec5761ea 1814 pr_debug("Using %s for symbols\n", symfs_vmlinux);
3846df2e 1815
a2928c42
ACM
1816 return err;
1817}
1818
a19afe46 1819int dso__load_vmlinux_path(struct dso *self, struct map *map,
9de89fe7 1820 symbol_filter_t filter)
a19afe46
ACM
1821{
1822 int i, err = 0;
5ad90e4e 1823 char *filename;
a19afe46
ACM
1824
1825 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
5ad90e4e
ACM
1826 vmlinux_path__nr_entries + 1);
1827
1828 filename = dso__build_id_filename(self, NULL, 0);
1829 if (filename != NULL) {
1830 err = dso__load_vmlinux(self, map, filename, filter);
1831 if (err > 0) {
1832 dso__set_long_name(self, filename);
1833 goto out;
1834 }
1835 free(filename);
1836 }
a19afe46
ACM
1837
1838 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
9de89fe7 1839 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
a19afe46 1840 if (err > 0) {
a19afe46
ACM
1841 dso__set_long_name(self, strdup(vmlinux_path[i]));
1842 break;
1843 }
1844 }
5ad90e4e 1845out:
a19afe46
ACM
1846 return err;
1847}
1848
c338aee8 1849static int dso__load_kernel_sym(struct dso *self, struct map *map,
9de89fe7 1850 symbol_filter_t filter)
a827c875 1851{
cc612d81 1852 int err;
9e201442
ACM
1853 const char *kallsyms_filename = NULL;
1854 char *kallsyms_allocated_filename = NULL;
dc8d6ab2 1855 /*
b226a5a7
DA
1856 * Step 1: if the user specified a kallsyms or vmlinux filename, use
1857 * it and only it, reporting errors to the user if it cannot be used.
dc8d6ab2
ACM
1858 *
1859 * For instance, try to analyse an ARM perf.data file _without_ a
1860 * build-id, or if the user specifies the wrong path to the right
1861 * vmlinux file, obviously we can't fallback to another vmlinux (a
1862 * x86_86 one, on the machine where analysis is being performed, say),
1863 * or worse, /proc/kallsyms.
1864 *
1865 * If the specified file _has_ a build-id and there is a build-id
1866 * section in the perf.data file, we will still do the expected
1867 * validation in dso__load_vmlinux and will bail out if they don't
1868 * match.
1869 */
b226a5a7
DA
1870 if (symbol_conf.kallsyms_name != NULL) {
1871 kallsyms_filename = symbol_conf.kallsyms_name;
1872 goto do_kallsyms;
1873 }
1874
dc8d6ab2 1875 if (symbol_conf.vmlinux_name != NULL) {
9de89fe7 1876 err = dso__load_vmlinux(self, map,
dc8d6ab2 1877 symbol_conf.vmlinux_name, filter);
e7dadc00
ACM
1878 if (err > 0) {
1879 dso__set_long_name(self,
1880 strdup(symbol_conf.vmlinux_name));
1881 goto out_fixup;
1882 }
1883 return err;
dc8d6ab2 1884 }
cc612d81
ACM
1885
1886 if (vmlinux_path != NULL) {
9de89fe7 1887 err = dso__load_vmlinux_path(self, map, filter);
a19afe46
ACM
1888 if (err > 0)
1889 goto out_fixup;
cc612d81
ACM
1890 }
1891
ec5761ea
DA
1892 /* do not try local files if a symfs was given */
1893 if (symbol_conf.symfs[0] != 0)
1894 return -1;
1895
b7cece76
ACM
1896 /*
1897 * Say the kernel DSO was created when processing the build-id header table,
1898 * we have a build-id, so check if it is the same as the running kernel,
1899 * using it if it is.
1900 */
1901 if (self->has_build_id) {
1902 u8 kallsyms_build_id[BUILD_ID_SIZE];
9e201442 1903 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
b7cece76
ACM
1904
1905 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
8d0591f6 1906 sizeof(kallsyms_build_id)) == 0) {
9e201442
ACM
1907 if (dso__build_id_equal(self, kallsyms_build_id)) {
1908 kallsyms_filename = "/proc/kallsyms";
8d0591f6 1909 goto do_kallsyms;
9e201442 1910 }
8d0591f6 1911 }
dc8d6ab2
ACM
1912 /*
1913 * Now look if we have it on the build-id cache in
1914 * $HOME/.debug/[kernel.kallsyms].
1915 */
9e201442
ACM
1916 build_id__sprintf(self->build_id, sizeof(self->build_id),
1917 sbuild_id);
1918
1919 if (asprintf(&kallsyms_allocated_filename,
1920 "%s/.debug/[kernel.kallsyms]/%s",
3846df2e
ACM
1921 getenv("HOME"), sbuild_id) == -1) {
1922 pr_err("Not enough memory for kallsyms file lookup\n");
dc8d6ab2 1923 return -1;
3846df2e 1924 }
dc8d6ab2 1925
19fc2ded
ACM
1926 kallsyms_filename = kallsyms_allocated_filename;
1927
dc8d6ab2 1928 if (access(kallsyms_filename, F_OK)) {
3846df2e
ACM
1929 pr_err("No kallsyms or vmlinux with build-id %s "
1930 "was found\n", sbuild_id);
9e201442 1931 free(kallsyms_allocated_filename);
dc8d6ab2 1932 return -1;
9e201442 1933 }
dc8d6ab2
ACM
1934 } else {
1935 /*
1936 * Last resort, if we don't have a build-id and couldn't find
1937 * any vmlinux file, try the running kernel kallsyms table.
1938 */
9e201442 1939 kallsyms_filename = "/proc/kallsyms";
9e201442 1940 }
439d473b 1941
cc612d81 1942do_kallsyms:
9de89fe7 1943 err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
3846df2e
ACM
1944 if (err > 0)
1945 pr_debug("Using %s for symbols\n", kallsyms_filename);
dc8d6ab2 1946 free(kallsyms_allocated_filename);
439d473b
ACM
1947
1948 if (err > 0) {
cc612d81 1949out_fixup:
e1c7c6a4 1950 if (kallsyms_filename != NULL)
dc8d6ab2 1951 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
6a4694a4
ACM
1952 map__fixup_start(map);
1953 map__fixup_end(map);
439d473b 1954 }
94cb9e38 1955
a827c875
ACM
1956 return err;
1957}
1958
a1645ce1
ZY
1959static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1960 symbol_filter_t filter)
1961{
1962 int err;
1963 const char *kallsyms_filename = NULL;
23346f21 1964 struct machine *machine;
a1645ce1
ZY
1965 char path[PATH_MAX];
1966
1967 if (!map->groups) {
1968 pr_debug("Guest kernel map hasn't the point to groups\n");
1969 return -1;
1970 }
23346f21 1971 machine = map->groups->machine;
a1645ce1 1972
23346f21 1973 if (machine__is_default_guest(machine)) {
a1645ce1
ZY
1974 /*
1975 * if the user specified a vmlinux filename, use it and only
1976 * it, reporting errors to the user if it cannot be used.
1977 * Or use file guest_kallsyms inputted by user on commandline
1978 */
1979 if (symbol_conf.default_guest_vmlinux_name != NULL) {
1980 err = dso__load_vmlinux(self, map,
1981 symbol_conf.default_guest_vmlinux_name, filter);
1982 goto out_try_fixup;
1983 }
1984
1985 kallsyms_filename = symbol_conf.default_guest_kallsyms;
1986 if (!kallsyms_filename)
1987 return -1;
1988 } else {
23346f21 1989 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
a1645ce1
ZY
1990 kallsyms_filename = path;
1991 }
1992
1993 err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1994 if (err > 0)
1995 pr_debug("Using %s for symbols\n", kallsyms_filename);
1996
1997out_try_fixup:
1998 if (err > 0) {
1999 if (kallsyms_filename != NULL) {
48ea8f54 2000 machine__mmap_name(machine, path, sizeof(path));
23346f21 2001 dso__set_long_name(self, strdup(path));
a1645ce1
ZY
2002 }
2003 map__fixup_start(map);
2004 map__fixup_end(map);
2005 }
2006
2007 return err;
2008}
cd84c2ac 2009
b0da954a 2010static void dsos__add(struct list_head *head, struct dso *dso)
cd84c2ac 2011{
b0da954a 2012 list_add_tail(&dso->node, head);
cd84c2ac
FW
2013}
2014
b0da954a 2015static struct dso *dsos__find(struct list_head *head, const char *name)
cd84c2ac
FW
2016{
2017 struct dso *pos;
2018
b0da954a 2019 list_for_each_entry(pos, head, node)
cf4e5b08 2020 if (strcmp(pos->long_name, name) == 0)
cd84c2ac
FW
2021 return pos;
2022 return NULL;
2023}
2024
a89e5abe 2025struct dso *__dsos__findnew(struct list_head *head, const char *name)
cd84c2ac 2026{
a89e5abe 2027 struct dso *dso = dsos__find(head, name);
cd84c2ac 2028
e4204992 2029 if (!dso) {
00a192b3 2030 dso = dso__new(name);
cfc10d3b 2031 if (dso != NULL) {
a89e5abe 2032 dsos__add(head, dso);
cfc10d3b
ACM
2033 dso__set_basename(dso);
2034 }
66bd8424 2035 }
cd84c2ac
FW
2036
2037 return dso;
cd84c2ac
FW
2038}
2039
1f626bc3 2040size_t __dsos__fprintf(struct list_head *head, FILE *fp)
cd84c2ac
FW
2041{
2042 struct dso *pos;
cbf69680 2043 size_t ret = 0;
cd84c2ac 2044
95011c60
ACM
2045 list_for_each_entry(pos, head, node) {
2046 int i;
2047 for (i = 0; i < MAP__NR_TYPES; ++i)
cbf69680 2048 ret += dso__fprintf(pos, i, fp);
95011c60 2049 }
cbf69680
ACM
2050
2051 return ret;
cd84c2ac
FW
2052}
2053
cbf69680 2054size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
b0da954a 2055{
a1645ce1 2056 struct rb_node *nd;
cbf69680 2057 size_t ret = 0;
a1645ce1 2058
cbf69680 2059 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
23346f21 2060 struct machine *pos = rb_entry(nd, struct machine, rb_node);
cbf69680
ACM
2061 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
2062 ret += __dsos__fprintf(&pos->user_dsos, fp);
a1645ce1 2063 }
cbf69680
ACM
2064
2065 return ret;
b0da954a
ACM
2066}
2067
88d3d9b7
ACM
2068static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
2069 bool with_hits)
9e03eb2d
ACM
2070{
2071 struct dso *pos;
2072 size_t ret = 0;
2073
b0da954a 2074 list_for_each_entry(pos, head, node) {
88d3d9b7
ACM
2075 if (with_hits && !pos->hit)
2076 continue;
9e03eb2d 2077 ret += dso__fprintf_buildid(pos, fp);
1124ba73 2078 ret += fprintf(fp, " %s\n", pos->long_name);
9e03eb2d
ACM
2079 }
2080 return ret;
2081}
2082
f869097e
ACM
2083size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits)
2084{
2085 return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) +
2086 __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits);
2087}
2088
cbf69680 2089size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
b0da954a 2090{
a1645ce1
ZY
2091 struct rb_node *nd;
2092 size_t ret = 0;
2093
cbf69680 2094 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
23346f21 2095 struct machine *pos = rb_entry(nd, struct machine, rb_node);
f869097e 2096 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
a1645ce1
ZY
2097 }
2098 return ret;
b0da954a
ACM
2099}
2100
fd1d908c
ACM
2101struct dso *dso__new_kernel(const char *name)
2102{
2103 struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
2104
2105 if (self != NULL) {
b63be8d7 2106 dso__set_short_name(self, "[kernel]");
a1645ce1
ZY
2107 self->kernel = DSO_TYPE_KERNEL;
2108 }
2109
2110 return self;
2111}
2112
23346f21 2113static struct dso *dso__new_guest_kernel(struct machine *machine,
a1645ce1
ZY
2114 const char *name)
2115{
48ea8f54
ACM
2116 char bf[PATH_MAX];
2117 struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
a1645ce1 2118
a1645ce1
ZY
2119 if (self != NULL) {
2120 dso__set_short_name(self, "[guest.kernel]");
2121 self->kernel = DSO_TYPE_GUEST_KERNEL;
fd1d908c
ACM
2122 }
2123
2124 return self;
2125}
2126
23346f21 2127void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
fd1d908c 2128{
a1645ce1
ZY
2129 char path[PATH_MAX];
2130
23346f21 2131 if (machine__is_default_guest(machine))
a1645ce1 2132 return;
23346f21 2133 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
a1645ce1 2134 if (sysfs__read_build_id(path, self->build_id,
fd1d908c
ACM
2135 sizeof(self->build_id)) == 0)
2136 self->has_build_id = true;
2137}
2138
5c0541d5 2139static struct dso *machine__create_kernel(struct machine *self)
cd84c2ac 2140{
a1645ce1
ZY
2141 const char *vmlinux_name = NULL;
2142 struct dso *kernel;
cd84c2ac 2143
5c0541d5 2144 if (machine__is_host(self)) {
a1645ce1
ZY
2145 vmlinux_name = symbol_conf.vmlinux_name;
2146 kernel = dso__new_kernel(vmlinux_name);
2147 } else {
5c0541d5 2148 if (machine__is_default_guest(self))
a1645ce1 2149 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
5c0541d5 2150 kernel = dso__new_guest_kernel(self, vmlinux_name);
8d92c02a 2151 }
cd84c2ac 2152
a1645ce1 2153 if (kernel != NULL) {
5c0541d5
ACM
2154 dso__read_running_kernel_build_id(kernel, self);
2155 dsos__add(&self->kernel_dsos, kernel);
a1645ce1 2156 }
f1dfa0b1 2157 return kernel;
f1dfa0b1
ACM
2158}
2159
d214afbd
ML
2160struct process_args {
2161 u64 start;
2162};
2163
2164static int symbol__in_kernel(void *arg, const char *name,
2165 char type __used, u64 start)
2166{
2167 struct process_args *args = arg;
2168
2169 if (strchr(name, '['))
2170 return 0;
2171
2172 args->start = start;
2173 return 1;
2174}
2175
2176/* Figure out the start address of kernel map from /proc/kallsyms */
2177static u64 machine__get_kernel_start_addr(struct machine *machine)
2178{
2179 const char *filename;
2180 char path[PATH_MAX];
2181 struct process_args args;
2182
2183 if (machine__is_host(machine)) {
2184 filename = "/proc/kallsyms";
2185 } else {
2186 if (machine__is_default_guest(machine))
2187 filename = (char *)symbol_conf.default_guest_kallsyms;
2188 else {
2189 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2190 filename = path;
2191 }
2192 }
2193
2194 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2195 return 0;
2196
2197 return args.start;
2198}
2199
d28c6223 2200int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
f1dfa0b1 2201{
de176489 2202 enum map_type type;
d214afbd 2203 u64 start = machine__get_kernel_start_addr(self);
f1dfa0b1 2204
de176489 2205 for (type = 0; type < MAP__NR_TYPES; ++type) {
9de89fe7
ACM
2206 struct kmap *kmap;
2207
d214afbd 2208 self->vmlinux_maps[type] = map__new2(start, kernel, type);
d28c6223 2209 if (self->vmlinux_maps[type] == NULL)
de176489 2210 return -1;
f1dfa0b1 2211
d28c6223
ACM
2212 self->vmlinux_maps[type]->map_ip =
2213 self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
9de89fe7 2214
d28c6223
ACM
2215 kmap = map__kmap(self->vmlinux_maps[type]);
2216 kmap->kmaps = &self->kmaps;
2217 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
f1dfa0b1
ACM
2218 }
2219
f1dfa0b1 2220 return 0;
2446042c
ACM
2221}
2222
076c6e45
ACM
2223void machine__destroy_kernel_maps(struct machine *self)
2224{
2225 enum map_type type;
2226
2227 for (type = 0; type < MAP__NR_TYPES; ++type) {
2228 struct kmap *kmap;
2229
2230 if (self->vmlinux_maps[type] == NULL)
2231 continue;
2232
2233 kmap = map__kmap(self->vmlinux_maps[type]);
2234 map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
2235 if (kmap->ref_reloc_sym) {
2236 /*
2237 * ref_reloc_sym is shared among all maps, so free just
2238 * on one of them.
2239 */
2240 if (type == MAP__FUNCTION) {
2241 free((char *)kmap->ref_reloc_sym->name);
2242 kmap->ref_reloc_sym->name = NULL;
2243 free(kmap->ref_reloc_sym);
2244 }
2245 kmap->ref_reloc_sym = NULL;
2246 }
2247
2248 map__delete(self->vmlinux_maps[type]);
2249 self->vmlinux_maps[type] = NULL;
2250 }
2251}
2252
5c0541d5
ACM
2253int machine__create_kernel_maps(struct machine *self)
2254{
2255 struct dso *kernel = machine__create_kernel(self);
2256
2257 if (kernel == NULL ||
2258 __machine__create_kernel_maps(self, kernel) < 0)
2259 return -1;
2260
2261 if (symbol_conf.use_modules && machine__create_modules(self) < 0)
2262 pr_debug("Problems creating module maps, continuing anyway...\n");
2263 /*
2264 * Now that we have all the maps created, just set the ->end of them:
2265 */
2266 map_groups__fixup_end(&self->kmaps);
2267 return 0;
2268}
2269
cc612d81
ACM
2270static void vmlinux_path__exit(void)
2271{
2272 while (--vmlinux_path__nr_entries >= 0) {
2273 free(vmlinux_path[vmlinux_path__nr_entries]);
2274 vmlinux_path[vmlinux_path__nr_entries] = NULL;
2275 }
2276
2277 free(vmlinux_path);
2278 vmlinux_path = NULL;
2279}
2280
2281static int vmlinux_path__init(void)
2282{
2283 struct utsname uts;
2284 char bf[PATH_MAX];
2285
cc612d81
ACM
2286 vmlinux_path = malloc(sizeof(char *) * 5);
2287 if (vmlinux_path == NULL)
2288 return -1;
2289
2290 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
2291 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2292 goto out_fail;
2293 ++vmlinux_path__nr_entries;
2294 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
2295 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2296 goto out_fail;
2297 ++vmlinux_path__nr_entries;
ec5761ea
DA
2298
2299 /* only try running kernel version if no symfs was given */
2300 if (symbol_conf.symfs[0] != 0)
2301 return 0;
2302
2303 if (uname(&uts) < 0)
2304 return -1;
2305
cc612d81
ACM
2306 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
2307 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2308 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2309 goto out_fail;
2310 ++vmlinux_path__nr_entries;
2311 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
2312 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2313 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2314 goto out_fail;
2315 ++vmlinux_path__nr_entries;
2316 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
2317 uts.release);
2318 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2319 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2320 goto out_fail;
2321 ++vmlinux_path__nr_entries;
2322
2323 return 0;
2324
2325out_fail:
2326 vmlinux_path__exit();
2327 return -1;
2328}
2329
5ad90e4e 2330size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp)
b0a9ab62
ACM
2331{
2332 int i;
2333 size_t printed = 0;
5ad90e4e
ACM
2334 struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso;
2335
2336 if (kdso->has_build_id) {
2337 char filename[PATH_MAX];
2338 if (dso__build_id_filename(kdso, filename, sizeof(filename)))
2339 printed += fprintf(fp, "[0] %s\n", filename);
2340 }
b0a9ab62
ACM
2341
2342 for (i = 0; i < vmlinux_path__nr_entries; ++i)
5ad90e4e
ACM
2343 printed += fprintf(fp, "[%d] %s\n",
2344 i + kdso->has_build_id, vmlinux_path[i]);
b0a9ab62
ACM
2345
2346 return printed;
2347}
2348
655000e7
ACM
2349static int setup_list(struct strlist **list, const char *list_str,
2350 const char *list_name)
2351{
2352 if (list_str == NULL)
2353 return 0;
2354
2355 *list = strlist__new(true, list_str);
2356 if (!*list) {
2357 pr_err("problems parsing %s list\n", list_name);
2358 return -1;
2359 }
2360 return 0;
2361}
2362
75be6cf4 2363int symbol__init(void)
2446042c 2364{
ec5761ea
DA
2365 const char *symfs;
2366
85e00b55
JZ
2367 if (symbol_conf.initialized)
2368 return 0;
2369
95011c60 2370 elf_version(EV_CURRENT);
75be6cf4
ACM
2371 if (symbol_conf.sort_by_name)
2372 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
2373 sizeof(struct symbol));
b32d133a 2374
75be6cf4 2375 if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
2446042c
ACM
2376 return -1;
2377
c410a338
ACM
2378 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2379 pr_err("'.' is the only non valid --field-separator argument\n");
2380 return -1;
2381 }
2382
655000e7
ACM
2383 if (setup_list(&symbol_conf.dso_list,
2384 symbol_conf.dso_list_str, "dso") < 0)
2385 return -1;
2386
2387 if (setup_list(&symbol_conf.comm_list,
2388 symbol_conf.comm_list_str, "comm") < 0)
2389 goto out_free_dso_list;
2390
2391 if (setup_list(&symbol_conf.sym_list,
2392 symbol_conf.sym_list_str, "symbol") < 0)
2393 goto out_free_comm_list;
2394
ec5761ea
DA
2395 /*
2396 * A path to symbols of "/" is identical to ""
2397 * reset here for simplicity.
2398 */
2399 symfs = realpath(symbol_conf.symfs, NULL);
2400 if (symfs == NULL)
2401 symfs = symbol_conf.symfs;
2402 if (strcmp(symfs, "/") == 0)
2403 symbol_conf.symfs = "";
2404 if (symfs != symbol_conf.symfs)
2405 free((void *)symfs);
2406
85e00b55 2407 symbol_conf.initialized = true;
4aa65636 2408 return 0;
655000e7
ACM
2409
2410out_free_dso_list:
2411 strlist__delete(symbol_conf.dso_list);
2412out_free_comm_list:
2413 strlist__delete(symbol_conf.comm_list);
2414 return -1;
4aa65636
ACM
2415}
2416
d65a458b
ACM
2417void symbol__exit(void)
2418{
85e00b55
JZ
2419 if (!symbol_conf.initialized)
2420 return;
d65a458b
ACM
2421 strlist__delete(symbol_conf.sym_list);
2422 strlist__delete(symbol_conf.dso_list);
2423 strlist__delete(symbol_conf.comm_list);
2424 vmlinux_path__exit();
2425 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
85e00b55 2426 symbol_conf.initialized = false;
d65a458b
ACM
2427}
2428
d28c6223 2429int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
4aa65636 2430{
d28c6223 2431 struct machine *machine = machines__findnew(self, pid);
9de89fe7 2432
23346f21 2433 if (machine == NULL)
a1645ce1 2434 return -1;
cc612d81 2435
5c0541d5 2436 return machine__create_kernel_maps(machine);
cd84c2ac 2437}
5aab621b
ACM
2438
2439static int hex(char ch)
2440{
2441 if ((ch >= '0') && (ch <= '9'))
2442 return ch - '0';
2443 if ((ch >= 'a') && (ch <= 'f'))
2444 return ch - 'a' + 10;
2445 if ((ch >= 'A') && (ch <= 'F'))
2446 return ch - 'A' + 10;
2447 return -1;
2448}
2449
2450/*
2451 * While we find nice hex chars, build a long_val.
2452 * Return number of chars processed.
2453 */
2454int hex2u64(const char *ptr, u64 *long_val)
2455{
2456 const char *p = ptr;
2457 *long_val = 0;
2458
2459 while (*p) {
2460 const int hex_val = hex(*p);
2461
2462 if (hex_val < 0)
2463 break;
2464
2465 *long_val = (*long_val << 4) | hex_val;
2466 p++;
2467 }
2468
2469 return p - ptr;
2470}
2471
2472char *strxfrchar(char *s, char from, char to)
2473{
2474 char *p = s;
2475
2476 while ((p = strchr(p, from)) != NULL)
2477 *p++ = to;
2478
2479 return s;
2480}
a1645ce1 2481
d28c6223 2482int machines__create_guest_kernel_maps(struct rb_root *self)
a1645ce1
ZY
2483{
2484 int ret = 0;
2485 struct dirent **namelist = NULL;
2486 int i, items = 0;
2487 char path[PATH_MAX];
2488 pid_t pid;
2489
2490 if (symbol_conf.default_guest_vmlinux_name ||
2491 symbol_conf.default_guest_modules ||
2492 symbol_conf.default_guest_kallsyms) {
d28c6223 2493 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
a1645ce1
ZY
2494 }
2495
2496 if (symbol_conf.guestmount) {
2497 items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
2498 if (items <= 0)
2499 return -ENOENT;
2500 for (i = 0; i < items; i++) {
2501 if (!isdigit(namelist[i]->d_name[0])) {
2502 /* Filter out . and .. */
2503 continue;
2504 }
2505 pid = atoi(namelist[i]->d_name);
2506 sprintf(path, "%s/%s/proc/kallsyms",
2507 symbol_conf.guestmount,
2508 namelist[i]->d_name);
2509 ret = access(path, R_OK);
2510 if (ret) {
2511 pr_debug("Can't access file %s\n", path);
2512 goto failure;
2513 }
d28c6223 2514 machines__create_kernel_maps(self, pid);
a1645ce1
ZY
2515 }
2516failure:
2517 free(namelist);
2518 }
2519
2520 return ret;
2521}
5c0541d5 2522
076c6e45
ACM
2523void machines__destroy_guest_kernel_maps(struct rb_root *self)
2524{
2525 struct rb_node *next = rb_first(self);
2526
2527 while (next) {
2528 struct machine *pos = rb_entry(next, struct machine, rb_node);
2529
2530 next = rb_next(&pos->rb_node);
2531 rb_erase(&pos->rb_node, self);
2532 machine__delete(pos);
2533 }
2534}
2535
5c0541d5
ACM
2536int machine__load_kallsyms(struct machine *self, const char *filename,
2537 enum map_type type, symbol_filter_t filter)
2538{
2539 struct map *map = self->vmlinux_maps[type];
2540 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2541
2542 if (ret > 0) {
2543 dso__set_loaded(map->dso, type);
2544 /*
2545 * Since /proc/kallsyms will have multiple sessions for the
2546 * kernel, with modules between them, fixup the end of all
2547 * sections.
2548 */
2549 __map_groups__fixup_end(&self->kmaps, type);
2550 }
2551
2552 return ret;
2553}
2554
2555int machine__load_vmlinux_path(struct machine *self, enum map_type type,
2556 symbol_filter_t filter)
2557{
2558 struct map *map = self->vmlinux_maps[type];
2559 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2560
2561 if (ret > 0) {
2562 dso__set_loaded(map->dso, type);
2563 map__reloc_vmlinux(map);
2564 }
2565
2566 return ret;
2567}
This page took 0.294648 seconds and 5 git commands to generate.