77f3b95bb46df07a0a3f2e1fbf307a741a584c72
[platform/adaptation/renesas_rcar/renesas_kernel.git] / tools / perf / util / symbol.c
1 #include <dirent.h>
2 #include <errno.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/param.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <inttypes.h>
12 #include "build-id.h"
13 #include "util.h"
14 #include "debug.h"
15 #include "machine.h"
16 #include "symbol.h"
17 #include "strlist.h"
18
19 #include <elf.h>
20 #include <limits.h>
21 #include <sys/utsname.h>
22
23 #ifndef KSYM_NAME_LEN
24 #define KSYM_NAME_LEN 256
25 #endif
26
27 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
28                                 symbol_filter_t filter);
29 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
30                         symbol_filter_t filter);
31 int vmlinux_path__nr_entries;
32 char **vmlinux_path;
33
34 struct symbol_conf symbol_conf = {
35         .use_modules      = true,
36         .try_vmlinux_path = true,
37         .annotate_src     = true,
38         .demangle         = true,
39         .symfs            = "",
40 };
41
42 static enum dso_binary_type binary_type_symtab[] = {
43         DSO_BINARY_TYPE__KALLSYMS,
44         DSO_BINARY_TYPE__GUEST_KALLSYMS,
45         DSO_BINARY_TYPE__JAVA_JIT,
46         DSO_BINARY_TYPE__DEBUGLINK,
47         DSO_BINARY_TYPE__BUILD_ID_CACHE,
48         DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
49         DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
50         DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
51         DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
52         DSO_BINARY_TYPE__GUEST_KMODULE,
53         DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
54         DSO_BINARY_TYPE__NOT_FOUND,
55 };
56
57 #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
58
59 bool symbol_type__is_a(char symbol_type, enum map_type map_type)
60 {
61         symbol_type = toupper(symbol_type);
62
63         switch (map_type) {
64         case MAP__FUNCTION:
65                 return symbol_type == 'T' || symbol_type == 'W';
66         case MAP__VARIABLE:
67                 return symbol_type == 'D';
68         default:
69                 return false;
70         }
71 }
72
73 static int prefix_underscores_count(const char *str)
74 {
75         const char *tail = str;
76
77         while (*tail == '_')
78                 tail++;
79
80         return tail - str;
81 }
82
83 #define SYMBOL_A 0
84 #define SYMBOL_B 1
85
86 static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
87 {
88         s64 a;
89         s64 b;
90         size_t na, nb;
91
92         /* Prefer a symbol with non zero length */
93         a = syma->end - syma->start;
94         b = symb->end - symb->start;
95         if ((b == 0) && (a > 0))
96                 return SYMBOL_A;
97         else if ((a == 0) && (b > 0))
98                 return SYMBOL_B;
99
100         /* Prefer a non weak symbol over a weak one */
101         a = syma->binding == STB_WEAK;
102         b = symb->binding == STB_WEAK;
103         if (b && !a)
104                 return SYMBOL_A;
105         if (a && !b)
106                 return SYMBOL_B;
107
108         /* Prefer a global symbol over a non global one */
109         a = syma->binding == STB_GLOBAL;
110         b = symb->binding == STB_GLOBAL;
111         if (a && !b)
112                 return SYMBOL_A;
113         if (b && !a)
114                 return SYMBOL_B;
115
116         /* Prefer a symbol with less underscores */
117         a = prefix_underscores_count(syma->name);
118         b = prefix_underscores_count(symb->name);
119         if (b > a)
120                 return SYMBOL_A;
121         else if (a > b)
122                 return SYMBOL_B;
123
124         /* Choose the symbol with the longest name */
125         na = strlen(syma->name);
126         nb = strlen(symb->name);
127         if (na > nb)
128                 return SYMBOL_A;
129         else if (na < nb)
130                 return SYMBOL_B;
131
132         /* Avoid "SyS" kernel syscall aliases */
133         if (na >= 3 && !strncmp(syma->name, "SyS", 3))
134                 return SYMBOL_B;
135         if (na >= 10 && !strncmp(syma->name, "compat_SyS", 10))
136                 return SYMBOL_B;
137
138         return SYMBOL_A;
139 }
140
141 void symbols__fixup_duplicate(struct rb_root *symbols)
142 {
143         struct rb_node *nd;
144         struct symbol *curr, *next;
145
146         nd = rb_first(symbols);
147
148         while (nd) {
149                 curr = rb_entry(nd, struct symbol, rb_node);
150 again:
151                 nd = rb_next(&curr->rb_node);
152                 next = rb_entry(nd, struct symbol, rb_node);
153
154                 if (!nd)
155                         break;
156
157                 if (curr->start != next->start)
158                         continue;
159
160                 if (choose_best_symbol(curr, next) == SYMBOL_A) {
161                         rb_erase(&next->rb_node, symbols);
162                         goto again;
163                 } else {
164                         nd = rb_next(&curr->rb_node);
165                         rb_erase(&curr->rb_node, symbols);
166                 }
167         }
168 }
169
170 void symbols__fixup_end(struct rb_root *symbols)
171 {
172         struct rb_node *nd, *prevnd = rb_first(symbols);
173         struct symbol *curr, *prev;
174
175         if (prevnd == NULL)
176                 return;
177
178         curr = rb_entry(prevnd, struct symbol, rb_node);
179
180         for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
181                 prev = curr;
182                 curr = rb_entry(nd, struct symbol, rb_node);
183
184                 if (prev->end == prev->start && prev->end != curr->start)
185                         prev->end = curr->start - 1;
186         }
187
188         /* Last entry */
189         if (curr->end == curr->start)
190                 curr->end = roundup(curr->start, 4096);
191 }
192
193 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
194 {
195         struct map *prev, *curr;
196         struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
197
198         if (prevnd == NULL)
199                 return;
200
201         curr = rb_entry(prevnd, struct map, rb_node);
202
203         for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
204                 prev = curr;
205                 curr = rb_entry(nd, struct map, rb_node);
206                 prev->end = curr->start - 1;
207         }
208
209         /*
210          * We still haven't the actual symbols, so guess the
211          * last map final address.
212          */
213         curr->end = ~0ULL;
214 }
215
216 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
217 {
218         size_t namelen = strlen(name) + 1;
219         struct symbol *sym = calloc(1, (symbol_conf.priv_size +
220                                         sizeof(*sym) + namelen));
221         if (sym == NULL)
222                 return NULL;
223
224         if (symbol_conf.priv_size)
225                 sym = ((void *)sym) + symbol_conf.priv_size;
226
227         sym->start   = start;
228         sym->end     = len ? start + len - 1 : start;
229         sym->binding = binding;
230         sym->namelen = namelen - 1;
231
232         pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
233                   __func__, name, start, sym->end);
234         memcpy(sym->name, name, namelen);
235
236         return sym;
237 }
238
239 void symbol__delete(struct symbol *sym)
240 {
241         free(((void *)sym) - symbol_conf.priv_size);
242 }
243
244 size_t symbol__fprintf(struct symbol *sym, FILE *fp)
245 {
246         return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
247                        sym->start, sym->end,
248                        sym->binding == STB_GLOBAL ? 'g' :
249                        sym->binding == STB_LOCAL  ? 'l' : 'w',
250                        sym->name);
251 }
252
253 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
254                                     const struct addr_location *al, FILE *fp)
255 {
256         unsigned long offset;
257         size_t length;
258
259         if (sym && sym->name) {
260                 length = fprintf(fp, "%s", sym->name);
261                 if (al) {
262                         offset = al->addr - sym->start;
263                         length += fprintf(fp, "+0x%lx", offset);
264                 }
265                 return length;
266         } else
267                 return fprintf(fp, "[unknown]");
268 }
269
270 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
271 {
272         return symbol__fprintf_symname_offs(sym, NULL, fp);
273 }
274
275 void symbols__delete(struct rb_root *symbols)
276 {
277         struct symbol *pos;
278         struct rb_node *next = rb_first(symbols);
279
280         while (next) {
281                 pos = rb_entry(next, struct symbol, rb_node);
282                 next = rb_next(&pos->rb_node);
283                 rb_erase(&pos->rb_node, symbols);
284                 symbol__delete(pos);
285         }
286 }
287
288 void symbols__insert(struct rb_root *symbols, struct symbol *sym)
289 {
290         struct rb_node **p = &symbols->rb_node;
291         struct rb_node *parent = NULL;
292         const u64 ip = sym->start;
293         struct symbol *s;
294
295         while (*p != NULL) {
296                 parent = *p;
297                 s = rb_entry(parent, struct symbol, rb_node);
298                 if (ip < s->start)
299                         p = &(*p)->rb_left;
300                 else
301                         p = &(*p)->rb_right;
302         }
303         rb_link_node(&sym->rb_node, parent, p);
304         rb_insert_color(&sym->rb_node, symbols);
305 }
306
307 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
308 {
309         struct rb_node *n;
310
311         if (symbols == NULL)
312                 return NULL;
313
314         n = symbols->rb_node;
315
316         while (n) {
317                 struct symbol *s = rb_entry(n, struct symbol, rb_node);
318
319                 if (ip < s->start)
320                         n = n->rb_left;
321                 else if (ip > s->end)
322                         n = n->rb_right;
323                 else
324                         return s;
325         }
326
327         return NULL;
328 }
329
330 static struct symbol *symbols__first(struct rb_root *symbols)
331 {
332         struct rb_node *n = rb_first(symbols);
333
334         if (n)
335                 return rb_entry(n, struct symbol, rb_node);
336
337         return NULL;
338 }
339
340 struct symbol_name_rb_node {
341         struct rb_node  rb_node;
342         struct symbol   sym;
343 };
344
345 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
346 {
347         struct rb_node **p = &symbols->rb_node;
348         struct rb_node *parent = NULL;
349         struct symbol_name_rb_node *symn, *s;
350
351         symn = container_of(sym, struct symbol_name_rb_node, sym);
352
353         while (*p != NULL) {
354                 parent = *p;
355                 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
356                 if (strcmp(sym->name, s->sym.name) < 0)
357                         p = &(*p)->rb_left;
358                 else
359                         p = &(*p)->rb_right;
360         }
361         rb_link_node(&symn->rb_node, parent, p);
362         rb_insert_color(&symn->rb_node, symbols);
363 }
364
365 static void symbols__sort_by_name(struct rb_root *symbols,
366                                   struct rb_root *source)
367 {
368         struct rb_node *nd;
369
370         for (nd = rb_first(source); nd; nd = rb_next(nd)) {
371                 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
372                 symbols__insert_by_name(symbols, pos);
373         }
374 }
375
376 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
377                                             const char *name)
378 {
379         struct rb_node *n;
380
381         if (symbols == NULL)
382                 return NULL;
383
384         n = symbols->rb_node;
385
386         while (n) {
387                 struct symbol_name_rb_node *s;
388                 int cmp;
389
390                 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
391                 cmp = strcmp(name, s->sym.name);
392
393                 if (cmp < 0)
394                         n = n->rb_left;
395                 else if (cmp > 0)
396                         n = n->rb_right;
397                 else
398                         return &s->sym;
399         }
400
401         return NULL;
402 }
403
404 struct symbol *dso__find_symbol(struct dso *dso,
405                                 enum map_type type, u64 addr)
406 {
407         return symbols__find(&dso->symbols[type], addr);
408 }
409
410 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
411 {
412         return symbols__first(&dso->symbols[type]);
413 }
414
415 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
416                                         const char *name)
417 {
418         return symbols__find_by_name(&dso->symbol_names[type], name);
419 }
420
421 void dso__sort_by_name(struct dso *dso, enum map_type type)
422 {
423         dso__set_sorted_by_name(dso, type);
424         return symbols__sort_by_name(&dso->symbol_names[type],
425                                      &dso->symbols[type]);
426 }
427
428 size_t dso__fprintf_symbols_by_name(struct dso *dso,
429                                     enum map_type type, FILE *fp)
430 {
431         size_t ret = 0;
432         struct rb_node *nd;
433         struct symbol_name_rb_node *pos;
434
435         for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
436                 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
437                 fprintf(fp, "%s\n", pos->sym.name);
438         }
439
440         return ret;
441 }
442
443 int kallsyms__parse(const char *filename, void *arg,
444                     int (*process_symbol)(void *arg, const char *name,
445                                           char type, u64 start))
446 {
447         char *line = NULL;
448         size_t n;
449         int err = -1;
450         FILE *file = fopen(filename, "r");
451
452         if (file == NULL)
453                 goto out_failure;
454
455         err = 0;
456
457         while (!feof(file)) {
458                 u64 start;
459                 int line_len, len;
460                 char symbol_type;
461                 char *symbol_name;
462
463                 line_len = getline(&line, &n, file);
464                 if (line_len < 0 || !line)
465                         break;
466
467                 line[--line_len] = '\0'; /* \n */
468
469                 len = hex2u64(line, &start);
470
471                 len++;
472                 if (len + 2 >= line_len)
473                         continue;
474
475                 symbol_type = line[len];
476                 len += 2;
477                 symbol_name = line + len;
478                 len = line_len - len;
479
480                 if (len >= KSYM_NAME_LEN) {
481                         err = -1;
482                         break;
483                 }
484
485                 err = process_symbol(arg, symbol_name,
486                                      symbol_type, start);
487                 if (err)
488                         break;
489         }
490
491         free(line);
492         fclose(file);
493         return err;
494
495 out_failure:
496         return -1;
497 }
498
499 struct process_kallsyms_args {
500         struct map *map;
501         struct dso *dso;
502 };
503
504 static u8 kallsyms2elf_type(char type)
505 {
506         if (type == 'W')
507                 return STB_WEAK;
508
509         return isupper(type) ? STB_GLOBAL : STB_LOCAL;
510 }
511
512 static int map__process_kallsym_symbol(void *arg, const char *name,
513                                        char type, u64 start)
514 {
515         struct symbol *sym;
516         struct process_kallsyms_args *a = arg;
517         struct rb_root *root = &a->dso->symbols[a->map->type];
518
519         if (!symbol_type__is_a(type, a->map->type))
520                 return 0;
521
522         /*
523          * module symbols are not sorted so we add all
524          * symbols, setting length to 0, and rely on
525          * symbols__fixup_end() to fix it up.
526          */
527         sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
528         if (sym == NULL)
529                 return -ENOMEM;
530         /*
531          * We will pass the symbols to the filter later, in
532          * map__split_kallsyms, when we have split the maps per module
533          */
534         symbols__insert(root, sym);
535
536         return 0;
537 }
538
539 /*
540  * Loads the function entries in /proc/kallsyms into kernel_map->dso,
541  * so that we can in the next step set the symbol ->end address and then
542  * call kernel_maps__split_kallsyms.
543  */
544 static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
545                                   struct map *map)
546 {
547         struct process_kallsyms_args args = { .map = map, .dso = dso, };
548         return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
549 }
550
551 static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
552                                          symbol_filter_t filter)
553 {
554         struct map_groups *kmaps = map__kmap(map)->kmaps;
555         struct map *curr_map;
556         struct symbol *pos;
557         int count = 0, moved = 0;
558         struct rb_root *root = &dso->symbols[map->type];
559         struct rb_node *next = rb_first(root);
560
561         while (next) {
562                 char *module;
563
564                 pos = rb_entry(next, struct symbol, rb_node);
565                 next = rb_next(&pos->rb_node);
566
567                 module = strchr(pos->name, '\t');
568                 if (module)
569                         *module = '\0';
570
571                 curr_map = map_groups__find(kmaps, map->type, pos->start);
572
573                 if (!curr_map || (filter && filter(curr_map, pos))) {
574                         rb_erase(&pos->rb_node, root);
575                         symbol__delete(pos);
576                 } else {
577                         pos->start -= curr_map->start - curr_map->pgoff;
578                         if (pos->end)
579                                 pos->end -= curr_map->start - curr_map->pgoff;
580                         if (curr_map != map) {
581                                 rb_erase(&pos->rb_node, root);
582                                 symbols__insert(
583                                         &curr_map->dso->symbols[curr_map->type],
584                                         pos);
585                                 ++moved;
586                         } else {
587                                 ++count;
588                         }
589                 }
590         }
591
592         /* Symbols have been adjusted */
593         dso->adjust_symbols = 1;
594
595         return count + moved;
596 }
597
598 /*
599  * Split the symbols into maps, making sure there are no overlaps, i.e. the
600  * kernel range is broken in several maps, named [kernel].N, as we don't have
601  * the original ELF section names vmlinux have.
602  */
603 static int dso__split_kallsyms(struct dso *dso, struct map *map,
604                                symbol_filter_t filter)
605 {
606         struct map_groups *kmaps = map__kmap(map)->kmaps;
607         struct machine *machine = kmaps->machine;
608         struct map *curr_map = map;
609         struct symbol *pos;
610         int count = 0, moved = 0;       
611         struct rb_root *root = &dso->symbols[map->type];
612         struct rb_node *next = rb_first(root);
613         int kernel_range = 0;
614
615         while (next) {
616                 char *module;
617
618                 pos = rb_entry(next, struct symbol, rb_node);
619                 next = rb_next(&pos->rb_node);
620
621                 module = strchr(pos->name, '\t');
622                 if (module) {
623                         if (!symbol_conf.use_modules)
624                                 goto discard_symbol;
625
626                         *module++ = '\0';
627
628                         if (strcmp(curr_map->dso->short_name, module)) {
629                                 if (curr_map != map &&
630                                     dso->kernel == DSO_TYPE_GUEST_KERNEL &&
631                                     machine__is_default_guest(machine)) {
632                                         /*
633                                          * We assume all symbols of a module are
634                                          * continuous in * kallsyms, so curr_map
635                                          * points to a module and all its
636                                          * symbols are in its kmap. Mark it as
637                                          * loaded.
638                                          */
639                                         dso__set_loaded(curr_map->dso,
640                                                         curr_map->type);
641                                 }
642
643                                 curr_map = map_groups__find_by_name(kmaps,
644                                                         map->type, module);
645                                 if (curr_map == NULL) {
646                                         pr_debug("%s/proc/{kallsyms,modules} "
647                                                  "inconsistency while looking "
648                                                  "for \"%s\" module!\n",
649                                                  machine->root_dir, module);
650                                         curr_map = map;
651                                         goto discard_symbol;
652                                 }
653
654                                 if (curr_map->dso->loaded &&
655                                     !machine__is_default_guest(machine))
656                                         goto discard_symbol;
657                         }
658                         /*
659                          * So that we look just like we get from .ko files,
660                          * i.e. not prelinked, relative to map->start.
661                          */
662                         pos->start = curr_map->map_ip(curr_map, pos->start);
663                         pos->end   = curr_map->map_ip(curr_map, pos->end);
664                 } else if (curr_map != map) {
665                         char dso_name[PATH_MAX];
666                         struct dso *ndso;
667
668                         if (count == 0) {
669                                 curr_map = map;
670                                 goto filter_symbol;
671                         }
672
673                         if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
674                                 snprintf(dso_name, sizeof(dso_name),
675                                         "[guest.kernel].%d",
676                                         kernel_range++);
677                         else
678                                 snprintf(dso_name, sizeof(dso_name),
679                                         "[kernel].%d",
680                                         kernel_range++);
681
682                         ndso = dso__new(dso_name);
683                         if (ndso == NULL)
684                                 return -1;
685
686                         ndso->kernel = dso->kernel;
687
688                         curr_map = map__new2(pos->start, ndso, map->type);
689                         if (curr_map == NULL) {
690                                 dso__delete(ndso);
691                                 return -1;
692                         }
693
694                         curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
695                         map_groups__insert(kmaps, curr_map);
696                         ++kernel_range;
697                 }
698 filter_symbol:
699                 if (filter && filter(curr_map, pos)) {
700 discard_symbol:         rb_erase(&pos->rb_node, root);
701                         symbol__delete(pos);
702                 } else {
703                         if (curr_map != map) {
704                                 rb_erase(&pos->rb_node, root);
705                                 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
706                                 ++moved;
707                         } else
708                                 ++count;
709                 }
710         }
711
712         if (curr_map != map &&
713             dso->kernel == DSO_TYPE_GUEST_KERNEL &&
714             machine__is_default_guest(kmaps->machine)) {
715                 dso__set_loaded(curr_map->dso, curr_map->type);
716         }
717
718         return count + moved;
719 }
720
721 bool symbol__restricted_filename(const char *filename,
722                                  const char *restricted_filename)
723 {
724         bool restricted = false;
725
726         if (symbol_conf.kptr_restrict) {
727                 char *r = realpath(filename, NULL);
728
729                 if (r != NULL) {
730                         restricted = strcmp(r, restricted_filename) == 0;
731                         free(r);
732                         return restricted;
733                 }
734         }
735
736         return restricted;
737 }
738
739 struct kcore_mapfn_data {
740         struct dso *dso;
741         enum map_type type;
742         struct list_head maps;
743 };
744
745 static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
746 {
747         struct kcore_mapfn_data *md = data;
748         struct map *map;
749
750         map = map__new2(start, md->dso, md->type);
751         if (map == NULL)
752                 return -ENOMEM;
753
754         map->end = map->start + len;
755         map->pgoff = pgoff;
756
757         list_add(&map->node, &md->maps);
758
759         return 0;
760 }
761
762 /*
763  * If kallsyms is referenced by name then we look for kcore in the same
764  * directory.
765  */
766 static bool kcore_filename_from_kallsyms_filename(char *kcore_filename,
767                                                   const char *kallsyms_filename)
768 {
769         char *name;
770
771         strcpy(kcore_filename, kallsyms_filename);
772         name = strrchr(kcore_filename, '/');
773         if (!name)
774                 return false;
775
776         if (!strcmp(name, "/kallsyms")) {
777                 strcpy(name, "/kcore");
778                 return true;
779         }
780
781         return false;
782 }
783
784 static int dso__load_kcore(struct dso *dso, struct map *map,
785                            const char *kallsyms_filename)
786 {
787         struct map_groups *kmaps = map__kmap(map)->kmaps;
788         struct machine *machine = kmaps->machine;
789         struct kcore_mapfn_data md;
790         struct map *old_map, *new_map, *replacement_map = NULL;
791         bool is_64_bit;
792         int err, fd;
793         char kcore_filename[PATH_MAX];
794         struct symbol *sym;
795
796         /* This function requires that the map is the kernel map */
797         if (map != machine->vmlinux_maps[map->type])
798                 return -EINVAL;
799
800         if (!kcore_filename_from_kallsyms_filename(kcore_filename,
801                                                    kallsyms_filename))
802                 return -EINVAL;
803
804         md.dso = dso;
805         md.type = map->type;
806         INIT_LIST_HEAD(&md.maps);
807
808         fd = open(kcore_filename, O_RDONLY);
809         if (fd < 0)
810                 return -EINVAL;
811
812         /* Read new maps into temporary lists */
813         err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md,
814                               &is_64_bit);
815         if (err)
816                 goto out_err;
817
818         if (list_empty(&md.maps)) {
819                 err = -EINVAL;
820                 goto out_err;
821         }
822
823         /* Remove old maps */
824         old_map = map_groups__first(kmaps, map->type);
825         while (old_map) {
826                 struct map *next = map_groups__next(old_map);
827
828                 if (old_map != map)
829                         map_groups__remove(kmaps, old_map);
830                 old_map = next;
831         }
832
833         /* Find the kernel map using the first symbol */
834         sym = dso__first_symbol(dso, map->type);
835         list_for_each_entry(new_map, &md.maps, node) {
836                 if (sym && sym->start >= new_map->start &&
837                     sym->start < new_map->end) {
838                         replacement_map = new_map;
839                         break;
840                 }
841         }
842
843         if (!replacement_map)
844                 replacement_map = list_entry(md.maps.next, struct map, node);
845
846         /* Add new maps */
847         while (!list_empty(&md.maps)) {
848                 new_map = list_entry(md.maps.next, struct map, node);
849                 list_del(&new_map->node);
850                 if (new_map == replacement_map) {
851                         map->start      = new_map->start;
852                         map->end        = new_map->end;
853                         map->pgoff      = new_map->pgoff;
854                         map->map_ip     = new_map->map_ip;
855                         map->unmap_ip   = new_map->unmap_ip;
856                         map__delete(new_map);
857                         /* Ensure maps are correctly ordered */
858                         map_groups__remove(kmaps, map);
859                         map_groups__insert(kmaps, map);
860                 } else {
861                         map_groups__insert(kmaps, new_map);
862                 }
863         }
864
865         /*
866          * Set the data type and long name so that kcore can be read via
867          * dso__data_read_addr().
868          */
869         if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
870                 dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
871         else
872                 dso->data_type = DSO_BINARY_TYPE__KCORE;
873         dso__set_long_name(dso, strdup(kcore_filename));
874
875         close(fd);
876
877         if (map->type == MAP__FUNCTION)
878                 pr_debug("Using %s for kernel object code\n", kcore_filename);
879         else
880                 pr_debug("Using %s for kernel data\n", kcore_filename);
881
882         return 0;
883
884 out_err:
885         while (!list_empty(&md.maps)) {
886                 map = list_entry(md.maps.next, struct map, node);
887                 list_del(&map->node);
888                 map__delete(map);
889         }
890         close(fd);
891         return -EINVAL;
892 }
893
894 int dso__load_kallsyms(struct dso *dso, const char *filename,
895                        struct map *map, symbol_filter_t filter)
896 {
897         if (symbol__restricted_filename(filename, "/proc/kallsyms"))
898                 return -1;
899
900         if (dso__load_all_kallsyms(dso, filename, map) < 0)
901                 return -1;
902
903         symbols__fixup_duplicate(&dso->symbols[map->type]);
904         symbols__fixup_end(&dso->symbols[map->type]);
905
906         if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
907                 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
908         else
909                 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
910
911         if (!dso__load_kcore(dso, map, filename))
912                 return dso__split_kallsyms_for_kcore(dso, map, filter);
913         else
914                 return dso__split_kallsyms(dso, map, filter);
915 }
916
917 static int dso__load_perf_map(struct dso *dso, struct map *map,
918                               symbol_filter_t filter)
919 {
920         char *line = NULL;
921         size_t n;
922         FILE *file;
923         int nr_syms = 0;
924
925         file = fopen(dso->long_name, "r");
926         if (file == NULL)
927                 goto out_failure;
928
929         while (!feof(file)) {
930                 u64 start, size;
931                 struct symbol *sym;
932                 int line_len, len;
933
934                 line_len = getline(&line, &n, file);
935                 if (line_len < 0)
936                         break;
937
938                 if (!line)
939                         goto out_failure;
940
941                 line[--line_len] = '\0'; /* \n */
942
943                 len = hex2u64(line, &start);
944
945                 len++;
946                 if (len + 2 >= line_len)
947                         continue;
948
949                 len += hex2u64(line + len, &size);
950
951                 len++;
952                 if (len + 2 >= line_len)
953                         continue;
954
955                 sym = symbol__new(start, size, STB_GLOBAL, line + len);
956
957                 if (sym == NULL)
958                         goto out_delete_line;
959
960                 if (filter && filter(map, sym))
961                         symbol__delete(sym);
962                 else {
963                         symbols__insert(&dso->symbols[map->type], sym);
964                         nr_syms++;
965                 }
966         }
967
968         free(line);
969         fclose(file);
970
971         return nr_syms;
972
973 out_delete_line:
974         free(line);
975 out_failure:
976         return -1;
977 }
978
979 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
980 {
981         char *name;
982         int ret = -1;
983         u_int i;
984         struct machine *machine;
985         char *root_dir = (char *) "";
986         int ss_pos = 0;
987         struct symsrc ss_[2];
988         struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
989
990         dso__set_loaded(dso, map->type);
991
992         if (dso->kernel == DSO_TYPE_KERNEL)
993                 return dso__load_kernel_sym(dso, map, filter);
994         else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
995                 return dso__load_guest_kernel_sym(dso, map, filter);
996
997         if (map->groups && map->groups->machine)
998                 machine = map->groups->machine;
999         else
1000                 machine = NULL;
1001
1002         dso->adjust_symbols = 0;
1003
1004         if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1005                 struct stat st;
1006
1007                 if (lstat(dso->name, &st) < 0)
1008                         return -1;
1009
1010                 if (st.st_uid && (st.st_uid != geteuid())) {
1011                         pr_warning("File %s not owned by current user or root, "
1012                                 "ignoring it.\n", dso->name);
1013                         return -1;
1014                 }
1015
1016                 ret = dso__load_perf_map(dso, map, filter);
1017                 dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
1018                                              DSO_BINARY_TYPE__NOT_FOUND;
1019                 return ret;
1020         }
1021
1022         if (machine)
1023                 root_dir = machine->root_dir;
1024
1025         name = malloc(PATH_MAX);
1026         if (!name)
1027                 return -1;
1028
1029         /* Iterate over candidate debug images.
1030          * Keep track of "interesting" ones (those which have a symtab, dynsym,
1031          * and/or opd section) for processing.
1032          */
1033         for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
1034                 struct symsrc *ss = &ss_[ss_pos];
1035                 bool next_slot = false;
1036
1037                 enum dso_binary_type symtab_type = binary_type_symtab[i];
1038
1039                 if (dso__binary_type_file(dso, symtab_type,
1040                                           root_dir, name, PATH_MAX))
1041                         continue;
1042
1043                 /* Name is now the name of the next image to try */
1044                 if (symsrc__init(ss, dso, name, symtab_type) < 0)
1045                         continue;
1046
1047                 if (!syms_ss && symsrc__has_symtab(ss)) {
1048                         syms_ss = ss;
1049                         next_slot = true;
1050                 }
1051
1052                 if (!runtime_ss && symsrc__possibly_runtime(ss)) {
1053                         runtime_ss = ss;
1054                         next_slot = true;
1055                 }
1056
1057                 if (next_slot) {
1058                         ss_pos++;
1059
1060                         if (syms_ss && runtime_ss)
1061                                 break;
1062                 }
1063
1064         }
1065
1066         if (!runtime_ss && !syms_ss)
1067                 goto out_free;
1068
1069         if (runtime_ss && !syms_ss) {
1070                 syms_ss = runtime_ss;
1071         }
1072
1073         /* We'll have to hope for the best */
1074         if (!runtime_ss && syms_ss)
1075                 runtime_ss = syms_ss;
1076
1077         if (syms_ss) {
1078                 int km;
1079
1080                 km = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
1081                      dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
1082                 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, km);
1083         } else {
1084                 ret = -1;
1085         }
1086
1087         if (ret > 0) {
1088                 int nr_plt;
1089
1090                 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
1091                 if (nr_plt > 0)
1092                         ret += nr_plt;
1093         }
1094
1095         for (; ss_pos > 0; ss_pos--)
1096                 symsrc__destroy(&ss_[ss_pos - 1]);
1097 out_free:
1098         free(name);
1099         if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1100                 return 0;
1101         return ret;
1102 }
1103
1104 struct map *map_groups__find_by_name(struct map_groups *mg,
1105                                      enum map_type type, const char *name)
1106 {
1107         struct rb_node *nd;
1108
1109         for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1110                 struct map *map = rb_entry(nd, struct map, rb_node);
1111
1112                 if (map->dso && strcmp(map->dso->short_name, name) == 0)
1113                         return map;
1114         }
1115
1116         return NULL;
1117 }
1118
1119 int dso__load_vmlinux(struct dso *dso, struct map *map,
1120                       const char *vmlinux, symbol_filter_t filter)
1121 {
1122         int err = -1;
1123         struct symsrc ss;
1124         char symfs_vmlinux[PATH_MAX];
1125         enum dso_binary_type symtab_type;
1126
1127         if (vmlinux[0] == '/')
1128                 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux);
1129         else
1130                 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
1131                          symbol_conf.symfs, vmlinux);
1132
1133         if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1134                 symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1135         else
1136                 symtab_type = DSO_BINARY_TYPE__VMLINUX;
1137
1138         if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
1139                 return -1;
1140
1141         err = dso__load_sym(dso, map, &ss, &ss, filter, 0);
1142         symsrc__destroy(&ss);
1143
1144         if (err > 0) {
1145                 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1146                         dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1147                 else
1148                         dso->data_type = DSO_BINARY_TYPE__VMLINUX;
1149                 dso__set_long_name(dso, (char *)vmlinux);
1150                 dso__set_loaded(dso, map->type);
1151                 pr_debug("Using %s for symbols\n", symfs_vmlinux);
1152         }
1153
1154         return err;
1155 }
1156
1157 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1158                            symbol_filter_t filter)
1159 {
1160         int i, err = 0;
1161         char *filename;
1162
1163         pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1164                  vmlinux_path__nr_entries + 1);
1165
1166         filename = dso__build_id_filename(dso, NULL, 0);
1167         if (filename != NULL) {
1168                 err = dso__load_vmlinux(dso, map, filename, filter);
1169                 if (err > 0) {
1170                         dso->lname_alloc = 1;
1171                         goto out;
1172                 }
1173                 free(filename);
1174         }
1175
1176         for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1177                 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
1178                 if (err > 0) {
1179                         dso__set_long_name(dso, strdup(vmlinux_path[i]));
1180                         dso->lname_alloc = 1;
1181                         break;
1182                 }
1183         }
1184 out:
1185         return err;
1186 }
1187
1188 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1189                                 symbol_filter_t filter)
1190 {
1191         int err;
1192         const char *kallsyms_filename = NULL;
1193         char *kallsyms_allocated_filename = NULL;
1194         /*
1195          * Step 1: if the user specified a kallsyms or vmlinux filename, use
1196          * it and only it, reporting errors to the user if it cannot be used.
1197          *
1198          * For instance, try to analyse an ARM perf.data file _without_ a
1199          * build-id, or if the user specifies the wrong path to the right
1200          * vmlinux file, obviously we can't fallback to another vmlinux (a
1201          * x86_86 one, on the machine where analysis is being performed, say),
1202          * or worse, /proc/kallsyms.
1203          *
1204          * If the specified file _has_ a build-id and there is a build-id
1205          * section in the perf.data file, we will still do the expected
1206          * validation in dso__load_vmlinux and will bail out if they don't
1207          * match.
1208          */
1209         if (symbol_conf.kallsyms_name != NULL) {
1210                 kallsyms_filename = symbol_conf.kallsyms_name;
1211                 goto do_kallsyms;
1212         }
1213
1214         if (symbol_conf.vmlinux_name != NULL) {
1215                 err = dso__load_vmlinux(dso, map,
1216                                         symbol_conf.vmlinux_name, filter);
1217                 if (err > 0) {
1218                         dso__set_long_name(dso,
1219                                            strdup(symbol_conf.vmlinux_name));
1220                         dso->lname_alloc = 1;
1221                         return err;
1222                 }
1223                 return err;
1224         }
1225
1226         if (vmlinux_path != NULL) {
1227                 err = dso__load_vmlinux_path(dso, map, filter);
1228                 if (err > 0)
1229                         return err;
1230         }
1231
1232         /* do not try local files if a symfs was given */
1233         if (symbol_conf.symfs[0] != 0)
1234                 return -1;
1235
1236         /*
1237          * Say the kernel DSO was created when processing the build-id header table,
1238          * we have a build-id, so check if it is the same as the running kernel,
1239          * using it if it is.
1240          */
1241         if (dso->has_build_id) {
1242                 u8 kallsyms_build_id[BUILD_ID_SIZE];
1243                 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1244
1245                 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1246                                          sizeof(kallsyms_build_id)) == 0) {
1247                         if (dso__build_id_equal(dso, kallsyms_build_id)) {
1248                                 kallsyms_filename = "/proc/kallsyms";
1249                                 goto do_kallsyms;
1250                         }
1251                 }
1252                 /*
1253                  * Now look if we have it on the build-id cache in
1254                  * $HOME/.debug/[kernel.kallsyms].
1255                  */
1256                 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1257                                   sbuild_id);
1258
1259                 if (asprintf(&kallsyms_allocated_filename,
1260                              "%s/.debug/[kernel.kallsyms]/%s",
1261                              getenv("HOME"), sbuild_id) == -1) {
1262                         pr_err("Not enough memory for kallsyms file lookup\n");
1263                         return -1;
1264                 }
1265
1266                 kallsyms_filename = kallsyms_allocated_filename;
1267
1268                 if (access(kallsyms_filename, F_OK)) {
1269                         pr_err("No kallsyms or vmlinux with build-id %s "
1270                                "was found\n", sbuild_id);
1271                         free(kallsyms_allocated_filename);
1272                         return -1;
1273                 }
1274         } else {
1275                 /*
1276                  * Last resort, if we don't have a build-id and couldn't find
1277                  * any vmlinux file, try the running kernel kallsyms table.
1278                  */
1279                 kallsyms_filename = "/proc/kallsyms";
1280         }
1281
1282 do_kallsyms:
1283         err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1284         if (err > 0)
1285                 pr_debug("Using %s for symbols\n", kallsyms_filename);
1286         free(kallsyms_allocated_filename);
1287
1288         if (err > 0 && !dso__is_kcore(dso)) {
1289                 dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
1290                 map__fixup_start(map);
1291                 map__fixup_end(map);
1292         }
1293
1294         return err;
1295 }
1296
1297 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1298                                       symbol_filter_t filter)
1299 {
1300         int err;
1301         const char *kallsyms_filename = NULL;
1302         struct machine *machine;
1303         char path[PATH_MAX];
1304
1305         if (!map->groups) {
1306                 pr_debug("Guest kernel map hasn't the point to groups\n");
1307                 return -1;
1308         }
1309         machine = map->groups->machine;
1310
1311         if (machine__is_default_guest(machine)) {
1312                 /*
1313                  * if the user specified a vmlinux filename, use it and only
1314                  * it, reporting errors to the user if it cannot be used.
1315                  * Or use file guest_kallsyms inputted by user on commandline
1316                  */
1317                 if (symbol_conf.default_guest_vmlinux_name != NULL) {
1318                         err = dso__load_vmlinux(dso, map,
1319                                 symbol_conf.default_guest_vmlinux_name, filter);
1320                         return err;
1321                 }
1322
1323                 kallsyms_filename = symbol_conf.default_guest_kallsyms;
1324                 if (!kallsyms_filename)
1325                         return -1;
1326         } else {
1327                 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1328                 kallsyms_filename = path;
1329         }
1330
1331         err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1332         if (err > 0)
1333                 pr_debug("Using %s for symbols\n", kallsyms_filename);
1334         if (err > 0 && !dso__is_kcore(dso)) {
1335                 machine__mmap_name(machine, path, sizeof(path));
1336                 dso__set_long_name(dso, strdup(path));
1337                 map__fixup_start(map);
1338                 map__fixup_end(map);
1339         }
1340
1341         return err;
1342 }
1343
1344 static void vmlinux_path__exit(void)
1345 {
1346         while (--vmlinux_path__nr_entries >= 0) {
1347                 free(vmlinux_path[vmlinux_path__nr_entries]);
1348                 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1349         }
1350
1351         free(vmlinux_path);
1352         vmlinux_path = NULL;
1353 }
1354
1355 static int vmlinux_path__init(void)
1356 {
1357         struct utsname uts;
1358         char bf[PATH_MAX];
1359
1360         vmlinux_path = malloc(sizeof(char *) * 5);
1361         if (vmlinux_path == NULL)
1362                 return -1;
1363
1364         vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1365         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1366                 goto out_fail;
1367         ++vmlinux_path__nr_entries;
1368         vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1369         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1370                 goto out_fail;
1371         ++vmlinux_path__nr_entries;
1372
1373         /* only try running kernel version if no symfs was given */
1374         if (symbol_conf.symfs[0] != 0)
1375                 return 0;
1376
1377         if (uname(&uts) < 0)
1378                 return -1;
1379
1380         snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1381         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1382         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1383                 goto out_fail;
1384         ++vmlinux_path__nr_entries;
1385         snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1386         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1387         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1388                 goto out_fail;
1389         ++vmlinux_path__nr_entries;
1390         snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1391                  uts.release);
1392         vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1393         if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1394                 goto out_fail;
1395         ++vmlinux_path__nr_entries;
1396
1397         return 0;
1398
1399 out_fail:
1400         vmlinux_path__exit();
1401         return -1;
1402 }
1403
1404 static int setup_list(struct strlist **list, const char *list_str,
1405                       const char *list_name)
1406 {
1407         if (list_str == NULL)
1408                 return 0;
1409
1410         *list = strlist__new(true, list_str);
1411         if (!*list) {
1412                 pr_err("problems parsing %s list\n", list_name);
1413                 return -1;
1414         }
1415         return 0;
1416 }
1417
1418 static bool symbol__read_kptr_restrict(void)
1419 {
1420         bool value = false;
1421
1422         if (geteuid() != 0) {
1423                 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
1424                 if (fp != NULL) {
1425                         char line[8];
1426
1427                         if (fgets(line, sizeof(line), fp) != NULL)
1428                                 value = atoi(line) != 0;
1429
1430                         fclose(fp);
1431                 }
1432         }
1433
1434         return value;
1435 }
1436
1437 int symbol__init(void)
1438 {
1439         const char *symfs;
1440
1441         if (symbol_conf.initialized)
1442                 return 0;
1443
1444         symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
1445
1446         symbol__elf_init();
1447
1448         if (symbol_conf.sort_by_name)
1449                 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1450                                           sizeof(struct symbol));
1451
1452         if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
1453                 return -1;
1454
1455         if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1456                 pr_err("'.' is the only non valid --field-separator argument\n");
1457                 return -1;
1458         }
1459
1460         if (setup_list(&symbol_conf.dso_list,
1461                        symbol_conf.dso_list_str, "dso") < 0)
1462                 return -1;
1463
1464         if (setup_list(&symbol_conf.comm_list,
1465                        symbol_conf.comm_list_str, "comm") < 0)
1466                 goto out_free_dso_list;
1467
1468         if (setup_list(&symbol_conf.sym_list,
1469                        symbol_conf.sym_list_str, "symbol") < 0)
1470                 goto out_free_comm_list;
1471
1472         /*
1473          * A path to symbols of "/" is identical to ""
1474          * reset here for simplicity.
1475          */
1476         symfs = realpath(symbol_conf.symfs, NULL);
1477         if (symfs == NULL)
1478                 symfs = symbol_conf.symfs;
1479         if (strcmp(symfs, "/") == 0)
1480                 symbol_conf.symfs = "";
1481         if (symfs != symbol_conf.symfs)
1482                 free((void *)symfs);
1483
1484         symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
1485
1486         symbol_conf.initialized = true;
1487         return 0;
1488
1489 out_free_comm_list:
1490         strlist__delete(symbol_conf.comm_list);
1491 out_free_dso_list:
1492         strlist__delete(symbol_conf.dso_list);
1493         return -1;
1494 }
1495
1496 void symbol__exit(void)
1497 {
1498         if (!symbol_conf.initialized)
1499                 return;
1500         strlist__delete(symbol_conf.sym_list);
1501         strlist__delete(symbol_conf.dso_list);
1502         strlist__delete(symbol_conf.comm_list);
1503         vmlinux_path__exit();
1504         symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
1505         symbol_conf.initialized = false;
1506 }