diff options
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r-- | tools/perf/util/machine.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 84cdb072ac83..620a1983b76b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "strlist.h" | 9 | #include "strlist.h" |
10 | #include "thread.h" | 10 | #include "thread.h" |
11 | #include <stdbool.h> | 11 | #include <stdbool.h> |
12 | #include <symbol/kallsyms.h> | ||
12 | #include "unwind.h" | 13 | #include "unwind.h" |
13 | 14 | ||
14 | int machine__init(struct machine *machine, const char *root_dir, pid_t pid) | 15 | int machine__init(struct machine *machine, const char *root_dir, pid_t pid) |
@@ -26,6 +27,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) | |||
26 | machine->pid = pid; | 27 | machine->pid = pid; |
27 | 28 | ||
28 | machine->symbol_filter = NULL; | 29 | machine->symbol_filter = NULL; |
30 | machine->id_hdr_size = 0; | ||
29 | 31 | ||
30 | machine->root_dir = strdup(root_dir); | 32 | machine->root_dir = strdup(root_dir); |
31 | if (machine->root_dir == NULL) | 33 | if (machine->root_dir == NULL) |
@@ -101,8 +103,7 @@ void machine__exit(struct machine *machine) | |||
101 | map_groups__exit(&machine->kmaps); | 103 | map_groups__exit(&machine->kmaps); |
102 | dsos__delete(&machine->user_dsos); | 104 | dsos__delete(&machine->user_dsos); |
103 | dsos__delete(&machine->kernel_dsos); | 105 | dsos__delete(&machine->kernel_dsos); |
104 | free(machine->root_dir); | 106 | zfree(&machine->root_dir); |
105 | machine->root_dir = NULL; | ||
106 | } | 107 | } |
107 | 108 | ||
108 | void machine__delete(struct machine *machine) | 109 | void machine__delete(struct machine *machine) |
@@ -495,23 +496,22 @@ static int symbol__in_kernel(void *arg, const char *name, | |||
495 | return 1; | 496 | return 1; |
496 | } | 497 | } |
497 | 498 | ||
499 | static void machine__get_kallsyms_filename(struct machine *machine, char *buf, | ||
500 | size_t bufsz) | ||
501 | { | ||
502 | if (machine__is_default_guest(machine)) | ||
503 | scnprintf(buf, bufsz, "%s", symbol_conf.default_guest_kallsyms); | ||
504 | else | ||
505 | scnprintf(buf, bufsz, "%s/proc/kallsyms", machine->root_dir); | ||
506 | } | ||
507 | |||
498 | /* Figure out the start address of kernel map from /proc/kallsyms */ | 508 | /* Figure out the start address of kernel map from /proc/kallsyms */ |
499 | static u64 machine__get_kernel_start_addr(struct machine *machine) | 509 | static u64 machine__get_kernel_start_addr(struct machine *machine) |
500 | { | 510 | { |
501 | const char *filename; | 511 | char filename[PATH_MAX]; |
502 | char path[PATH_MAX]; | ||
503 | struct process_args args; | 512 | struct process_args args; |
504 | 513 | ||
505 | if (machine__is_host(machine)) { | 514 | machine__get_kallsyms_filename(machine, filename, PATH_MAX); |
506 | filename = "/proc/kallsyms"; | ||
507 | } else { | ||
508 | if (machine__is_default_guest(machine)) | ||
509 | filename = (char *)symbol_conf.default_guest_kallsyms; | ||
510 | else { | ||
511 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
512 | filename = path; | ||
513 | } | ||
514 | } | ||
515 | 515 | ||
516 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | 516 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) |
517 | return 0; | 517 | return 0; |
@@ -565,11 +565,10 @@ void machine__destroy_kernel_maps(struct machine *machine) | |||
565 | * on one of them. | 565 | * on one of them. |
566 | */ | 566 | */ |
567 | if (type == MAP__FUNCTION) { | 567 | if (type == MAP__FUNCTION) { |
568 | free((char *)kmap->ref_reloc_sym->name); | 568 | zfree((char **)&kmap->ref_reloc_sym->name); |
569 | kmap->ref_reloc_sym->name = NULL; | 569 | zfree(&kmap->ref_reloc_sym); |
570 | free(kmap->ref_reloc_sym); | 570 | } else |
571 | } | 571 | kmap->ref_reloc_sym = NULL; |
572 | kmap->ref_reloc_sym = NULL; | ||
573 | } | 572 | } |
574 | 573 | ||
575 | map__delete(machine->vmlinux_maps[type]); | 574 | map__delete(machine->vmlinux_maps[type]); |
@@ -767,8 +766,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, | |||
767 | ret = -1; | 766 | ret = -1; |
768 | goto out; | 767 | goto out; |
769 | } | 768 | } |
770 | dso__set_long_name(map->dso, long_name); | 769 | dso__set_long_name(map->dso, long_name, true); |
771 | map->dso->lname_alloc = 1; | ||
772 | dso__kernel_module_get_build_id(map->dso, ""); | 770 | dso__kernel_module_get_build_id(map->dso, ""); |
773 | } | 771 | } |
774 | } | 772 | } |
@@ -834,9 +832,25 @@ static int machine__create_modules(struct machine *machine) | |||
834 | return 0; | 832 | return 0; |
835 | } | 833 | } |
836 | 834 | ||
835 | const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; | ||
836 | |||
837 | int machine__create_kernel_maps(struct machine *machine) | 837 | int machine__create_kernel_maps(struct machine *machine) |
838 | { | 838 | { |
839 | struct dso *kernel = machine__get_kernel(machine); | 839 | struct dso *kernel = machine__get_kernel(machine); |
840 | char filename[PATH_MAX]; | ||
841 | const char *name; | ||
842 | u64 addr = 0; | ||
843 | int i; | ||
844 | |||
845 | machine__get_kallsyms_filename(machine, filename, PATH_MAX); | ||
846 | |||
847 | for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { | ||
848 | addr = kallsyms__get_function_start(filename, name); | ||
849 | if (addr) | ||
850 | break; | ||
851 | } | ||
852 | if (!addr) | ||
853 | return -1; | ||
840 | 854 | ||
841 | if (kernel == NULL || | 855 | if (kernel == NULL || |
842 | __machine__create_kernel_maps(machine, kernel) < 0) | 856 | __machine__create_kernel_maps(machine, kernel) < 0) |
@@ -855,6 +869,13 @@ int machine__create_kernel_maps(struct machine *machine) | |||
855 | * Now that we have all the maps created, just set the ->end of them: | 869 | * Now that we have all the maps created, just set the ->end of them: |
856 | */ | 870 | */ |
857 | map_groups__fixup_end(&machine->kmaps); | 871 | map_groups__fixup_end(&machine->kmaps); |
872 | |||
873 | if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, | ||
874 | addr)) { | ||
875 | machine__destroy_kernel_maps(machine); | ||
876 | return -1; | ||
877 | } | ||
878 | |||
858 | return 0; | 879 | return 0; |
859 | } | 880 | } |
860 | 881 | ||
@@ -939,8 +960,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, | |||
939 | if (name == NULL) | 960 | if (name == NULL) |
940 | goto out_problem; | 961 | goto out_problem; |
941 | 962 | ||
942 | map->dso->short_name = name; | 963 | dso__set_short_name(map->dso, name, true); |
943 | map->dso->sname_alloc = 1; | ||
944 | map->end = map->start + event->mmap.len; | 964 | map->end = map->start + event->mmap.len; |
945 | } else if (is_kernel_mmap) { | 965 | } else if (is_kernel_mmap) { |
946 | const char *symbol_name = (event->mmap.filename + | 966 | const char *symbol_name = (event->mmap.filename + |
@@ -1193,7 +1213,7 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread, | |||
1193 | */ | 1213 | */ |
1194 | thread__find_addr_location(thread, machine, m, MAP__FUNCTION, | 1214 | thread__find_addr_location(thread, machine, m, MAP__FUNCTION, |
1195 | ip, &al); | 1215 | ip, &al); |
1196 | if (al.sym) | 1216 | if (al.map) |
1197 | goto found; | 1217 | goto found; |
1198 | } | 1218 | } |
1199 | found: | 1219 | found: |
@@ -1320,8 +1340,6 @@ static int machine__resolve_callchain_sample(struct machine *machine, | |||
1320 | *root_al = al; | 1340 | *root_al = al; |
1321 | callchain_cursor_reset(&callchain_cursor); | 1341 | callchain_cursor_reset(&callchain_cursor); |
1322 | } | 1342 | } |
1323 | if (!symbol_conf.use_callchain) | ||
1324 | break; | ||
1325 | } | 1343 | } |
1326 | 1344 | ||
1327 | err = callchain_cursor_append(&callchain_cursor, | 1345 | err = callchain_cursor_append(&callchain_cursor, |