Merge tag 'pm-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[linux-2.6-block.git] / tools / perf / util / dso.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
bda6ee4a 2#include <asm/bug.h>
877a7a11 3#include <linux/kernel.h>
af0de0c5 4#include <linux/string.h>
7f7c536f 5#include <linux/zalloc.h>
c6580451
JO
6#include <sys/time.h>
7#include <sys/resource.h>
7a8ef4c4
ACM
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <unistd.h>
a43783ae 11#include <errno.h>
c23c2a0f 12#include <fcntl.h>
f2a39fe8 13#include <stdlib.h>
ef0580ec 14#ifdef HAVE_LIBBPF_SUPPORT
6c398d72
JO
15#include <bpf/libbpf.h>
16#include "bpf-event.h"
6ac22d03 17#include "bpf-utils.h"
ef0580ec 18#endif
611f0afe 19#include "compress.h"
f2a39fe8 20#include "env.h"
40f3b2d2 21#include "namespaces.h"
9a3993d4 22#include "path.h"
1101f69a 23#include "map.h"
cdd059d7 24#include "symbol.h"
11ea2515 25#include "srcline.h"
cdd059d7 26#include "dso.h"
4a3cec84 27#include "dsos.h"
69d2591a 28#include "machine.h"
cfe9174f 29#include "auxtrace.h"
7f7c536f 30#include "util.h" /* O_CLOEXEC for older systems */
cdd059d7 31#include "debug.h"
a067558e 32#include "string2.h"
6ae98ba6 33#include "vdso.h"
fc044c53 34#include "annotate-data.h"
cdd059d7 35
9343e45b
MGP
36static const char * const debuglink_paths[] = {
37 "%.0s%s",
38 "%s/%s",
39 "%s/.debug/%s",
40 "/usr/lib/debug%s/%s"
41};
42
ee756ef7
IR
43void dso__set_nsinfo(struct dso *dso, struct nsinfo *nsi)
44{
45 nsinfo__put(RC_CHK_ACCESS(dso)->nsinfo);
46 RC_CHK_ACCESS(dso)->nsinfo = nsi;
47}
48
cdd059d7
JO
49char dso__symtab_origin(const struct dso *dso)
50{
51 static const char origin[] = {
9cd00941
RRD
52 [DSO_BINARY_TYPE__KALLSYMS] = 'k',
53 [DSO_BINARY_TYPE__VMLINUX] = 'v',
54 [DSO_BINARY_TYPE__JAVA_JIT] = 'j',
55 [DSO_BINARY_TYPE__DEBUGLINK] = 'l',
56 [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
d2396999 57 [DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO] = 'D',
9cd00941
RRD
58 [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
59 [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
85afd355 60 [DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO] = 'x',
9cd00941
RRD
61 [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o',
62 [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
63 [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
64 [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
c00c48fc 65 [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP] = 'm',
9cd00941
RRD
66 [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
67 [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
c00c48fc 68 [DSO_BINARY_TYPE__GUEST_KMODULE_COMP] = 'M',
9cd00941 69 [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
b10f7430 70 [DSO_BINARY_TYPE__GNU_DEBUGDATA] = 'n',
cdd059d7
JO
71 };
72
ee756ef7 73 if (dso == NULL || dso__symtab_type(dso) == DSO_BINARY_TYPE__NOT_FOUND)
cdd059d7 74 return '!';
ee756ef7 75 return origin[dso__symtab_type(dso)];
cdd059d7
JO
76}
77
d3b52f71
AH
78bool dso__is_object_file(const struct dso *dso)
79{
ee756ef7 80 switch (dso__binary_type(dso)) {
d3b52f71
AH
81 case DSO_BINARY_TYPE__KALLSYMS:
82 case DSO_BINARY_TYPE__GUEST_KALLSYMS:
83 case DSO_BINARY_TYPE__JAVA_JIT:
84 case DSO_BINARY_TYPE__BPF_PROG_INFO:
85 case DSO_BINARY_TYPE__BPF_IMAGE:
86 case DSO_BINARY_TYPE__OOL:
87 return false;
88 case DSO_BINARY_TYPE__VMLINUX:
89 case DSO_BINARY_TYPE__GUEST_VMLINUX:
90 case DSO_BINARY_TYPE__DEBUGLINK:
91 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
92 case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
93 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
94 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
95 case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
96 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
b10f7430 97 case DSO_BINARY_TYPE__GNU_DEBUGDATA:
d3b52f71
AH
98 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
99 case DSO_BINARY_TYPE__GUEST_KMODULE:
100 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
101 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
102 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
103 case DSO_BINARY_TYPE__KCORE:
104 case DSO_BINARY_TYPE__GUEST_KCORE:
105 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
106 case DSO_BINARY_TYPE__NOT_FOUND:
107 default:
108 return true;
109 }
110}
111
ee4e9625
ACM
112int dso__read_binary_type_filename(const struct dso *dso,
113 enum dso_binary_type type,
114 char *root_dir, char *filename, size_t size)
cdd059d7 115{
b5d8bbe8 116 char build_id_hex[SBUILD_ID_SIZE];
cdd059d7 117 int ret = 0;
972f393b 118 size_t len;
cdd059d7
JO
119
120 switch (type) {
9343e45b
MGP
121 case DSO_BINARY_TYPE__DEBUGLINK:
122 {
123 const char *last_slash;
124 char dso_dir[PATH_MAX];
125 char symfile[PATH_MAX];
126 unsigned int i;
cdd059d7 127
ee756ef7 128 len = __symbol__join_symfs(filename, size, dso__long_name(dso));
9343e45b
MGP
129 last_slash = filename + len;
130 while (last_slash != filename && *last_slash != '/')
131 last_slash--;
40356721 132
9343e45b
MGP
133 strncpy(dso_dir, filename, last_slash - filename);
134 dso_dir[last_slash-filename] = '\0';
135
136 if (!is_regular_file(filename)) {
137 ret = -1;
40356721 138 break;
9343e45b 139 }
40356721 140
9343e45b
MGP
141 ret = filename__read_debuglink(filename, symfile, PATH_MAX);
142 if (ret)
143 break;
144
145 /* Check predefined locations where debug file might reside */
146 ret = -1;
147 for (i = 0; i < ARRAY_SIZE(debuglink_paths); i++) {
148 snprintf(filename, size,
149 debuglink_paths[i], dso_dir, symfile);
150 if (is_regular_file(filename)) {
151 ret = 0;
152 break;
153 }
cdd059d7 154 }
9343e45b 155
cdd059d7 156 break;
9343e45b 157 }
cdd059d7 158 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
d2396999
KJ
159 if (dso__build_id_filename(dso, filename, size, false) == NULL)
160 ret = -1;
161 break;
162
163 case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
164 if (dso__build_id_filename(dso, filename, size, true) == NULL)
cdd059d7
JO
165 ret = -1;
166 break;
167
168 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
972f393b 169 len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
ee756ef7 170 snprintf(filename + len, size - len, "%s.debug", dso__long_name(dso));
cdd059d7
JO
171 break;
172
173 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
972f393b 174 len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
ee756ef7 175 snprintf(filename + len, size - len, "%s", dso__long_name(dso));
cdd059d7
JO
176 break;
177
85afd355
AH
178 case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
179 /*
180 * Ubuntu can mixup /usr/lib with /lib, putting debuginfo in
181 * /usr/lib/debug/lib when it is expected to be in
182 * /usr/lib/debug/usr/lib
183 */
ee756ef7
IR
184 if (strlen(dso__long_name(dso)) < 9 ||
185 strncmp(dso__long_name(dso), "/usr/lib/", 9)) {
85afd355
AH
186 ret = -1;
187 break;
188 }
189 len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
ee756ef7 190 snprintf(filename + len, size - len, "%s", dso__long_name(dso) + 4);
85afd355
AH
191 break;
192
9cd00941
RRD
193 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
194 {
bf4414ae 195 const char *last_slash;
9cd00941
RRD
196 size_t dir_size;
197
ee756ef7
IR
198 last_slash = dso__long_name(dso) + dso__long_name_len(dso);
199 while (last_slash != dso__long_name(dso) && *last_slash != '/')
9cd00941
RRD
200 last_slash--;
201
972f393b 202 len = __symbol__join_symfs(filename, size, "");
ee756ef7 203 dir_size = last_slash - dso__long_name(dso) + 2;
9cd00941
RRD
204 if (dir_size > (size - len)) {
205 ret = -1;
206 break;
207 }
ee756ef7 208 len += scnprintf(filename + len, dir_size, "%s", dso__long_name(dso));
7d2a5122 209 len += scnprintf(filename + len , size - len, ".debug%s",
9cd00941
RRD
210 last_slash);
211 break;
212 }
213
cdd059d7 214 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
ee756ef7 215 if (!dso__has_build_id(dso)) {
cdd059d7
JO
216 ret = -1;
217 break;
218 }
219
ee756ef7 220 build_id__sprintf(dso__bid_const(dso), build_id_hex);
972f393b
ACM
221 len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/");
222 snprintf(filename + len, size - len, "%.2s/%s.debug",
223 build_id_hex, build_id_hex + 2);
cdd059d7
JO
224 break;
225
39b12f78
AH
226 case DSO_BINARY_TYPE__VMLINUX:
227 case DSO_BINARY_TYPE__GUEST_VMLINUX:
cdd059d7 228 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
b10f7430 229 case DSO_BINARY_TYPE__GNU_DEBUGDATA:
ee756ef7 230 __symbol__join_symfs(filename, size, dso__long_name(dso));
cdd059d7
JO
231 break;
232
233 case DSO_BINARY_TYPE__GUEST_KMODULE:
c00c48fc 234 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
972f393b 235 path__join3(filename, size, symbol_conf.symfs,
ee756ef7 236 root_dir, dso__long_name(dso));
cdd059d7
JO
237 break;
238
239 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
c00c48fc 240 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
ee756ef7 241 __symbol__join_symfs(filename, size, dso__long_name(dso));
cdd059d7
JO
242 break;
243
8e0cf965
AH
244 case DSO_BINARY_TYPE__KCORE:
245 case DSO_BINARY_TYPE__GUEST_KCORE:
ee756ef7 246 snprintf(filename, size, "%s", dso__long_name(dso));
8e0cf965
AH
247 break;
248
cdd059d7
JO
249 default:
250 case DSO_BINARY_TYPE__KALLSYMS:
cdd059d7 251 case DSO_BINARY_TYPE__GUEST_KALLSYMS:
cdd059d7 252 case DSO_BINARY_TYPE__JAVA_JIT:
9b86d04d 253 case DSO_BINARY_TYPE__BPF_PROG_INFO:
3c29d448 254 case DSO_BINARY_TYPE__BPF_IMAGE:
789e2419 255 case DSO_BINARY_TYPE__OOL:
cdd059d7
JO
256 case DSO_BINARY_TYPE__NOT_FOUND:
257 ret = -1;
258 break;
259 }
260
261 return ret;
262}
263
4b838b0d
JO
264enum {
265 COMP_ID__NONE = 0,
266};
267
c00c48fc
NK
268static const struct {
269 const char *fmt;
270 int (*decompress)(const char *input, int output);
8b42b7e5 271 bool (*is_compressed)(const char *input);
c00c48fc 272} compressions[] = {
4b838b0d 273 [COMP_ID__NONE] = { .fmt = NULL, },
e92ce12e 274#ifdef HAVE_ZLIB_SUPPORT
8b42b7e5 275 { "gz", gzip_decompress_to_file, gzip_is_compressed },
80a32e5b
JO
276#endif
277#ifdef HAVE_LZMA_SUPPORT
8b42b7e5 278 { "xz", lzma_decompress_to_file, lzma_is_compressed },
e92ce12e 279#endif
8b42b7e5 280 { NULL, NULL, NULL },
c00c48fc
NK
281};
282
4b838b0d 283static int is_supported_compression(const char *ext)
c00c48fc
NK
284{
285 unsigned i;
286
4b838b0d 287 for (i = 1; compressions[i].fmt; i++) {
c00c48fc 288 if (!strcmp(ext, compressions[i].fmt))
4b838b0d 289 return i;
c00c48fc 290 }
4b838b0d 291 return COMP_ID__NONE;
c00c48fc
NK
292}
293
1f121b03 294bool is_kernel_module(const char *pathname, int cpumode)
c00c48fc 295{
8dee9ff1 296 struct kmod_path m;
1f121b03
WN
297 int mode = cpumode & PERF_RECORD_MISC_CPUMODE_MASK;
298
299 WARN_ONCE(mode != cpumode,
300 "Internal error: passing unmasked cpumode (%x) to is_kernel_module",
301 cpumode);
302
303 switch (mode) {
304 case PERF_RECORD_MISC_USER:
305 case PERF_RECORD_MISC_HYPERVISOR:
306 case PERF_RECORD_MISC_GUEST_USER:
307 return false;
308 /* Treat PERF_RECORD_MISC_CPUMODE_UNKNOWN as kernel */
309 default:
310 if (kmod_path__parse(&m, pathname)) {
311 pr_err("Failed to check whether %s is a kernel module or not. Assume it is.",
312 pathname);
313 return true;
314 }
315 }
c00c48fc 316
8dee9ff1 317 return m.kmod;
c00c48fc
NK
318}
319
c00c48fc
NK
320bool dso__needs_decompress(struct dso *dso)
321{
ee756ef7
IR
322 return dso__symtab_type(dso) == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
323 dso__symtab_type(dso) == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
c00c48fc
NK
324}
325
7ac22b08
JO
326int filename__decompress(const char *name, char *pathname,
327 size_t len, int comp, int *err)
42b3fa67 328{
c9a8a613 329 char tmpbuf[] = KMOD_DECOMP_NAME;
42b3fa67 330 int fd = -1;
42b3fa67 331
8b42b7e5
JO
332 /*
333 * We have proper compression id for DSO and yet the file
334 * behind the 'name' can still be plain uncompressed object.
335 *
336 * The reason is behind the logic we open the DSO object files,
337 * when we try all possible 'debug' objects until we find the
338 * data. So even if the DSO is represented by 'krava.xz' module,
339 * we can end up here opening ~/.debug/....23432432/debug' file
340 * which is not compressed.
341 *
342 * To keep this transparent, we detect this and return the file
343 * descriptor to the uncompressed file.
344 */
7ac22b08 345 if (!compressions[comp].is_compressed(name))
8b42b7e5
JO
346 return open(name, O_RDONLY);
347
42b3fa67
NK
348 fd = mkstemp(tmpbuf);
349 if (fd < 0) {
7ac22b08 350 *err = errno;
dde755a9 351 return -1;
42b3fa67
NK
352 }
353
7ac22b08
JO
354 if (compressions[comp].decompress(name, fd)) {
355 *err = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
42b3fa67
NK
356 close(fd);
357 fd = -1;
358 }
359
c9a8a613
JO
360 if (!pathname || (fd < 0))
361 unlink(tmpbuf);
362
363 if (pathname && (fd >= 0))
fca5085c 364 strlcpy(pathname, tmpbuf, len);
c9a8a613 365
42b3fa67
NK
366 return fd;
367}
368
7ac22b08
JO
369static int decompress_kmodule(struct dso *dso, const char *name,
370 char *pathname, size_t len)
371{
372 if (!dso__needs_decompress(dso))
373 return -1;
374
ee756ef7 375 if (dso__comp(dso) == COMP_ID__NONE)
7ac22b08
JO
376 return -1;
377
ee756ef7 378 return filename__decompress(name, pathname, len, dso__comp(dso), dso__load_errno(dso));
7ac22b08
JO
379}
380
42b3fa67
NK
381int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
382{
c9a8a613 383 return decompress_kmodule(dso, name, NULL, 0);
42b3fa67
NK
384}
385
386int dso__decompress_kmodule_path(struct dso *dso, const char *name,
387 char *pathname, size_t len)
388{
c9a8a613 389 int fd = decompress_kmodule(dso, name, pathname, len);
42b3fa67 390
42b3fa67 391 close(fd);
c9a8a613 392 return fd >= 0 ? 0 : -1;
42b3fa67
NK
393}
394
3c8a67f5
JO
395/*
396 * Parses kernel module specified in @path and updates
397 * @m argument like:
398 *
399 * @comp - true if @path contains supported compression suffix,
400 * false otherwise
401 * @kmod - true if @path contains '.ko' suffix in right position,
402 * false otherwise
403 * @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
404 * of the kernel module without suffixes, otherwise strudup-ed
405 * base name of @path
406 * @ext - if (@alloc_ext && @comp) is true, it contains strdup-ed string
407 * the compression suffix
408 *
409 * Returns 0 if there's no strdup error, -ENOMEM otherwise.
410 */
411int __kmod_path__parse(struct kmod_path *m, const char *path,
b946cd37 412 bool alloc_name)
3c8a67f5
JO
413{
414 const char *name = strrchr(path, '/');
415 const char *ext = strrchr(path, '.');
1f121b03 416 bool is_simple_name = false;
3c8a67f5
JO
417
418 memset(m, 0x0, sizeof(*m));
419 name = name ? name + 1 : path;
420
1f121b03
WN
421 /*
422 * '.' is also a valid character for module name. For example:
423 * [aaa.bbb] is a valid module name. '[' should have higher
424 * priority than '.ko' suffix.
425 *
426 * The kernel names are from machine__mmap_name. Such
427 * name should belong to kernel itself, not kernel module.
428 */
429 if (name[0] == '[') {
430 is_simple_name = true;
431 if ((strncmp(name, "[kernel.kallsyms]", 17) == 0) ||
432 (strncmp(name, "[guest.kernel.kallsyms", 22) == 0) ||
433 (strncmp(name, "[vdso]", 6) == 0) ||
aef4feac
AH
434 (strncmp(name, "[vdso32]", 8) == 0) ||
435 (strncmp(name, "[vdsox32]", 9) == 0) ||
1f121b03
WN
436 (strncmp(name, "[vsyscall]", 10) == 0)) {
437 m->kmod = false;
438
439 } else
440 m->kmod = true;
441 }
442
3c8a67f5 443 /* No extension, just return name. */
1f121b03 444 if ((ext == NULL) || is_simple_name) {
3c8a67f5
JO
445 if (alloc_name) {
446 m->name = strdup(name);
447 return m->name ? 0 : -ENOMEM;
448 }
449 return 0;
450 }
451
4b838b0d
JO
452 m->comp = is_supported_compression(ext + 1);
453 if (m->comp > COMP_ID__NONE)
3c8a67f5 454 ext -= 3;
3c8a67f5
JO
455
456 /* Check .ko extension only if there's enough name left. */
457 if (ext > name)
458 m->kmod = !strncmp(ext, ".ko", 3);
459
460 if (alloc_name) {
461 if (m->kmod) {
462 if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
463 return -ENOMEM;
464 } else {
465 if (asprintf(&m->name, "%s", name) == -1)
466 return -ENOMEM;
467 }
468
af0de0c5 469 strreplace(m->name, '-', '_');
3c8a67f5
JO
470 }
471
3c8a67f5
JO
472 return 0;
473}
474
6b335e8f
NK
475void dso__set_module_info(struct dso *dso, struct kmod_path *m,
476 struct machine *machine)
477{
478 if (machine__is_host(machine))
ee756ef7 479 dso__set_symtab_type(dso, DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE);
6b335e8f 480 else
ee756ef7 481 dso__set_symtab_type(dso, DSO_BINARY_TYPE__GUEST_KMODULE);
6b335e8f
NK
482
483 /* _KMODULE_COMP should be next to _KMODULE */
2af52475 484 if (m->kmod && m->comp) {
ee756ef7
IR
485 dso__set_symtab_type(dso, dso__symtab_type(dso) + 1);
486 dso__set_comp(dso, m->comp);
2af52475 487 }
6b335e8f 488
ee756ef7 489 dso__set_is_kmod(dso);
6b335e8f
NK
490 dso__set_short_name(dso, strdup(m->name), true);
491}
492
eba5102d 493/*
bda6ee4a 494 * Global list of open DSOs and the counter.
eba5102d 495 */
5ac22c35 496struct mutex _dso__data_open_lock;
eba5102d 497static LIST_HEAD(dso__data_open);
5ac22c35 498static long dso__data_open_cnt GUARDED_BY(_dso__data_open_lock);
eba5102d 499
5ac22c35
IR
500static void dso__data_open_lock_init(void)
501{
502 mutex_init(&_dso__data_open_lock);
503}
504
505static struct mutex *dso__data_open_lock(void) LOCK_RETURNED(_dso__data_open_lock)
506{
507 static pthread_once_t data_open_lock_once = PTHREAD_ONCE_INIT;
508
509 pthread_once(&data_open_lock_once, dso__data_open_lock_init);
510
511 return &_dso__data_open_lock;
512}
513
514static void dso__list_add(struct dso *dso) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
eba5102d 515{
ee756ef7 516 list_add_tail(&dso__data(dso)->open_entry, &dso__data_open);
37862d6f 517#ifdef REFCNT_CHECKING
ee756ef7 518 dso__data(dso)->dso = dso__get(dso);
37862d6f
IR
519#endif
520 /* Assume the dso is part of dsos, hence the optional reference count above. */
521 assert(dso__dsos(dso));
bda6ee4a 522 dso__data_open_cnt++;
eba5102d
JO
523}
524
5ac22c35 525static void dso__list_del(struct dso *dso) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
eba5102d 526{
ee756ef7 527 list_del_init(&dso__data(dso)->open_entry);
37862d6f 528#ifdef REFCNT_CHECKING
5ac22c35 529 mutex_unlock(dso__data_open_lock());
ee756ef7 530 dso__put(dso__data(dso)->dso);
5ac22c35 531 mutex_lock(dso__data_open_lock());
37862d6f 532#endif
bda6ee4a
JO
533 WARN_ONCE(dso__data_open_cnt <= 0,
534 "DSO data fd counter out of bounds.");
535 dso__data_open_cnt--;
eba5102d
JO
536}
537
a08cae03
JO
538static void close_first_dso(void);
539
5ac22c35 540static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
a08cae03
JO
541{
542 int fd;
6e81c74c 543 char sbuf[STRERR_BUFSIZE];
a08cae03
JO
544
545 do {
4c0d8d27 546 fd = open(name, O_RDONLY|O_CLOEXEC);
a08cae03
JO
547 if (fd >= 0)
548 return fd;
549
a3c0cc2a 550 pr_debug("dso open failed: %s\n",
c8b5f2c9 551 str_error_r(errno, sbuf, sizeof(sbuf)));
a08cae03
JO
552 if (!dso__data_open_cnt || errno != EMFILE)
553 break;
554
555 close_first_dso();
556 } while (1);
557
558 return -1;
559}
560
7031edac
ACM
561char *dso__filename_with_chroot(const struct dso *dso, const char *filename)
562{
ee756ef7 563 return filename_with_chroot(nsinfo__pid(dso__nsinfo_const(dso)), filename);
7031edac
ACM
564}
565
eba5102d 566static int __open_dso(struct dso *dso, struct machine *machine)
5ac22c35 567 EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
cdd059d7 568{
8ba29adf 569 int fd = -EINVAL;
ee4e9625
ACM
570 char *root_dir = (char *)"";
571 char *name = malloc(PATH_MAX);
d68a29c2 572 bool decomp = false;
cdd059d7 573
cdd059d7
JO
574 if (!name)
575 return -ENOMEM;
576
ee756ef7 577 mutex_lock(dso__lock(dso));
cdd059d7
JO
578 if (machine)
579 root_dir = machine->root_dir;
580
ee756ef7 581 if (dso__read_binary_type_filename(dso, dso__binary_type(dso),
8ba29adf
NK
582 root_dir, name, PATH_MAX))
583 goto out;
cdd059d7 584
67fd1892
NK
585 if (!is_regular_file(name)) {
586 char *new_name;
587
ee756ef7 588 if (errno != ENOENT || dso__nsinfo(dso) == NULL)
67fd1892
NK
589 goto out;
590
7031edac 591 new_name = dso__filename_with_chroot(dso, name);
67fd1892
NK
592 if (!new_name)
593 goto out;
594
595 free(name);
596 name = new_name;
597 }
3c028a0c 598
1d6b3c9b
NK
599 if (dso__needs_decompress(dso)) {
600 char newpath[KMOD_DECOMP_LEN];
601 size_t len = sizeof(newpath);
602
603 if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
ee756ef7 604 fd = -(*dso__load_errno(dso));
8ba29adf 605 goto out;
1d6b3c9b
NK
606 }
607
d68a29c2 608 decomp = true;
1d6b3c9b
NK
609 strcpy(name, newpath);
610 }
611
a08cae03 612 fd = do_open(name);
1d6b3c9b 613
d68a29c2 614 if (decomp)
1d6b3c9b
NK
615 unlink(name);
616
8ba29adf 617out:
ee756ef7 618 mutex_unlock(dso__lock(dso));
cdd059d7
JO
619 free(name);
620 return fd;
621}
622
c6580451
JO
623static void check_data_close(void);
624
c1f9aa0a
JO
625/**
626 * dso_close - Open DSO data file
627 * @dso: dso object
628 *
629 * Open @dso's data file descriptor and updates
630 * list/count of open DSO objects.
631 */
eba5102d 632static int open_dso(struct dso *dso, struct machine *machine)
5ac22c35 633 EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
eba5102d 634{
f045b8c4
KJ
635 int fd;
636 struct nscookie nsc;
637
ee756ef7
IR
638 if (dso__binary_type(dso) != DSO_BINARY_TYPE__BUILD_ID_CACHE) {
639 mutex_lock(dso__lock(dso));
640 nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
641 mutex_unlock(dso__lock(dso));
e54dea69 642 }
f045b8c4 643 fd = __open_dso(dso, machine);
ee756ef7 644 if (dso__binary_type(dso) != DSO_BINARY_TYPE__BUILD_ID_CACHE)
f045b8c4 645 nsinfo__mountns_exit(&nsc);
eba5102d 646
a6f6ae99 647 if (fd >= 0) {
eba5102d 648 dso__list_add(dso);
c6580451
JO
649 /*
650 * Check if we crossed the allowed number
651 * of opened DSOs and close one if needed.
652 */
653 check_data_close();
654 }
eba5102d
JO
655
656 return fd;
657}
658
5ac22c35 659static void close_data_fd(struct dso *dso) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
53fa8eaa 660{
ee756ef7
IR
661 if (dso__data(dso)->fd >= 0) {
662 close(dso__data(dso)->fd);
663 dso__data(dso)->fd = -1;
664 dso__data(dso)->file_size = 0;
eba5102d 665 dso__list_del(dso);
53fa8eaa
JO
666 }
667}
668
c1f9aa0a
JO
669/**
670 * dso_close - Close DSO data file
671 * @dso: dso object
672 *
673 * Close @dso's data file descriptor and updates
674 * list/count of open DSO objects.
675 */
5ac22c35 676static void close_dso(struct dso *dso) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
eba5102d
JO
677{
678 close_data_fd(dso);
679}
680
5ac22c35 681static void close_first_dso(void) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
c6580451 682{
ee756ef7 683 struct dso_data *dso_data;
37862d6f 684 struct dso *dso;
c6580451 685
ee756ef7 686 dso_data = list_first_entry(&dso__data_open, struct dso_data, open_entry);
37862d6f
IR
687#ifdef REFCNT_CHECKING
688 dso = dso_data->dso;
689#else
690 dso = container_of(dso_data, struct dso, data);
691#endif
692 close_dso(dso);
c6580451
JO
693}
694
695static rlim_t get_fd_limit(void)
696{
697 struct rlimit l;
698 rlim_t limit = 0;
699
700 /* Allow half of the current open fd limit. */
701 if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
702 if (l.rlim_cur == RLIM_INFINITY)
703 limit = l.rlim_cur;
704 else
705 limit = l.rlim_cur / 2;
706 } else {
707 pr_err("failed to get fd limit\n");
708 limit = 1;
709 }
710
711 return limit;
712}
713
f3069249
JO
714static rlim_t fd_limit;
715
716/*
717 * Used only by tests/dso-data.c to reset the environment
718 * for tests. I dont expect we should change this during
719 * standard runtime.
720 */
721void reset_fd_limit(void)
c6580451 722{
f3069249
JO
723 fd_limit = 0;
724}
c6580451 725
5ac22c35 726static bool may_cache_fd(void) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
f3069249
JO
727{
728 if (!fd_limit)
729 fd_limit = get_fd_limit();
c6580451 730
f3069249 731 if (fd_limit == RLIM_INFINITY)
c6580451
JO
732 return true;
733
f3069249 734 return fd_limit > (rlim_t) dso__data_open_cnt;
c6580451
JO
735}
736
c1f9aa0a
JO
737/*
738 * Check and close LRU dso if we crossed allowed limit
739 * for opened dso file descriptors. The limit is half
740 * of the RLIMIT_NOFILE files opened.
741*/
5ac22c35 742static void check_data_close(void) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
c6580451
JO
743{
744 bool cache_fd = may_cache_fd();
745
746 if (!cache_fd)
747 close_first_dso();
748}
749
c1f9aa0a
JO
750/**
751 * dso__data_close - Close DSO data file
752 * @dso: dso object
753 *
754 * External interface to close @dso's data file descriptor.
755 */
eba5102d
JO
756void dso__data_close(struct dso *dso)
757{
5ac22c35 758 mutex_lock(dso__data_open_lock());
eba5102d 759 close_dso(dso);
5ac22c35 760 mutex_unlock(dso__data_open_lock());
eba5102d
JO
761}
762
71ff824a 763static void try_to_open_dso(struct dso *dso, struct machine *machine)
5ac22c35 764 EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
cdd059d7 765{
631d34b5 766 enum dso_binary_type binary_type_data[] = {
cdd059d7
JO
767 DSO_BINARY_TYPE__BUILD_ID_CACHE,
768 DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
769 DSO_BINARY_TYPE__NOT_FOUND,
770 };
771 int i = 0;
ee756ef7 772 struct dso_data *dso_data = dso__data(dso);
cdd059d7 773
ee756ef7 774 if (dso_data->fd >= 0)
71ff824a 775 return;
53fa8eaa 776
ee756ef7
IR
777 if (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND) {
778 dso_data->fd = open_dso(dso, machine);
c27697d6 779 goto out;
53fa8eaa 780 }
cdd059d7
JO
781
782 do {
ee756ef7 783 dso__set_binary_type(dso, binary_type_data[i++]);
cdd059d7 784
ee756ef7
IR
785 dso_data->fd = open_dso(dso, machine);
786 if (dso_data->fd >= 0)
c27697d6 787 goto out;
cdd059d7 788
ee756ef7 789 } while (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND);
c27697d6 790out:
ee756ef7
IR
791 if (dso_data->fd >= 0)
792 dso_data->status = DSO_DATA_STATUS_OK;
c27697d6 793 else
ee756ef7 794 dso_data->status = DSO_DATA_STATUS_ERROR;
71ff824a
NK
795}
796
797/**
4bb11d01 798 * dso__data_get_fd - Get dso's data file descriptor
71ff824a
NK
799 * @dso: dso object
800 * @machine: machine object
801 *
802 * External interface to find dso's file, open it and
4bb11d01
NK
803 * returns file descriptor. It should be paired with
804 * dso__data_put_fd() if it returns non-negative value.
71ff824a 805 */
5ac22c35 806bool dso__data_get_fd(struct dso *dso, struct machine *machine, int *fd)
71ff824a 807{
5ac22c35 808 *fd = -1;
ee756ef7 809 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR)
5ac22c35 810 return false;
cdd059d7 811
5ac22c35 812 mutex_lock(dso__data_open_lock());
4bb11d01 813
71ff824a 814 try_to_open_dso(dso, machine);
4bb11d01 815
5ac22c35
IR
816 *fd = dso__data(dso)->fd;
817 if (*fd >= 0)
818 return true;
71ff824a 819
5ac22c35
IR
820 mutex_unlock(dso__data_open_lock());
821 return false;
cdd059d7
JO
822}
823
4bb11d01
NK
824void dso__data_put_fd(struct dso *dso __maybe_unused)
825{
5ac22c35 826 mutex_unlock(dso__data_open_lock());
4bb11d01
NK
827}
828
288be943
AH
829bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by)
830{
831 u32 flag = 1 << by;
832
ee756ef7 833 if (dso__data(dso)->status_seen & flag)
288be943
AH
834 return true;
835
ee756ef7 836 dso__data(dso)->status_seen |= flag;
288be943
AH
837
838 return false;
839}
840
ef0580ec 841#ifdef HAVE_LIBBPF_SUPPORT
6c398d72
JO
842static ssize_t bpf_read(struct dso *dso, u64 offset, char *data)
843{
844 struct bpf_prog_info_node *node;
845 ssize_t size = DSO__DATA_CACHE_SIZE;
ee756ef7 846 struct dso_bpf_prog *dso_bpf_prog = dso__bpf_prog(dso);
6c398d72
JO
847 u64 len;
848 u8 *buf;
849
ee756ef7 850 node = perf_env__find_bpf_prog_info(dso_bpf_prog->env, dso_bpf_prog->id);
6c398d72 851 if (!node || !node->info_linear) {
ee756ef7 852 dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
6c398d72
JO
853 return -1;
854 }
855
856 len = node->info_linear->info.jited_prog_len;
857 buf = (u8 *)(uintptr_t)node->info_linear->info.jited_prog_insns;
858
859 if (offset >= len)
860 return -1;
861
862 size = (ssize_t)min(len - offset, (u64)size);
863 memcpy(data, buf + offset, size);
864 return size;
865}
866
867static int bpf_size(struct dso *dso)
868{
869 struct bpf_prog_info_node *node;
ee756ef7 870 struct dso_bpf_prog *dso_bpf_prog = dso__bpf_prog(dso);
6c398d72 871
ee756ef7 872 node = perf_env__find_bpf_prog_info(dso_bpf_prog->env, dso_bpf_prog->id);
6c398d72 873 if (!node || !node->info_linear) {
ee756ef7 874 dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
6c398d72
JO
875 return -1;
876 }
877
ee756ef7 878 dso__data(dso)->file_size = node->info_linear->info.jited_prog_len;
6c398d72
JO
879 return 0;
880}
ef0580ec 881#endif // HAVE_LIBBPF_SUPPORT
6c398d72 882
cdd059d7 883static void
8e67b725 884dso_cache__free(struct dso *dso)
cdd059d7 885{
ee756ef7 886 struct rb_root *root = &dso__data(dso)->cache;
cdd059d7
JO
887 struct rb_node *next = rb_first(root);
888
ee756ef7 889 mutex_lock(dso__lock(dso));
cdd059d7
JO
890 while (next) {
891 struct dso_cache *cache;
892
893 cache = rb_entry(next, struct dso_cache, rb_node);
894 next = rb_next(&cache->rb_node);
895 rb_erase(&cache->rb_node, root);
896 free(cache);
897 }
ee756ef7 898 mutex_unlock(dso__lock(dso));
cdd059d7
JO
899}
900
366df726 901static struct dso_cache *__dso_cache__find(struct dso *dso, u64 offset)
cdd059d7 902{
ee756ef7 903 const struct rb_root *root = &dso__data(dso)->cache;
3344996e
ACM
904 struct rb_node * const *p = &root->rb_node;
905 const struct rb_node *parent = NULL;
cdd059d7
JO
906 struct dso_cache *cache;
907
908 while (*p != NULL) {
909 u64 end;
910
911 parent = *p;
912 cache = rb_entry(parent, struct dso_cache, rb_node);
913 end = cache->offset + DSO__DATA_CACHE_SIZE;
914
915 if (offset < cache->offset)
916 p = &(*p)->rb_left;
917 else if (offset >= end)
918 p = &(*p)->rb_right;
919 else
920 return cache;
921 }
8e67b725 922
cdd059d7
JO
923 return NULL;
924}
925
8e67b725
NK
926static struct dso_cache *
927dso_cache__insert(struct dso *dso, struct dso_cache *new)
cdd059d7 928{
ee756ef7 929 struct rb_root *root = &dso__data(dso)->cache;
cdd059d7
JO
930 struct rb_node **p = &root->rb_node;
931 struct rb_node *parent = NULL;
932 struct dso_cache *cache;
933 u64 offset = new->offset;
934
ee756ef7 935 mutex_lock(dso__lock(dso));
cdd059d7
JO
936 while (*p != NULL) {
937 u64 end;
938
939 parent = *p;
940 cache = rb_entry(parent, struct dso_cache, rb_node);
941 end = cache->offset + DSO__DATA_CACHE_SIZE;
942
943 if (offset < cache->offset)
944 p = &(*p)->rb_left;
945 else if (offset >= end)
946 p = &(*p)->rb_right;
8e67b725
NK
947 else
948 goto out;
cdd059d7
JO
949 }
950
951 rb_link_node(&new->rb_node, parent, p);
952 rb_insert_color(&new->rb_node, root);
8e67b725
NK
953
954 cache = NULL;
955out:
ee756ef7 956 mutex_unlock(dso__lock(dso));
8e67b725 957 return cache;
cdd059d7
JO
958}
959
b86a9d91
AH
960static ssize_t dso_cache__memcpy(struct dso_cache *cache, u64 offset, u8 *data,
961 u64 size, bool out)
cdd059d7
JO
962{
963 u64 cache_offset = offset - cache->offset;
964 u64 cache_size = min(cache->size - cache_offset, size);
965
b86a9d91
AH
966 if (out)
967 memcpy(data, cache->data + cache_offset, cache_size);
968 else
969 memcpy(cache->data + cache_offset, data, cache_size);
cdd059d7
JO
970 return cache_size;
971}
972
ea5db1bd
JO
973static ssize_t file_read(struct dso *dso, struct machine *machine,
974 u64 offset, char *data)
975{
976 ssize_t ret;
977
5ac22c35 978 mutex_lock(dso__data_open_lock());
ea5db1bd
JO
979
980 /*
ee756ef7 981 * dso__data(dso)->fd might be closed if other thread opened another
ea5db1bd
JO
982 * file (dso) due to open file limit (RLIMIT_NOFILE).
983 */
984 try_to_open_dso(dso, machine);
985
ee756ef7
IR
986 if (dso__data(dso)->fd < 0) {
987 dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
ea5db1bd
JO
988 ret = -errno;
989 goto out;
990 }
991
ee756ef7 992 ret = pread(dso__data(dso)->fd, data, DSO__DATA_CACHE_SIZE, offset);
ea5db1bd 993out:
5ac22c35 994 mutex_unlock(dso__data_open_lock());
ea5db1bd
JO
995 return ret;
996}
997
366df726
AH
998static struct dso_cache *dso_cache__populate(struct dso *dso,
999 struct machine *machine,
1000 u64 offset, ssize_t *ret)
cdd059d7 1001{
cacddfe7 1002 u64 cache_offset = offset & DSO__DATA_CACHE_MASK;
cdd059d7 1003 struct dso_cache *cache;
8e67b725 1004 struct dso_cache *old;
cdd059d7 1005
cacddfe7 1006 cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
366df726
AH
1007 if (!cache) {
1008 *ret = -ENOMEM;
1009 return NULL;
1010 }
ef0580ec 1011#ifdef HAVE_LIBBPF_SUPPORT
ee756ef7 1012 if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO)
366df726 1013 *ret = bpf_read(dso, cache_offset, cache->data);
ef0580ec
ACM
1014 else
1015#endif
ee756ef7 1016 if (dso__binary_type(dso) == DSO_BINARY_TYPE__OOL)
789e2419 1017 *ret = DSO__DATA_CACHE_SIZE;
6c398d72 1018 else
366df726 1019 *ret = file_read(dso, machine, cache_offset, cache->data);
6c398d72 1020
366df726
AH
1021 if (*ret <= 0) {
1022 free(cache);
1023 return NULL;
1024 }
33bdedce 1025
366df726
AH
1026 cache->offset = cache_offset;
1027 cache->size = *ret;
cdd059d7 1028
366df726
AH
1029 old = dso_cache__insert(dso, cache);
1030 if (old) {
1031 /* we lose the race */
1032 free(cache);
1033 cache = old;
33bdedce 1034 }
cdd059d7 1035
366df726
AH
1036 return cache;
1037}
cdd059d7 1038
366df726
AH
1039static struct dso_cache *dso_cache__find(struct dso *dso,
1040 struct machine *machine,
1041 u64 offset,
1042 ssize_t *ret)
1043{
1044 struct dso_cache *cache = __dso_cache__find(dso, offset);
1045
1046 return cache ? cache : dso_cache__populate(dso, machine, offset, ret);
cdd059d7
JO
1047}
1048
b86a9d91
AH
1049static ssize_t dso_cache_io(struct dso *dso, struct machine *machine,
1050 u64 offset, u8 *data, ssize_t size, bool out)
cdd059d7
JO
1051{
1052 struct dso_cache *cache;
366df726 1053 ssize_t ret = 0;
cdd059d7 1054
366df726
AH
1055 cache = dso_cache__find(dso, machine, offset, &ret);
1056 if (!cache)
1057 return ret;
1058
b86a9d91 1059 return dso_cache__memcpy(cache, offset, data, size, out);
cdd059d7
JO
1060}
1061
c1f9aa0a
JO
1062/*
1063 * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks
1064 * in the rb_tree. Any read to already cached data is served
b86a9d91 1065 * by cached data. Writes update the cache only, not the backing file.
c1f9aa0a 1066 */
b86a9d91
AH
1067static ssize_t cached_io(struct dso *dso, struct machine *machine,
1068 u64 offset, u8 *data, ssize_t size, bool out)
cdd059d7
JO
1069{
1070 ssize_t r = 0;
1071 u8 *p = data;
1072
1073 do {
1074 ssize_t ret;
1075
b86a9d91 1076 ret = dso_cache_io(dso, machine, offset, p, size, out);
cdd059d7
JO
1077 if (ret < 0)
1078 return ret;
1079
1080 /* Reached EOF, return what we have. */
1081 if (!ret)
1082 break;
1083
1084 BUG_ON(ret > size);
1085
1086 r += ret;
1087 p += ret;
1088 offset += ret;
1089 size -= ret;
1090
1091 } while (size);
1092
1093 return r;
1094}
1095
5523769e 1096static int file_size(struct dso *dso, struct machine *machine)
c3fbd2a6 1097{
33bdedce 1098 int ret = 0;
c3fbd2a6 1099 struct stat st;
6e81c74c 1100 char sbuf[STRERR_BUFSIZE];
c3fbd2a6 1101
5ac22c35 1102 mutex_lock(dso__data_open_lock());
33bdedce
NK
1103
1104 /*
ee756ef7 1105 * dso__data(dso)->fd might be closed if other thread opened another
33bdedce
NK
1106 * file (dso) due to open file limit (RLIMIT_NOFILE).
1107 */
71ff824a
NK
1108 try_to_open_dso(dso, machine);
1109
ee756ef7 1110 if (dso__data(dso)->fd < 0) {
71ff824a 1111 ret = -errno;
ee756ef7 1112 dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
71ff824a 1113 goto out;
c3fbd2a6
JO
1114 }
1115
ee756ef7 1116 if (fstat(dso__data(dso)->fd, &st) < 0) {
33bdedce
NK
1117 ret = -errno;
1118 pr_err("dso cache fstat failed: %s\n",
c8b5f2c9 1119 str_error_r(errno, sbuf, sizeof(sbuf)));
ee756ef7 1120 dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
33bdedce
NK
1121 goto out;
1122 }
ee756ef7 1123 dso__data(dso)->file_size = st.st_size;
33bdedce
NK
1124
1125out:
5ac22c35 1126 mutex_unlock(dso__data_open_lock());
33bdedce 1127 return ret;
c3fbd2a6
JO
1128}
1129
5523769e
JO
1130int dso__data_file_size(struct dso *dso, struct machine *machine)
1131{
ee756ef7 1132 if (dso__data(dso)->file_size)
5523769e
JO
1133 return 0;
1134
ee756ef7 1135 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR)
5523769e 1136 return -1;
ef0580ec 1137#ifdef HAVE_LIBBPF_SUPPORT
ee756ef7 1138 if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO)
6c398d72 1139 return bpf_size(dso);
ef0580ec 1140#endif
5523769e
JO
1141 return file_size(dso, machine);
1142}
1143
6d363459
AH
1144/**
1145 * dso__data_size - Return dso data size
1146 * @dso: dso object
1147 * @machine: machine object
1148 *
1149 * Return: dso data size
1150 */
1151off_t dso__data_size(struct dso *dso, struct machine *machine)
1152{
b5c2161c 1153 if (dso__data_file_size(dso, machine))
6d363459
AH
1154 return -1;
1155
1156 /* For now just estimate dso data size is close to file size */
ee756ef7 1157 return dso__data(dso)->file_size;
6d363459
AH
1158}
1159
b86a9d91
AH
1160static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine,
1161 u64 offset, u8 *data, ssize_t size,
1162 bool out)
c3fbd2a6 1163{
b5c2161c 1164 if (dso__data_file_size(dso, machine))
c3fbd2a6
JO
1165 return -1;
1166
1167 /* Check the offset sanity. */
ee756ef7 1168 if (offset > dso__data(dso)->file_size)
c3fbd2a6
JO
1169 return -1;
1170
1171 if (offset + size < offset)
1172 return -1;
1173
b86a9d91 1174 return cached_io(dso, machine, offset, data, size, out);
c3fbd2a6
JO
1175}
1176
c1f9aa0a
JO
1177/**
1178 * dso__data_read_offset - Read data from dso file offset
1179 * @dso: dso object
1180 * @machine: machine object
1181 * @offset: file offset
1182 * @data: buffer to store data
1183 * @size: size of the @data buffer
1184 *
1185 * External interface to read data from dso file offset. Open
1186 * dso data file and use cached_read to get the data.
1187 */
c3fbd2a6
JO
1188ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
1189 u64 offset, u8 *data, ssize_t size)
1190{
ee756ef7 1191 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR)
c3fbd2a6
JO
1192 return -1;
1193
b86a9d91 1194 return data_read_write_offset(dso, machine, offset, data, size, true);
c3fbd2a6
JO
1195}
1196
afffec6f
IR
1197uint16_t dso__e_machine(struct dso *dso, struct machine *machine)
1198{
1199 uint16_t e_machine = EM_NONE;
1200 int fd;
1201
1202 switch (dso__binary_type(dso)) {
1203 case DSO_BINARY_TYPE__KALLSYMS:
1204 case DSO_BINARY_TYPE__GUEST_KALLSYMS:
1205 case DSO_BINARY_TYPE__VMLINUX:
1206 case DSO_BINARY_TYPE__GUEST_VMLINUX:
1207 case DSO_BINARY_TYPE__GUEST_KMODULE:
1208 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
1209 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
1210 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
1211 case DSO_BINARY_TYPE__KCORE:
1212 case DSO_BINARY_TYPE__GUEST_KCORE:
1213 case DSO_BINARY_TYPE__BPF_PROG_INFO:
1214 case DSO_BINARY_TYPE__BPF_IMAGE:
1215 case DSO_BINARY_TYPE__OOL:
1216 case DSO_BINARY_TYPE__JAVA_JIT:
1217 return EM_HOST;
1218 case DSO_BINARY_TYPE__DEBUGLINK:
1219 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
1220 case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
1221 case DSO_BINARY_TYPE__GNU_DEBUGDATA:
1222 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
1223 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
1224 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
1225 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
1226 case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
1227 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
1228 break;
1229 case DSO_BINARY_TYPE__NOT_FOUND:
1230 default:
1231 return EM_NONE;
1232 }
1233
1234 mutex_lock(dso__data_open_lock());
1235
1236 /*
1237 * dso__data(dso)->fd might be closed if other thread opened another
1238 * file (dso) due to open file limit (RLIMIT_NOFILE).
1239 */
1240 try_to_open_dso(dso, machine);
1241 fd = dso__data(dso)->fd;
1242 if (fd >= 0) {
1243 _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset");
1244 _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset");
1245 if (dso__needs_swap(dso) == DSO_SWAP__UNSET) {
1246 unsigned char eidata;
1247
1248 if (pread(fd, &eidata, sizeof(eidata), EI_DATA) == sizeof(eidata))
1249 dso__swap_init(dso, eidata);
1250 }
1251 if (dso__needs_swap(dso) != DSO_SWAP__UNSET &&
1252 pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine))
1253 e_machine = DSO__SWAP(dso, uint16_t, e_machine);
1254 }
1255 mutex_unlock(dso__data_open_lock());
1256 return e_machine;
1257}
1258
c1f9aa0a
JO
1259/**
1260 * dso__data_read_addr - Read data from dso address
1261 * @dso: dso object
1262 * @machine: machine object
1263 * @add: virtual memory address
1264 * @data: buffer to store data
1265 * @size: size of the @data buffer
1266 *
1267 * External interface to read data from dso address.
1268 */
cdd059d7
JO
1269ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
1270 struct machine *machine, u64 addr,
1271 u8 *data, ssize_t size)
1272{
78a1f7cd
IR
1273 u64 offset = map__map_ip(map, addr);
1274
cdd059d7
JO
1275 return dso__data_read_offset(dso, machine, offset, data, size);
1276}
1277
b86a9d91
AH
1278/**
1279 * dso__data_write_cache_offs - Write data to dso data cache at file offset
1280 * @dso: dso object
1281 * @machine: machine object
1282 * @offset: file offset
1283 * @data: buffer to write
1284 * @size: size of the @data buffer
1285 *
1286 * Write into the dso file data cache, but do not change the file itself.
1287 */
1288ssize_t dso__data_write_cache_offs(struct dso *dso, struct machine *machine,
1289 u64 offset, const u8 *data_in, ssize_t size)
1290{
1291 u8 *data = (u8 *)data_in; /* cast away const to use same fns for r/w */
1292
ee756ef7 1293 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR)
b86a9d91
AH
1294 return -1;
1295
1296 return data_read_write_offset(dso, machine, offset, data, size, false);
1297}
1298
1299/**
1300 * dso__data_write_cache_addr - Write data to dso data cache at dso address
1301 * @dso: dso object
1302 * @machine: machine object
1303 * @add: virtual memory address
1304 * @data: buffer to write
1305 * @size: size of the @data buffer
1306 *
1307 * External interface to write into the dso file data cache, but do not change
1308 * the file itself.
1309 */
1310ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
1311 struct machine *machine, u64 addr,
1312 const u8 *data, ssize_t size)
1313{
78a1f7cd
IR
1314 u64 offset = map__map_ip(map, addr);
1315
b86a9d91
AH
1316 return dso__data_write_cache_offs(dso, machine, offset, data, size);
1317}
1318
cdd059d7
JO
1319struct map *dso__new_map(const char *name)
1320{
1321 struct map *map = NULL;
1322 struct dso *dso = dso__new(name);
1323
581e295a 1324 if (dso) {
3183f8ca 1325 map = map__new2(0, dso);
581e295a
RM
1326 dso__put(dso);
1327 }
cdd059d7
JO
1328
1329 return map;
1330}
1331
459ce518
ACM
1332struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
1333 const char *short_name, int dso_type)
cdd059d7
JO
1334{
1335 /*
1336 * The kernel dso could be created by build_id processing.
1337 */
aa7cc2ae 1338 struct dso *dso = machine__findnew_dso(machine, name);
cdd059d7
JO
1339
1340 /*
1341 * We need to run this in all cases, since during the build_id
1342 * processing we had no idea this was the kernel dso.
1343 */
1344 if (dso != NULL) {
58a98c9c 1345 dso__set_short_name(dso, short_name, false);
ee756ef7 1346 dso__set_kernel(dso, dso_type);
cdd059d7
JO
1347 }
1348
1349 return dso;
1350}
1351
ab2c742d
IR
1352static void __dso__set_long_name_id(struct dso *dso, const char *name, bool name_allocated)
1353{
1354 if (dso__long_name_allocated(dso))
1355 free((char *)dso__long_name(dso));
1356
1357 RC_CHK_ACCESS(dso)->long_name = name;
1358 RC_CHK_ACCESS(dso)->long_name_len = strlen(name);
1359 dso__set_long_name_allocated(dso, name_allocated);
1360}
1361
3f4ac23a 1362static void dso__set_long_name_id(struct dso *dso, const char *name, bool name_allocated)
cdd059d7 1363{
ee756ef7 1364 struct dsos *dsos = dso__dsos(dso);
e266a753 1365
cdd059d7
JO
1366 if (name == NULL)
1367 return;
7e155d4d 1368
3f4ac23a 1369 if (dsos) {
e266a753 1370 /*
3f4ac23a
IR
1371 * Need to avoid re-sorting the dsos breaking by non-atomically
1372 * renaming the dso.
e266a753 1373 */
3f4ac23a 1374 down_write(&dsos->lock);
ab2c742d 1375 __dso__set_long_name_id(dso, name, name_allocated);
3f4ac23a
IR
1376 dsos->sorted = false;
1377 up_write(&dsos->lock);
ab2c742d
IR
1378 } else {
1379 __dso__set_long_name_id(dso, name, name_allocated);
3f4ac23a 1380 }
0e3149f8
ACM
1381}
1382
3f4ac23a 1383static int __dso_id__cmp(const struct dso_id *a, const struct dso_id *b)
1d6eff93
IR
1384{
1385 if (a->maj > b->maj) return -1;
1386 if (a->maj < b->maj) return 1;
1387
1388 if (a->min > b->min) return -1;
1389 if (a->min < b->min) return 1;
1390
1391 if (a->ino > b->ino) return -1;
1392 if (a->ino < b->ino) return 1;
1393
1394 /*
1395 * Synthesized MMAP events have zero ino_generation, avoid comparing
1396 * them with MMAP events with actual ino_generation.
1397 *
1398 * I found it harmful because the mismatch resulted in a new
1399 * dso that did not have a build ID whereas the original dso did have a
1400 * build ID. The build ID was essential because the object was not found
1401 * otherwise. - Adrian
1402 */
1403 if (a->ino_generation && b->ino_generation) {
1404 if (a->ino_generation > b->ino_generation) return -1;
1405 if (a->ino_generation < b->ino_generation) return 1;
1406 }
1407
1408 return 0;
1409}
1410
3f4ac23a 1411bool dso_id__empty(const struct dso_id *id)
1d6eff93
IR
1412{
1413 if (!id)
1414 return true;
1415
1416 return !id->maj && !id->min && !id->ino && !id->ino_generation;
1417}
1418
e4bb4caa 1419void __dso__inject_id(struct dso *dso, const struct dso_id *id)
1d6eff93 1420{
ee756ef7
IR
1421 struct dsos *dsos = dso__dsos(dso);
1422 struct dso_id *dso_id = dso__id(dso);
3f4ac23a
IR
1423
1424 /* dsos write lock held by caller. */
1425
ee756ef7
IR
1426 dso_id->maj = id->maj;
1427 dso_id->min = id->min;
1428 dso_id->ino = id->ino;
1429 dso_id->ino_generation = id->ino_generation;
3f4ac23a
IR
1430
1431 if (dsos)
1432 dsos->sorted = false;
1d6eff93
IR
1433}
1434
3f4ac23a 1435int dso_id__cmp(const struct dso_id *a, const struct dso_id *b)
1d6eff93
IR
1436{
1437 /*
1438 * The second is always dso->id, so zeroes if not set, assume passing
1439 * NULL for a means a zeroed id
1440 */
1441 if (dso_id__empty(a) || dso_id__empty(b))
1442 return 0;
1443
1444 return __dso_id__cmp(a, b);
1445}
1446
1447int dso__cmp_id(struct dso *a, struct dso *b)
1448{
ee756ef7 1449 return __dso_id__cmp(dso__id(a), dso__id(b));
1d6eff93
IR
1450}
1451
0e3149f8
ACM
1452void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
1453{
3f4ac23a 1454 dso__set_long_name_id(dso, name, name_allocated);
cdd059d7
JO
1455}
1456
ab2c742d
IR
1457static void __dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
1458{
1459 if (dso__short_name_allocated(dso))
1460 free((char *)dso__short_name(dso));
1461
1462 RC_CHK_ACCESS(dso)->short_name = name;
1463 RC_CHK_ACCESS(dso)->short_name_len = strlen(name);
1464 dso__set_short_name_allocated(dso, name_allocated);
1465}
1466
58a98c9c 1467void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
cdd059d7 1468{
ee756ef7 1469 struct dsos *dsos = dso__dsos(dso);
3f4ac23a 1470
cdd059d7
JO
1471 if (name == NULL)
1472 return;
58a98c9c 1473
3f4ac23a
IR
1474 if (dsos) {
1475 /*
1476 * Need to avoid re-sorting the dsos breaking by non-atomically
1477 * renaming the dso.
1478 */
1479 down_write(&dsos->lock);
ab2c742d 1480 __dso__set_short_name(dso, name, name_allocated);
3f4ac23a
IR
1481 dsos->sorted = false;
1482 up_write(&dsos->lock);
ab2c742d
IR
1483 } else {
1484 __dso__set_short_name(dso, name, name_allocated);
3f4ac23a 1485 }
cdd059d7
JO
1486}
1487
cdd059d7
JO
1488int dso__name_len(const struct dso *dso)
1489{
1490 if (!dso)
1491 return strlen("[unknown]");
bb963e16 1492 if (verbose > 0)
ee756ef7 1493 return dso__long_name_len(dso);
cdd059d7 1494
ee756ef7 1495 return dso__short_name_len(dso);
cdd059d7
JO
1496}
1497
3183f8ca 1498bool dso__loaded(const struct dso *dso)
cdd059d7 1499{
ee756ef7 1500 return RC_CHK_ACCESS(dso)->loaded;
cdd059d7
JO
1501}
1502
3183f8ca 1503bool dso__sorted_by_name(const struct dso *dso)
cdd059d7 1504{
ee756ef7 1505 return RC_CHK_ACCESS(dso)->sorted_by_name;
cdd059d7
JO
1506}
1507
3183f8ca 1508void dso__set_sorted_by_name(struct dso *dso)
cdd059d7 1509{
ee756ef7 1510 RC_CHK_ACCESS(dso)->sorted_by_name = true;
cdd059d7
JO
1511}
1512
e4bb4caa 1513struct dso *dso__new_id(const char *name, const struct dso_id *id)
cdd059d7 1514{
ee756ef7
IR
1515 RC_STRUCT(dso) *dso = zalloc(sizeof(*dso) + strlen(name) + 1);
1516 struct dso *res;
1517 struct dso_data *data;
cdd059d7 1518
ee756ef7
IR
1519 if (!dso)
1520 return NULL;
1521
1522 if (ADD_RC_CHK(res, dso)) {
cdd059d7 1523 strcpy(dso->name, name);
0e3149f8
ACM
1524 if (id)
1525 dso->id = *id;
ee756ef7
IR
1526 dso__set_long_name_id(res, dso->name, false);
1527 dso__set_short_name(res, dso->name, false);
259dce91
IR
1528 dso->symbols = RB_ROOT_CACHED;
1529 dso->symbol_names = NULL;
1530 dso->symbol_names_len = 0;
55ecd631
DB
1531 dso->inlined_nodes = RB_ROOT_CACHED;
1532 dso->srclines = RB_ROOT_CACHED;
fc044c53 1533 dso->data_types = RB_ROOT;
55ee3d00 1534 dso->global_vars = RB_ROOT;
53fa8eaa 1535 dso->data.fd = -1;
c27697d6 1536 dso->data.status = DSO_DATA_STATUS_UNKNOWN;
cdd059d7 1537 dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
5f70619d 1538 dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
c6d8f2a4 1539 dso->is_64_bit = (sizeof(void *) == 8);
cdd059d7 1540 dso->loaded = 0;
0131c4ec 1541 dso->rel = 0;
cdd059d7
JO
1542 dso->sorted_by_name = 0;
1543 dso->has_build_id = 0;
2cc9d0ef 1544 dso->has_srcline = 1;
906049c8 1545 dso->a2l_fails = 1;
1c695c88 1546 dso->kernel = DSO_SPACE__USER;
6be5d828 1547 dso->is_kmod = 0;
cdd059d7 1548 dso->needs_swap = DSO_SWAP__UNSET;
2af52475 1549 dso->comp = COMP_ID__NONE;
d9a0d6b8 1550 mutex_init(&dso->lock);
7100810a 1551 refcount_set(&dso->refcnt, 1);
ee756ef7
IR
1552 data = &dso->data;
1553 data->cache = RB_ROOT;
1554 data->fd = -1;
1555 data->status = DSO_DATA_STATUS_UNKNOWN;
1556 INIT_LIST_HEAD(&data->open_entry);
37862d6f 1557#ifdef REFCNT_CHECKING
ee756ef7 1558 data->dso = NULL; /* Set when on the open_entry list. */
37862d6f 1559#endif
cdd059d7 1560 }
ee756ef7 1561 return res;
cdd059d7
JO
1562}
1563
0e3149f8
ACM
1564struct dso *dso__new(const char *name)
1565{
1566 return dso__new_id(name, NULL);
1567}
1568
cdd059d7
JO
1569void dso__delete(struct dso *dso)
1570{
ee756ef7
IR
1571 if (dso__dsos(dso))
1572 pr_err("DSO %s is still in rbtree when being deleted!\n", dso__long_name(dso));
11ea2515
MW
1573
1574 /* free inlines first, as they reference symbols */
ee756ef7
IR
1575 inlines__tree_delete(&RC_CHK_ACCESS(dso)->inlined_nodes);
1576 srcline__tree_delete(&RC_CHK_ACCESS(dso)->srclines);
1577 symbols__delete(&RC_CHK_ACCESS(dso)->symbols);
1578 RC_CHK_ACCESS(dso)->symbol_names_len = 0;
1579 zfree(&RC_CHK_ACCESS(dso)->symbol_names);
1580 annotated_data_type__tree_delete(dso__data_types(dso));
1581 global_var_type__tree_delete(dso__global_vars(dso));
1582
1583 if (RC_CHK_ACCESS(dso)->short_name_allocated) {
1584 zfree((char **)&RC_CHK_ACCESS(dso)->short_name);
1585 RC_CHK_ACCESS(dso)->short_name_allocated = false;
ee021d42
ACM
1586 }
1587
ee756ef7
IR
1588 if (RC_CHK_ACCESS(dso)->long_name_allocated) {
1589 zfree((char **)&RC_CHK_ACCESS(dso)->long_name);
1590 RC_CHK_ACCESS(dso)->long_name_allocated = false;
ee021d42
ACM
1591 }
1592
53fa8eaa 1593 dso__data_close(dso);
ee756ef7 1594 auxtrace_cache__free(RC_CHK_ACCESS(dso)->auxtrace_cache);
8e67b725 1595 dso_cache__free(dso);
454ff00f 1596 dso__free_a2l(dso);
92717bc0 1597 dso__free_symsrc_filename(dso);
ee756ef7
IR
1598 nsinfo__zput(RC_CHK_ACCESS(dso)->nsinfo);
1599 mutex_destroy(dso__lock(dso));
1600 RC_CHK_FREE(dso);
cdd059d7
JO
1601}
1602
d3a7c489
ACM
1603struct dso *dso__get(struct dso *dso)
1604{
ee756ef7
IR
1605 struct dso *result;
1606
1607 if (RC_CHK_GET(result, dso))
1608 refcount_inc(&RC_CHK_ACCESS(dso)->refcnt);
1609
1610 return result;
d3a7c489
ACM
1611}
1612
1613void dso__put(struct dso *dso)
1614{
ee756ef7 1615 if (dso && refcount_dec_and_test(&RC_CHK_ACCESS(dso)->refcnt))
d3a7c489 1616 dso__delete(dso);
ee756ef7
IR
1617 else
1618 RC_CHK_PUT(dso);
d3a7c489
ACM
1619}
1620
afffec6f
IR
1621int dso__swap_init(struct dso *dso, unsigned char eidata)
1622{
1623 static unsigned int const endian = 1;
1624
1625 dso__set_needs_swap(dso, DSO_SWAP__NO);
1626
1627 switch (eidata) {
1628 case ELFDATA2LSB:
1629 /* We are big endian, DSO is little endian. */
1630 if (*(unsigned char const *)&endian != 1)
1631 dso__set_needs_swap(dso, DSO_SWAP__YES);
1632 break;
1633
1634 case ELFDATA2MSB:
1635 /* We are little endian, DSO is big endian. */
1636 if (*(unsigned char const *)&endian != 0)
1637 dso__set_needs_swap(dso, DSO_SWAP__YES);
1638 break;
1639
1640 default:
1641 pr_err("unrecognized DSO data encoding %d\n", eidata);
1642 return -EINVAL;
1643 }
1644
1645 return 0;
1646}
1647
8dfdf440 1648void dso__set_build_id(struct dso *dso, struct build_id *bid)
cdd059d7 1649{
ee756ef7
IR
1650 RC_CHK_ACCESS(dso)->bid = *bid;
1651 RC_CHK_ACCESS(dso)->has_build_id = 1;
cdd059d7
JO
1652}
1653
39be8d01 1654bool dso__build_id_equal(const struct dso *dso, struct build_id *bid)
cdd059d7 1655{
ee756ef7
IR
1656 const struct build_id *dso_bid = dso__bid_const(dso);
1657
1658 if (dso_bid->size > bid->size && dso_bid->size == BUILD_ID_SIZE) {
4a86d414
NK
1659 /*
1660 * For the backward compatibility, it allows a build-id has
1661 * trailing zeros.
1662 */
ee756ef7
IR
1663 return !memcmp(dso_bid->data, bid->data, bid->size) &&
1664 !memchr_inv(&dso_bid->data[bid->size], 0,
1665 dso_bid->size - bid->size);
4a86d414
NK
1666 }
1667
ee756ef7
IR
1668 return dso_bid->size == bid->size &&
1669 memcmp(dso_bid->data, bid->data, dso_bid->size) == 0;
cdd059d7
JO
1670}
1671
1672void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
1673{
1674 char path[PATH_MAX];
1675
1676 if (machine__is_default_guest(machine))
1677 return;
1678 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
ee756ef7
IR
1679 if (sysfs__read_build_id(path, dso__bid(dso)) == 0)
1680 dso__set_has_build_id(dso);
cdd059d7
JO
1681}
1682
1683int dso__kernel_module_get_build_id(struct dso *dso,
1684 const char *root_dir)
1685{
1686 char filename[PATH_MAX];
1687 /*
1688 * kernel module short names are of the form "[module]" and
1689 * we need just "module" here.
1690 */
ee756ef7 1691 const char *name = dso__short_name(dso) + 1;
cdd059d7
JO
1692
1693 snprintf(filename, sizeof(filename),
1694 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1695 root_dir, (int)strlen(name) - 1, name);
1696
ee756ef7
IR
1697 if (sysfs__read_build_id(filename, dso__bid(dso)) == 0)
1698 dso__set_has_build_id(dso);
cdd059d7
JO
1699
1700 return 0;
1701}
1702
e9ad9438 1703static size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
cdd059d7 1704{
b5d8bbe8 1705 char sbuild_id[SBUILD_ID_SIZE];
cdd059d7 1706
ee756ef7 1707 build_id__sprintf(dso__bid(dso), sbuild_id);
cdd059d7
JO
1708 return fprintf(fp, "%s", sbuild_id);
1709}
1710
3183f8ca 1711size_t dso__fprintf(struct dso *dso, FILE *fp)
cdd059d7
JO
1712{
1713 struct rb_node *nd;
ee756ef7 1714 size_t ret = fprintf(fp, "dso: %s (", dso__short_name(dso));
cdd059d7 1715
ee756ef7
IR
1716 if (dso__short_name(dso) != dso__long_name(dso))
1717 ret += fprintf(fp, "%s, ", dso__long_name(dso));
3183f8ca 1718 ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
cdd059d7
JO
1719 ret += dso__fprintf_buildid(dso, fp);
1720 ret += fprintf(fp, ")\n");
ee756ef7 1721 for (nd = rb_first_cached(dso__symbols(dso)); nd; nd = rb_next(nd)) {
cdd059d7
JO
1722 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
1723 ret += symbol__fprintf(pos, fp);
1724 }
1725
1726 return ret;
1727}
2b5b8bb2
AH
1728
1729enum dso_type dso__type(struct dso *dso, struct machine *machine)
1730{
5ac22c35 1731 int fd = -1;
4bb11d01 1732 enum dso_type type = DSO__TYPE_UNKNOWN;
2b5b8bb2 1733
5ac22c35 1734 if (dso__data_get_fd(dso, machine, &fd)) {
4bb11d01
NK
1735 type = dso__type_fd(fd);
1736 dso__data_put_fd(dso);
1737 }
2b5b8bb2 1738
4bb11d01 1739 return type;
2b5b8bb2 1740}
18425f13
ACM
1741
1742int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
1743{
ee756ef7 1744 int idx, errnum = *dso__load_errno(dso);
18425f13
ACM
1745 /*
1746 * This must have a same ordering as the enum dso_load_errno.
1747 */
1748 static const char *dso_load__error_str[] = {
1749 "Internal tools/perf/ library error",
1750 "Invalid ELF file",
1751 "Can not read build id",
1752 "Mismatching build id",
1753 "Decompression failure",
1754 };
1755
1756 BUG_ON(buflen == 0);
1757
1758 if (errnum >= 0) {
c8b5f2c9 1759 const char *err = str_error_r(errnum, buf, buflen);
18425f13
ACM
1760
1761 if (err != buf)
1762 scnprintf(buf, buflen, "%s", err);
1763
1764 return 0;
1765 }
1766
1767 if (errnum < __DSO_LOAD_ERRNO__START || errnum >= __DSO_LOAD_ERRNO__END)
1768 return -1;
1769
1770 idx = errnum - __DSO_LOAD_ERRNO__START;
1771 scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
1772 return 0;
1773}
b0979f00
AR
1774
1775bool perf_pid_map_tid(const char *dso_name, int *tid)
1776{
1777 return sscanf(dso_name, "/tmp/perf-%d.map", tid) == 1;
1778}
1779
1780bool is_perf_pid_map_name(const char *dso_name)
1781{
1782 int tid;
1783
1784 return perf_pid_map_tid(dso_name, &tid);
1785}