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