PageRenderTime 186ms CodeModel.GetById 16ms app.highlight 142ms RepoModel.GetById 2ms app.codeStats 1ms

/tools/perf/util/symbol.c

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