diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-07-22 08:14:32 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-07-25 10:32:36 -0400 |
commit | 44f24cb3156a1e7d2b6bb501b7f6153aed08994c (patch) | |
tree | 4976180e4efe6296ab182d797a429fea8cc9378e /tools/perf/util/symbol.c | |
parent | 6654f5d8bdaa438b1e60dfeb90f9d46ca969c012 (diff) |
perf symbols: Factor DSO symtab types to generic binary types
Adding interface to access DSOs so it could be used
from another place.
New DSO binary type is added - making current SYMTAB__*
types more general:
DSO_BINARY_TYPE__* = SYMTAB__*
Following function is added to return path based on the specified
binary type:
dso__binary_type_file
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Benjamin Redelings <benjamin.redelings@nescent.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Ulrich Drepper <drepper@gmail.com>
Link: http://lkml.kernel.org/r/1342959280-5361-10-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 209 |
1 files changed, 125 insertions, 84 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 66c132e52875..60677a63bc7d 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -48,6 +48,23 @@ struct symbol_conf symbol_conf = { | |||
48 | .symfs = "", | 48 | .symfs = "", |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static enum dso_binary_type binary_type_symtab[] = { | ||
52 | DSO_BINARY_TYPE__KALLSYMS, | ||
53 | DSO_BINARY_TYPE__GUEST_KALLSYMS, | ||
54 | DSO_BINARY_TYPE__JAVA_JIT, | ||
55 | DSO_BINARY_TYPE__DEBUGLINK, | ||
56 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | ||
57 | DSO_BINARY_TYPE__FEDORA_DEBUGINFO, | ||
58 | DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, | ||
59 | DSO_BINARY_TYPE__BUILDID_DEBUGINFO, | ||
60 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | ||
61 | DSO_BINARY_TYPE__GUEST_KMODULE, | ||
62 | DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, | ||
63 | DSO_BINARY_TYPE__NOT_FOUND, | ||
64 | }; | ||
65 | |||
66 | #define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) | ||
67 | |||
51 | int dso__name_len(const struct dso *dso) | 68 | int dso__name_len(const struct dso *dso) |
52 | { | 69 | { |
53 | if (!dso) | 70 | if (!dso) |
@@ -318,7 +335,7 @@ struct dso *dso__new(const char *name) | |||
318 | dso__set_short_name(dso, dso->name); | 335 | dso__set_short_name(dso, dso->name); |
319 | for (i = 0; i < MAP__NR_TYPES; ++i) | 336 | for (i = 0; i < MAP__NR_TYPES; ++i) |
320 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; | 337 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; |
321 | dso->symtab_type = SYMTAB__NOT_FOUND; | 338 | dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; |
322 | dso->loaded = 0; | 339 | dso->loaded = 0; |
323 | dso->sorted_by_name = 0; | 340 | dso->sorted_by_name = 0; |
324 | dso->has_build_id = 0; | 341 | dso->has_build_id = 0; |
@@ -806,9 +823,9 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, | |||
806 | symbols__fixup_end(&dso->symbols[map->type]); | 823 | symbols__fixup_end(&dso->symbols[map->type]); |
807 | 824 | ||
808 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) | 825 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
809 | dso->symtab_type = SYMTAB__GUEST_KALLSYMS; | 826 | dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; |
810 | else | 827 | else |
811 | dso->symtab_type = SYMTAB__KALLSYMS; | 828 | dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; |
812 | 829 | ||
813 | return dso__split_kallsyms(dso, map, filter); | 830 | return dso__split_kallsyms(dso, map, filter); |
814 | } | 831 | } |
@@ -1660,32 +1677,110 @@ out: | |||
1660 | char dso__symtab_origin(const struct dso *dso) | 1677 | char dso__symtab_origin(const struct dso *dso) |
1661 | { | 1678 | { |
1662 | static const char origin[] = { | 1679 | static const char origin[] = { |
1663 | [SYMTAB__KALLSYMS] = 'k', | 1680 | [DSO_BINARY_TYPE__KALLSYMS] = 'k', |
1664 | [SYMTAB__JAVA_JIT] = 'j', | 1681 | [DSO_BINARY_TYPE__JAVA_JIT] = 'j', |
1665 | [SYMTAB__DEBUGLINK] = 'l', | 1682 | [DSO_BINARY_TYPE__DEBUGLINK] = 'l', |
1666 | [SYMTAB__BUILD_ID_CACHE] = 'B', | 1683 | [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', |
1667 | [SYMTAB__FEDORA_DEBUGINFO] = 'f', | 1684 | [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', |
1668 | [SYMTAB__UBUNTU_DEBUGINFO] = 'u', | 1685 | [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', |
1669 | [SYMTAB__BUILDID_DEBUGINFO] = 'b', | 1686 | [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', |
1670 | [SYMTAB__SYSTEM_PATH_DSO] = 'd', | 1687 | [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', |
1671 | [SYMTAB__SYSTEM_PATH_KMODULE] = 'K', | 1688 | [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K', |
1672 | [SYMTAB__GUEST_KALLSYMS] = 'g', | 1689 | [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g', |
1673 | [SYMTAB__GUEST_KMODULE] = 'G', | 1690 | [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G', |
1674 | }; | 1691 | }; |
1675 | 1692 | ||
1676 | if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND) | 1693 | if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) |
1677 | return '!'; | 1694 | return '!'; |
1678 | return origin[dso->symtab_type]; | 1695 | return origin[dso->symtab_type]; |
1679 | } | 1696 | } |
1680 | 1697 | ||
1698 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | ||
1699 | char *root_dir, char *file, size_t size) | ||
1700 | { | ||
1701 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
1702 | int ret = 0; | ||
1703 | |||
1704 | switch (type) { | ||
1705 | case DSO_BINARY_TYPE__DEBUGLINK: { | ||
1706 | char *debuglink; | ||
1707 | |||
1708 | strncpy(file, dso->long_name, size); | ||
1709 | debuglink = file + dso->long_name_len; | ||
1710 | while (debuglink != file && *debuglink != '/') | ||
1711 | debuglink--; | ||
1712 | if (*debuglink == '/') | ||
1713 | debuglink++; | ||
1714 | filename__read_debuglink(dso->long_name, debuglink, | ||
1715 | size - (debuglink - file)); | ||
1716 | } | ||
1717 | break; | ||
1718 | case DSO_BINARY_TYPE__BUILD_ID_CACHE: | ||
1719 | /* skip the locally configured cache if a symfs is given */ | ||
1720 | if (symbol_conf.symfs[0] || | ||
1721 | (dso__build_id_filename(dso, file, size) == NULL)) | ||
1722 | ret = -1; | ||
1723 | break; | ||
1724 | |||
1725 | case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: | ||
1726 | snprintf(file, size, "%s/usr/lib/debug%s.debug", | ||
1727 | symbol_conf.symfs, dso->long_name); | ||
1728 | break; | ||
1729 | |||
1730 | case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: | ||
1731 | snprintf(file, size, "%s/usr/lib/debug%s", | ||
1732 | symbol_conf.symfs, dso->long_name); | ||
1733 | break; | ||
1734 | |||
1735 | case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: | ||
1736 | if (!dso->has_build_id) { | ||
1737 | ret = -1; | ||
1738 | break; | ||
1739 | } | ||
1740 | |||
1741 | build_id__sprintf(dso->build_id, | ||
1742 | sizeof(dso->build_id), | ||
1743 | build_id_hex); | ||
1744 | snprintf(file, size, | ||
1745 | "%s/usr/lib/debug/.build-id/%.2s/%s.debug", | ||
1746 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); | ||
1747 | break; | ||
1748 | |||
1749 | case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: | ||
1750 | snprintf(file, size, "%s%s", | ||
1751 | symbol_conf.symfs, dso->long_name); | ||
1752 | break; | ||
1753 | |||
1754 | case DSO_BINARY_TYPE__GUEST_KMODULE: | ||
1755 | snprintf(file, size, "%s%s%s", symbol_conf.symfs, | ||
1756 | root_dir, dso->long_name); | ||
1757 | break; | ||
1758 | |||
1759 | case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: | ||
1760 | snprintf(file, size, "%s%s", symbol_conf.symfs, | ||
1761 | dso->long_name); | ||
1762 | break; | ||
1763 | |||
1764 | default: | ||
1765 | case DSO_BINARY_TYPE__KALLSYMS: | ||
1766 | case DSO_BINARY_TYPE__GUEST_KALLSYMS: | ||
1767 | case DSO_BINARY_TYPE__JAVA_JIT: | ||
1768 | case DSO_BINARY_TYPE__NOT_FOUND: | ||
1769 | ret = -1; | ||
1770 | break; | ||
1771 | } | ||
1772 | |||
1773 | return ret; | ||
1774 | } | ||
1775 | |||
1681 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | 1776 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) |
1682 | { | 1777 | { |
1683 | int size = PATH_MAX; | ||
1684 | char *name; | 1778 | char *name; |
1685 | int ret = -1; | 1779 | int ret = -1; |
1686 | int fd; | 1780 | int fd; |
1781 | u_int i; | ||
1687 | struct machine *machine; | 1782 | struct machine *machine; |
1688 | const char *root_dir; | 1783 | char *root_dir = (char *) ""; |
1689 | int want_symtab; | 1784 | int want_symtab; |
1690 | 1785 | ||
1691 | dso__set_loaded(dso, map->type); | 1786 | dso__set_loaded(dso, map->type); |
@@ -1700,7 +1795,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1700 | else | 1795 | else |
1701 | machine = NULL; | 1796 | machine = NULL; |
1702 | 1797 | ||
1703 | name = malloc(size); | 1798 | name = malloc(PATH_MAX); |
1704 | if (!name) | 1799 | if (!name) |
1705 | return -1; | 1800 | return -1; |
1706 | 1801 | ||
@@ -1719,81 +1814,27 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1719 | } | 1814 | } |
1720 | 1815 | ||
1721 | ret = dso__load_perf_map(dso, map, filter); | 1816 | ret = dso__load_perf_map(dso, map, filter); |
1722 | dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : | 1817 | dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : |
1723 | SYMTAB__NOT_FOUND; | 1818 | DSO_BINARY_TYPE__NOT_FOUND; |
1724 | return ret; | 1819 | return ret; |
1725 | } | 1820 | } |
1726 | 1821 | ||
1822 | if (machine) | ||
1823 | root_dir = machine->root_dir; | ||
1824 | |||
1727 | /* Iterate over candidate debug images. | 1825 | /* Iterate over candidate debug images. |
1728 | * On the first pass, only load images if they have a full symtab. | 1826 | * On the first pass, only load images if they have a full symtab. |
1729 | * Failing that, do a second pass where we accept .dynsym also | 1827 | * Failing that, do a second pass where we accept .dynsym also |
1730 | */ | 1828 | */ |
1731 | want_symtab = 1; | 1829 | want_symtab = 1; |
1732 | restart: | 1830 | restart: |
1733 | for (dso->symtab_type = SYMTAB__DEBUGLINK; | 1831 | for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { |
1734 | dso->symtab_type != SYMTAB__NOT_FOUND; | ||
1735 | dso->symtab_type++) { | ||
1736 | switch (dso->symtab_type) { | ||
1737 | case SYMTAB__DEBUGLINK: { | ||
1738 | char *debuglink; | ||
1739 | strncpy(name, dso->long_name, size); | ||
1740 | debuglink = name + dso->long_name_len; | ||
1741 | while (debuglink != name && *debuglink != '/') | ||
1742 | debuglink--; | ||
1743 | if (*debuglink == '/') | ||
1744 | debuglink++; | ||
1745 | filename__read_debuglink(dso->long_name, debuglink, | ||
1746 | size - (debuglink - name)); | ||
1747 | } | ||
1748 | break; | ||
1749 | case SYMTAB__BUILD_ID_CACHE: | ||
1750 | /* skip the locally configured cache if a symfs is given */ | ||
1751 | if (symbol_conf.symfs[0] || | ||
1752 | (dso__build_id_filename(dso, name, size) == NULL)) { | ||
1753 | continue; | ||
1754 | } | ||
1755 | break; | ||
1756 | case SYMTAB__FEDORA_DEBUGINFO: | ||
1757 | snprintf(name, size, "%s/usr/lib/debug%s.debug", | ||
1758 | symbol_conf.symfs, dso->long_name); | ||
1759 | break; | ||
1760 | case SYMTAB__UBUNTU_DEBUGINFO: | ||
1761 | snprintf(name, size, "%s/usr/lib/debug%s", | ||
1762 | symbol_conf.symfs, dso->long_name); | ||
1763 | break; | ||
1764 | case SYMTAB__BUILDID_DEBUGINFO: { | ||
1765 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
1766 | |||
1767 | if (!dso->has_build_id) | ||
1768 | continue; | ||
1769 | 1832 | ||
1770 | build_id__sprintf(dso->build_id, | 1833 | dso->symtab_type = binary_type_symtab[i]; |
1771 | sizeof(dso->build_id), | ||
1772 | build_id_hex); | ||
1773 | snprintf(name, size, | ||
1774 | "%s/usr/lib/debug/.build-id/%.2s/%s.debug", | ||
1775 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); | ||
1776 | } | ||
1777 | break; | ||
1778 | case SYMTAB__SYSTEM_PATH_DSO: | ||
1779 | snprintf(name, size, "%s%s", | ||
1780 | symbol_conf.symfs, dso->long_name); | ||
1781 | break; | ||
1782 | case SYMTAB__GUEST_KMODULE: | ||
1783 | if (map->groups && machine) | ||
1784 | root_dir = machine->root_dir; | ||
1785 | else | ||
1786 | root_dir = ""; | ||
1787 | snprintf(name, size, "%s%s%s", symbol_conf.symfs, | ||
1788 | root_dir, dso->long_name); | ||
1789 | break; | ||
1790 | 1834 | ||
1791 | case SYMTAB__SYSTEM_PATH_KMODULE: | 1835 | if (dso__binary_type_file(dso, dso->symtab_type, |
1792 | snprintf(name, size, "%s%s", symbol_conf.symfs, | 1836 | root_dir, name, PATH_MAX)) |
1793 | dso->long_name); | 1837 | continue; |
1794 | break; | ||
1795 | default:; | ||
1796 | } | ||
1797 | 1838 | ||
1798 | /* Name is now the name of the next image to try */ | 1839 | /* Name is now the name of the next image to try */ |
1799 | fd = open(name, O_RDONLY); | 1840 | fd = open(name, O_RDONLY); |
@@ -2010,9 +2051,9 @@ struct map *machine__new_module(struct machine *machine, u64 start, | |||
2010 | return NULL; | 2051 | return NULL; |
2011 | 2052 | ||
2012 | if (machine__is_host(machine)) | 2053 | if (machine__is_host(machine)) |
2013 | dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE; | 2054 | dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE; |
2014 | else | 2055 | else |
2015 | dso->symtab_type = SYMTAB__GUEST_KMODULE; | 2056 | dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE; |
2016 | map_groups__insert(&machine->kmaps, map); | 2057 | map_groups__insert(&machine->kmaps, map); |
2017 | return map; | 2058 | return map; |
2018 | } | 2059 | } |