diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/header.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3724707425e..6a9c041134b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -1703,21 +1703,41 @@ int perf_file_header__read(struct perf_file_header *header, | |||
1703 | bitmap_zero(header->adds_features, HEADER_FEAT_BITS); | 1703 | bitmap_zero(header->adds_features, HEADER_FEAT_BITS); |
1704 | else | 1704 | else |
1705 | return -1; | 1705 | return -1; |
1706 | } else if (ph->needs_swap) { | ||
1707 | unsigned int i; | ||
1708 | /* | ||
1709 | * feature bitmap is declared as an array of unsigned longs -- | ||
1710 | * not good since its size can differ between the host that | ||
1711 | * generated the data file and the host analyzing the file. | ||
1712 | * | ||
1713 | * We need to handle endianness, but we don't know the size of | ||
1714 | * the unsigned long where the file was generated. Take a best | ||
1715 | * guess at determining it: try 64-bit swap first (ie., file | ||
1716 | * created on a 64-bit host), and check if the hostname feature | ||
1717 | * bit is set (this feature bit is forced on as of fbe96f2). | ||
1718 | * If the bit is not, undo the 64-bit swap and try a 32-bit | ||
1719 | * swap. If the hostname bit is still not set (e.g., older data | ||
1720 | * file), punt and fallback to the original behavior -- | ||
1721 | * clearing all feature bits and setting buildid. | ||
1722 | */ | ||
1723 | for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) | ||
1724 | header->adds_features[i] = bswap_64(header->adds_features[i]); | ||
1725 | |||
1726 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { | ||
1727 | for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) { | ||
1728 | header->adds_features[i] = bswap_64(header->adds_features[i]); | ||
1729 | header->adds_features[i] = bswap_32(header->adds_features[i]); | ||
1730 | } | ||
1731 | } | ||
1732 | |||
1733 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { | ||
1734 | bitmap_zero(header->adds_features, HEADER_FEAT_BITS); | ||
1735 | set_bit(HEADER_BUILD_ID, header->adds_features); | ||
1736 | } | ||
1706 | } | 1737 | } |
1707 | 1738 | ||
1708 | memcpy(&ph->adds_features, &header->adds_features, | 1739 | memcpy(&ph->adds_features, &header->adds_features, |
1709 | sizeof(ph->adds_features)); | 1740 | sizeof(ph->adds_features)); |
1710 | /* | ||
1711 | * FIXME: hack that assumes that if we need swap the perf.data file | ||
1712 | * may be coming from an arch with a different word-size, ergo different | ||
1713 | * DEFINE_BITMAP format, investigate more later, but for now its mostly | ||
1714 | * safe to assume that we have a build-id section. Trace files probably | ||
1715 | * have several other issues in this realm anyway... | ||
1716 | */ | ||
1717 | if (ph->needs_swap) { | ||
1718 | memset(&ph->adds_features, 0, sizeof(ph->adds_features)); | ||
1719 | perf_header__set_feat(ph, HEADER_BUILD_ID); | ||
1720 | } | ||
1721 | 1741 | ||
1722 | ph->event_offset = header->event_types.offset; | 1742 | ph->event_offset = header->event_types.offset; |
1723 | ph->event_size = header->event_types.size; | 1743 | ph->event_size = header->event_types.size; |