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