Home | History | Annotate | Download | only in util
      1 #include "symbol.h"
      2 #include "dso.h"
      3 #include "machine.h"
      4 #include "util.h"
      5 #include "debug.h"
      6 
      7 char dso__symtab_origin(const struct dso *dso)
      8 {
      9 	static const char origin[] = {
     10 		[DSO_BINARY_TYPE__KALLSYMS]		= 'k',
     11 		[DSO_BINARY_TYPE__VMLINUX]		= 'v',
     12 		[DSO_BINARY_TYPE__JAVA_JIT]		= 'j',
     13 		[DSO_BINARY_TYPE__DEBUGLINK]		= 'l',
     14 		[DSO_BINARY_TYPE__BUILD_ID_CACHE]	= 'B',
     15 		[DSO_BINARY_TYPE__FEDORA_DEBUGINFO]	= 'f',
     16 		[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO]	= 'u',
     17 		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]	= 'b',
     18 		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]	= 'd',
     19 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]	= 'K',
     20 		[DSO_BINARY_TYPE__GUEST_KALLSYMS]	= 'g',
     21 		[DSO_BINARY_TYPE__GUEST_KMODULE]	= 'G',
     22 		[DSO_BINARY_TYPE__GUEST_VMLINUX]	= 'V',
     23 	};
     24 
     25 	if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
     26 		return '!';
     27 	return origin[dso->symtab_type];
     28 }
     29 
     30 int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
     31 			  char *root_dir, char *file, size_t size)
     32 {
     33 	char build_id_hex[BUILD_ID_SIZE * 2 + 1];
     34 	int ret = 0;
     35 
     36 	switch (type) {
     37 	case DSO_BINARY_TYPE__DEBUGLINK: {
     38 		char *debuglink;
     39 
     40 		strncpy(file, dso->long_name, size);
     41 		debuglink = file + dso->long_name_len;
     42 		while (debuglink != file && *debuglink != '/')
     43 			debuglink--;
     44 		if (*debuglink == '/')
     45 			debuglink++;
     46 		filename__read_debuglink(dso->long_name, debuglink,
     47 					 size - (debuglink - file));
     48 		}
     49 		break;
     50 	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
     51 		/* skip the locally configured cache if a symfs is given */
     52 		if (symbol_conf.symfs[0] ||
     53 		    (dso__build_id_filename(dso, file, size) == NULL))
     54 			ret = -1;
     55 		break;
     56 
     57 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
     58 		snprintf(file, size, "%s/usr/lib/debug%s.debug",
     59 			 symbol_conf.symfs, dso->long_name);
     60 		break;
     61 
     62 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
     63 		snprintf(file, size, "%s/usr/lib/debug%s",
     64 			 symbol_conf.symfs, dso->long_name);
     65 		break;
     66 
     67 	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
     68 		if (!dso->has_build_id) {
     69 			ret = -1;
     70 			break;
     71 		}
     72 
     73 		build_id__sprintf(dso->build_id,
     74 				  sizeof(dso->build_id),
     75 				  build_id_hex);
     76 		snprintf(file, size,
     77 			 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
     78 			 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
     79 		break;
     80 
     81 	case DSO_BINARY_TYPE__VMLINUX:
     82 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
     83 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
     84 		snprintf(file, size, "%s%s",
     85 			 symbol_conf.symfs, dso->long_name);
     86 		break;
     87 
     88 	case DSO_BINARY_TYPE__GUEST_KMODULE:
     89 		snprintf(file, size, "%s%s%s", symbol_conf.symfs,
     90 			 root_dir, dso->long_name);
     91 		break;
     92 
     93 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
     94 		snprintf(file, size, "%s%s", symbol_conf.symfs,
     95 			 dso->long_name);
     96 		break;
     97 
     98 	case DSO_BINARY_TYPE__KCORE:
     99 	case DSO_BINARY_TYPE__GUEST_KCORE:
    100 		snprintf(file, size, "%s", dso->long_name);
    101 		break;
    102 
    103 	default:
    104 	case DSO_BINARY_TYPE__KALLSYMS:
    105 	case DSO_BINARY_TYPE__GUEST_KALLSYMS:
    106 	case DSO_BINARY_TYPE__JAVA_JIT:
    107 	case DSO_BINARY_TYPE__NOT_FOUND:
    108 		ret = -1;
    109 		break;
    110 	}
    111 
    112 	return ret;
    113 }
    114 
    115 static int open_dso(struct dso *dso, struct machine *machine)
    116 {
    117 	char *root_dir = (char *) "";
    118 	char *name;
    119 	int fd;
    120 
    121 	name = malloc(PATH_MAX);
    122 	if (!name)
    123 		return -ENOMEM;
    124 
    125 	if (machine)
    126 		root_dir = machine->root_dir;
    127 
    128 	if (dso__binary_type_file(dso, dso->data_type,
    129 				  root_dir, name, PATH_MAX)) {
    130 		free(name);
    131 		return -EINVAL;
    132 	}
    133 
    134 	fd = open(name, O_RDONLY);
    135 	free(name);
    136 	return fd;
    137 }
    138 
    139 int dso__data_fd(struct dso *dso, struct machine *machine)
    140 {
    141 	static enum dso_binary_type binary_type_data[] = {
    142 		DSO_BINARY_TYPE__BUILD_ID_CACHE,
    143 		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
    144 		DSO_BINARY_TYPE__NOT_FOUND,
    145 	};
    146 	int i = 0;
    147 
    148 	if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND)
    149 		return open_dso(dso, machine);
    150 
    151 	do {
    152 		int fd;
    153 
    154 		dso->data_type = binary_type_data[i++];
    155 
    156 		fd = open_dso(dso, machine);
    157 		if (fd >= 0)
    158 			return fd;
    159 
    160 	} while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND);
    161 
    162 	return -EINVAL;
    163 }
    164 
    165 static void
    166 dso_cache__free(struct rb_root *root)
    167 {
    168 	struct rb_node *next = rb_first(root);
    169 
    170 	while (next) {
    171 		struct dso_cache *cache;
    172 
    173 		cache = rb_entry(next, struct dso_cache, rb_node);
    174 		next = rb_next(&cache->rb_node);
    175 		rb_erase(&cache->rb_node, root);
    176 		free(cache);
    177 	}
    178 }
    179 
    180 static struct dso_cache*
    181 dso_cache__find(struct rb_root *root, u64 offset)
    182 {
    183 	struct rb_node **p = &root->rb_node;
    184 	struct rb_node *parent = NULL;
    185 	struct dso_cache *cache;
    186 
    187 	while (*p != NULL) {
    188 		u64 end;
    189 
    190 		parent = *p;
    191 		cache = rb_entry(parent, struct dso_cache, rb_node);
    192 		end = cache->offset + DSO__DATA_CACHE_SIZE;
    193 
    194 		if (offset < cache->offset)
    195 			p = &(*p)->rb_left;
    196 		else if (offset >= end)
    197 			p = &(*p)->rb_right;
    198 		else
    199 			return cache;
    200 	}
    201 	return NULL;
    202 }
    203 
    204 static void
    205 dso_cache__insert(struct rb_root *root, struct dso_cache *new)
    206 {
    207 	struct rb_node **p = &root->rb_node;
    208 	struct rb_node *parent = NULL;
    209 	struct dso_cache *cache;
    210 	u64 offset = new->offset;
    211 
    212 	while (*p != NULL) {
    213 		u64 end;
    214 
    215 		parent = *p;
    216 		cache = rb_entry(parent, struct dso_cache, rb_node);
    217 		end = cache->offset + DSO__DATA_CACHE_SIZE;
    218 
    219 		if (offset < cache->offset)
    220 			p = &(*p)->rb_left;
    221 		else if (offset >= end)
    222 			p = &(*p)->rb_right;
    223 	}
    224 
    225 	rb_link_node(&new->rb_node, parent, p);
    226 	rb_insert_color(&new->rb_node, root);
    227 }
    228 
    229 static ssize_t
    230 dso_cache__memcpy(struct dso_cache *cache, u64 offset,
    231 		  u8 *data, u64 size)
    232 {
    233 	u64 cache_offset = offset - cache->offset;
    234 	u64 cache_size   = min(cache->size - cache_offset, size);
    235 
    236 	memcpy(data, cache->data + cache_offset, cache_size);
    237 	return cache_size;
    238 }
    239 
    240 static ssize_t
    241 dso_cache__read(struct dso *dso, struct machine *machine,
    242 		 u64 offset, u8 *data, ssize_t size)
    243 {
    244 	struct dso_cache *cache;
    245 	ssize_t ret;
    246 	int fd;
    247 
    248 	fd = dso__data_fd(dso, machine);
    249 	if (fd < 0)
    250 		return -1;
    251 
    252 	do {
    253 		u64 cache_offset;
    254 
    255 		ret = -ENOMEM;
    256 
    257 		cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
    258 		if (!cache)
    259 			break;
    260 
    261 		cache_offset = offset & DSO__DATA_CACHE_MASK;
    262 		ret = -EINVAL;
    263 
    264 		if (-1 == lseek(fd, cache_offset, SEEK_SET))
    265 			break;
    266 
    267 		ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE);
    268 		if (ret <= 0)
    269 			break;
    270 
    271 		cache->offset = cache_offset;
    272 		cache->size   = ret;
    273 		dso_cache__insert(&dso->cache, cache);
    274 
    275 		ret = dso_cache__memcpy(cache, offset, data, size);
    276 
    277 	} while (0);
    278 
    279 	if (ret <= 0)
    280 		free(cache);
    281 
    282 	close(fd);
    283 	return ret;
    284 }
    285 
    286 static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
    287 			      u64 offset, u8 *data, ssize_t size)
    288 {
    289 	struct dso_cache *cache;
    290 
    291 	cache = dso_cache__find(&dso->cache, offset);
    292 	if (cache)
    293 		return dso_cache__memcpy(cache, offset, data, size);
    294 	else
    295 		return dso_cache__read(dso, machine, offset, data, size);
    296 }
    297 
    298 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
    299 			      u64 offset, u8 *data, ssize_t size)
    300 {
    301 	ssize_t r = 0;
    302 	u8 *p = data;
    303 
    304 	do {
    305 		ssize_t ret;
    306 
    307 		ret = dso_cache_read(dso, machine, offset, p, size);
    308 		if (ret < 0)
    309 			return ret;
    310 
    311 		/* Reached EOF, return what we have. */
    312 		if (!ret)
    313 			break;
    314 
    315 		BUG_ON(ret > size);
    316 
    317 		r      += ret;
    318 		p      += ret;
    319 		offset += ret;
    320 		size   -= ret;
    321 
    322 	} while (size);
    323 
    324 	return r;
    325 }
    326 
    327 ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
    328 			    struct machine *machine, u64 addr,
    329 			    u8 *data, ssize_t size)
    330 {
    331 	u64 offset = map->map_ip(map, addr);
    332 	return dso__data_read_offset(dso, machine, offset, data, size);
    333 }
    334 
    335 struct map *dso__new_map(const char *name)
    336 {
    337 	struct map *map = NULL;
    338 	struct dso *dso = dso__new(name);
    339 
    340 	if (dso)
    341 		map = map__new2(0, dso, MAP__FUNCTION);
    342 
    343 	return map;
    344 }
    345 
    346 struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
    347 		    const char *short_name, int dso_type)
    348 {
    349 	/*
    350 	 * The kernel dso could be created by build_id processing.
    351 	 */
    352 	struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
    353 
    354 	/*
    355 	 * We need to run this in all cases, since during the build_id
    356 	 * processing we had no idea this was the kernel dso.
    357 	 */
    358 	if (dso != NULL) {
    359 		dso__set_short_name(dso, short_name);
    360 		dso->kernel = dso_type;
    361 	}
    362 
    363 	return dso;
    364 }
    365 
    366 void dso__set_long_name(struct dso *dso, char *name)
    367 {
    368 	if (name == NULL)
    369 		return;
    370 	dso->long_name = name;
    371 	dso->long_name_len = strlen(name);
    372 }
    373 
    374 void dso__set_short_name(struct dso *dso, const char *name)
    375 {
    376 	if (name == NULL)
    377 		return;
    378 	dso->short_name = name;
    379 	dso->short_name_len = strlen(name);
    380 }
    381 
    382 static void dso__set_basename(struct dso *dso)
    383 {
    384 	char *lname, *base;
    385 
    386 	/*
    387 	 * basename may modify path buffer, so we must pass
    388 	 * a copy.
    389 	 */
    390 	lname = strdup(dso->long_name);
    391 	if (!lname)
    392 		return;
    393 
    394 	/*
    395 	 * basename may return pointer to internal
    396 	 * storage which is reused in subsequent calls
    397 	 * so copy the result
    398 	 */
    399 	base = strdup(basename(lname));
    400 
    401 	free(lname);
    402 
    403 	if (!base)
    404 		return;
    405 
    406 	/*
    407 	 * basename may modify content, so we must pass
    408 	 * a copy. Moreover basename may return pointer to internal
    409 	 * storage we may be reusing later on
    410 	 */
    411 	dso__set_short_name(dso, base);
    412 }
    413 
    414 int dso__name_len(const struct dso *dso)
    415 {
    416 	if (!dso)
    417 		return strlen("[unknown]");
    418 	if (verbose)
    419 		return dso->long_name_len;
    420 
    421 	return dso->short_name_len;
    422 }
    423 
    424 bool dso__loaded(const struct dso *dso, enum map_type type)
    425 {
    426 	return dso->loaded & (1 << type);
    427 }
    428 
    429 bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
    430 {
    431 	return dso->sorted_by_name & (1 << type);
    432 }
    433 
    434 void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
    435 {
    436 	dso->sorted_by_name |= (1 << type);
    437 }
    438 
    439 struct dso *dso__new(const char *name)
    440 {
    441 	struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
    442 
    443 	if (dso != NULL) {
    444 		int i;
    445 		strcpy(dso->name, name);
    446 		dso__set_long_name(dso, dso->name);
    447 		dso__set_short_name(dso, dso->name);
    448 		for (i = 0; i < MAP__NR_TYPES; ++i)
    449 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
    450 		dso->cache = RB_ROOT;
    451 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
    452 		dso->data_type   = DSO_BINARY_TYPE__NOT_FOUND;
    453 		dso->loaded = 0;
    454 		dso->rel = 0;
    455 		dso->sorted_by_name = 0;
    456 		dso->has_build_id = 0;
    457 		dso->kernel = DSO_TYPE_USER;
    458 		dso->needs_swap = DSO_SWAP__UNSET;
    459 		INIT_LIST_HEAD(&dso->node);
    460 	}
    461 
    462 	return dso;
    463 }
    464 
    465 void dso__delete(struct dso *dso)
    466 {
    467 	int i;
    468 	for (i = 0; i < MAP__NR_TYPES; ++i)
    469 		symbols__delete(&dso->symbols[i]);
    470 	if (dso->sname_alloc)
    471 		free((char *)dso->short_name);
    472 	if (dso->lname_alloc)
    473 		free(dso->long_name);
    474 	dso_cache__free(&dso->cache);
    475 	free(dso);
    476 }
    477 
    478 void dso__set_build_id(struct dso *dso, void *build_id)
    479 {
    480 	memcpy(dso->build_id, build_id, sizeof(dso->build_id));
    481 	dso->has_build_id = 1;
    482 }
    483 
    484 bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
    485 {
    486 	return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
    487 }
    488 
    489 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
    490 {
    491 	char path[PATH_MAX];
    492 
    493 	if (machine__is_default_guest(machine))
    494 		return;
    495 	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
    496 	if (sysfs__read_build_id(path, dso->build_id,
    497 				 sizeof(dso->build_id)) == 0)
    498 		dso->has_build_id = true;
    499 }
    500 
    501 int dso__kernel_module_get_build_id(struct dso *dso,
    502 				    const char *root_dir)
    503 {
    504 	char filename[PATH_MAX];
    505 	/*
    506 	 * kernel module short names are of the form "[module]" and
    507 	 * we need just "module" here.
    508 	 */
    509 	const char *name = dso->short_name + 1;
    510 
    511 	snprintf(filename, sizeof(filename),
    512 		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
    513 		 root_dir, (int)strlen(name) - 1, name);
    514 
    515 	if (sysfs__read_build_id(filename, dso->build_id,
    516 				 sizeof(dso->build_id)) == 0)
    517 		dso->has_build_id = true;
    518 
    519 	return 0;
    520 }
    521 
    522 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
    523 {
    524 	bool have_build_id = false;
    525 	struct dso *pos;
    526 
    527 	list_for_each_entry(pos, head, node) {
    528 		if (with_hits && !pos->hit)
    529 			continue;
    530 		if (pos->has_build_id) {
    531 			have_build_id = true;
    532 			continue;
    533 		}
    534 		if (filename__read_build_id(pos->long_name, pos->build_id,
    535 					    sizeof(pos->build_id)) > 0) {
    536 			have_build_id	  = true;
    537 			pos->has_build_id = true;
    538 		}
    539 	}
    540 
    541 	return have_build_id;
    542 }
    543 
    544 void dsos__add(struct list_head *head, struct dso *dso)
    545 {
    546 	list_add_tail(&dso->node, head);
    547 }
    548 
    549 struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
    550 {
    551 	struct dso *pos;
    552 
    553 	if (cmp_short) {
    554 		list_for_each_entry(pos, head, node)
    555 			if (strcmp(pos->short_name, name) == 0)
    556 				return pos;
    557 		return NULL;
    558 	}
    559 	list_for_each_entry(pos, head, node)
    560 		if (strcmp(pos->long_name, name) == 0)
    561 			return pos;
    562 	return NULL;
    563 }
    564 
    565 struct dso *__dsos__findnew(struct list_head *head, const char *name)
    566 {
    567 	struct dso *dso = dsos__find(head, name, false);
    568 
    569 	if (!dso) {
    570 		dso = dso__new(name);
    571 		if (dso != NULL) {
    572 			dsos__add(head, dso);
    573 			dso__set_basename(dso);
    574 		}
    575 	}
    576 
    577 	return dso;
    578 }
    579 
    580 size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
    581 			       bool (skip)(struct dso *dso, int parm), int parm)
    582 {
    583 	struct dso *pos;
    584 	size_t ret = 0;
    585 
    586 	list_for_each_entry(pos, head, node) {
    587 		if (skip && skip(pos, parm))
    588 			continue;
    589 		ret += dso__fprintf_buildid(pos, fp);
    590 		ret += fprintf(fp, " %s\n", pos->long_name);
    591 	}
    592 	return ret;
    593 }
    594 
    595 size_t __dsos__fprintf(struct list_head *head, FILE *fp)
    596 {
    597 	struct dso *pos;
    598 	size_t ret = 0;
    599 
    600 	list_for_each_entry(pos, head, node) {
    601 		int i;
    602 		for (i = 0; i < MAP__NR_TYPES; ++i)
    603 			ret += dso__fprintf(pos, i, fp);
    604 	}
    605 
    606 	return ret;
    607 }
    608 
    609 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
    610 {
    611 	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
    612 
    613 	build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
    614 	return fprintf(fp, "%s", sbuild_id);
    615 }
    616 
    617 size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
    618 {
    619 	struct rb_node *nd;
    620 	size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
    621 
    622 	if (dso->short_name != dso->long_name)
    623 		ret += fprintf(fp, "%s, ", dso->long_name);
    624 	ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
    625 		       dso__loaded(dso, type) ? "" : "NOT ");
    626 	ret += dso__fprintf_buildid(dso, fp);
    627 	ret += fprintf(fp, ")\n");
    628 	for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
    629 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
    630 		ret += symbol__fprintf(pos, fp);
    631 	}
    632 
    633 	return ret;
    634 }
    635