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