xref: /openbmc/linux/tools/perf/util/dso.c (revision a17922de)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <asm/bug.h>
3 #include <linux/kernel.h>
4 #include <sys/time.h>
5 #include <sys/resource.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include "compress.h"
12 #include "path.h"
13 #include "symbol.h"
14 #include "srcline.h"
15 #include "dso.h"
16 #include "machine.h"
17 #include "auxtrace.h"
18 #include "util.h"
19 #include "debug.h"
20 #include "string2.h"
21 #include "vdso.h"
22 
23 static const char * const debuglink_paths[] = {
24 	"%.0s%s",
25 	"%s/%s",
26 	"%s/.debug/%s",
27 	"/usr/lib/debug%s/%s"
28 };
29 
30 char dso__symtab_origin(const struct dso *dso)
31 {
32 	static const char origin[] = {
33 		[DSO_BINARY_TYPE__KALLSYMS]			= 'k',
34 		[DSO_BINARY_TYPE__VMLINUX]			= 'v',
35 		[DSO_BINARY_TYPE__JAVA_JIT]			= 'j',
36 		[DSO_BINARY_TYPE__DEBUGLINK]			= 'l',
37 		[DSO_BINARY_TYPE__BUILD_ID_CACHE]		= 'B',
38 		[DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO]	= 'D',
39 		[DSO_BINARY_TYPE__FEDORA_DEBUGINFO]		= 'f',
40 		[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO]		= 'u',
41 		[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]	= 'o',
42 		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
43 		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
44 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
45 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]	= 'm',
46 		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
47 		[DSO_BINARY_TYPE__GUEST_KMODULE]		= 'G',
48 		[DSO_BINARY_TYPE__GUEST_KMODULE_COMP]		= 'M',
49 		[DSO_BINARY_TYPE__GUEST_VMLINUX]		= 'V',
50 	};
51 
52 	if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
53 		return '!';
54 	return origin[dso->symtab_type];
55 }
56 
57 int dso__read_binary_type_filename(const struct dso *dso,
58 				   enum dso_binary_type type,
59 				   char *root_dir, char *filename, size_t size)
60 {
61 	char build_id_hex[SBUILD_ID_SIZE];
62 	int ret = 0;
63 	size_t len;
64 
65 	switch (type) {
66 	case DSO_BINARY_TYPE__DEBUGLINK:
67 	{
68 		const char *last_slash;
69 		char dso_dir[PATH_MAX];
70 		char symfile[PATH_MAX];
71 		unsigned int i;
72 
73 		len = __symbol__join_symfs(filename, size, dso->long_name);
74 		last_slash = filename + len;
75 		while (last_slash != filename && *last_slash != '/')
76 			last_slash--;
77 
78 		strncpy(dso_dir, filename, last_slash - filename);
79 		dso_dir[last_slash-filename] = '\0';
80 
81 		if (!is_regular_file(filename)) {
82 			ret = -1;
83 			break;
84 		}
85 
86 		ret = filename__read_debuglink(filename, symfile, PATH_MAX);
87 		if (ret)
88 			break;
89 
90 		/* Check predefined locations where debug file might reside */
91 		ret = -1;
92 		for (i = 0; i < ARRAY_SIZE(debuglink_paths); i++) {
93 			snprintf(filename, size,
94 					debuglink_paths[i], dso_dir, symfile);
95 			if (is_regular_file(filename)) {
96 				ret = 0;
97 				break;
98 			}
99 		}
100 
101 		break;
102 	}
103 	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
104 		if (dso__build_id_filename(dso, filename, size, false) == NULL)
105 			ret = -1;
106 		break;
107 
108 	case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
109 		if (dso__build_id_filename(dso, filename, size, true) == NULL)
110 			ret = -1;
111 		break;
112 
113 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
114 		len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
115 		snprintf(filename + len, size - len, "%s.debug", dso->long_name);
116 		break;
117 
118 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
119 		len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
120 		snprintf(filename + len, size - len, "%s", dso->long_name);
121 		break;
122 
123 	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
124 	{
125 		const char *last_slash;
126 		size_t dir_size;
127 
128 		last_slash = dso->long_name + dso->long_name_len;
129 		while (last_slash != dso->long_name && *last_slash != '/')
130 			last_slash--;
131 
132 		len = __symbol__join_symfs(filename, size, "");
133 		dir_size = last_slash - dso->long_name + 2;
134 		if (dir_size > (size - len)) {
135 			ret = -1;
136 			break;
137 		}
138 		len += scnprintf(filename + len, dir_size, "%s",  dso->long_name);
139 		len += scnprintf(filename + len , size - len, ".debug%s",
140 								last_slash);
141 		break;
142 	}
143 
144 	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
145 		if (!dso->has_build_id) {
146 			ret = -1;
147 			break;
148 		}
149 
150 		build_id__sprintf(dso->build_id,
151 				  sizeof(dso->build_id),
152 				  build_id_hex);
153 		len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/");
154 		snprintf(filename + len, size - len, "%.2s/%s.debug",
155 			 build_id_hex, build_id_hex + 2);
156 		break;
157 
158 	case DSO_BINARY_TYPE__VMLINUX:
159 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
160 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
161 		__symbol__join_symfs(filename, size, dso->long_name);
162 		break;
163 
164 	case DSO_BINARY_TYPE__GUEST_KMODULE:
165 	case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
166 		path__join3(filename, size, symbol_conf.symfs,
167 			    root_dir, dso->long_name);
168 		break;
169 
170 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
171 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
172 		__symbol__join_symfs(filename, size, dso->long_name);
173 		break;
174 
175 	case DSO_BINARY_TYPE__KCORE:
176 	case DSO_BINARY_TYPE__GUEST_KCORE:
177 		snprintf(filename, size, "%s", dso->long_name);
178 		break;
179 
180 	default:
181 	case DSO_BINARY_TYPE__KALLSYMS:
182 	case DSO_BINARY_TYPE__GUEST_KALLSYMS:
183 	case DSO_BINARY_TYPE__JAVA_JIT:
184 	case DSO_BINARY_TYPE__NOT_FOUND:
185 		ret = -1;
186 		break;
187 	}
188 
189 	return ret;
190 }
191 
192 static const struct {
193 	const char *fmt;
194 	int (*decompress)(const char *input, int output);
195 } compressions[] = {
196 #ifdef HAVE_ZLIB_SUPPORT
197 	{ "gz", gzip_decompress_to_file },
198 #endif
199 #ifdef HAVE_LZMA_SUPPORT
200 	{ "xz", lzma_decompress_to_file },
201 #endif
202 	{ NULL, NULL },
203 };
204 
205 bool is_supported_compression(const char *ext)
206 {
207 	unsigned i;
208 
209 	for (i = 0; compressions[i].fmt; i++) {
210 		if (!strcmp(ext, compressions[i].fmt))
211 			return true;
212 	}
213 	return false;
214 }
215 
216 bool is_kernel_module(const char *pathname, int cpumode)
217 {
218 	struct kmod_path m;
219 	int mode = cpumode & PERF_RECORD_MISC_CPUMODE_MASK;
220 
221 	WARN_ONCE(mode != cpumode,
222 		  "Internal error: passing unmasked cpumode (%x) to is_kernel_module",
223 		  cpumode);
224 
225 	switch (mode) {
226 	case PERF_RECORD_MISC_USER:
227 	case PERF_RECORD_MISC_HYPERVISOR:
228 	case PERF_RECORD_MISC_GUEST_USER:
229 		return false;
230 	/* Treat PERF_RECORD_MISC_CPUMODE_UNKNOWN as kernel */
231 	default:
232 		if (kmod_path__parse(&m, pathname)) {
233 			pr_err("Failed to check whether %s is a kernel module or not. Assume it is.",
234 					pathname);
235 			return true;
236 		}
237 	}
238 
239 	return m.kmod;
240 }
241 
242 bool decompress_to_file(const char *ext, const char *filename, int output_fd)
243 {
244 	unsigned i;
245 
246 	for (i = 0; compressions[i].fmt; i++) {
247 		if (!strcmp(ext, compressions[i].fmt))
248 			return !compressions[i].decompress(filename,
249 							   output_fd);
250 	}
251 	return false;
252 }
253 
254 bool dso__needs_decompress(struct dso *dso)
255 {
256 	return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
257 		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
258 }
259 
260 static int decompress_kmodule(struct dso *dso, const char *name, char *tmpbuf)
261 {
262 	int fd = -1;
263 	struct kmod_path m;
264 
265 	if (!dso__needs_decompress(dso))
266 		return -1;
267 
268 	if (kmod_path__parse_ext(&m, dso->long_name))
269 		return -1;
270 
271 	if (!m.comp)
272 		goto out;
273 
274 	fd = mkstemp(tmpbuf);
275 	if (fd < 0) {
276 		dso->load_errno = errno;
277 		goto out;
278 	}
279 
280 	if (!decompress_to_file(m.ext, name, fd)) {
281 		dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
282 		close(fd);
283 		fd = -1;
284 	}
285 
286 out:
287 	free(m.ext);
288 	return fd;
289 }
290 
291 int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
292 {
293 	char tmpbuf[] = KMOD_DECOMP_NAME;
294 	int fd;
295 
296 	fd = decompress_kmodule(dso, name, tmpbuf);
297 	unlink(tmpbuf);
298 	return fd;
299 }
300 
301 int dso__decompress_kmodule_path(struct dso *dso, const char *name,
302 				 char *pathname, size_t len)
303 {
304 	char tmpbuf[] = KMOD_DECOMP_NAME;
305 	int fd;
306 
307 	fd = decompress_kmodule(dso, name, tmpbuf);
308 	if (fd < 0) {
309 		unlink(tmpbuf);
310 		return -1;
311 	}
312 
313 	strncpy(pathname, tmpbuf, len);
314 	close(fd);
315 	return 0;
316 }
317 
318 /*
319  * Parses kernel module specified in @path and updates
320  * @m argument like:
321  *
322  *    @comp - true if @path contains supported compression suffix,
323  *            false otherwise
324  *    @kmod - true if @path contains '.ko' suffix in right position,
325  *            false otherwise
326  *    @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
327  *            of the kernel module without suffixes, otherwise strudup-ed
328  *            base name of @path
329  *    @ext  - if (@alloc_ext && @comp) is true, it contains strdup-ed string
330  *            the compression suffix
331  *
332  * Returns 0 if there's no strdup error, -ENOMEM otherwise.
333  */
334 int __kmod_path__parse(struct kmod_path *m, const char *path,
335 		       bool alloc_name, bool alloc_ext)
336 {
337 	const char *name = strrchr(path, '/');
338 	const char *ext  = strrchr(path, '.');
339 	bool is_simple_name = false;
340 
341 	memset(m, 0x0, sizeof(*m));
342 	name = name ? name + 1 : path;
343 
344 	/*
345 	 * '.' is also a valid character for module name. For example:
346 	 * [aaa.bbb] is a valid module name. '[' should have higher
347 	 * priority than '.ko' suffix.
348 	 *
349 	 * The kernel names are from machine__mmap_name. Such
350 	 * name should belong to kernel itself, not kernel module.
351 	 */
352 	if (name[0] == '[') {
353 		is_simple_name = true;
354 		if ((strncmp(name, "[kernel.kallsyms]", 17) == 0) ||
355 		    (strncmp(name, "[guest.kernel.kallsyms", 22) == 0) ||
356 		    (strncmp(name, "[vdso]", 6) == 0) ||
357 		    (strncmp(name, "[vdso32]", 8) == 0) ||
358 		    (strncmp(name, "[vdsox32]", 9) == 0) ||
359 		    (strncmp(name, "[vsyscall]", 10) == 0)) {
360 			m->kmod = false;
361 
362 		} else
363 			m->kmod = true;
364 	}
365 
366 	/* No extension, just return name. */
367 	if ((ext == NULL) || is_simple_name) {
368 		if (alloc_name) {
369 			m->name = strdup(name);
370 			return m->name ? 0 : -ENOMEM;
371 		}
372 		return 0;
373 	}
374 
375 	if (is_supported_compression(ext + 1)) {
376 		m->comp = true;
377 		ext -= 3;
378 	}
379 
380 	/* Check .ko extension only if there's enough name left. */
381 	if (ext > name)
382 		m->kmod = !strncmp(ext, ".ko", 3);
383 
384 	if (alloc_name) {
385 		if (m->kmod) {
386 			if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
387 				return -ENOMEM;
388 		} else {
389 			if (asprintf(&m->name, "%s", name) == -1)
390 				return -ENOMEM;
391 		}
392 
393 		strxfrchar(m->name, '-', '_');
394 	}
395 
396 	if (alloc_ext && m->comp) {
397 		m->ext = strdup(ext + 4);
398 		if (!m->ext) {
399 			free((void *) m->name);
400 			return -ENOMEM;
401 		}
402 	}
403 
404 	return 0;
405 }
406 
407 void dso__set_module_info(struct dso *dso, struct kmod_path *m,
408 			  struct machine *machine)
409 {
410 	if (machine__is_host(machine))
411 		dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
412 	else
413 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
414 
415 	/* _KMODULE_COMP should be next to _KMODULE */
416 	if (m->kmod && m->comp)
417 		dso->symtab_type++;
418 
419 	dso__set_short_name(dso, strdup(m->name), true);
420 }
421 
422 /*
423  * Global list of open DSOs and the counter.
424  */
425 static LIST_HEAD(dso__data_open);
426 static long dso__data_open_cnt;
427 static pthread_mutex_t dso__data_open_lock = PTHREAD_MUTEX_INITIALIZER;
428 
429 static void dso__list_add(struct dso *dso)
430 {
431 	list_add_tail(&dso->data.open_entry, &dso__data_open);
432 	dso__data_open_cnt++;
433 }
434 
435 static void dso__list_del(struct dso *dso)
436 {
437 	list_del(&dso->data.open_entry);
438 	WARN_ONCE(dso__data_open_cnt <= 0,
439 		  "DSO data fd counter out of bounds.");
440 	dso__data_open_cnt--;
441 }
442 
443 static void close_first_dso(void);
444 
445 static int do_open(char *name)
446 {
447 	int fd;
448 	char sbuf[STRERR_BUFSIZE];
449 
450 	do {
451 		fd = open(name, O_RDONLY|O_CLOEXEC);
452 		if (fd >= 0)
453 			return fd;
454 
455 		pr_debug("dso open failed: %s\n",
456 			 str_error_r(errno, sbuf, sizeof(sbuf)));
457 		if (!dso__data_open_cnt || errno != EMFILE)
458 			break;
459 
460 		close_first_dso();
461 	} while (1);
462 
463 	return -1;
464 }
465 
466 static int __open_dso(struct dso *dso, struct machine *machine)
467 {
468 	int fd = -EINVAL;
469 	char *root_dir = (char *)"";
470 	char *name = malloc(PATH_MAX);
471 
472 	if (!name)
473 		return -ENOMEM;
474 
475 	if (machine)
476 		root_dir = machine->root_dir;
477 
478 	if (dso__read_binary_type_filename(dso, dso->binary_type,
479 					    root_dir, name, PATH_MAX))
480 		goto out;
481 
482 	if (!is_regular_file(name))
483 		goto out;
484 
485 	if (dso__needs_decompress(dso)) {
486 		char newpath[KMOD_DECOMP_LEN];
487 		size_t len = sizeof(newpath);
488 
489 		if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
490 			fd = -dso->load_errno;
491 			goto out;
492 		}
493 
494 		strcpy(name, newpath);
495 	}
496 
497 	fd = do_open(name);
498 
499 	if (dso__needs_decompress(dso))
500 		unlink(name);
501 
502 out:
503 	free(name);
504 	return fd;
505 }
506 
507 static void check_data_close(void);
508 
509 /**
510  * dso_close - Open DSO data file
511  * @dso: dso object
512  *
513  * Open @dso's data file descriptor and updates
514  * list/count of open DSO objects.
515  */
516 static int open_dso(struct dso *dso, struct machine *machine)
517 {
518 	int fd;
519 	struct nscookie nsc;
520 
521 	if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
522 		nsinfo__mountns_enter(dso->nsinfo, &nsc);
523 	fd = __open_dso(dso, machine);
524 	if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
525 		nsinfo__mountns_exit(&nsc);
526 
527 	if (fd >= 0) {
528 		dso__list_add(dso);
529 		/*
530 		 * Check if we crossed the allowed number
531 		 * of opened DSOs and close one if needed.
532 		 */
533 		check_data_close();
534 	}
535 
536 	return fd;
537 }
538 
539 static void close_data_fd(struct dso *dso)
540 {
541 	if (dso->data.fd >= 0) {
542 		close(dso->data.fd);
543 		dso->data.fd = -1;
544 		dso->data.file_size = 0;
545 		dso__list_del(dso);
546 	}
547 }
548 
549 /**
550  * dso_close - Close DSO data file
551  * @dso: dso object
552  *
553  * Close @dso's data file descriptor and updates
554  * list/count of open DSO objects.
555  */
556 static void close_dso(struct dso *dso)
557 {
558 	close_data_fd(dso);
559 }
560 
561 static void close_first_dso(void)
562 {
563 	struct dso *dso;
564 
565 	dso = list_first_entry(&dso__data_open, struct dso, data.open_entry);
566 	close_dso(dso);
567 }
568 
569 static rlim_t get_fd_limit(void)
570 {
571 	struct rlimit l;
572 	rlim_t limit = 0;
573 
574 	/* Allow half of the current open fd limit. */
575 	if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
576 		if (l.rlim_cur == RLIM_INFINITY)
577 			limit = l.rlim_cur;
578 		else
579 			limit = l.rlim_cur / 2;
580 	} else {
581 		pr_err("failed to get fd limit\n");
582 		limit = 1;
583 	}
584 
585 	return limit;
586 }
587 
588 static rlim_t fd_limit;
589 
590 /*
591  * Used only by tests/dso-data.c to reset the environment
592  * for tests. I dont expect we should change this during
593  * standard runtime.
594  */
595 void reset_fd_limit(void)
596 {
597 	fd_limit = 0;
598 }
599 
600 static bool may_cache_fd(void)
601 {
602 	if (!fd_limit)
603 		fd_limit = get_fd_limit();
604 
605 	if (fd_limit == RLIM_INFINITY)
606 		return true;
607 
608 	return fd_limit > (rlim_t) dso__data_open_cnt;
609 }
610 
611 /*
612  * Check and close LRU dso if we crossed allowed limit
613  * for opened dso file descriptors. The limit is half
614  * of the RLIMIT_NOFILE files opened.
615 */
616 static void check_data_close(void)
617 {
618 	bool cache_fd = may_cache_fd();
619 
620 	if (!cache_fd)
621 		close_first_dso();
622 }
623 
624 /**
625  * dso__data_close - Close DSO data file
626  * @dso: dso object
627  *
628  * External interface to close @dso's data file descriptor.
629  */
630 void dso__data_close(struct dso *dso)
631 {
632 	pthread_mutex_lock(&dso__data_open_lock);
633 	close_dso(dso);
634 	pthread_mutex_unlock(&dso__data_open_lock);
635 }
636 
637 static void try_to_open_dso(struct dso *dso, struct machine *machine)
638 {
639 	enum dso_binary_type binary_type_data[] = {
640 		DSO_BINARY_TYPE__BUILD_ID_CACHE,
641 		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
642 		DSO_BINARY_TYPE__NOT_FOUND,
643 	};
644 	int i = 0;
645 
646 	if (dso->data.fd >= 0)
647 		return;
648 
649 	if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
650 		dso->data.fd = open_dso(dso, machine);
651 		goto out;
652 	}
653 
654 	do {
655 		dso->binary_type = binary_type_data[i++];
656 
657 		dso->data.fd = open_dso(dso, machine);
658 		if (dso->data.fd >= 0)
659 			goto out;
660 
661 	} while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
662 out:
663 	if (dso->data.fd >= 0)
664 		dso->data.status = DSO_DATA_STATUS_OK;
665 	else
666 		dso->data.status = DSO_DATA_STATUS_ERROR;
667 }
668 
669 /**
670  * dso__data_get_fd - Get dso's data file descriptor
671  * @dso: dso object
672  * @machine: machine object
673  *
674  * External interface to find dso's file, open it and
675  * returns file descriptor.  It should be paired with
676  * dso__data_put_fd() if it returns non-negative value.
677  */
678 int dso__data_get_fd(struct dso *dso, struct machine *machine)
679 {
680 	if (dso->data.status == DSO_DATA_STATUS_ERROR)
681 		return -1;
682 
683 	if (pthread_mutex_lock(&dso__data_open_lock) < 0)
684 		return -1;
685 
686 	try_to_open_dso(dso, machine);
687 
688 	if (dso->data.fd < 0)
689 		pthread_mutex_unlock(&dso__data_open_lock);
690 
691 	return dso->data.fd;
692 }
693 
694 void dso__data_put_fd(struct dso *dso __maybe_unused)
695 {
696 	pthread_mutex_unlock(&dso__data_open_lock);
697 }
698 
699 bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by)
700 {
701 	u32 flag = 1 << by;
702 
703 	if (dso->data.status_seen & flag)
704 		return true;
705 
706 	dso->data.status_seen |= flag;
707 
708 	return false;
709 }
710 
711 static void
712 dso_cache__free(struct dso *dso)
713 {
714 	struct rb_root *root = &dso->data.cache;
715 	struct rb_node *next = rb_first(root);
716 
717 	pthread_mutex_lock(&dso->lock);
718 	while (next) {
719 		struct dso_cache *cache;
720 
721 		cache = rb_entry(next, struct dso_cache, rb_node);
722 		next = rb_next(&cache->rb_node);
723 		rb_erase(&cache->rb_node, root);
724 		free(cache);
725 	}
726 	pthread_mutex_unlock(&dso->lock);
727 }
728 
729 static struct dso_cache *dso_cache__find(struct dso *dso, u64 offset)
730 {
731 	const struct rb_root *root = &dso->data.cache;
732 	struct rb_node * const *p = &root->rb_node;
733 	const struct rb_node *parent = NULL;
734 	struct dso_cache *cache;
735 
736 	while (*p != NULL) {
737 		u64 end;
738 
739 		parent = *p;
740 		cache = rb_entry(parent, struct dso_cache, rb_node);
741 		end = cache->offset + DSO__DATA_CACHE_SIZE;
742 
743 		if (offset < cache->offset)
744 			p = &(*p)->rb_left;
745 		else if (offset >= end)
746 			p = &(*p)->rb_right;
747 		else
748 			return cache;
749 	}
750 
751 	return NULL;
752 }
753 
754 static struct dso_cache *
755 dso_cache__insert(struct dso *dso, struct dso_cache *new)
756 {
757 	struct rb_root *root = &dso->data.cache;
758 	struct rb_node **p = &root->rb_node;
759 	struct rb_node *parent = NULL;
760 	struct dso_cache *cache;
761 	u64 offset = new->offset;
762 
763 	pthread_mutex_lock(&dso->lock);
764 	while (*p != NULL) {
765 		u64 end;
766 
767 		parent = *p;
768 		cache = rb_entry(parent, struct dso_cache, rb_node);
769 		end = cache->offset + DSO__DATA_CACHE_SIZE;
770 
771 		if (offset < cache->offset)
772 			p = &(*p)->rb_left;
773 		else if (offset >= end)
774 			p = &(*p)->rb_right;
775 		else
776 			goto out;
777 	}
778 
779 	rb_link_node(&new->rb_node, parent, p);
780 	rb_insert_color(&new->rb_node, root);
781 
782 	cache = NULL;
783 out:
784 	pthread_mutex_unlock(&dso->lock);
785 	return cache;
786 }
787 
788 static ssize_t
789 dso_cache__memcpy(struct dso_cache *cache, u64 offset,
790 		  u8 *data, u64 size)
791 {
792 	u64 cache_offset = offset - cache->offset;
793 	u64 cache_size   = min(cache->size - cache_offset, size);
794 
795 	memcpy(data, cache->data + cache_offset, cache_size);
796 	return cache_size;
797 }
798 
799 static ssize_t
800 dso_cache__read(struct dso *dso, struct machine *machine,
801 		u64 offset, u8 *data, ssize_t size)
802 {
803 	struct dso_cache *cache;
804 	struct dso_cache *old;
805 	ssize_t ret;
806 
807 	do {
808 		u64 cache_offset;
809 
810 		cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
811 		if (!cache)
812 			return -ENOMEM;
813 
814 		pthread_mutex_lock(&dso__data_open_lock);
815 
816 		/*
817 		 * dso->data.fd might be closed if other thread opened another
818 		 * file (dso) due to open file limit (RLIMIT_NOFILE).
819 		 */
820 		try_to_open_dso(dso, machine);
821 
822 		if (dso->data.fd < 0) {
823 			ret = -errno;
824 			dso->data.status = DSO_DATA_STATUS_ERROR;
825 			break;
826 		}
827 
828 		cache_offset = offset & DSO__DATA_CACHE_MASK;
829 
830 		ret = pread(dso->data.fd, cache->data, DSO__DATA_CACHE_SIZE, cache_offset);
831 		if (ret <= 0)
832 			break;
833 
834 		cache->offset = cache_offset;
835 		cache->size   = ret;
836 	} while (0);
837 
838 	pthread_mutex_unlock(&dso__data_open_lock);
839 
840 	if (ret > 0) {
841 		old = dso_cache__insert(dso, cache);
842 		if (old) {
843 			/* we lose the race */
844 			free(cache);
845 			cache = old;
846 		}
847 
848 		ret = dso_cache__memcpy(cache, offset, data, size);
849 	}
850 
851 	if (ret <= 0)
852 		free(cache);
853 
854 	return ret;
855 }
856 
857 static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
858 			      u64 offset, u8 *data, ssize_t size)
859 {
860 	struct dso_cache *cache;
861 
862 	cache = dso_cache__find(dso, offset);
863 	if (cache)
864 		return dso_cache__memcpy(cache, offset, data, size);
865 	else
866 		return dso_cache__read(dso, machine, offset, data, size);
867 }
868 
869 /*
870  * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks
871  * in the rb_tree. Any read to already cached data is served
872  * by cached data.
873  */
874 static ssize_t cached_read(struct dso *dso, struct machine *machine,
875 			   u64 offset, u8 *data, ssize_t size)
876 {
877 	ssize_t r = 0;
878 	u8 *p = data;
879 
880 	do {
881 		ssize_t ret;
882 
883 		ret = dso_cache_read(dso, machine, offset, p, size);
884 		if (ret < 0)
885 			return ret;
886 
887 		/* Reached EOF, return what we have. */
888 		if (!ret)
889 			break;
890 
891 		BUG_ON(ret > size);
892 
893 		r      += ret;
894 		p      += ret;
895 		offset += ret;
896 		size   -= ret;
897 
898 	} while (size);
899 
900 	return r;
901 }
902 
903 static int data_file_size(struct dso *dso, struct machine *machine)
904 {
905 	int ret = 0;
906 	struct stat st;
907 	char sbuf[STRERR_BUFSIZE];
908 
909 	if (dso->data.file_size)
910 		return 0;
911 
912 	if (dso->data.status == DSO_DATA_STATUS_ERROR)
913 		return -1;
914 
915 	pthread_mutex_lock(&dso__data_open_lock);
916 
917 	/*
918 	 * dso->data.fd might be closed if other thread opened another
919 	 * file (dso) due to open file limit (RLIMIT_NOFILE).
920 	 */
921 	try_to_open_dso(dso, machine);
922 
923 	if (dso->data.fd < 0) {
924 		ret = -errno;
925 		dso->data.status = DSO_DATA_STATUS_ERROR;
926 		goto out;
927 	}
928 
929 	if (fstat(dso->data.fd, &st) < 0) {
930 		ret = -errno;
931 		pr_err("dso cache fstat failed: %s\n",
932 		       str_error_r(errno, sbuf, sizeof(sbuf)));
933 		dso->data.status = DSO_DATA_STATUS_ERROR;
934 		goto out;
935 	}
936 	dso->data.file_size = st.st_size;
937 
938 out:
939 	pthread_mutex_unlock(&dso__data_open_lock);
940 	return ret;
941 }
942 
943 /**
944  * dso__data_size - Return dso data size
945  * @dso: dso object
946  * @machine: machine object
947  *
948  * Return: dso data size
949  */
950 off_t dso__data_size(struct dso *dso, struct machine *machine)
951 {
952 	if (data_file_size(dso, machine))
953 		return -1;
954 
955 	/* For now just estimate dso data size is close to file size */
956 	return dso->data.file_size;
957 }
958 
959 static ssize_t data_read_offset(struct dso *dso, struct machine *machine,
960 				u64 offset, u8 *data, ssize_t size)
961 {
962 	if (data_file_size(dso, machine))
963 		return -1;
964 
965 	/* Check the offset sanity. */
966 	if (offset > dso->data.file_size)
967 		return -1;
968 
969 	if (offset + size < offset)
970 		return -1;
971 
972 	return cached_read(dso, machine, offset, data, size);
973 }
974 
975 /**
976  * dso__data_read_offset - Read data from dso file offset
977  * @dso: dso object
978  * @machine: machine object
979  * @offset: file offset
980  * @data: buffer to store data
981  * @size: size of the @data buffer
982  *
983  * External interface to read data from dso file offset. Open
984  * dso data file and use cached_read to get the data.
985  */
986 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
987 			      u64 offset, u8 *data, ssize_t size)
988 {
989 	if (dso->data.status == DSO_DATA_STATUS_ERROR)
990 		return -1;
991 
992 	return data_read_offset(dso, machine, offset, data, size);
993 }
994 
995 /**
996  * dso__data_read_addr - Read data from dso address
997  * @dso: dso object
998  * @machine: machine object
999  * @add: virtual memory address
1000  * @data: buffer to store data
1001  * @size: size of the @data buffer
1002  *
1003  * External interface to read data from dso address.
1004  */
1005 ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
1006 			    struct machine *machine, u64 addr,
1007 			    u8 *data, ssize_t size)
1008 {
1009 	u64 offset = map->map_ip(map, addr);
1010 	return dso__data_read_offset(dso, machine, offset, data, size);
1011 }
1012 
1013 struct map *dso__new_map(const char *name)
1014 {
1015 	struct map *map = NULL;
1016 	struct dso *dso = dso__new(name);
1017 
1018 	if (dso)
1019 		map = map__new2(0, dso);
1020 
1021 	return map;
1022 }
1023 
1024 struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
1025 				    const char *short_name, int dso_type)
1026 {
1027 	/*
1028 	 * The kernel dso could be created by build_id processing.
1029 	 */
1030 	struct dso *dso = machine__findnew_dso(machine, name);
1031 
1032 	/*
1033 	 * We need to run this in all cases, since during the build_id
1034 	 * processing we had no idea this was the kernel dso.
1035 	 */
1036 	if (dso != NULL) {
1037 		dso__set_short_name(dso, short_name, false);
1038 		dso->kernel = dso_type;
1039 	}
1040 
1041 	return dso;
1042 }
1043 
1044 /*
1045  * Find a matching entry and/or link current entry to RB tree.
1046  * Either one of the dso or name parameter must be non-NULL or the
1047  * function will not work.
1048  */
1049 static struct dso *__dso__findlink_by_longname(struct rb_root *root,
1050 					       struct dso *dso, const char *name)
1051 {
1052 	struct rb_node **p = &root->rb_node;
1053 	struct rb_node  *parent = NULL;
1054 
1055 	if (!name)
1056 		name = dso->long_name;
1057 	/*
1058 	 * Find node with the matching name
1059 	 */
1060 	while (*p) {
1061 		struct dso *this = rb_entry(*p, struct dso, rb_node);
1062 		int rc = strcmp(name, this->long_name);
1063 
1064 		parent = *p;
1065 		if (rc == 0) {
1066 			/*
1067 			 * In case the new DSO is a duplicate of an existing
1068 			 * one, print a one-time warning & put the new entry
1069 			 * at the end of the list of duplicates.
1070 			 */
1071 			if (!dso || (dso == this))
1072 				return this;	/* Find matching dso */
1073 			/*
1074 			 * The core kernel DSOs may have duplicated long name.
1075 			 * In this case, the short name should be different.
1076 			 * Comparing the short names to differentiate the DSOs.
1077 			 */
1078 			rc = strcmp(dso->short_name, this->short_name);
1079 			if (rc == 0) {
1080 				pr_err("Duplicated dso name: %s\n", name);
1081 				return NULL;
1082 			}
1083 		}
1084 		if (rc < 0)
1085 			p = &parent->rb_left;
1086 		else
1087 			p = &parent->rb_right;
1088 	}
1089 	if (dso) {
1090 		/* Add new node and rebalance tree */
1091 		rb_link_node(&dso->rb_node, parent, p);
1092 		rb_insert_color(&dso->rb_node, root);
1093 		dso->root = root;
1094 	}
1095 	return NULL;
1096 }
1097 
1098 static inline struct dso *__dso__find_by_longname(struct rb_root *root,
1099 						  const char *name)
1100 {
1101 	return __dso__findlink_by_longname(root, NULL, name);
1102 }
1103 
1104 void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
1105 {
1106 	struct rb_root *root = dso->root;
1107 
1108 	if (name == NULL)
1109 		return;
1110 
1111 	if (dso->long_name_allocated)
1112 		free((char *)dso->long_name);
1113 
1114 	if (root) {
1115 		rb_erase(&dso->rb_node, root);
1116 		/*
1117 		 * __dso__findlink_by_longname() isn't guaranteed to add it
1118 		 * back, so a clean removal is required here.
1119 		 */
1120 		RB_CLEAR_NODE(&dso->rb_node);
1121 		dso->root = NULL;
1122 	}
1123 
1124 	dso->long_name		 = name;
1125 	dso->long_name_len	 = strlen(name);
1126 	dso->long_name_allocated = name_allocated;
1127 
1128 	if (root)
1129 		__dso__findlink_by_longname(root, dso, NULL);
1130 }
1131 
1132 void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
1133 {
1134 	if (name == NULL)
1135 		return;
1136 
1137 	if (dso->short_name_allocated)
1138 		free((char *)dso->short_name);
1139 
1140 	dso->short_name		  = name;
1141 	dso->short_name_len	  = strlen(name);
1142 	dso->short_name_allocated = name_allocated;
1143 }
1144 
1145 static void dso__set_basename(struct dso *dso)
1146 {
1147        /*
1148         * basename() may modify path buffer, so we must pass
1149         * a copy.
1150         */
1151        char *base, *lname = strdup(dso->long_name);
1152 
1153        if (!lname)
1154                return;
1155 
1156        /*
1157         * basename() may return a pointer to internal
1158         * storage which is reused in subsequent calls
1159         * so copy the result.
1160         */
1161        base = strdup(basename(lname));
1162 
1163        free(lname);
1164 
1165        if (!base)
1166                return;
1167 
1168        dso__set_short_name(dso, base, true);
1169 }
1170 
1171 int dso__name_len(const struct dso *dso)
1172 {
1173 	if (!dso)
1174 		return strlen("[unknown]");
1175 	if (verbose > 0)
1176 		return dso->long_name_len;
1177 
1178 	return dso->short_name_len;
1179 }
1180 
1181 bool dso__loaded(const struct dso *dso)
1182 {
1183 	return dso->loaded;
1184 }
1185 
1186 bool dso__sorted_by_name(const struct dso *dso)
1187 {
1188 	return dso->sorted_by_name;
1189 }
1190 
1191 void dso__set_sorted_by_name(struct dso *dso)
1192 {
1193 	dso->sorted_by_name = true;
1194 }
1195 
1196 struct dso *dso__new(const char *name)
1197 {
1198 	struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
1199 
1200 	if (dso != NULL) {
1201 		strcpy(dso->name, name);
1202 		dso__set_long_name(dso, dso->name, false);
1203 		dso__set_short_name(dso, dso->name, false);
1204 		dso->symbols = dso->symbol_names = RB_ROOT;
1205 		dso->data.cache = RB_ROOT;
1206 		dso->inlined_nodes = RB_ROOT;
1207 		dso->srclines = RB_ROOT;
1208 		dso->data.fd = -1;
1209 		dso->data.status = DSO_DATA_STATUS_UNKNOWN;
1210 		dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
1211 		dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
1212 		dso->is_64_bit = (sizeof(void *) == 8);
1213 		dso->loaded = 0;
1214 		dso->rel = 0;
1215 		dso->sorted_by_name = 0;
1216 		dso->has_build_id = 0;
1217 		dso->has_srcline = 1;
1218 		dso->a2l_fails = 1;
1219 		dso->kernel = DSO_TYPE_USER;
1220 		dso->needs_swap = DSO_SWAP__UNSET;
1221 		RB_CLEAR_NODE(&dso->rb_node);
1222 		dso->root = NULL;
1223 		INIT_LIST_HEAD(&dso->node);
1224 		INIT_LIST_HEAD(&dso->data.open_entry);
1225 		pthread_mutex_init(&dso->lock, NULL);
1226 		refcount_set(&dso->refcnt, 1);
1227 	}
1228 
1229 	return dso;
1230 }
1231 
1232 void dso__delete(struct dso *dso)
1233 {
1234 	if (!RB_EMPTY_NODE(&dso->rb_node))
1235 		pr_err("DSO %s is still in rbtree when being deleted!\n",
1236 		       dso->long_name);
1237 
1238 	/* free inlines first, as they reference symbols */
1239 	inlines__tree_delete(&dso->inlined_nodes);
1240 	srcline__tree_delete(&dso->srclines);
1241 	symbols__delete(&dso->symbols);
1242 
1243 	if (dso->short_name_allocated) {
1244 		zfree((char **)&dso->short_name);
1245 		dso->short_name_allocated = false;
1246 	}
1247 
1248 	if (dso->long_name_allocated) {
1249 		zfree((char **)&dso->long_name);
1250 		dso->long_name_allocated = false;
1251 	}
1252 
1253 	dso__data_close(dso);
1254 	auxtrace_cache__free(dso->auxtrace_cache);
1255 	dso_cache__free(dso);
1256 	dso__free_a2l(dso);
1257 	zfree(&dso->symsrc_filename);
1258 	nsinfo__zput(dso->nsinfo);
1259 	pthread_mutex_destroy(&dso->lock);
1260 	free(dso);
1261 }
1262 
1263 struct dso *dso__get(struct dso *dso)
1264 {
1265 	if (dso)
1266 		refcount_inc(&dso->refcnt);
1267 	return dso;
1268 }
1269 
1270 void dso__put(struct dso *dso)
1271 {
1272 	if (dso && refcount_dec_and_test(&dso->refcnt))
1273 		dso__delete(dso);
1274 }
1275 
1276 void dso__set_build_id(struct dso *dso, void *build_id)
1277 {
1278 	memcpy(dso->build_id, build_id, sizeof(dso->build_id));
1279 	dso->has_build_id = 1;
1280 }
1281 
1282 bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1283 {
1284 	return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1285 }
1286 
1287 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
1288 {
1289 	char path[PATH_MAX];
1290 
1291 	if (machine__is_default_guest(machine))
1292 		return;
1293 	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
1294 	if (sysfs__read_build_id(path, dso->build_id,
1295 				 sizeof(dso->build_id)) == 0)
1296 		dso->has_build_id = true;
1297 }
1298 
1299 int dso__kernel_module_get_build_id(struct dso *dso,
1300 				    const char *root_dir)
1301 {
1302 	char filename[PATH_MAX];
1303 	/*
1304 	 * kernel module short names are of the form "[module]" and
1305 	 * we need just "module" here.
1306 	 */
1307 	const char *name = dso->short_name + 1;
1308 
1309 	snprintf(filename, sizeof(filename),
1310 		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1311 		 root_dir, (int)strlen(name) - 1, name);
1312 
1313 	if (sysfs__read_build_id(filename, dso->build_id,
1314 				 sizeof(dso->build_id)) == 0)
1315 		dso->has_build_id = true;
1316 
1317 	return 0;
1318 }
1319 
1320 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1321 {
1322 	bool have_build_id = false;
1323 	struct dso *pos;
1324 	struct nscookie nsc;
1325 
1326 	list_for_each_entry(pos, head, node) {
1327 		if (with_hits && !pos->hit && !dso__is_vdso(pos))
1328 			continue;
1329 		if (pos->has_build_id) {
1330 			have_build_id = true;
1331 			continue;
1332 		}
1333 		nsinfo__mountns_enter(pos->nsinfo, &nsc);
1334 		if (filename__read_build_id(pos->long_name, pos->build_id,
1335 					    sizeof(pos->build_id)) > 0) {
1336 			have_build_id	  = true;
1337 			pos->has_build_id = true;
1338 		}
1339 		nsinfo__mountns_exit(&nsc);
1340 	}
1341 
1342 	return have_build_id;
1343 }
1344 
1345 void __dsos__add(struct dsos *dsos, struct dso *dso)
1346 {
1347 	list_add_tail(&dso->node, &dsos->head);
1348 	__dso__findlink_by_longname(&dsos->root, dso, NULL);
1349 	/*
1350 	 * It is now in the linked list, grab a reference, then garbage collect
1351 	 * this when needing memory, by looking at LRU dso instances in the
1352 	 * list with atomic_read(&dso->refcnt) == 1, i.e. no references
1353 	 * anywhere besides the one for the list, do, under a lock for the
1354 	 * list: remove it from the list, then a dso__put(), that probably will
1355 	 * be the last and will then call dso__delete(), end of life.
1356 	 *
1357 	 * That, or at the end of the 'struct machine' lifetime, when all
1358 	 * 'struct dso' instances will be removed from the list, in
1359 	 * dsos__exit(), if they have no other reference from some other data
1360 	 * structure.
1361 	 *
1362 	 * E.g.: after processing a 'perf.data' file and storing references
1363 	 * to objects instantiated while processing events, we will have
1364 	 * references to the 'thread', 'map', 'dso' structs all from 'struct
1365 	 * hist_entry' instances, but we may not need anything not referenced,
1366 	 * so we might as well call machines__exit()/machines__delete() and
1367 	 * garbage collect it.
1368 	 */
1369 	dso__get(dso);
1370 }
1371 
1372 void dsos__add(struct dsos *dsos, struct dso *dso)
1373 {
1374 	down_write(&dsos->lock);
1375 	__dsos__add(dsos, dso);
1376 	up_write(&dsos->lock);
1377 }
1378 
1379 struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
1380 {
1381 	struct dso *pos;
1382 
1383 	if (cmp_short) {
1384 		list_for_each_entry(pos, &dsos->head, node)
1385 			if (strcmp(pos->short_name, name) == 0)
1386 				return pos;
1387 		return NULL;
1388 	}
1389 	return __dso__find_by_longname(&dsos->root, name);
1390 }
1391 
1392 struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
1393 {
1394 	struct dso *dso;
1395 	down_read(&dsos->lock);
1396 	dso = __dsos__find(dsos, name, cmp_short);
1397 	up_read(&dsos->lock);
1398 	return dso;
1399 }
1400 
1401 struct dso *__dsos__addnew(struct dsos *dsos, const char *name)
1402 {
1403 	struct dso *dso = dso__new(name);
1404 
1405 	if (dso != NULL) {
1406 		__dsos__add(dsos, dso);
1407 		dso__set_basename(dso);
1408 		/* Put dso here because __dsos_add already got it */
1409 		dso__put(dso);
1410 	}
1411 	return dso;
1412 }
1413 
1414 struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
1415 {
1416 	struct dso *dso = __dsos__find(dsos, name, false);
1417 
1418 	return dso ? dso : __dsos__addnew(dsos, name);
1419 }
1420 
1421 struct dso *dsos__findnew(struct dsos *dsos, const char *name)
1422 {
1423 	struct dso *dso;
1424 	down_write(&dsos->lock);
1425 	dso = dso__get(__dsos__findnew(dsos, name));
1426 	up_write(&dsos->lock);
1427 	return dso;
1428 }
1429 
1430 size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1431 			       bool (skip)(struct dso *dso, int parm), int parm)
1432 {
1433 	struct dso *pos;
1434 	size_t ret = 0;
1435 
1436 	list_for_each_entry(pos, head, node) {
1437 		if (skip && skip(pos, parm))
1438 			continue;
1439 		ret += dso__fprintf_buildid(pos, fp);
1440 		ret += fprintf(fp, " %s\n", pos->long_name);
1441 	}
1442 	return ret;
1443 }
1444 
1445 size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1446 {
1447 	struct dso *pos;
1448 	size_t ret = 0;
1449 
1450 	list_for_each_entry(pos, head, node) {
1451 		ret += dso__fprintf(pos, fp);
1452 	}
1453 
1454 	return ret;
1455 }
1456 
1457 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
1458 {
1459 	char sbuild_id[SBUILD_ID_SIZE];
1460 
1461 	build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1462 	return fprintf(fp, "%s", sbuild_id);
1463 }
1464 
1465 size_t dso__fprintf(struct dso *dso, FILE *fp)
1466 {
1467 	struct rb_node *nd;
1468 	size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
1469 
1470 	if (dso->short_name != dso->long_name)
1471 		ret += fprintf(fp, "%s, ", dso->long_name);
1472 	ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
1473 	ret += dso__fprintf_buildid(dso, fp);
1474 	ret += fprintf(fp, ")\n");
1475 	for (nd = rb_first(&dso->symbols); nd; nd = rb_next(nd)) {
1476 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
1477 		ret += symbol__fprintf(pos, fp);
1478 	}
1479 
1480 	return ret;
1481 }
1482 
1483 enum dso_type dso__type(struct dso *dso, struct machine *machine)
1484 {
1485 	int fd;
1486 	enum dso_type type = DSO__TYPE_UNKNOWN;
1487 
1488 	fd = dso__data_get_fd(dso, machine);
1489 	if (fd >= 0) {
1490 		type = dso__type_fd(fd);
1491 		dso__data_put_fd(dso);
1492 	}
1493 
1494 	return type;
1495 }
1496 
1497 int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
1498 {
1499 	int idx, errnum = dso->load_errno;
1500 	/*
1501 	 * This must have a same ordering as the enum dso_load_errno.
1502 	 */
1503 	static const char *dso_load__error_str[] = {
1504 	"Internal tools/perf/ library error",
1505 	"Invalid ELF file",
1506 	"Can not read build id",
1507 	"Mismatching build id",
1508 	"Decompression failure",
1509 	};
1510 
1511 	BUG_ON(buflen == 0);
1512 
1513 	if (errnum >= 0) {
1514 		const char *err = str_error_r(errnum, buf, buflen);
1515 
1516 		if (err != buf)
1517 			scnprintf(buf, buflen, "%s", err);
1518 
1519 		return 0;
1520 	}
1521 
1522 	if (errnum <  __DSO_LOAD_ERRNO__START || errnum >= __DSO_LOAD_ERRNO__END)
1523 		return -1;
1524 
1525 	idx = errnum - __DSO_LOAD_ERRNO__START;
1526 	scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
1527 	return 0;
1528 }
1529