blob: cdfc2e5f55f513b063841a7dba636458df7f5f81 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Jiri Olsabda6ee42014-04-30 15:25:10 +02002#include <asm/bug.h>
Arnaldo Carvalho de Melo877a7a12017-04-17 11:39:06 -03003#include <linux/kernel.h>
Jiri Olsac6580452014-04-30 15:47:27 +02004#include <sys/time.h>
5#include <sys/resource.h>
Arnaldo Carvalho de Melo7a8ef4c2017-04-19 20:57:47 -03006#include <sys/types.h>
7#include <sys/stat.h>
8#include <unistd.h>
Arnaldo Carvalho de Meloa43783a2017-04-18 10:46:11 -03009#include <errno.h>
Arnaldo Carvalho de Meloc23c2a02017-09-11 10:50:26 -030010#include <fcntl.h>
Arnaldo Carvalho de Melo611f0af2017-04-19 16:29:38 -030011#include "compress.h"
Arnaldo Carvalho de Melo9a3993d2017-04-18 11:33:48 -030012#include "path.h"
Jiri Olsacdd059d2012-10-27 23:18:32 +020013#include "symbol.h"
Milian Wolff11ea2512017-10-09 22:32:59 +020014#include "srcline.h"
Jiri Olsacdd059d2012-10-27 23:18:32 +020015#include "dso.h"
Arnaldo Carvalho de Melo69d25912012-11-09 11:32:52 -030016#include "machine.h"
Adrian Huntercfe91742015-04-09 18:53:55 +030017#include "auxtrace.h"
Jiri Olsacdd059d2012-10-27 23:18:32 +020018#include "util.h"
19#include "debug.h"
Arnaldo Carvalho de Meloa0675582017-04-17 16:51:59 -030020#include "string2.h"
He Kuang6ae98ba2016-05-12 08:43:11 +000021#include "vdso.h"
Jiri Olsacdd059d2012-10-27 23:18:32 +020022
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +010023static const char * const debuglink_paths[] = {
24 "%.0s%s",
25 "%s/%s",
26 "%s/.debug/%s",
27 "/usr/lib/debug%s/%s"
28};
29
Jiri Olsacdd059d2012-10-27 23:18:32 +020030char dso__symtab_origin(const struct dso *dso)
31{
32 static const char origin[] = {
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +020033 [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',
Krister Johansend2396992017-07-05 18:48:13 -070038 [DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO] = 'D',
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +020039 [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',
Namhyung Kimc00c48f2014-11-04 10:14:27 +090045 [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP] = 'm',
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +020046 [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
47 [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
Namhyung Kimc00c48f2014-11-04 10:14:27 +090048 [DSO_BINARY_TYPE__GUEST_KMODULE_COMP] = 'M',
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +020049 [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
Jiri Olsacdd059d2012-10-27 23:18:32 +020050 };
51
52 if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
53 return '!';
54 return origin[dso->symtab_type];
55}
56
Arnaldo Carvalho de Meloee4e9622013-12-16 17:03:18 -030057int dso__read_binary_type_filename(const struct dso *dso,
58 enum dso_binary_type type,
59 char *root_dir, char *filename, size_t size)
Jiri Olsacdd059d2012-10-27 23:18:32 +020060{
Masami Hiramatsub5d8bbe2016-05-11 22:51:59 +090061 char build_id_hex[SBUILD_ID_SIZE];
Jiri Olsacdd059d2012-10-27 23:18:32 +020062 int ret = 0;
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -030063 size_t len;
Jiri Olsacdd059d2012-10-27 23:18:32 +020064
65 switch (type) {
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +010066 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;
Jiri Olsacdd059d2012-10-27 23:18:32 +020072
Victor Kamenskydc6254c2015-01-26 22:34:02 -080073 len = __symbol__join_symfs(filename, size, dso->long_name);
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +010074 last_slash = filename + len;
75 while (last_slash != filename && *last_slash != '/')
76 last_slash--;
Jiri Olsa40356722016-01-20 12:56:32 +010077
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +010078 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)
Jiri Olsa40356722016-01-20 12:56:32 +010088 break;
89
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +010090 /* 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 }
Jiri Olsacdd059d2012-10-27 23:18:32 +020099 }
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +0100100
Jiri Olsacdd059d2012-10-27 23:18:32 +0200101 break;
Matija Glavinic Pecotic9343e452017-01-17 15:50:35 +0100102 }
Jiri Olsacdd059d2012-10-27 23:18:32 +0200103 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
Krister Johansend2396992017-07-05 18:48:13 -0700104 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)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200110 ret = -1;
111 break;
112
113 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300114 len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
115 snprintf(filename + len, size - len, "%s.debug", dso->long_name);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200116 break;
117
118 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300119 len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
120 snprintf(filename + len, size - len, "%s", dso->long_name);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200121 break;
122
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +0200123 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
124 {
Arnaldo Carvalho de Melobf4414a2013-12-10 15:19:23 -0300125 const char *last_slash;
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +0200126 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
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300132 len = __symbol__join_symfs(filename, size, "");
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +0200133 dir_size = last_slash - dso->long_name + 2;
134 if (dir_size > (size - len)) {
135 ret = -1;
136 break;
137 }
Arnaldo Carvalho de Melo7d2a5122013-12-10 16:02:50 -0300138 len += scnprintf(filename + len, dir_size, "%s", dso->long_name);
139 len += scnprintf(filename + len , size - len, ".debug%s",
Ricardo Ribalda Delgado9cd00942013-09-18 15:56:14 +0200140 last_slash);
141 break;
142 }
143
Jiri Olsacdd059d2012-10-27 23:18:32 +0200144 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);
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300153 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);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200156 break;
157
Adrian Hunter39b12f782013-08-07 14:38:47 +0300158 case DSO_BINARY_TYPE__VMLINUX:
159 case DSO_BINARY_TYPE__GUEST_VMLINUX:
Jiri Olsacdd059d2012-10-27 23:18:32 +0200160 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300161 __symbol__join_symfs(filename, size, dso->long_name);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200162 break;
163
164 case DSO_BINARY_TYPE__GUEST_KMODULE:
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900165 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300166 path__join3(filename, size, symbol_conf.symfs,
167 root_dir, dso->long_name);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200168 break;
169
170 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900171 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
Arnaldo Carvalho de Melo972f3932014-07-29 10:21:58 -0300172 __symbol__join_symfs(filename, size, dso->long_name);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200173 break;
174
Adrian Hunter8e0cf962013-08-07 14:38:51 +0300175 case DSO_BINARY_TYPE__KCORE:
176 case DSO_BINARY_TYPE__GUEST_KCORE:
Arnaldo Carvalho de Melo7d2a5122013-12-10 16:02:50 -0300177 snprintf(filename, size, "%s", dso->long_name);
Adrian Hunter8e0cf962013-08-07 14:38:51 +0300178 break;
179
Jiri Olsacdd059d2012-10-27 23:18:32 +0200180 default:
181 case DSO_BINARY_TYPE__KALLSYMS:
Jiri Olsacdd059d2012-10-27 23:18:32 +0200182 case DSO_BINARY_TYPE__GUEST_KALLSYMS:
Jiri Olsacdd059d2012-10-27 23:18:32 +0200183 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
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900192static const struct {
193 const char *fmt;
194 int (*decompress)(const char *input, int output);
195} compressions[] = {
Namhyung Kime92ce122014-10-31 16:51:38 +0900196#ifdef HAVE_ZLIB_SUPPORT
197 { "gz", gzip_decompress_to_file },
198#endif
Jiri Olsa80a32e5b2015-01-29 13:29:39 +0100199#ifdef HAVE_LZMA_SUPPORT
200 { "xz", lzma_decompress_to_file },
201#endif
Namhyung Kime92ce122014-10-31 16:51:38 +0900202 { NULL, NULL },
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900203};
204
205bool 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
Wang Nan1f121b02015-06-03 08:52:21 +0000216bool is_kernel_module(const char *pathname, int cpumode)
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900217{
Jiri Olsa8dee9ff112015-02-12 15:56:21 +0100218 struct kmod_path m;
Wang Nan1f121b02015-06-03 08:52:21 +0000219 int mode = cpumode & PERF_RECORD_MISC_CPUMODE_MASK;
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900220
Wang Nan1f121b02015-06-03 08:52:21 +0000221 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 }
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900238
Jiri Olsa8dee9ff112015-02-12 15:56:21 +0100239 return m.kmod;
Namhyung Kimc00c48f2014-11-04 10:14:27 +0900240}
241
242bool 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
254bool 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
Namhyung Kim42b3fa62017-06-08 16:31:03 +0900260static 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
286out:
287 free(m.ext);
288 return fd;
289}
290
291int 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
301int 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
Jiri Olsaeba51022014-04-30 15:00:59 +0200318/*
Jiri Olsa3c8a67f2015-02-05 15:40:25 +0100319 * 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 */
334int __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, '.');
Wang Nan1f121b02015-06-03 08:52:21 +0000339 bool is_simple_name = false;
Jiri Olsa3c8a67f2015-02-05 15:40:25 +0100340
341 memset(m, 0x0, sizeof(*m));
342 name = name ? name + 1 : path;
343
Wang Nan1f121b02015-06-03 08:52:21 +0000344 /*
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, "[vsyscall]", 10) == 0)) {
358 m->kmod = false;
359
360 } else
361 m->kmod = true;
362 }
363
Jiri Olsa3c8a67f2015-02-05 15:40:25 +0100364 /* No extension, just return name. */
Wang Nan1f121b02015-06-03 08:52:21 +0000365 if ((ext == NULL) || is_simple_name) {
Jiri Olsa3c8a67f2015-02-05 15:40:25 +0100366 if (alloc_name) {
367 m->name = strdup(name);
368 return m->name ? 0 : -ENOMEM;
369 }
370 return 0;
371 }
372
373 if (is_supported_compression(ext + 1)) {
374 m->comp = true;
375 ext -= 3;
376 }
377
378 /* Check .ko extension only if there's enough name left. */
379 if (ext > name)
380 m->kmod = !strncmp(ext, ".ko", 3);
381
382 if (alloc_name) {
383 if (m->kmod) {
384 if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
385 return -ENOMEM;
386 } else {
387 if (asprintf(&m->name, "%s", name) == -1)
388 return -ENOMEM;
389 }
390
391 strxfrchar(m->name, '-', '_');
392 }
393
394 if (alloc_ext && m->comp) {
395 m->ext = strdup(ext + 4);
396 if (!m->ext) {
397 free((void *) m->name);
398 return -ENOMEM;
399 }
400 }
401
402 return 0;
403}
404
Namhyung Kim6b335e82017-05-31 21:01:04 +0900405void dso__set_module_info(struct dso *dso, struct kmod_path *m,
406 struct machine *machine)
407{
408 if (machine__is_host(machine))
409 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
410 else
411 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
412
413 /* _KMODULE_COMP should be next to _KMODULE */
414 if (m->kmod && m->comp)
415 dso->symtab_type++;
416
417 dso__set_short_name(dso, strdup(m->name), true);
418}
419
Jiri Olsa3c8a67f2015-02-05 15:40:25 +0100420/*
Jiri Olsabda6ee42014-04-30 15:25:10 +0200421 * Global list of open DSOs and the counter.
Jiri Olsaeba51022014-04-30 15:00:59 +0200422 */
423static LIST_HEAD(dso__data_open);
Jiri Olsabda6ee42014-04-30 15:25:10 +0200424static long dso__data_open_cnt;
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900425static pthread_mutex_t dso__data_open_lock = PTHREAD_MUTEX_INITIALIZER;
Jiri Olsaeba51022014-04-30 15:00:59 +0200426
427static void dso__list_add(struct dso *dso)
428{
429 list_add_tail(&dso->data.open_entry, &dso__data_open);
Jiri Olsabda6ee42014-04-30 15:25:10 +0200430 dso__data_open_cnt++;
Jiri Olsaeba51022014-04-30 15:00:59 +0200431}
432
433static void dso__list_del(struct dso *dso)
434{
435 list_del(&dso->data.open_entry);
Jiri Olsabda6ee42014-04-30 15:25:10 +0200436 WARN_ONCE(dso__data_open_cnt <= 0,
437 "DSO data fd counter out of bounds.");
438 dso__data_open_cnt--;
Jiri Olsaeba51022014-04-30 15:00:59 +0200439}
440
Jiri Olsaa08cae02014-05-07 21:35:02 +0200441static void close_first_dso(void);
442
443static int do_open(char *name)
444{
445 int fd;
Masami Hiramatsu6e81c742014-08-14 02:22:36 +0000446 char sbuf[STRERR_BUFSIZE];
Jiri Olsaa08cae02014-05-07 21:35:02 +0200447
448 do {
Wang YanQing4c0d8d272018-01-15 13:04:48 +0800449 fd = open(name, O_RDONLY|O_CLOEXEC);
Jiri Olsaa08cae02014-05-07 21:35:02 +0200450 if (fd >= 0)
451 return fd;
452
Namhyung Kima3c0cc22015-01-30 11:33:29 +0900453 pr_debug("dso open failed: %s\n",
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300454 str_error_r(errno, sbuf, sizeof(sbuf)));
Jiri Olsaa08cae02014-05-07 21:35:02 +0200455 if (!dso__data_open_cnt || errno != EMFILE)
456 break;
457
458 close_first_dso();
459 } while (1);
460
461 return -1;
462}
463
Jiri Olsaeba51022014-04-30 15:00:59 +0200464static int __open_dso(struct dso *dso, struct machine *machine)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200465{
Namhyung Kim8ba29ad2017-06-08 16:31:06 +0900466 int fd = -EINVAL;
Arnaldo Carvalho de Meloee4e9622013-12-16 17:03:18 -0300467 char *root_dir = (char *)"";
468 char *name = malloc(PATH_MAX);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200469
Jiri Olsacdd059d2012-10-27 23:18:32 +0200470 if (!name)
471 return -ENOMEM;
472
473 if (machine)
474 root_dir = machine->root_dir;
475
Arnaldo Carvalho de Melo5f706192013-12-17 16:14:07 -0300476 if (dso__read_binary_type_filename(dso, dso->binary_type,
Namhyung Kim8ba29ad2017-06-08 16:31:06 +0900477 root_dir, name, PATH_MAX))
478 goto out;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200479
Namhyung Kim8ba29ad2017-06-08 16:31:06 +0900480 if (!is_regular_file(name))
481 goto out;
Jiri Olsa3c028a02016-09-20 18:12:45 +0200482
Namhyung Kim1d6b3c92017-06-08 16:31:05 +0900483 if (dso__needs_decompress(dso)) {
484 char newpath[KMOD_DECOMP_LEN];
485 size_t len = sizeof(newpath);
486
487 if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) {
Namhyung Kim8ba29ad2017-06-08 16:31:06 +0900488 fd = -dso->load_errno;
489 goto out;
Namhyung Kim1d6b3c92017-06-08 16:31:05 +0900490 }
491
492 strcpy(name, newpath);
493 }
494
Jiri Olsaa08cae02014-05-07 21:35:02 +0200495 fd = do_open(name);
Namhyung Kim1d6b3c92017-06-08 16:31:05 +0900496
497 if (dso__needs_decompress(dso))
498 unlink(name);
499
Namhyung Kim8ba29ad2017-06-08 16:31:06 +0900500out:
Jiri Olsacdd059d2012-10-27 23:18:32 +0200501 free(name);
502 return fd;
503}
504
Jiri Olsac6580452014-04-30 15:47:27 +0200505static void check_data_close(void);
506
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200507/**
508 * dso_close - Open DSO data file
509 * @dso: dso object
510 *
511 * Open @dso's data file descriptor and updates
512 * list/count of open DSO objects.
513 */
Jiri Olsaeba51022014-04-30 15:00:59 +0200514static int open_dso(struct dso *dso, struct machine *machine)
515{
Krister Johansenf045b8c2017-07-05 18:48:11 -0700516 int fd;
517 struct nscookie nsc;
518
519 if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
520 nsinfo__mountns_enter(dso->nsinfo, &nsc);
521 fd = __open_dso(dso, machine);
522 if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
523 nsinfo__mountns_exit(&nsc);
Jiri Olsaeba51022014-04-30 15:00:59 +0200524
Adrian Huntera6f6ae92014-07-17 11:43:09 +0300525 if (fd >= 0) {
Jiri Olsaeba51022014-04-30 15:00:59 +0200526 dso__list_add(dso);
Jiri Olsac6580452014-04-30 15:47:27 +0200527 /*
528 * Check if we crossed the allowed number
529 * of opened DSOs and close one if needed.
530 */
531 check_data_close();
532 }
Jiri Olsaeba51022014-04-30 15:00:59 +0200533
534 return fd;
535}
536
537static void close_data_fd(struct dso *dso)
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +0200538{
539 if (dso->data.fd >= 0) {
540 close(dso->data.fd);
541 dso->data.fd = -1;
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200542 dso->data.file_size = 0;
Jiri Olsaeba51022014-04-30 15:00:59 +0200543 dso__list_del(dso);
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +0200544 }
545}
546
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200547/**
548 * dso_close - Close DSO data file
549 * @dso: dso object
550 *
551 * Close @dso's data file descriptor and updates
552 * list/count of open DSO objects.
553 */
Jiri Olsaeba51022014-04-30 15:00:59 +0200554static void close_dso(struct dso *dso)
555{
556 close_data_fd(dso);
557}
558
Jiri Olsac6580452014-04-30 15:47:27 +0200559static void close_first_dso(void)
560{
561 struct dso *dso;
562
563 dso = list_first_entry(&dso__data_open, struct dso, data.open_entry);
564 close_dso(dso);
565}
566
567static rlim_t get_fd_limit(void)
568{
569 struct rlimit l;
570 rlim_t limit = 0;
571
572 /* Allow half of the current open fd limit. */
573 if (getrlimit(RLIMIT_NOFILE, &l) == 0) {
574 if (l.rlim_cur == RLIM_INFINITY)
575 limit = l.rlim_cur;
576 else
577 limit = l.rlim_cur / 2;
578 } else {
579 pr_err("failed to get fd limit\n");
580 limit = 1;
581 }
582
583 return limit;
584}
585
Jiri Olsaf3069242016-06-28 13:29:02 +0200586static rlim_t fd_limit;
587
588/*
589 * Used only by tests/dso-data.c to reset the environment
590 * for tests. I dont expect we should change this during
591 * standard runtime.
592 */
593void reset_fd_limit(void)
594{
595 fd_limit = 0;
596}
597
Jiri Olsac6580452014-04-30 15:47:27 +0200598static bool may_cache_fd(void)
599{
Jiri Olsaf3069242016-06-28 13:29:02 +0200600 if (!fd_limit)
601 fd_limit = get_fd_limit();
Jiri Olsac6580452014-04-30 15:47:27 +0200602
Jiri Olsaf3069242016-06-28 13:29:02 +0200603 if (fd_limit == RLIM_INFINITY)
Jiri Olsac6580452014-04-30 15:47:27 +0200604 return true;
605
Jiri Olsaf3069242016-06-28 13:29:02 +0200606 return fd_limit > (rlim_t) dso__data_open_cnt;
Jiri Olsac6580452014-04-30 15:47:27 +0200607}
608
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200609/*
610 * Check and close LRU dso if we crossed allowed limit
611 * for opened dso file descriptors. The limit is half
612 * of the RLIMIT_NOFILE files opened.
613*/
Jiri Olsac6580452014-04-30 15:47:27 +0200614static void check_data_close(void)
615{
616 bool cache_fd = may_cache_fd();
617
618 if (!cache_fd)
619 close_first_dso();
620}
621
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200622/**
623 * dso__data_close - Close DSO data file
624 * @dso: dso object
625 *
626 * External interface to close @dso's data file descriptor.
627 */
Jiri Olsaeba51022014-04-30 15:00:59 +0200628void dso__data_close(struct dso *dso)
629{
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900630 pthread_mutex_lock(&dso__data_open_lock);
Jiri Olsaeba51022014-04-30 15:00:59 +0200631 close_dso(dso);
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900632 pthread_mutex_unlock(&dso__data_open_lock);
Jiri Olsaeba51022014-04-30 15:00:59 +0200633}
634
Namhyung Kim71ff8242015-05-21 01:03:39 +0900635static void try_to_open_dso(struct dso *dso, struct machine *machine)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200636{
Arnaldo Carvalho de Melo631d34b2013-12-16 16:57:43 -0300637 enum dso_binary_type binary_type_data[] = {
Jiri Olsacdd059d2012-10-27 23:18:32 +0200638 DSO_BINARY_TYPE__BUILD_ID_CACHE,
639 DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
640 DSO_BINARY_TYPE__NOT_FOUND,
641 };
642 int i = 0;
643
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +0200644 if (dso->data.fd >= 0)
Namhyung Kim71ff8242015-05-21 01:03:39 +0900645 return;
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +0200646
647 if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) {
648 dso->data.fd = open_dso(dso, machine);
Adrian Hunterc27697d2014-07-22 16:17:18 +0300649 goto out;
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +0200650 }
Jiri Olsacdd059d2012-10-27 23:18:32 +0200651
652 do {
Arnaldo Carvalho de Melo5f706192013-12-17 16:14:07 -0300653 dso->binary_type = binary_type_data[i++];
Jiri Olsacdd059d2012-10-27 23:18:32 +0200654
Adrian Hunterc27697d2014-07-22 16:17:18 +0300655 dso->data.fd = open_dso(dso, machine);
656 if (dso->data.fd >= 0)
657 goto out;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200658
Arnaldo Carvalho de Melo5f706192013-12-17 16:14:07 -0300659 } while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND);
Adrian Hunterc27697d2014-07-22 16:17:18 +0300660out:
661 if (dso->data.fd >= 0)
662 dso->data.status = DSO_DATA_STATUS_OK;
663 else
664 dso->data.status = DSO_DATA_STATUS_ERROR;
Namhyung Kim71ff8242015-05-21 01:03:39 +0900665}
Jiri Olsacdd059d2012-10-27 23:18:32 +0200666
Namhyung Kim71ff8242015-05-21 01:03:39 +0900667/**
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900668 * dso__data_get_fd - Get dso's data file descriptor
Namhyung Kim71ff8242015-05-21 01:03:39 +0900669 * @dso: dso object
670 * @machine: machine object
671 *
672 * External interface to find dso's file, open it and
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900673 * returns file descriptor. It should be paired with
674 * dso__data_put_fd() if it returns non-negative value.
Namhyung Kim71ff8242015-05-21 01:03:39 +0900675 */
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900676int dso__data_get_fd(struct dso *dso, struct machine *machine)
Namhyung Kim71ff8242015-05-21 01:03:39 +0900677{
678 if (dso->data.status == DSO_DATA_STATUS_ERROR)
679 return -1;
680
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900681 if (pthread_mutex_lock(&dso__data_open_lock) < 0)
682 return -1;
683
Namhyung Kim71ff8242015-05-21 01:03:39 +0900684 try_to_open_dso(dso, machine);
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900685
686 if (dso->data.fd < 0)
687 pthread_mutex_unlock(&dso__data_open_lock);
Namhyung Kim71ff8242015-05-21 01:03:39 +0900688
Adrian Hunterc27697d2014-07-22 16:17:18 +0300689 return dso->data.fd;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200690}
691
Namhyung Kim4bb11d02015-05-21 01:03:41 +0900692void dso__data_put_fd(struct dso *dso __maybe_unused)
693{
694 pthread_mutex_unlock(&dso__data_open_lock);
695}
696
Adrian Hunter288be942014-07-22 16:17:19 +0300697bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by)
698{
699 u32 flag = 1 << by;
700
701 if (dso->data.status_seen & flag)
702 return true;
703
704 dso->data.status_seen |= flag;
705
706 return false;
707}
708
Jiri Olsacdd059d2012-10-27 23:18:32 +0200709static void
Namhyung Kim8e67b722015-05-18 09:30:41 +0900710dso_cache__free(struct dso *dso)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200711{
Namhyung Kim8e67b722015-05-18 09:30:41 +0900712 struct rb_root *root = &dso->data.cache;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200713 struct rb_node *next = rb_first(root);
714
Namhyung Kim8e67b722015-05-18 09:30:41 +0900715 pthread_mutex_lock(&dso->lock);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200716 while (next) {
717 struct dso_cache *cache;
718
719 cache = rb_entry(next, struct dso_cache, rb_node);
720 next = rb_next(&cache->rb_node);
721 rb_erase(&cache->rb_node, root);
722 free(cache);
723 }
Namhyung Kim8e67b722015-05-18 09:30:41 +0900724 pthread_mutex_unlock(&dso->lock);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200725}
726
Namhyung Kim8e67b722015-05-18 09:30:41 +0900727static struct dso_cache *dso_cache__find(struct dso *dso, u64 offset)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200728{
Namhyung Kim8e67b722015-05-18 09:30:41 +0900729 const struct rb_root *root = &dso->data.cache;
Arnaldo Carvalho de Melo33449962013-12-10 15:46:29 -0300730 struct rb_node * const *p = &root->rb_node;
731 const struct rb_node *parent = NULL;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200732 struct dso_cache *cache;
733
734 while (*p != NULL) {
735 u64 end;
736
737 parent = *p;
738 cache = rb_entry(parent, struct dso_cache, rb_node);
739 end = cache->offset + DSO__DATA_CACHE_SIZE;
740
741 if (offset < cache->offset)
742 p = &(*p)->rb_left;
743 else if (offset >= end)
744 p = &(*p)->rb_right;
745 else
746 return cache;
747 }
Namhyung Kim8e67b722015-05-18 09:30:41 +0900748
Jiri Olsacdd059d2012-10-27 23:18:32 +0200749 return NULL;
750}
751
Namhyung Kim8e67b722015-05-18 09:30:41 +0900752static struct dso_cache *
753dso_cache__insert(struct dso *dso, struct dso_cache *new)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200754{
Namhyung Kim8e67b722015-05-18 09:30:41 +0900755 struct rb_root *root = &dso->data.cache;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200756 struct rb_node **p = &root->rb_node;
757 struct rb_node *parent = NULL;
758 struct dso_cache *cache;
759 u64 offset = new->offset;
760
Namhyung Kim8e67b722015-05-18 09:30:41 +0900761 pthread_mutex_lock(&dso->lock);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200762 while (*p != NULL) {
763 u64 end;
764
765 parent = *p;
766 cache = rb_entry(parent, struct dso_cache, rb_node);
767 end = cache->offset + DSO__DATA_CACHE_SIZE;
768
769 if (offset < cache->offset)
770 p = &(*p)->rb_left;
771 else if (offset >= end)
772 p = &(*p)->rb_right;
Namhyung Kim8e67b722015-05-18 09:30:41 +0900773 else
774 goto out;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200775 }
776
777 rb_link_node(&new->rb_node, parent, p);
778 rb_insert_color(&new->rb_node, root);
Namhyung Kim8e67b722015-05-18 09:30:41 +0900779
780 cache = NULL;
781out:
782 pthread_mutex_unlock(&dso->lock);
783 return cache;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200784}
785
786static ssize_t
787dso_cache__memcpy(struct dso_cache *cache, u64 offset,
788 u8 *data, u64 size)
789{
790 u64 cache_offset = offset - cache->offset;
791 u64 cache_size = min(cache->size - cache_offset, size);
792
793 memcpy(data, cache->data + cache_offset, cache_size);
794 return cache_size;
795}
796
797static ssize_t
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900798dso_cache__read(struct dso *dso, struct machine *machine,
799 u64 offset, u8 *data, ssize_t size)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200800{
801 struct dso_cache *cache;
Namhyung Kim8e67b722015-05-18 09:30:41 +0900802 struct dso_cache *old;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200803 ssize_t ret;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200804
805 do {
806 u64 cache_offset;
807
Jiri Olsacdd059d2012-10-27 23:18:32 +0200808 cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE);
809 if (!cache)
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900810 return -ENOMEM;
811
812 pthread_mutex_lock(&dso__data_open_lock);
813
814 /*
815 * dso->data.fd might be closed if other thread opened another
816 * file (dso) due to open file limit (RLIMIT_NOFILE).
817 */
Namhyung Kim71ff8242015-05-21 01:03:39 +0900818 try_to_open_dso(dso, machine);
819
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900820 if (dso->data.fd < 0) {
Namhyung Kim71ff8242015-05-21 01:03:39 +0900821 ret = -errno;
822 dso->data.status = DSO_DATA_STATUS_ERROR;
823 break;
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900824 }
Jiri Olsacdd059d2012-10-27 23:18:32 +0200825
826 cache_offset = offset & DSO__DATA_CACHE_MASK;
Jiri Olsacdd059d2012-10-27 23:18:32 +0200827
Namhyung Kimc52686f2015-01-29 17:02:01 -0300828 ret = pread(dso->data.fd, cache->data, DSO__DATA_CACHE_SIZE, cache_offset);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200829 if (ret <= 0)
830 break;
831
832 cache->offset = cache_offset;
833 cache->size = ret;
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900834 } while (0);
835
836 pthread_mutex_unlock(&dso__data_open_lock);
837
838 if (ret > 0) {
Namhyung Kim8e67b722015-05-18 09:30:41 +0900839 old = dso_cache__insert(dso, cache);
840 if (old) {
841 /* we lose the race */
842 free(cache);
843 cache = old;
844 }
Jiri Olsacdd059d2012-10-27 23:18:32 +0200845
846 ret = dso_cache__memcpy(cache, offset, data, size);
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900847 }
Jiri Olsacdd059d2012-10-27 23:18:32 +0200848
849 if (ret <= 0)
850 free(cache);
851
Jiri Olsacdd059d2012-10-27 23:18:32 +0200852 return ret;
853}
854
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900855static ssize_t dso_cache_read(struct dso *dso, struct machine *machine,
856 u64 offset, u8 *data, ssize_t size)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200857{
858 struct dso_cache *cache;
859
Namhyung Kim8e67b722015-05-18 09:30:41 +0900860 cache = dso_cache__find(dso, offset);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200861 if (cache)
862 return dso_cache__memcpy(cache, offset, data, size);
863 else
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900864 return dso_cache__read(dso, machine, offset, data, size);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200865}
866
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200867/*
868 * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks
869 * in the rb_tree. Any read to already cached data is served
870 * by cached data.
871 */
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900872static ssize_t cached_read(struct dso *dso, struct machine *machine,
873 u64 offset, u8 *data, ssize_t size)
Jiri Olsacdd059d2012-10-27 23:18:32 +0200874{
875 ssize_t r = 0;
876 u8 *p = data;
877
878 do {
879 ssize_t ret;
880
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900881 ret = dso_cache_read(dso, machine, offset, p, size);
Jiri Olsacdd059d2012-10-27 23:18:32 +0200882 if (ret < 0)
883 return ret;
884
885 /* Reached EOF, return what we have. */
886 if (!ret)
887 break;
888
889 BUG_ON(ret > size);
890
891 r += ret;
892 p += ret;
893 offset += ret;
894 size -= ret;
895
896 } while (size);
897
898 return r;
899}
900
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900901static int data_file_size(struct dso *dso, struct machine *machine)
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200902{
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900903 int ret = 0;
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200904 struct stat st;
Masami Hiramatsu6e81c742014-08-14 02:22:36 +0000905 char sbuf[STRERR_BUFSIZE];
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200906
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900907 if (dso->data.file_size)
908 return 0;
909
Namhyung Kim71ff8242015-05-21 01:03:39 +0900910 if (dso->data.status == DSO_DATA_STATUS_ERROR)
911 return -1;
912
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900913 pthread_mutex_lock(&dso__data_open_lock);
914
915 /*
916 * dso->data.fd might be closed if other thread opened another
917 * file (dso) due to open file limit (RLIMIT_NOFILE).
918 */
Namhyung Kim71ff8242015-05-21 01:03:39 +0900919 try_to_open_dso(dso, machine);
920
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900921 if (dso->data.fd < 0) {
Namhyung Kim71ff8242015-05-21 01:03:39 +0900922 ret = -errno;
923 dso->data.status = DSO_DATA_STATUS_ERROR;
924 goto out;
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200925 }
926
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900927 if (fstat(dso->data.fd, &st) < 0) {
928 ret = -errno;
929 pr_err("dso cache fstat failed: %s\n",
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -0300930 str_error_r(errno, sbuf, sizeof(sbuf)));
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900931 dso->data.status = DSO_DATA_STATUS_ERROR;
932 goto out;
933 }
934 dso->data.file_size = st.st_size;
935
936out:
937 pthread_mutex_unlock(&dso__data_open_lock);
938 return ret;
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200939}
940
Adrian Hunter6d363452014-07-22 16:17:35 +0300941/**
942 * dso__data_size - Return dso data size
943 * @dso: dso object
944 * @machine: machine object
945 *
946 * Return: dso data size
947 */
948off_t dso__data_size(struct dso *dso, struct machine *machine)
949{
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900950 if (data_file_size(dso, machine))
Adrian Hunter6d363452014-07-22 16:17:35 +0300951 return -1;
952
953 /* For now just estimate dso data size is close to file size */
954 return dso->data.file_size;
955}
956
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900957static ssize_t data_read_offset(struct dso *dso, struct machine *machine,
958 u64 offset, u8 *data, ssize_t size)
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200959{
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900960 if (data_file_size(dso, machine))
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200961 return -1;
962
963 /* Check the offset sanity. */
964 if (offset > dso->data.file_size)
965 return -1;
966
967 if (offset + size < offset)
968 return -1;
969
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900970 return cached_read(dso, machine, offset, data, size);
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200971}
972
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200973/**
974 * dso__data_read_offset - Read data from dso file offset
975 * @dso: dso object
976 * @machine: machine object
977 * @offset: file offset
978 * @data: buffer to store data
979 * @size: size of the @data buffer
980 *
981 * External interface to read data from dso file offset. Open
982 * dso data file and use cached_read to get the data.
983 */
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200984ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine,
985 u64 offset, u8 *data, ssize_t size)
986{
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900987 if (dso->data.status == DSO_DATA_STATUS_ERROR)
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200988 return -1;
989
Namhyung Kim33bdedc2015-05-18 09:30:42 +0900990 return data_read_offset(dso, machine, offset, data, size);
Jiri Olsac3fbd2a2014-05-07 18:51:41 +0200991}
992
Jiri Olsac1f9aa02014-05-07 21:09:59 +0200993/**
994 * dso__data_read_addr - Read data from dso address
995 * @dso: dso object
996 * @machine: machine object
997 * @add: virtual memory address
998 * @data: buffer to store data
999 * @size: size of the @data buffer
1000 *
1001 * External interface to read data from dso address.
1002 */
Jiri Olsacdd059d2012-10-27 23:18:32 +02001003ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
1004 struct machine *machine, u64 addr,
1005 u8 *data, ssize_t size)
1006{
1007 u64 offset = map->map_ip(map, addr);
1008 return dso__data_read_offset(dso, machine, offset, data, size);
1009}
1010
1011struct map *dso__new_map(const char *name)
1012{
1013 struct map *map = NULL;
1014 struct dso *dso = dso__new(name);
1015
1016 if (dso)
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001017 map = map__new2(0, dso);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001018
1019 return map;
1020}
1021
Arnaldo Carvalho de Melo459ce512015-05-28 12:40:55 -03001022struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
1023 const char *short_name, int dso_type)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001024{
1025 /*
1026 * The kernel dso could be created by build_id processing.
1027 */
Arnaldo Carvalho de Meloaa7cc2a2015-05-29 11:31:12 -03001028 struct dso *dso = machine__findnew_dso(machine, name);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001029
1030 /*
1031 * We need to run this in all cases, since during the build_id
1032 * processing we had no idea this was the kernel dso.
1033 */
1034 if (dso != NULL) {
Adrian Hunter58a98c92013-12-10 11:11:46 -03001035 dso__set_short_name(dso, short_name, false);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001036 dso->kernel = dso_type;
1037 }
1038
1039 return dso;
1040}
1041
Waiman Long4598a0a2014-09-30 13:36:15 -04001042/*
1043 * Find a matching entry and/or link current entry to RB tree.
1044 * Either one of the dso or name parameter must be non-NULL or the
1045 * function will not work.
1046 */
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001047static struct dso *__dso__findlink_by_longname(struct rb_root *root,
1048 struct dso *dso, const char *name)
Waiman Long4598a0a2014-09-30 13:36:15 -04001049{
1050 struct rb_node **p = &root->rb_node;
1051 struct rb_node *parent = NULL;
1052
1053 if (!name)
1054 name = dso->long_name;
1055 /*
1056 * Find node with the matching name
1057 */
1058 while (*p) {
1059 struct dso *this = rb_entry(*p, struct dso, rb_node);
1060 int rc = strcmp(name, this->long_name);
1061
1062 parent = *p;
1063 if (rc == 0) {
1064 /*
1065 * In case the new DSO is a duplicate of an existing
Masahiro Yamada0f5e1552017-02-27 14:28:52 -08001066 * one, print a one-time warning & put the new entry
Waiman Long4598a0a2014-09-30 13:36:15 -04001067 * at the end of the list of duplicates.
1068 */
1069 if (!dso || (dso == this))
1070 return this; /* Find matching dso */
1071 /*
1072 * The core kernel DSOs may have duplicated long name.
1073 * In this case, the short name should be different.
1074 * Comparing the short names to differentiate the DSOs.
1075 */
1076 rc = strcmp(dso->short_name, this->short_name);
1077 if (rc == 0) {
1078 pr_err("Duplicated dso name: %s\n", name);
1079 return NULL;
1080 }
1081 }
1082 if (rc < 0)
1083 p = &parent->rb_left;
1084 else
1085 p = &parent->rb_right;
1086 }
1087 if (dso) {
1088 /* Add new node and rebalance tree */
1089 rb_link_node(&dso->rb_node, parent, p);
1090 rb_insert_color(&dso->rb_node, root);
Adrian Huntere266a752015-11-13 11:48:30 +02001091 dso->root = root;
Waiman Long4598a0a2014-09-30 13:36:15 -04001092 }
1093 return NULL;
1094}
1095
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001096static inline struct dso *__dso__find_by_longname(struct rb_root *root,
1097 const char *name)
Waiman Long4598a0a2014-09-30 13:36:15 -04001098{
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001099 return __dso__findlink_by_longname(root, NULL, name);
Waiman Long4598a0a2014-09-30 13:36:15 -04001100}
1101
Arnaldo Carvalho de Melobf4414a2013-12-10 15:19:23 -03001102void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001103{
Adrian Huntere266a752015-11-13 11:48:30 +02001104 struct rb_root *root = dso->root;
1105
Jiri Olsacdd059d2012-10-27 23:18:32 +02001106 if (name == NULL)
1107 return;
Arnaldo Carvalho de Melo7e155d42013-12-10 15:08:44 -03001108
1109 if (dso->long_name_allocated)
Arnaldo Carvalho de Melobf4414a2013-12-10 15:19:23 -03001110 free((char *)dso->long_name);
Arnaldo Carvalho de Melo7e155d42013-12-10 15:08:44 -03001111
Adrian Huntere266a752015-11-13 11:48:30 +02001112 if (root) {
1113 rb_erase(&dso->rb_node, root);
1114 /*
1115 * __dso__findlink_by_longname() isn't guaranteed to add it
1116 * back, so a clean removal is required here.
1117 */
1118 RB_CLEAR_NODE(&dso->rb_node);
1119 dso->root = NULL;
1120 }
1121
Arnaldo Carvalho de Melo7e155d42013-12-10 15:08:44 -03001122 dso->long_name = name;
1123 dso->long_name_len = strlen(name);
1124 dso->long_name_allocated = name_allocated;
Adrian Huntere266a752015-11-13 11:48:30 +02001125
1126 if (root)
1127 __dso__findlink_by_longname(root, dso, NULL);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001128}
1129
Adrian Hunter58a98c92013-12-10 11:11:46 -03001130void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001131{
1132 if (name == NULL)
1133 return;
Adrian Hunter58a98c92013-12-10 11:11:46 -03001134
1135 if (dso->short_name_allocated)
1136 free((char *)dso->short_name);
1137
1138 dso->short_name = name;
1139 dso->short_name_len = strlen(name);
1140 dso->short_name_allocated = name_allocated;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001141}
1142
1143static void dso__set_basename(struct dso *dso)
1144{
Stephane Eranianac5e7f82013-12-05 19:26:42 +01001145 /*
1146 * basename() may modify path buffer, so we must pass
1147 * a copy.
1148 */
1149 char *base, *lname = strdup(dso->long_name);
1150
1151 if (!lname)
1152 return;
1153
1154 /*
1155 * basename() may return a pointer to internal
1156 * storage which is reused in subsequent calls
1157 * so copy the result.
1158 */
1159 base = strdup(basename(lname));
1160
1161 free(lname);
1162
1163 if (!base)
1164 return;
1165
1166 dso__set_short_name(dso, base, true);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001167}
1168
1169int dso__name_len(const struct dso *dso)
1170{
1171 if (!dso)
1172 return strlen("[unknown]");
Namhyung Kimbb963e12017-02-17 17:17:38 +09001173 if (verbose > 0)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001174 return dso->long_name_len;
1175
1176 return dso->short_name_len;
1177}
1178
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001179bool dso__loaded(const struct dso *dso)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001180{
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001181 return dso->loaded;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001182}
1183
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001184bool dso__sorted_by_name(const struct dso *dso)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001185{
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001186 return dso->sorted_by_name;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001187}
1188
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001189void dso__set_sorted_by_name(struct dso *dso)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001190{
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001191 dso->sorted_by_name = true;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001192}
1193
1194struct dso *dso__new(const char *name)
1195{
1196 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
1197
1198 if (dso != NULL) {
Jiri Olsacdd059d2012-10-27 23:18:32 +02001199 strcpy(dso->name, name);
Arnaldo Carvalho de Melo7e155d42013-12-10 15:08:44 -03001200 dso__set_long_name(dso, dso->name, false);
Adrian Hunter58a98c92013-12-10 11:11:46 -03001201 dso__set_short_name(dso, dso->name, false);
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001202 dso->symbols = dso->symbol_names = RB_ROOT;
Jiri Olsaca40e2a2014-05-07 18:30:45 +02001203 dso->data.cache = RB_ROOT;
Milian Wolff11ea2512017-10-09 22:32:59 +02001204 dso->inlined_nodes = RB_ROOT;
Milian Wolff21ac9d52017-10-19 13:38:34 +02001205 dso->srclines = RB_ROOT;
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +02001206 dso->data.fd = -1;
Adrian Hunterc27697d2014-07-22 16:17:18 +03001207 dso->data.status = DSO_DATA_STATUS_UNKNOWN;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001208 dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
Arnaldo Carvalho de Melo5f706192013-12-17 16:14:07 -03001209 dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND;
Adrian Hunterc6d8f2a2014-07-14 13:02:41 +03001210 dso->is_64_bit = (sizeof(void *) == 8);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001211 dso->loaded = 0;
Adrian Hunter0131c4e2013-08-07 14:38:50 +03001212 dso->rel = 0;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001213 dso->sorted_by_name = 0;
1214 dso->has_build_id = 0;
Namhyung Kim2cc9d0e2013-09-11 14:09:31 +09001215 dso->has_srcline = 1;
Adrian Hunter906049c82013-12-03 09:23:10 +02001216 dso->a2l_fails = 1;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001217 dso->kernel = DSO_TYPE_USER;
1218 dso->needs_swap = DSO_SWAP__UNSET;
Waiman Long4598a0a2014-09-30 13:36:15 -04001219 RB_CLEAR_NODE(&dso->rb_node);
Adrian Huntere266a752015-11-13 11:48:30 +02001220 dso->root = NULL;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001221 INIT_LIST_HEAD(&dso->node);
Jiri Olsaeba51022014-04-30 15:00:59 +02001222 INIT_LIST_HEAD(&dso->data.open_entry);
Namhyung Kim4a936ed2015-05-18 09:30:40 +09001223 pthread_mutex_init(&dso->lock, NULL);
Elena Reshetova71008102017-02-21 17:34:58 +02001224 refcount_set(&dso->refcnt, 1);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001225 }
1226
1227 return dso;
1228}
1229
1230void dso__delete(struct dso *dso)
1231{
Waiman Long4598a0a2014-09-30 13:36:15 -04001232 if (!RB_EMPTY_NODE(&dso->rb_node))
1233 pr_err("DSO %s is still in rbtree when being deleted!\n",
1234 dso->long_name);
Milian Wolff11ea2512017-10-09 22:32:59 +02001235
1236 /* free inlines first, as they reference symbols */
1237 inlines__tree_delete(&dso->inlined_nodes);
Milian Wolff21ac9d52017-10-19 13:38:34 +02001238 srcline__tree_delete(&dso->srclines);
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001239 symbols__delete(&dso->symbols);
Arnaldo Carvalho de Meloee021d42013-12-10 15:26:55 -03001240
1241 if (dso->short_name_allocated) {
Arnaldo Carvalho de Melo04662522013-12-26 17:41:15 -03001242 zfree((char **)&dso->short_name);
Arnaldo Carvalho de Meloee021d42013-12-10 15:26:55 -03001243 dso->short_name_allocated = false;
1244 }
1245
1246 if (dso->long_name_allocated) {
Arnaldo Carvalho de Melo04662522013-12-26 17:41:15 -03001247 zfree((char **)&dso->long_name);
Arnaldo Carvalho de Meloee021d42013-12-10 15:26:55 -03001248 dso->long_name_allocated = false;
1249 }
1250
Jiri Olsa53fa8eaa2014-04-28 16:43:43 +02001251 dso__data_close(dso);
Adrian Huntercfe91742015-04-09 18:53:55 +03001252 auxtrace_cache__free(dso->auxtrace_cache);
Namhyung Kim8e67b722015-05-18 09:30:41 +09001253 dso_cache__free(dso);
Adrian Hunter454ff002013-12-03 09:23:07 +02001254 dso__free_a2l(dso);
Arnaldo Carvalho de Melo04662522013-12-26 17:41:15 -03001255 zfree(&dso->symsrc_filename);
Krister Johansen843ff372017-07-05 18:48:08 -07001256 nsinfo__zput(dso->nsinfo);
Namhyung Kim4a936ed2015-05-18 09:30:40 +09001257 pthread_mutex_destroy(&dso->lock);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001258 free(dso);
1259}
1260
Arnaldo Carvalho de Melod3a7c482015-06-02 11:53:26 -03001261struct dso *dso__get(struct dso *dso)
1262{
1263 if (dso)
Elena Reshetova71008102017-02-21 17:34:58 +02001264 refcount_inc(&dso->refcnt);
Arnaldo Carvalho de Melod3a7c482015-06-02 11:53:26 -03001265 return dso;
1266}
1267
1268void dso__put(struct dso *dso)
1269{
Elena Reshetova71008102017-02-21 17:34:58 +02001270 if (dso && refcount_dec_and_test(&dso->refcnt))
Arnaldo Carvalho de Melod3a7c482015-06-02 11:53:26 -03001271 dso__delete(dso);
1272}
1273
Jiri Olsacdd059d2012-10-27 23:18:32 +02001274void dso__set_build_id(struct dso *dso, void *build_id)
1275{
1276 memcpy(dso->build_id, build_id, sizeof(dso->build_id));
1277 dso->has_build_id = 1;
1278}
1279
1280bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1281{
1282 return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1283}
1284
1285void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
1286{
1287 char path[PATH_MAX];
1288
1289 if (machine__is_default_guest(machine))
1290 return;
1291 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
1292 if (sysfs__read_build_id(path, dso->build_id,
1293 sizeof(dso->build_id)) == 0)
1294 dso->has_build_id = true;
1295}
1296
1297int dso__kernel_module_get_build_id(struct dso *dso,
1298 const char *root_dir)
1299{
1300 char filename[PATH_MAX];
1301 /*
1302 * kernel module short names are of the form "[module]" and
1303 * we need just "module" here.
1304 */
1305 const char *name = dso->short_name + 1;
1306
1307 snprintf(filename, sizeof(filename),
1308 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1309 root_dir, (int)strlen(name) - 1, name);
1310
1311 if (sysfs__read_build_id(filename, dso->build_id,
1312 sizeof(dso->build_id)) == 0)
1313 dso->has_build_id = true;
1314
1315 return 0;
1316}
1317
1318bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1319{
1320 bool have_build_id = false;
1321 struct dso *pos;
Krister Johansenf045b8c2017-07-05 18:48:11 -07001322 struct nscookie nsc;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001323
1324 list_for_each_entry(pos, head, node) {
He Kuang6ae98ba2016-05-12 08:43:11 +00001325 if (with_hits && !pos->hit && !dso__is_vdso(pos))
Jiri Olsacdd059d2012-10-27 23:18:32 +02001326 continue;
1327 if (pos->has_build_id) {
1328 have_build_id = true;
1329 continue;
1330 }
Krister Johansenf045b8c2017-07-05 18:48:11 -07001331 nsinfo__mountns_enter(pos->nsinfo, &nsc);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001332 if (filename__read_build_id(pos->long_name, pos->build_id,
1333 sizeof(pos->build_id)) > 0) {
1334 have_build_id = true;
1335 pos->has_build_id = true;
1336 }
Krister Johansenf045b8c2017-07-05 18:48:11 -07001337 nsinfo__mountns_exit(&nsc);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001338 }
1339
1340 return have_build_id;
1341}
1342
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001343void __dsos__add(struct dsos *dsos, struct dso *dso)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001344{
Waiman Long8fa7d872014-09-29 16:07:28 -04001345 list_add_tail(&dso->node, &dsos->head);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001346 __dso__findlink_by_longname(&dsos->root, dso, NULL);
Arnaldo Carvalho de Melod3a7c482015-06-02 11:53:26 -03001347 /*
1348 * It is now in the linked list, grab a reference, then garbage collect
1349 * this when needing memory, by looking at LRU dso instances in the
1350 * list with atomic_read(&dso->refcnt) == 1, i.e. no references
1351 * anywhere besides the one for the list, do, under a lock for the
1352 * list: remove it from the list, then a dso__put(), that probably will
1353 * be the last and will then call dso__delete(), end of life.
1354 *
1355 * That, or at the end of the 'struct machine' lifetime, when all
1356 * 'struct dso' instances will be removed from the list, in
1357 * dsos__exit(), if they have no other reference from some other data
1358 * structure.
1359 *
1360 * E.g.: after processing a 'perf.data' file and storing references
1361 * to objects instantiated while processing events, we will have
1362 * references to the 'thread', 'map', 'dso' structs all from 'struct
1363 * hist_entry' instances, but we may not need anything not referenced,
1364 * so we might as well call machines__exit()/machines__delete() and
1365 * garbage collect it.
1366 */
1367 dso__get(dso);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001368}
1369
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001370void dsos__add(struct dsos *dsos, struct dso *dso)
1371{
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001372 down_write(&dsos->lock);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001373 __dsos__add(dsos, dso);
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001374 up_write(&dsos->lock);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001375}
1376
1377struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001378{
1379 struct dso *pos;
1380
Waiman Longf9ceffb2013-05-09 10:42:48 -04001381 if (cmp_short) {
Waiman Long8fa7d872014-09-29 16:07:28 -04001382 list_for_each_entry(pos, &dsos->head, node)
Waiman Longf9ceffb2013-05-09 10:42:48 -04001383 if (strcmp(pos->short_name, name) == 0)
1384 return pos;
1385 return NULL;
1386 }
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001387 return __dso__find_by_longname(&dsos->root, name);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001388}
1389
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001390struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short)
1391{
1392 struct dso *dso;
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001393 down_read(&dsos->lock);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001394 dso = __dsos__find(dsos, name, cmp_short);
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001395 up_read(&dsos->lock);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001396 return dso;
1397}
1398
1399struct dso *__dsos__addnew(struct dsos *dsos, const char *name)
Jiri Olsa701d8d72015-02-12 22:06:09 +01001400{
1401 struct dso *dso = dso__new(name);
1402
1403 if (dso != NULL) {
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001404 __dsos__add(dsos, dso);
Jiri Olsa701d8d72015-02-12 22:06:09 +01001405 dso__set_basename(dso);
Masami Hiramatsu82de26a2015-11-18 15:40:31 +09001406 /* Put dso here because __dsos_add already got it */
1407 dso__put(dso);
Jiri Olsa701d8d72015-02-12 22:06:09 +01001408 }
1409 return dso;
1410}
1411
Waiman Long8fa7d872014-09-29 16:07:28 -04001412struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001413{
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001414 struct dso *dso = __dsos__find(dsos, name, false);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001415
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001416 return dso ? dso : __dsos__addnew(dsos, name);
1417}
1418
1419struct dso *dsos__findnew(struct dsos *dsos, const char *name)
1420{
1421 struct dso *dso;
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001422 down_write(&dsos->lock);
Arnaldo Carvalho de Melod3a7c482015-06-02 11:53:26 -03001423 dso = dso__get(__dsos__findnew(dsos, name));
Arnaldo Carvalho de Melo0a7c74e2017-04-04 13:15:04 -03001424 up_write(&dsos->lock);
Arnaldo Carvalho de Meloe8807842015-06-01 15:40:01 -03001425 return dso;
Jiri Olsacdd059d2012-10-27 23:18:32 +02001426}
1427
1428size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
Arnaldo Carvalho de Melo417c2ff2012-12-07 09:53:58 -03001429 bool (skip)(struct dso *dso, int parm), int parm)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001430{
1431 struct dso *pos;
1432 size_t ret = 0;
1433
1434 list_for_each_entry(pos, head, node) {
Arnaldo Carvalho de Melo417c2ff2012-12-07 09:53:58 -03001435 if (skip && skip(pos, parm))
Jiri Olsacdd059d2012-10-27 23:18:32 +02001436 continue;
1437 ret += dso__fprintf_buildid(pos, fp);
1438 ret += fprintf(fp, " %s\n", pos->long_name);
1439 }
1440 return ret;
1441}
1442
1443size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1444{
1445 struct dso *pos;
1446 size_t ret = 0;
1447
1448 list_for_each_entry(pos, head, node) {
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001449 ret += dso__fprintf(pos, fp);
Jiri Olsacdd059d2012-10-27 23:18:32 +02001450 }
1451
1452 return ret;
1453}
1454
1455size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
1456{
Masami Hiramatsub5d8bbe2016-05-11 22:51:59 +09001457 char sbuild_id[SBUILD_ID_SIZE];
Jiri Olsacdd059d2012-10-27 23:18:32 +02001458
1459 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1460 return fprintf(fp, "%s", sbuild_id);
1461}
1462
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001463size_t dso__fprintf(struct dso *dso, FILE *fp)
Jiri Olsacdd059d2012-10-27 23:18:32 +02001464{
1465 struct rb_node *nd;
1466 size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
1467
1468 if (dso->short_name != dso->long_name)
1469 ret += fprintf(fp, "%s, ", dso->long_name);
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001470 ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT ");
Jiri Olsacdd059d2012-10-27 23:18:32 +02001471 ret += dso__fprintf_buildid(dso, fp);
1472 ret += fprintf(fp, ")\n");
Arnaldo Carvalho de Melo3183f8c2018-04-26 16:52:34 -03001473 for (nd = rb_first(&dso->symbols); nd; nd = rb_next(nd)) {
Jiri Olsacdd059d2012-10-27 23:18:32 +02001474 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
1475 ret += symbol__fprintf(pos, fp);
1476 }
1477
1478 return ret;
1479}
Adrian Hunter2b5b8bb2014-07-22 16:17:59 +03001480
1481enum dso_type dso__type(struct dso *dso, struct machine *machine)
1482{
1483 int fd;
Namhyung Kim4bb11d02015-05-21 01:03:41 +09001484 enum dso_type type = DSO__TYPE_UNKNOWN;
Adrian Hunter2b5b8bb2014-07-22 16:17:59 +03001485
Namhyung Kim4bb11d02015-05-21 01:03:41 +09001486 fd = dso__data_get_fd(dso, machine);
1487 if (fd >= 0) {
1488 type = dso__type_fd(fd);
1489 dso__data_put_fd(dso);
1490 }
Adrian Hunter2b5b8bb2014-07-22 16:17:59 +03001491
Namhyung Kim4bb11d02015-05-21 01:03:41 +09001492 return type;
Adrian Hunter2b5b8bb2014-07-22 16:17:59 +03001493}
Arnaldo Carvalho de Melo18425f12015-03-24 11:49:02 -03001494
1495int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
1496{
1497 int idx, errnum = dso->load_errno;
1498 /*
1499 * This must have a same ordering as the enum dso_load_errno.
1500 */
1501 static const char *dso_load__error_str[] = {
1502 "Internal tools/perf/ library error",
1503 "Invalid ELF file",
1504 "Can not read build id",
1505 "Mismatching build id",
1506 "Decompression failure",
1507 };
1508
1509 BUG_ON(buflen == 0);
1510
1511 if (errnum >= 0) {
Arnaldo Carvalho de Meloc8b5f2c2016-07-06 11:56:20 -03001512 const char *err = str_error_r(errnum, buf, buflen);
Arnaldo Carvalho de Melo18425f12015-03-24 11:49:02 -03001513
1514 if (err != buf)
1515 scnprintf(buf, buflen, "%s", err);
1516
1517 return 0;
1518 }
1519
1520 if (errnum < __DSO_LOAD_ERRNO__START || errnum >= __DSO_LOAD_ERRNO__END)
1521 return -1;
1522
1523 idx = errnum - __DSO_LOAD_ERRNO__START;
1524 scnprintf(buf, buflen, "%s", dso_load__error_str[idx]);
1525 return 0;
1526}