diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 236 |
1 files changed, 128 insertions, 108 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e77c33a11de3..4c0146a49063 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -485,7 +485,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
485 | symbol_filter_t filter) | 485 | symbol_filter_t filter) |
486 | { | 486 | { |
487 | struct map_groups *kmaps = map__kmap(map)->kmaps; | 487 | struct map_groups *kmaps = map__kmap(map)->kmaps; |
488 | struct kernel_info *kerninfo = kmaps->this_kerninfo; | 488 | struct machine *machine = kmaps->machine; |
489 | struct map *curr_map = map; | 489 | struct map *curr_map = map; |
490 | struct symbol *pos; | 490 | struct symbol *pos; |
491 | int count = 0; | 491 | int count = 0; |
@@ -508,8 +508,8 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
508 | 508 | ||
509 | if (strcmp(curr_map->dso->short_name, module)) { | 509 | if (strcmp(curr_map->dso->short_name, module)) { |
510 | if (curr_map != map && | 510 | if (curr_map != map && |
511 | self->kernel == DSO_TYPE_GUEST_KERNEL && | 511 | self->kernel == DSO_TYPE_GUEST_KERNEL && |
512 | is_default_guest(kerninfo)) { | 512 | machine__is_default_guest(machine)) { |
513 | /* | 513 | /* |
514 | * We assume all symbols of a module are | 514 | * We assume all symbols of a module are |
515 | * continuous in * kallsyms, so curr_map | 515 | * continuous in * kallsyms, so curr_map |
@@ -527,13 +527,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
527 | pr_err("%s/proc/{kallsyms,modules} " | 527 | pr_err("%s/proc/{kallsyms,modules} " |
528 | "inconsistency while looking " | 528 | "inconsistency while looking " |
529 | "for \"%s\" module!\n", | 529 | "for \"%s\" module!\n", |
530 | kerninfo->root_dir, module); | 530 | machine->root_dir, module); |
531 | curr_map = map; | 531 | curr_map = map; |
532 | goto discard_symbol; | 532 | goto discard_symbol; |
533 | } | 533 | } |
534 | 534 | ||
535 | if (curr_map->dso->loaded && | 535 | if (curr_map->dso->loaded && |
536 | !is_default_guest(kmaps->this_kerninfo)) | 536 | !machine__is_default_guest(machine)) |
537 | goto discard_symbol; | 537 | goto discard_symbol; |
538 | } | 538 | } |
539 | /* | 539 | /* |
@@ -586,7 +586,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
586 | 586 | ||
587 | if (curr_map != map && | 587 | if (curr_map != map && |
588 | self->kernel == DSO_TYPE_GUEST_KERNEL && | 588 | self->kernel == DSO_TYPE_GUEST_KERNEL && |
589 | is_default_guest(kmaps->this_kerninfo)) { | 589 | machine__is_default_guest(kmaps->machine)) { |
590 | dso__set_loaded(curr_map->dso, curr_map->type); | 590 | dso__set_loaded(curr_map->dso, curr_map->type); |
591 | } | 591 | } |
592 | 592 | ||
@@ -1291,7 +1291,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1291 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | 1291 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; |
1292 | int ret = -1; | 1292 | int ret = -1; |
1293 | int fd; | 1293 | int fd; |
1294 | struct kernel_info *kerninfo; | 1294 | struct machine *machine; |
1295 | const char *root_dir; | 1295 | const char *root_dir; |
1296 | 1296 | ||
1297 | dso__set_loaded(self, map->type); | 1297 | dso__set_loaded(self, map->type); |
@@ -1301,10 +1301,10 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1301 | else if (self->kernel == DSO_TYPE_GUEST_KERNEL) | 1301 | else if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
1302 | return dso__load_guest_kernel_sym(self, map, filter); | 1302 | return dso__load_guest_kernel_sym(self, map, filter); |
1303 | 1303 | ||
1304 | if (map->groups && map->groups->this_kerninfo) | 1304 | if (map->groups && map->groups->machine) |
1305 | kerninfo = map->groups->this_kerninfo; | 1305 | machine = map->groups->machine; |
1306 | else | 1306 | else |
1307 | kerninfo = NULL; | 1307 | machine = NULL; |
1308 | 1308 | ||
1309 | name = malloc(size); | 1309 | name = malloc(size); |
1310 | if (!name) | 1310 | if (!name) |
@@ -1359,8 +1359,8 @@ more: | |||
1359 | snprintf(name, size, "%s", self->long_name); | 1359 | snprintf(name, size, "%s", self->long_name); |
1360 | break; | 1360 | break; |
1361 | case DSO__ORIG_GUEST_KMODULE: | 1361 | case DSO__ORIG_GUEST_KMODULE: |
1362 | if (map->groups && map->groups->this_kerninfo) | 1362 | if (map->groups && map->groups->machine) |
1363 | root_dir = map->groups->this_kerninfo->root_dir; | 1363 | root_dir = map->groups->machine->root_dir; |
1364 | else | 1364 | else |
1365 | root_dir = ""; | 1365 | root_dir = ""; |
1366 | snprintf(name, size, "%s%s", root_dir, self->long_name); | 1366 | snprintf(name, size, "%s%s", root_dir, self->long_name); |
@@ -1528,21 +1528,20 @@ static char *get_kernel_version(const char *root_dir) | |||
1528 | return strdup(name); | 1528 | return strdup(name); |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | static int map_groups__set_modules_path(struct map_groups *self, | 1531 | static int machine__set_modules_path(struct machine *self) |
1532 | const char *root_dir) | ||
1533 | { | 1532 | { |
1534 | char *version; | 1533 | char *version; |
1535 | char modules_path[PATH_MAX]; | 1534 | char modules_path[PATH_MAX]; |
1536 | 1535 | ||
1537 | version = get_kernel_version(root_dir); | 1536 | version = get_kernel_version(self->root_dir); |
1538 | if (!version) | 1537 | if (!version) |
1539 | return -1; | 1538 | return -1; |
1540 | 1539 | ||
1541 | snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", | 1540 | snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", |
1542 | root_dir, version); | 1541 | self->root_dir, version); |
1543 | free(version); | 1542 | free(version); |
1544 | 1543 | ||
1545 | return map_groups__set_modules_path_dir(self, modules_path); | 1544 | return map_groups__set_modules_path_dir(&self->kmaps, modules_path); |
1546 | } | 1545 | } |
1547 | 1546 | ||
1548 | /* | 1547 | /* |
@@ -1564,14 +1563,12 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) | |||
1564 | return self; | 1563 | return self; |
1565 | } | 1564 | } |
1566 | 1565 | ||
1567 | struct map *map_groups__new_module(struct map_groups *self, u64 start, | 1566 | struct map *machine__new_module(struct machine *self, u64 start, |
1568 | const char *filename, | 1567 | const char *filename) |
1569 | struct kernel_info *kerninfo) | ||
1570 | { | 1568 | { |
1571 | struct map *map; | 1569 | struct map *map; |
1572 | struct dso *dso; | 1570 | struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename); |
1573 | 1571 | ||
1574 | dso = __dsos__findnew(&kerninfo->dsos__kernel, filename); | ||
1575 | if (dso == NULL) | 1572 | if (dso == NULL) |
1576 | return NULL; | 1573 | return NULL; |
1577 | 1574 | ||
@@ -1579,28 +1576,27 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start, | |||
1579 | if (map == NULL) | 1576 | if (map == NULL) |
1580 | return NULL; | 1577 | return NULL; |
1581 | 1578 | ||
1582 | if (is_host_kernel(kerninfo)) | 1579 | if (machine__is_host(self)) |
1583 | dso->origin = DSO__ORIG_KMODULE; | 1580 | dso->origin = DSO__ORIG_KMODULE; |
1584 | else | 1581 | else |
1585 | dso->origin = DSO__ORIG_GUEST_KMODULE; | 1582 | dso->origin = DSO__ORIG_GUEST_KMODULE; |
1586 | map_groups__insert(self, map); | 1583 | map_groups__insert(&self->kmaps, map); |
1587 | return map; | 1584 | return map; |
1588 | } | 1585 | } |
1589 | 1586 | ||
1590 | static int map_groups__create_modules(struct kernel_info *kerninfo) | 1587 | static int machine__create_modules(struct machine *self) |
1591 | { | 1588 | { |
1592 | char *line = NULL; | 1589 | char *line = NULL; |
1593 | size_t n; | 1590 | size_t n; |
1594 | FILE *file; | 1591 | FILE *file; |
1595 | struct map *map; | 1592 | struct map *map; |
1596 | const char *root_dir; | ||
1597 | const char *modules; | 1593 | const char *modules; |
1598 | char path[PATH_MAX]; | 1594 | char path[PATH_MAX]; |
1599 | 1595 | ||
1600 | if (is_default_guest(kerninfo)) | 1596 | if (machine__is_default_guest(self)) |
1601 | modules = symbol_conf.default_guest_modules; | 1597 | modules = symbol_conf.default_guest_modules; |
1602 | else { | 1598 | else { |
1603 | sprintf(path, "%s/proc/modules", kerninfo->root_dir); | 1599 | sprintf(path, "%s/proc/modules", self->root_dir); |
1604 | modules = path; | 1600 | modules = path; |
1605 | } | 1601 | } |
1606 | 1602 | ||
@@ -1608,8 +1604,6 @@ static int map_groups__create_modules(struct kernel_info *kerninfo) | |||
1608 | if (file == NULL) | 1604 | if (file == NULL) |
1609 | return -1; | 1605 | return -1; |
1610 | 1606 | ||
1611 | root_dir = kerninfo->root_dir; | ||
1612 | |||
1613 | while (!feof(file)) { | 1607 | while (!feof(file)) { |
1614 | char name[PATH_MAX]; | 1608 | char name[PATH_MAX]; |
1615 | u64 start; | 1609 | u64 start; |
@@ -1638,17 +1632,16 @@ static int map_groups__create_modules(struct kernel_info *kerninfo) | |||
1638 | *sep = '\0'; | 1632 | *sep = '\0'; |
1639 | 1633 | ||
1640 | snprintf(name, sizeof(name), "[%s]", line); | 1634 | snprintf(name, sizeof(name), "[%s]", line); |
1641 | map = map_groups__new_module(&kerninfo->kmaps, | 1635 | map = machine__new_module(self, start, name); |
1642 | start, name, kerninfo); | ||
1643 | if (map == NULL) | 1636 | if (map == NULL) |
1644 | goto out_delete_line; | 1637 | goto out_delete_line; |
1645 | dso__kernel_module_get_build_id(map->dso, root_dir); | 1638 | dso__kernel_module_get_build_id(map->dso, self->root_dir); |
1646 | } | 1639 | } |
1647 | 1640 | ||
1648 | free(line); | 1641 | free(line); |
1649 | fclose(file); | 1642 | fclose(file); |
1650 | 1643 | ||
1651 | return map_groups__set_modules_path(&kerninfo->kmaps, root_dir); | 1644 | return machine__set_modules_path(self); |
1652 | 1645 | ||
1653 | out_delete_line: | 1646 | out_delete_line: |
1654 | free(line); | 1647 | free(line); |
@@ -1820,16 +1813,16 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, | |||
1820 | { | 1813 | { |
1821 | int err; | 1814 | int err; |
1822 | const char *kallsyms_filename = NULL; | 1815 | const char *kallsyms_filename = NULL; |
1823 | struct kernel_info *kerninfo; | 1816 | struct machine *machine; |
1824 | char path[PATH_MAX]; | 1817 | char path[PATH_MAX]; |
1825 | 1818 | ||
1826 | if (!map->groups) { | 1819 | if (!map->groups) { |
1827 | pr_debug("Guest kernel map hasn't the point to groups\n"); | 1820 | pr_debug("Guest kernel map hasn't the point to groups\n"); |
1828 | return -1; | 1821 | return -1; |
1829 | } | 1822 | } |
1830 | kerninfo = map->groups->this_kerninfo; | 1823 | machine = map->groups->machine; |
1831 | 1824 | ||
1832 | if (is_default_guest(kerninfo)) { | 1825 | if (machine__is_default_guest(machine)) { |
1833 | /* | 1826 | /* |
1834 | * if the user specified a vmlinux filename, use it and only | 1827 | * if the user specified a vmlinux filename, use it and only |
1835 | * it, reporting errors to the user if it cannot be used. | 1828 | * it, reporting errors to the user if it cannot be used. |
@@ -1845,7 +1838,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, | |||
1845 | if (!kallsyms_filename) | 1838 | if (!kallsyms_filename) |
1846 | return -1; | 1839 | return -1; |
1847 | } else { | 1840 | } else { |
1848 | sprintf(path, "%s/proc/kallsyms", kerninfo->root_dir); | 1841 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); |
1849 | kallsyms_filename = path; | 1842 | kallsyms_filename = path; |
1850 | } | 1843 | } |
1851 | 1844 | ||
@@ -1856,9 +1849,8 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, | |||
1856 | out_try_fixup: | 1849 | out_try_fixup: |
1857 | if (err > 0) { | 1850 | if (err > 0) { |
1858 | if (kallsyms_filename != NULL) { | 1851 | if (kallsyms_filename != NULL) { |
1859 | kern_mmap_name(kerninfo, path); | 1852 | machine__mmap_name(machine, path, sizeof(path)); |
1860 | dso__set_long_name(self, | 1853 | dso__set_long_name(self, strdup(path)); |
1861 | strdup(path)); | ||
1862 | } | 1854 | } |
1863 | map__fixup_start(map); | 1855 | map__fixup_start(map); |
1864 | map__fixup_end(map); | 1856 | map__fixup_end(map); |
@@ -1897,27 +1889,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name) | |||
1897 | return dso; | 1889 | return dso; |
1898 | } | 1890 | } |
1899 | 1891 | ||
1900 | static void __dsos__fprintf(struct list_head *head, FILE *fp) | 1892 | static size_t __dsos__fprintf(struct list_head *head, FILE *fp) |
1901 | { | 1893 | { |
1902 | struct dso *pos; | 1894 | struct dso *pos; |
1895 | size_t ret = 0; | ||
1903 | 1896 | ||
1904 | list_for_each_entry(pos, head, node) { | 1897 | list_for_each_entry(pos, head, node) { |
1905 | int i; | 1898 | int i; |
1906 | for (i = 0; i < MAP__NR_TYPES; ++i) | 1899 | for (i = 0; i < MAP__NR_TYPES; ++i) |
1907 | dso__fprintf(pos, i, fp); | 1900 | ret += dso__fprintf(pos, i, fp); |
1908 | } | 1901 | } |
1902 | |||
1903 | return ret; | ||
1909 | } | 1904 | } |
1910 | 1905 | ||
1911 | void dsos__fprintf(struct rb_root *kerninfo_root, FILE *fp) | 1906 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp) |
1912 | { | 1907 | { |
1913 | struct rb_node *nd; | 1908 | struct rb_node *nd; |
1909 | size_t ret = 0; | ||
1914 | 1910 | ||
1915 | for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { | 1911 | for (nd = rb_first(self); nd; nd = rb_next(nd)) { |
1916 | struct kernel_info *pos = rb_entry(nd, struct kernel_info, | 1912 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
1917 | rb_node); | 1913 | ret += __dsos__fprintf(&pos->kernel_dsos, fp); |
1918 | __dsos__fprintf(&pos->dsos__kernel, fp); | 1914 | ret += __dsos__fprintf(&pos->user_dsos, fp); |
1919 | __dsos__fprintf(&pos->dsos__user, fp); | ||
1920 | } | 1915 | } |
1916 | |||
1917 | return ret; | ||
1921 | } | 1918 | } |
1922 | 1919 | ||
1923 | static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | 1920 | static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, |
@@ -1935,19 +1932,15 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | |||
1935 | return ret; | 1932 | return ret; |
1936 | } | 1933 | } |
1937 | 1934 | ||
1938 | size_t dsos__fprintf_buildid(struct rb_root *kerninfo_root, | 1935 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits) |
1939 | FILE *fp, bool with_hits) | ||
1940 | { | 1936 | { |
1941 | struct rb_node *nd; | 1937 | struct rb_node *nd; |
1942 | size_t ret = 0; | 1938 | size_t ret = 0; |
1943 | 1939 | ||
1944 | for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { | 1940 | for (nd = rb_first(self); nd; nd = rb_next(nd)) { |
1945 | struct kernel_info *pos = rb_entry(nd, struct kernel_info, | 1941 | struct machine *pos = rb_entry(nd, struct machine, rb_node); |
1946 | rb_node); | 1942 | ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits); |
1947 | ret += __dsos__fprintf_buildid(&pos->dsos__kernel, | 1943 | ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits); |
1948 | fp, with_hits); | ||
1949 | ret += __dsos__fprintf_buildid(&pos->dsos__user, | ||
1950 | fp, with_hits); | ||
1951 | } | 1944 | } |
1952 | return ret; | 1945 | return ret; |
1953 | } | 1946 | } |
@@ -1964,14 +1957,12 @@ struct dso *dso__new_kernel(const char *name) | |||
1964 | return self; | 1957 | return self; |
1965 | } | 1958 | } |
1966 | 1959 | ||
1967 | static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo, | 1960 | static struct dso *dso__new_guest_kernel(struct machine *machine, |
1968 | const char *name) | 1961 | const char *name) |
1969 | { | 1962 | { |
1970 | char buff[PATH_MAX]; | 1963 | char bf[PATH_MAX]; |
1971 | struct dso *self; | 1964 | struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf))); |
1972 | 1965 | ||
1973 | kern_mmap_name(kerninfo, buff); | ||
1974 | self = dso__new(name ?: buff); | ||
1975 | if (self != NULL) { | 1966 | if (self != NULL) { |
1976 | dso__set_short_name(self, "[guest.kernel]"); | 1967 | dso__set_short_name(self, "[guest.kernel]"); |
1977 | self->kernel = DSO_TYPE_GUEST_KERNEL; | 1968 | self->kernel = DSO_TYPE_GUEST_KERNEL; |
@@ -1980,64 +1971,78 @@ static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo, | |||
1980 | return self; | 1971 | return self; |
1981 | } | 1972 | } |
1982 | 1973 | ||
1983 | void dso__read_running_kernel_build_id(struct dso *self, | 1974 | void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine) |
1984 | struct kernel_info *kerninfo) | ||
1985 | { | 1975 | { |
1986 | char path[PATH_MAX]; | 1976 | char path[PATH_MAX]; |
1987 | 1977 | ||
1988 | if (is_default_guest(kerninfo)) | 1978 | if (machine__is_default_guest(machine)) |
1989 | return; | 1979 | return; |
1990 | sprintf(path, "%s/sys/kernel/notes", kerninfo->root_dir); | 1980 | sprintf(path, "%s/sys/kernel/notes", machine->root_dir); |
1991 | if (sysfs__read_build_id(path, self->build_id, | 1981 | if (sysfs__read_build_id(path, self->build_id, |
1992 | sizeof(self->build_id)) == 0) | 1982 | sizeof(self->build_id)) == 0) |
1993 | self->has_build_id = true; | 1983 | self->has_build_id = true; |
1994 | } | 1984 | } |
1995 | 1985 | ||
1996 | static struct dso *dsos__create_kernel(struct kernel_info *kerninfo) | 1986 | static struct dso *machine__create_kernel(struct machine *self) |
1997 | { | 1987 | { |
1998 | const char *vmlinux_name = NULL; | 1988 | const char *vmlinux_name = NULL; |
1999 | struct dso *kernel; | 1989 | struct dso *kernel; |
2000 | 1990 | ||
2001 | if (is_host_kernel(kerninfo)) { | 1991 | if (machine__is_host(self)) { |
2002 | vmlinux_name = symbol_conf.vmlinux_name; | 1992 | vmlinux_name = symbol_conf.vmlinux_name; |
2003 | kernel = dso__new_kernel(vmlinux_name); | 1993 | kernel = dso__new_kernel(vmlinux_name); |
2004 | } else { | 1994 | } else { |
2005 | if (is_default_guest(kerninfo)) | 1995 | if (machine__is_default_guest(self)) |
2006 | vmlinux_name = symbol_conf.default_guest_vmlinux_name; | 1996 | vmlinux_name = symbol_conf.default_guest_vmlinux_name; |
2007 | kernel = dso__new_guest_kernel(kerninfo, vmlinux_name); | 1997 | kernel = dso__new_guest_kernel(self, vmlinux_name); |
2008 | } | 1998 | } |
2009 | 1999 | ||
2010 | if (kernel != NULL) { | 2000 | if (kernel != NULL) { |
2011 | dso__read_running_kernel_build_id(kernel, kerninfo); | 2001 | dso__read_running_kernel_build_id(kernel, self); |
2012 | dsos__add(&kerninfo->dsos__kernel, kernel); | 2002 | dsos__add(&self->kernel_dsos, kernel); |
2013 | } | 2003 | } |
2014 | return kernel; | 2004 | return kernel; |
2015 | } | 2005 | } |
2016 | 2006 | ||
2017 | int __map_groups__create_kernel_maps(struct map_groups *self, | 2007 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) |
2018 | struct map *vmlinux_maps[MAP__NR_TYPES], | ||
2019 | struct dso *kernel) | ||
2020 | { | 2008 | { |
2021 | enum map_type type; | 2009 | enum map_type type; |
2022 | 2010 | ||
2023 | for (type = 0; type < MAP__NR_TYPES; ++type) { | 2011 | for (type = 0; type < MAP__NR_TYPES; ++type) { |
2024 | struct kmap *kmap; | 2012 | struct kmap *kmap; |
2025 | 2013 | ||
2026 | vmlinux_maps[type] = map__new2(0, kernel, type); | 2014 | self->vmlinux_maps[type] = map__new2(0, kernel, type); |
2027 | if (vmlinux_maps[type] == NULL) | 2015 | if (self->vmlinux_maps[type] == NULL) |
2028 | return -1; | 2016 | return -1; |
2029 | 2017 | ||
2030 | vmlinux_maps[type]->map_ip = | 2018 | self->vmlinux_maps[type]->map_ip = |
2031 | vmlinux_maps[type]->unmap_ip = identity__map_ip; | 2019 | self->vmlinux_maps[type]->unmap_ip = identity__map_ip; |
2032 | 2020 | ||
2033 | kmap = map__kmap(vmlinux_maps[type]); | 2021 | kmap = map__kmap(self->vmlinux_maps[type]); |
2034 | kmap->kmaps = self; | 2022 | kmap->kmaps = &self->kmaps; |
2035 | map_groups__insert(self, vmlinux_maps[type]); | 2023 | map_groups__insert(&self->kmaps, self->vmlinux_maps[type]); |
2036 | } | 2024 | } |
2037 | 2025 | ||
2038 | return 0; | 2026 | return 0; |
2039 | } | 2027 | } |
2040 | 2028 | ||
2029 | int machine__create_kernel_maps(struct machine *self) | ||
2030 | { | ||
2031 | struct dso *kernel = machine__create_kernel(self); | ||
2032 | |||
2033 | if (kernel == NULL || | ||
2034 | __machine__create_kernel_maps(self, kernel) < 0) | ||
2035 | return -1; | ||
2036 | |||
2037 | if (symbol_conf.use_modules && machine__create_modules(self) < 0) | ||
2038 | pr_debug("Problems creating module maps, continuing anyway...\n"); | ||
2039 | /* | ||
2040 | * Now that we have all the maps created, just set the ->end of them: | ||
2041 | */ | ||
2042 | map_groups__fixup_end(&self->kmaps); | ||
2043 | return 0; | ||
2044 | } | ||
2045 | |||
2041 | static void vmlinux_path__exit(void) | 2046 | static void vmlinux_path__exit(void) |
2042 | { | 2047 | { |
2043 | while (--vmlinux_path__nr_entries >= 0) { | 2048 | while (--vmlinux_path__nr_entries >= 0) { |
@@ -2154,30 +2159,14 @@ out_free_comm_list: | |||
2154 | return -1; | 2159 | return -1; |
2155 | } | 2160 | } |
2156 | 2161 | ||
2157 | int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid) | 2162 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid) |
2158 | { | 2163 | { |
2159 | struct kernel_info *kerninfo; | 2164 | struct machine *machine = machines__findnew(self, pid); |
2160 | struct dso *kernel; | ||
2161 | |||
2162 | kerninfo = kerninfo__findnew(kerninfo_root, pid); | ||
2163 | if (kerninfo == NULL) | ||
2164 | return -1; | ||
2165 | kernel = dsos__create_kernel(kerninfo); | ||
2166 | if (kernel == NULL) | ||
2167 | return -1; | ||
2168 | 2165 | ||
2169 | if (__map_groups__create_kernel_maps(&kerninfo->kmaps, | 2166 | if (machine == NULL) |
2170 | kerninfo->vmlinux_maps, kernel) < 0) | ||
2171 | return -1; | 2167 | return -1; |
2172 | 2168 | ||
2173 | if (symbol_conf.use_modules && | 2169 | return machine__create_kernel_maps(machine); |
2174 | map_groups__create_modules(kerninfo) < 0) | ||
2175 | pr_debug("Problems creating module maps, continuing anyway...\n"); | ||
2176 | /* | ||
2177 | * Now that we have all the maps created, just set the ->end of them: | ||
2178 | */ | ||
2179 | map_groups__fixup_end(&kerninfo->kmaps); | ||
2180 | return 0; | ||
2181 | } | 2170 | } |
2182 | 2171 | ||
2183 | static int hex(char ch) | 2172 | static int hex(char ch) |
@@ -2223,7 +2212,7 @@ char *strxfrchar(char *s, char from, char to) | |||
2223 | return s; | 2212 | return s; |
2224 | } | 2213 | } |
2225 | 2214 | ||
2226 | int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root) | 2215 | int machines__create_guest_kernel_maps(struct rb_root *self) |
2227 | { | 2216 | { |
2228 | int ret = 0; | 2217 | int ret = 0; |
2229 | struct dirent **namelist = NULL; | 2218 | struct dirent **namelist = NULL; |
@@ -2234,8 +2223,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root) | |||
2234 | if (symbol_conf.default_guest_vmlinux_name || | 2223 | if (symbol_conf.default_guest_vmlinux_name || |
2235 | symbol_conf.default_guest_modules || | 2224 | symbol_conf.default_guest_modules || |
2236 | symbol_conf.default_guest_kallsyms) { | 2225 | symbol_conf.default_guest_kallsyms) { |
2237 | map_groups__create_kernel_maps(kerninfo_root, | 2226 | machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID); |
2238 | DEFAULT_GUEST_KERNEL_ID); | ||
2239 | } | 2227 | } |
2240 | 2228 | ||
2241 | if (symbol_conf.guestmount) { | 2229 | if (symbol_conf.guestmount) { |
@@ -2256,8 +2244,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root) | |||
2256 | pr_debug("Can't access file %s\n", path); | 2244 | pr_debug("Can't access file %s\n", path); |
2257 | goto failure; | 2245 | goto failure; |
2258 | } | 2246 | } |
2259 | map_groups__create_kernel_maps(kerninfo_root, | 2247 | machines__create_kernel_maps(self, pid); |
2260 | pid); | ||
2261 | } | 2248 | } |
2262 | failure: | 2249 | failure: |
2263 | free(namelist); | 2250 | free(namelist); |
@@ -2265,3 +2252,36 @@ failure: | |||
2265 | 2252 | ||
2266 | return ret; | 2253 | return ret; |
2267 | } | 2254 | } |
2255 | |||
2256 | int machine__load_kallsyms(struct machine *self, const char *filename, | ||
2257 | enum map_type type, symbol_filter_t filter) | ||
2258 | { | ||
2259 | struct map *map = self->vmlinux_maps[type]; | ||
2260 | int ret = dso__load_kallsyms(map->dso, filename, map, filter); | ||
2261 | |||
2262 | if (ret > 0) { | ||
2263 | dso__set_loaded(map->dso, type); | ||
2264 | /* | ||
2265 | * Since /proc/kallsyms will have multiple sessions for the | ||
2266 | * kernel, with modules between them, fixup the end of all | ||
2267 | * sections. | ||
2268 | */ | ||
2269 | __map_groups__fixup_end(&self->kmaps, type); | ||
2270 | } | ||
2271 | |||
2272 | return ret; | ||
2273 | } | ||
2274 | |||
2275 | int machine__load_vmlinux_path(struct machine *self, enum map_type type, | ||
2276 | symbol_filter_t filter) | ||
2277 | { | ||
2278 | struct map *map = self->vmlinux_maps[type]; | ||
2279 | int ret = dso__load_vmlinux_path(map->dso, map, filter); | ||
2280 | |||
2281 | if (ret > 0) { | ||
2282 | dso__set_loaded(map->dso, type); | ||
2283 | map__reloc_vmlinux(map); | ||
2284 | } | ||
2285 | |||
2286 | return ret; | ||
2287 | } | ||