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 	dso__set_short_name(dso, basename(dso->long_name));
    385 }
    386 
    387 int dso__name_len(const struct dso *dso)
    388 {
    389 	if (!dso)
    390 		return strlen("[unknown]");
    391 	if (verbose)
    392 		return dso->long_name_len;
    393 
    394 	return dso->short_name_len;
    395 }
    396 
    397 bool dso__loaded(const struct dso *dso, enum map_type type)
    398 {
    399 	return dso->loaded & (1 << type);
    400 }
    401 
    402 bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
    403 {
    404 	return dso->sorted_by_name & (1 << type);
    405 }
    406 
    407 void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
    408 {
    409 	dso->sorted_by_name |= (1 << type);
    410 }
    411 
    412 struct dso *dso__new(const char *name)
    413 {
    414 	struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
    415 
    416 	if (dso != NULL) {
    417 		int i;
    418 		strcpy(dso->name, name);
    419 		dso__set_long_name(dso, dso->name);
    420 		dso__set_short_name(dso, dso->name);
    421 		for (i = 0; i < MAP__NR_TYPES; ++i)
    422 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
    423 		dso->cache = RB_ROOT;
    424 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
    425 		dso->data_type   = DSO_BINARY_TYPE__NOT_FOUND;
    426 		dso->loaded = 0;
    427 		dso->rel = 0;
    428 		dso->sorted_by_name = 0;
    429 		dso->has_build_id = 0;
    430 		dso->kernel = DSO_TYPE_USER;
    431 		dso->needs_swap = DSO_SWAP__UNSET;
    432 		INIT_LIST_HEAD(&dso->node);
    433 	}
    434 
    435 	return dso;
    436 }
    437 
    438 void dso__delete(struct dso *dso)
    439 {
    440 	int i;
    441 	for (i = 0; i < MAP__NR_TYPES; ++i)
    442 		symbols__delete(&dso->symbols[i]);
    443 	if (dso->sname_alloc)
    444 		free((char *)dso->short_name);
    445 	if (dso->lname_alloc)
    446 		free(dso->long_name);
    447 	dso_cache__free(&dso->cache);
    448 	free(dso);
    449 }
    450 
    451 void dso__set_build_id(struct dso *dso, void *build_id)
    452 {
    453 	memcpy(dso->build_id, build_id, sizeof(dso->build_id));
    454 	dso->has_build_id = 1;
    455 }
    456 
    457 bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
    458 {
    459 	return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
    460 }
    461 
    462 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
    463 {
    464 	char path[PATH_MAX];
    465 
    466 	if (machine__is_default_guest(machine))
    467 		return;
    468 	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
    469 	if (sysfs__read_build_id(path, dso->build_id,
    470 				 sizeof(dso->build_id)) == 0)
    471 		dso->has_build_id = true;
    472 }
    473 
    474 int dso__kernel_module_get_build_id(struct dso *dso,
    475 				    const char *root_dir)
    476 {
    477 	char filename[PATH_MAX];
    478 	/*
    479 	 * kernel module short names are of the form "[module]" and
    480 	 * we need just "module" here.
    481 	 */
    482 	const char *name = dso->short_name + 1;
    483 
    484 	snprintf(filename, sizeof(filename),
    485 		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
    486 		 root_dir, (int)strlen(name) - 1, name);
    487 
    488 	if (sysfs__read_build_id(filename, dso->build_id,
    489 				 sizeof(dso->build_id)) == 0)
    490 		dso->has_build_id = true;
    491 
    492 	return 0;
    493 }
    494 
    495 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
    496 {
    497 	bool have_build_id = false;
    498 	struct dso *pos;
    499 
    500 	list_for_each_entry(pos, head, node) {
    501 		if (with_hits && !pos->hit)
    502 			continue;
    503 		if (pos->has_build_id) {
    504 			have_build_id = true;
    505 			continue;
    506 		}
    507 		if (filename__read_build_id(pos->long_name, pos->build_id,
    508 					    sizeof(pos->build_id)) > 0) {
    509 			have_build_id	  = true;
    510 			pos->has_build_id = true;
    511 		}
    512 	}
    513 
    514 	return have_build_id;
    515 }
    516 
    517 void dsos__add(struct list_head *head, struct dso *dso)
    518 {
    519 	list_add_tail(&dso->node, head);
    520 }
    521 
    522 struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
    523 {
    524 	struct dso *pos;
    525 
    526 	if (cmp_short) {
    527 		list_for_each_entry(pos, head, node)
    528 			if (strcmp(pos->short_name, name) == 0)
    529 				return pos;
    530 		return NULL;
    531 	}
    532 	list_for_each_entry(pos, head, node)
    533 		if (strcmp(pos->long_name, name) == 0)
    534 			return pos;
    535 	return NULL;
    536 }
    537 
    538 struct dso *__dsos__findnew(struct list_head *head, const char *name)
    539 {
    540 	struct dso *dso = dsos__find(head, name, false);
    541 
    542 	if (!dso) {
    543 		dso = dso__new(name);
    544 		if (dso != NULL) {
    545 			dsos__add(head, dso);
    546 			dso__set_basename(dso);
    547 		}
    548 	}
    549 
    550 	return dso;
    551 }
    552 
    553 size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
    554 			       bool (skip)(struct dso *dso, int parm), int parm)
    555 {
    556 	struct dso *pos;
    557 	size_t ret = 0;
    558 
    559 	list_for_each_entry(pos, head, node) {
    560 		if (skip && skip(pos, parm))
    561 			continue;
    562 		ret += dso__fprintf_buildid(pos, fp);
    563 		ret += fprintf(fp, " %s\n", pos->long_name);
    564 	}
    565 	return ret;
    566 }
    567 
    568 size_t __dsos__fprintf(struct list_head *head, FILE *fp)
    569 {
    570 	struct dso *pos;
    571 	size_t ret = 0;
    572 
    573 	list_for_each_entry(pos, head, node) {
    574 		int i;
    575 		for (i = 0; i < MAP__NR_TYPES; ++i)
    576 			ret += dso__fprintf(pos, i, fp);
    577 	}
    578 
    579 	return ret;
    580 }
    581 
    582 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
    583 {
    584 	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
    585 
    586 	build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
    587 	return fprintf(fp, "%s", sbuild_id);
    588 }
    589 
    590 size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
    591 {
    592 	struct rb_node *nd;
    593 	size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
    594 
    595 	if (dso->short_name != dso->long_name)
    596 		ret += fprintf(fp, "%s, ", dso->long_name);
    597 	ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
    598 		       dso__loaded(dso, type) ? "" : "NOT ");
    599 	ret += dso__fprintf_buildid(dso, fp);
    600 	ret += fprintf(fp, ")\n");
    601 	for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
    602 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
    603 		ret += symbol__fprintf(pos, fp);
    604 	}
    605 
    606 	return ret;
    607 }
    608