Home | History | Annotate | Download | only in quipper
      1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "perf_reader.h"
      6 
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 #include <sys/time.h>
     11 
     12 #include <algorithm>
     13 #include <vector>
     14 
     15 #include "base/logging.h"
     16 #include "base/macros.h"
     17 
     18 #include "binary_data_utils.h"
     19 #include "buffer_reader.h"
     20 #include "buffer_writer.h"
     21 #include "compat/string.h"
     22 #include "file_reader.h"
     23 #include "file_utils.h"
     24 #include "perf_data_structures.h"
     25 #include "perf_data_utils.h"
     26 #include "sample_info_reader.h"
     27 
     28 namespace quipper {
     29 
     30 using PerfEvent = PerfDataProto_PerfEvent;
     31 using SampleInfo = PerfDataProto_SampleInfo;
     32 using StringAndMd5sumPrefix =
     33     PerfDataProto_StringMetadata_StringAndMd5sumPrefix;
     34 
     35 namespace {
     36 
     37 // The type of the storage size of a string, prefixed before each string field
     38 // in raw data.
     39 typedef u32 string_size_type;
     40 
     41 // The type of the number of string data, found in the command line metadata in
     42 // the perf data file.
     43 typedef u32 num_string_data_type;
     44 
     45 // Types of the event desc fields that are not found in other structs.
     46 typedef u32 event_desc_num_events;
     47 typedef u32 event_desc_attr_size;
     48 typedef u32 event_desc_num_unique_ids;
     49 
     50 // The type of the number of nodes field in NUMA topology.
     51 typedef u32 numa_topology_num_nodes_type;
     52 
     53 // The type of the number of mappings in pmu mappings.
     54 typedef u32 pmu_mappings_num_mappings_type;
     55 
     56 // The type of the number of groups in group desc.
     57 typedef u32 group_desc_num_groups_type;
     58 
     59 // A mask that is applied to |metadata_mask()| in order to get a mask for
     60 // only the metadata supported by quipper.
     61 const uint32_t kSupportedMetadataMask =
     62     1 << HEADER_TRACING_DATA | 1 << HEADER_BUILD_ID | 1 << HEADER_HOSTNAME |
     63     1 << HEADER_OSRELEASE | 1 << HEADER_VERSION | 1 << HEADER_ARCH |
     64     1 << HEADER_NRCPUS | 1 << HEADER_CPUDESC | 1 << HEADER_CPUID |
     65     1 << HEADER_TOTAL_MEM | 1 << HEADER_CMDLINE | 1 << HEADER_EVENT_DESC |
     66     1 << HEADER_CPU_TOPOLOGY | 1 << HEADER_NUMA_TOPOLOGY |
     67     1 << HEADER_BRANCH_STACK | 1 << HEADER_PMU_MAPPINGS |
     68     1 << HEADER_GROUP_DESC;
     69 
     70 // By default, the build ID event has PID = -1.
     71 const uint32_t kDefaultBuildIDEventPid = static_cast<uint32_t>(-1);
     72 
     73 // Eight bits in a byte.
     74 size_t BytesToBits(size_t num_bytes) { return num_bytes * 8; }
     75 
     76 u8 ReverseByte(u8 x) {
     77   x = (x & 0xf0) >> 4 | (x & 0x0f) << 4;  // exchange nibbles
     78   x = (x & 0xcc) >> 2 | (x & 0x33) << 2;  // exchange pairs
     79   x = (x & 0xaa) >> 1 | (x & 0x55) << 1;  // exchange neighbors
     80   return x;
     81 }
     82 
     83 // If field points to the start of a bitfield padded to len bytes, this
     84 // performs an endian swap of the bitfield, assuming the compiler that produced
     85 // it conforms to the same ABI (bitfield layout is not completely specified by
     86 // the language).
     87 void SwapBitfieldOfBits(u8* field, size_t len) {
     88   for (size_t i = 0; i < len; i++) {
     89     field[i] = ReverseByte(field[i]);
     90   }
     91 }
     92 
     93 // The code currently assumes that the compiler will not add any padding to the
     94 // various structs.  These CHECKs make sure that this is true.
     95 void CheckNoEventHeaderPadding() {
     96   perf_event_header header;
     97   CHECK_EQ(sizeof(header),
     98            sizeof(header.type) + sizeof(header.misc) + sizeof(header.size));
     99 }
    100 
    101 void CheckNoPerfEventAttrPadding() {
    102   perf_event_attr attr;
    103   CHECK_EQ(sizeof(attr), (reinterpret_cast<u64>(&attr.__reserved_2) -
    104                           reinterpret_cast<u64>(&attr)) +
    105                              sizeof(attr.__reserved_2));
    106 }
    107 
    108 void CheckNoEventTypePadding() {
    109   perf_trace_event_type event_type;
    110   CHECK_EQ(sizeof(event_type),
    111            sizeof(event_type.event_id) + sizeof(event_type.name));
    112 }
    113 
    114 void CheckNoBuildIDEventPadding() {
    115   build_id_event event;
    116   CHECK_EQ(sizeof(event), sizeof(event.header.type) +
    117                               sizeof(event.header.misc) +
    118                               sizeof(event.header.size) + sizeof(event.pid) +
    119                               sizeof(event.build_id));
    120 }
    121 
    122 // Creates a new build ID event with the given build ID string, filename, and
    123 // misc value.
    124 malloced_unique_ptr<build_id_event> CreateBuildIDEvent(const string& build_id,
    125                                                        const string& filename,
    126                                                        uint16_t misc) {
    127   size_t filename_len = GetUint64AlignedStringLength(filename);
    128   size_t size = sizeof(struct build_id_event) + filename_len;
    129   malloced_unique_ptr<build_id_event> event(CallocMemoryForBuildID(size));
    130   event->header.type = HEADER_BUILD_ID;
    131   event->header.misc = misc;
    132   event->header.size = size;
    133 
    134   event->pid = kDefaultBuildIDEventPid;
    135   snprintf(event->filename, filename_len, "%s", filename.c_str());
    136   memset(event->filename + filename.size(), 0, filename_len - filename.size());
    137 
    138   HexStringToRawData(build_id, event->build_id, sizeof(event->build_id));
    139   return event;
    140 }
    141 
    142 // Given a string, returns the total size required to store the string in perf
    143 // data, including a preceding length field and extra padding to align the
    144 // string + null terminator to a multiple of uint64s.
    145 size_t ExpectedStorageSizeOf(const string& str) {
    146   return sizeof(string_size_type) + GetUint64AlignedStringLength(str);
    147 }
    148 
    149 // Reads a perf_event_header from |data| and performs byte swapping if
    150 // necessary. Returns true on success, or false if there was an error.
    151 bool ReadPerfEventHeader(DataReader* data, struct perf_event_header* header) {
    152   if (!data->ReadData(sizeof(struct perf_event_header), header)) {
    153     LOG(ERROR) << "Error reading perf event header.";
    154     return false;
    155   }
    156   if (data->is_cross_endian()) {
    157     ByteSwap(&header->type);
    158     ByteSwap(&header->size);
    159     ByteSwap(&header->misc);
    160   }
    161   return true;
    162 }
    163 
    164 // Reads a perf_file_section from |data| and performs byte swapping if
    165 // necessary. Returns true on success, or false if there was an error.
    166 bool ReadPerfFileSection(DataReader* data, struct perf_file_section* section) {
    167   if (!data->ReadData(sizeof(*section), section)) {
    168     LOG(ERROR) << "Error reading perf file section info.";
    169     return false;
    170   }
    171   if (data->is_cross_endian()) {
    172     ByteSwap(&section->offset);
    173     ByteSwap(&section->size);
    174   }
    175   return true;
    176 }
    177 
    178 // Returns true if |e1| has an earlier timestamp than |e2|. Used to sort an
    179 // array of events.
    180 static bool CompareEventTimes(const PerfEvent* e1, const PerfEvent* e2) {
    181   return e1->timestamp() < e2->timestamp();
    182 }
    183 
    184 }  // namespace
    185 
    186 PerfReader::PerfReader()
    187     : proto_(Arena::CreateMessage<PerfDataProto>(&arena_)),
    188       is_cross_endian_(false) {
    189   // The metadata mask is stored in |proto_|. It should be initialized to 0
    190   // since it is used heavily.
    191   proto_->add_metadata_mask(0);
    192 }
    193 
    194 PerfReader::~PerfReader() {}
    195 
    196 bool PerfReader::Serialize(PerfDataProto* perf_data_proto) const {
    197   perf_data_proto->CopyFrom(*proto_);
    198 
    199   // Add a timestamp_sec to the protobuf.
    200   struct timeval timestamp_sec;
    201   if (!gettimeofday(&timestamp_sec, NULL))
    202     perf_data_proto->set_timestamp_sec(timestamp_sec.tv_sec);
    203   return true;
    204 }
    205 
    206 bool PerfReader::Deserialize(const PerfDataProto& perf_data_proto) {
    207   proto_->CopyFrom(perf_data_proto);
    208 
    209   // Iterate through all attrs and create a SampleInfoReader for each of them.
    210   // This is necessary for writing the proto representation of perf data to raw
    211   // data.
    212   for (const auto& stored_attr : proto_->file_attrs()) {
    213     PerfFileAttr attr;
    214     serializer_.DeserializePerfFileAttr(stored_attr, &attr);
    215     serializer_.CreateSampleInfoReader(attr, false /* read_cross_endian */);
    216   }
    217   return true;
    218 }
    219 
    220 bool PerfReader::ReadFile(const string& filename) {
    221   FileReader reader(filename);
    222   if (!reader.IsOpen()) {
    223     LOG(ERROR) << "Unable to open file " << filename;
    224     return false;
    225   }
    226   return ReadFromData(&reader);
    227 }
    228 
    229 bool PerfReader::ReadFromVector(const std::vector<char>& data) {
    230   return ReadFromPointer(data.data(), data.size());
    231 }
    232 
    233 bool PerfReader::ReadFromString(const string& str) {
    234   return ReadFromPointer(str.data(), str.size());
    235 }
    236 
    237 bool PerfReader::ReadFromPointer(const char* data, size_t size) {
    238   BufferReader buffer(data, size);
    239   return ReadFromData(&buffer);
    240 }
    241 
    242 bool PerfReader::ReadFromData(DataReader* data) {
    243   if (data->size() == 0) {
    244     LOG(ERROR) << "Input data is empty";
    245     return false;
    246   }
    247   if (!ReadHeader(data)) return false;
    248 
    249   // Check if it is normal perf data.
    250   if (header_.size == sizeof(header_)) {
    251     DVLOG(1) << "Perf data is in normal format.";
    252     return ReadFileData(data);
    253   }
    254 
    255   // Otherwise it is piped data.
    256   if (piped_header_.size != sizeof(piped_header_)) {
    257     LOG(ERROR) << "Expecting piped data format, but header size "
    258                << piped_header_.size << " does not match expected size "
    259                << sizeof(piped_header_);
    260     return false;
    261   }
    262 
    263   return ReadPipedData(data);
    264 }
    265 
    266 bool PerfReader::WriteFile(const string& filename) {
    267   std::vector<char> data;
    268   return WriteToVector(&data) && BufferToFile(filename, data);
    269 }
    270 
    271 bool PerfReader::WriteToVector(std::vector<char>* data) {
    272   data->resize(GetSize());
    273   return WriteToPointerWithoutCheckingSize(&data->at(0), data->size());
    274 }
    275 
    276 bool PerfReader::WriteToString(string* str) {
    277   str->resize(GetSize());
    278   return WriteToPointerWithoutCheckingSize(&str->at(0), str->size());
    279 }
    280 
    281 bool PerfReader::WriteToPointer(char* buffer, size_t size) {
    282   size_t required_size = GetSize();
    283   if (size < required_size) {
    284     LOG(ERROR) << "Buffer is too small - buffer size is " << size
    285                << " and required size is " << required_size;
    286     return false;
    287   }
    288   return WriteToPointerWithoutCheckingSize(buffer, size);
    289 }
    290 
    291 bool PerfReader::WriteToPointerWithoutCheckingSize(char* buffer, size_t size) {
    292   BufferWriter data(buffer, size);
    293   struct perf_file_header header;
    294   GenerateHeader(&header);
    295 
    296   return WriteHeader(header, &data) && WriteAttrs(header, &data) &&
    297          WriteData(header, &data) && WriteMetadata(header, &data);
    298 }
    299 
    300 size_t PerfReader::GetSize() const {
    301   struct perf_file_header header;
    302   GenerateHeader(&header);
    303 
    304   size_t total_size = 0;
    305   total_size += header.size;
    306   total_size += header.attrs.size;
    307   total_size += header.event_types.size;
    308   total_size += header.data.size;
    309   // Add the ID info, whose size is not explicitly included in the header.
    310   for (const auto& attr : proto_->file_attrs()) {
    311     total_size +=
    312         attr.ids_size() * sizeof(decltype(PerfFileAttr::ids)::value_type);
    313   }
    314 
    315   // Additional info about metadata.  See WriteMetadata for explanation.
    316   total_size += GetNumSupportedMetadata() * sizeof(struct perf_file_section);
    317 
    318   // Add the sizes of the various metadata.
    319   total_size += tracing_data().size();
    320   total_size += GetBuildIDMetadataSize();
    321   total_size += GetStringMetadataSize();
    322   total_size += GetUint32MetadataSize();
    323   total_size += GetUint64MetadataSize();
    324   total_size += GetEventDescMetadataSize();
    325   total_size += GetCPUTopologyMetadataSize();
    326   total_size += GetNUMATopologyMetadataSize();
    327   total_size += GetPMUMappingsMetadataSize();
    328   total_size += GetGroupDescMetadataSize();
    329   return total_size;
    330 }
    331 
    332 void PerfReader::GenerateHeader(struct perf_file_header* header) const {
    333   // This is the order of the input perf file contents in normal mode:
    334   // 1. Header
    335   // 2. Attribute IDs (pointed to by attr.ids.offset)
    336   // 3. Attributes
    337   // 4. Event types
    338   // 5. Data
    339   // 6. Metadata
    340 
    341   // Compute offsets in the above order.
    342   CheckNoEventHeaderPadding();
    343   memset(header, 0, sizeof(*header));
    344   header->magic = kPerfMagic;
    345   header->size = sizeof(*header);
    346   header->attr_size = sizeof(perf_file_attr);
    347   header->attrs.size = header->attr_size * attrs().size();
    348   for (const PerfEvent& event : proto_->events()) {
    349     header->data.size += event.header().size();
    350     // Auxtrace event contain trace data at the end of the event. Add the size
    351     // of this trace data to the header.data size.
    352     if (event.header().type() == PERF_RECORD_AUXTRACE) {
    353       header->data.size += event.auxtrace_event().size();
    354     }
    355   }
    356   // Do not use the event_types section. Use EVENT_DESC metadata instead.
    357   header->event_types.size = 0;
    358 
    359   u64 current_offset = 0;
    360   current_offset += header->size;
    361   for (const auto& attr : proto_->file_attrs()) {
    362     current_offset +=
    363         sizeof(decltype(PerfFileAttr::ids)::value_type) * attr.ids_size();
    364   }
    365   header->attrs.offset = current_offset;
    366   current_offset += header->attrs.size;
    367   header->event_types.offset = current_offset;
    368   current_offset += header->event_types.size;
    369 
    370   header->data.offset = current_offset;
    371 
    372   // Construct the header feature bits.
    373   memset(&header->adds_features, 0, sizeof(header->adds_features));
    374   // The following code makes the assumption that all feature bits are in the
    375   // first word of |adds_features|.  If the perf data format changes and the
    376   // assumption is no longer valid, this CHECK will fail, at which point the
    377   // below code needs to be updated.  For now, sticking to that assumption keeps
    378   // the code simple.
    379   // This assumption is also used when reading metadata, so that code
    380   // will also have to be updated if this CHECK starts to fail.
    381   CHECK_LE(static_cast<size_t>(HEADER_LAST_FEATURE),
    382            BytesToBits(sizeof(header->adds_features[0])));
    383   header->adds_features[0] |= metadata_mask() & kSupportedMetadataMask;
    384 }
    385 
    386 bool PerfReader::InjectBuildIDs(
    387     const std::map<string, string>& filenames_to_build_ids) {
    388   set_metadata_mask_bit(HEADER_BUILD_ID);
    389   std::set<string> updated_filenames;
    390   // Inject new build ID's for existing build ID events.
    391   for (auto& build_id : *proto_->mutable_build_ids()) {
    392     auto find_result = filenames_to_build_ids.find(build_id.filename());
    393     if (find_result == filenames_to_build_ids.end()) continue;
    394     const string& build_id_string = find_result->second;
    395     const int kHexCharsPerByte = 2;
    396     std::vector<uint8_t> build_id_data(build_id_string.size() /
    397                                        kHexCharsPerByte);
    398     if (!HexStringToRawData(build_id_string, build_id_data.data(),
    399                             build_id_data.size())) {
    400       LOG(ERROR) << "Could not convert hex string to raw data: "
    401                  << build_id_string;
    402       return false;
    403     }
    404     build_id.set_build_id_hash(build_id_data.data(), build_id_data.size());
    405 
    406     updated_filenames.insert(build_id.filename());
    407   }
    408 
    409   // For files with no existing build ID events, create new build ID events.
    410   // This requires a lookup of all MMAP's to determine the |misc| field of each
    411   // build ID event.
    412   std::map<string, uint16_t> filename_to_misc;
    413   for (const PerfEvent& event : proto_->events()) {
    414     if (event.header().type() == PERF_RECORD_MMAP ||
    415         event.header().type() == PERF_RECORD_MMAP2) {
    416       filename_to_misc[event.mmap_event().filename()] = event.header().misc();
    417     }
    418   }
    419 
    420   std::map<string, string>::const_iterator it;
    421   for (it = filenames_to_build_ids.begin(); it != filenames_to_build_ids.end();
    422        ++it) {
    423     const string& filename = it->first;
    424     if (updated_filenames.find(filename) != updated_filenames.end()) continue;
    425 
    426     // Determine the misc field.
    427     uint16_t new_misc = PERF_RECORD_MISC_KERNEL;
    428     std::map<string, uint16_t>::const_iterator misc_iter =
    429         filename_to_misc.find(filename);
    430     if (misc_iter != filename_to_misc.end()) new_misc = misc_iter->second;
    431 
    432     string build_id = it->second;
    433     malloced_unique_ptr<build_id_event> event =
    434         CreateBuildIDEvent(build_id, filename, new_misc);
    435     if (!serializer_.SerializeBuildIDEvent(event, proto_->add_build_ids())) {
    436       LOG(ERROR) << "Could not serialize build ID event with ID " << build_id;
    437       return false;
    438     }
    439   }
    440   return true;
    441 }
    442 
    443 bool PerfReader::Localize(
    444     const std::map<string, string>& build_ids_to_filenames) {
    445   std::map<string, string> filename_map;
    446   for (auto& build_id : *proto_->mutable_build_ids()) {
    447     string build_id_string = RawDataToHexString(build_id.build_id_hash());
    448     auto find_result = build_ids_to_filenames.find(build_id_string);
    449     if (find_result == build_ids_to_filenames.end()) continue;
    450     const string& new_filename = find_result->second;
    451     filename_map[build_id.filename()] = new_filename;
    452   }
    453 
    454   return LocalizeUsingFilenames(filename_map);
    455 }
    456 
    457 bool PerfReader::LocalizeUsingFilenames(
    458     const std::map<string, string>& filename_map) {
    459   LocalizeMMapFilenames(filename_map);
    460   for (auto& build_id : *proto_->mutable_build_ids()) {
    461     auto find_result = filename_map.find(build_id.filename());
    462     if (find_result != filename_map.end())
    463       build_id.set_filename(find_result->second);
    464   }
    465   return true;
    466 }
    467 
    468 void PerfReader::GetFilenames(std::vector<string>* filenames) const {
    469   std::set<string> filename_set;
    470   GetFilenamesAsSet(&filename_set);
    471   filenames->clear();
    472   filenames->insert(filenames->begin(), filename_set.begin(),
    473                     filename_set.end());
    474 }
    475 
    476 void PerfReader::GetFilenamesAsSet(std::set<string>* filenames) const {
    477   filenames->clear();
    478   for (const PerfEvent& event : proto_->events()) {
    479     if (event.header().type() == PERF_RECORD_MMAP ||
    480         event.header().type() == PERF_RECORD_MMAP2) {
    481       filenames->insert(event.mmap_event().filename());
    482     }
    483   }
    484 }
    485 
    486 void PerfReader::GetFilenamesToBuildIDs(
    487     std::map<string, string>* filenames_to_build_ids) const {
    488   filenames_to_build_ids->clear();
    489   for (const auto& build_id : proto_->build_ids()) {
    490     string build_id_string = RawDataToHexString(build_id.build_id_hash());
    491     PerfizeBuildIDString(&build_id_string);
    492     (*filenames_to_build_ids)[build_id.filename()] = build_id_string;
    493   }
    494 }
    495 
    496 void PerfReader::MaybeSortEventsByTime() {
    497   // Events can not be sorted by time if PERF_SAMPLE_TIME is not set in
    498   // attr.sample_type for all attrs.
    499   for (const auto& attr : attrs()) {
    500     if (!(attr.attr().sample_type() & PERF_SAMPLE_TIME)) {
    501       return;
    502     }
    503   }
    504 
    505   // Sort the events based on timestamp.
    506 
    507   // This sorts the pointers in the proto-internal vector, which
    508   // requires no copying and less external space.
    509   std::stable_sort(proto_->mutable_events()->pointer_begin(),
    510                    proto_->mutable_events()->pointer_end(), CompareEventTimes);
    511 }
    512 
    513 bool PerfReader::ReadHeader(DataReader* data) {
    514   CheckNoEventHeaderPadding();
    515   // The header is the first thing to be read. Don't use SeekSet(0) because it
    516   // doesn't make sense for piped files. Instead, verify that the reader points
    517   // to the start of the data.
    518   CHECK_EQ(0U, data->Tell());
    519   if (!data->ReadUint64(&piped_header_.magic)) {
    520     LOG(ERROR) << "Error reading header magic number.";
    521     return false;
    522   }
    523 
    524   if (piped_header_.magic != kPerfMagic &&
    525       piped_header_.magic != bswap_64(kPerfMagic)) {
    526     // clang-format off
    527     LOG(ERROR) << "Read wrong magic. Expected: 0x" << std::hex << kPerfMagic
    528                << " or 0x" << std::hex << bswap_64(kPerfMagic)
    529                << " Got: 0x" << std::hex << piped_header_.magic;
    530     // clang-format on
    531     return false;
    532   }
    533   is_cross_endian_ = (piped_header_.magic != kPerfMagic);
    534   data->set_is_cross_endian(is_cross_endian_);
    535 
    536   if (!data->ReadUint64(&piped_header_.size)) {
    537     LOG(ERROR) << "Error reading header size.";
    538     return false;
    539   }
    540 
    541   CHECK_EQ(data->Tell(), sizeof(piped_header_));
    542 
    543   // Header can be a piped header.
    544   if (piped_header_.size == sizeof(piped_header_)) return true;
    545 
    546   // Read as a non-piped header.
    547   if (!data->ReadUint64(&header_.attr_size)) {
    548     LOG(ERROR) << "Error reading header::attr_size.";
    549     return false;
    550   }
    551   if (!ReadPerfFileSection(data, &header_.attrs) ||
    552       !ReadPerfFileSection(data, &header_.data) ||
    553       !ReadPerfFileSection(data, &header_.event_types)) {
    554     LOG(ERROR) << "Error reading header file section info.";
    555     return false;
    556   }
    557 
    558   const size_t features_size = sizeof(header_.adds_features);
    559   CHECK_EQ(data->Tell(), sizeof(header_) - features_size);
    560 
    561   if (!data->ReadData(features_size, header_.adds_features)) {
    562     LOG(ERROR) << "Error reading header::adds_features.";
    563     return false;
    564   }
    565   proto_->set_metadata_mask(0, header_.adds_features[0]);
    566 
    567   // Byte-swapping |adds_features| is tricky. It is defined as an array of
    568   // unsigned longs, which can vary between architectures. However, the overall
    569   // size of the array in bytes is fixed.
    570   //
    571   // According to perf's perf_file_header__read() function, the hostname feature
    572   // should always be set. Try byte-swapping as uint64s first and check the
    573   // hostname bit. If it's not set, then try swapping as uint32s. This is
    574   // similar to the algorithm used in perf.
    575   if (data->is_cross_endian()) {
    576     static_assert(sizeof(header_.adds_features[0]) == sizeof(uint32_t) ||
    577                       sizeof(header_.adds_features[0]) == sizeof(uint64_t),
    578                   "|header_.adds_features| must be defined as an array of "
    579                   "either 32-bit or 64-bit words.");
    580 
    581     uint64_t features64 = 0;
    582     // Some compilers will complain if we directly cast |header_.adds_features|
    583     // to a uint64_t*. Instead, determine the first uint64_t without using
    584     // pointer aliasing.
    585     if (sizeof(header_.adds_features[0]) == sizeof(uint64_t)) {
    586       features64 = bswap_64(header_.adds_features[0]);
    587     } else {
    588       // If the native |adds_features| is composed of 32-bit words, swap the
    589       // byte order of each word and then swap their positions to create a
    590       // 64-bit word.
    591       features64 = static_cast<uint64_t>(bswap_32(header_.adds_features[0]))
    592                    << 32;
    593       features64 |= bswap_32(header_.adds_features[1]);
    594     }
    595     if (features64 & (1 << HEADER_HOSTNAME)) {
    596       for (size_t i = 0; i < features_size / sizeof(uint64_t); ++i)
    597         ByteSwap(reinterpret_cast<uint64_t*>(header_.adds_features) + i);
    598     } else {
    599       for (size_t i = 0; i < features_size / sizeof(uint32_t); ++i)
    600         ByteSwap(reinterpret_cast<uint32_t*>(header_.adds_features) + i);
    601     }
    602   }
    603 
    604   return true;
    605 }
    606 
    607 bool PerfReader::ReadAttrsSection(DataReader* data) {
    608   size_t num_attrs = header_.attrs.size / header_.attr_size;
    609   if (header_.attrs.size % header_.attr_size != 0) {
    610     LOG(ERROR) << "Total size of attrs " << header_.attrs.size
    611                << " is not a multiple of attr size " << header_.attr_size;
    612   }
    613   data->SeekSet(header_.attrs.offset);
    614   for (size_t i = 0; i < num_attrs; i++) {
    615     if (!ReadAttr(data)) return false;
    616   }
    617   return true;
    618 }
    619 
    620 bool PerfReader::ReadAttr(DataReader* data) {
    621   PerfFileAttr attr;
    622   if (!ReadEventAttr(data, &attr.attr)) return false;
    623 
    624   perf_file_section ids;
    625   if (!ReadPerfFileSection(data, &ids)) return false;
    626 
    627   // The ID may be stored at a different location in the file than where we're
    628   // currently reading.
    629   size_t saved_offset = data->Tell();
    630   data->SeekSet(ids.offset);
    631 
    632   size_t num_ids = ids.size / sizeof(decltype(attr.ids)::value_type);
    633   if (!ReadUniqueIDs(data, num_ids, &attr.ids)) return false;
    634   data->SeekSet(saved_offset);
    635   AddPerfFileAttr(attr);
    636 
    637   return true;
    638 }
    639 
    640 bool PerfReader::ReadEventAttr(DataReader* data, perf_event_attr* attr) {
    641   CheckNoPerfEventAttrPadding();
    642   *attr = {0};
    643 
    644   static_assert(
    645       offsetof(struct perf_event_attr, size) == sizeof(perf_event_attr::type),
    646       "type and size should be the first to fields of perf_event_attr");
    647 
    648   if (!data->ReadUint32(&attr->type) || !data->ReadUint32(&attr->size)) {
    649     LOG(ERROR) << "Error reading event attr type and size.";
    650     return false;
    651   }
    652 
    653   // Now read the rest of the attr struct.
    654   const size_t attr_offset = sizeof(attr->type) + sizeof(attr->size);
    655   const size_t attr_readable_size =
    656       std::min(static_cast<size_t>(attr->size), sizeof(*attr));
    657   if (!data->ReadDataValue(attr_readable_size - attr_offset, "attribute",
    658                            reinterpret_cast<char*>(attr) + attr_offset)) {
    659     return false;
    660   }
    661   data->SeekSet(data->Tell() + attr->size - attr_readable_size);
    662 
    663   if (data->is_cross_endian()) {
    664     // Depending on attr->size, some of these might not have actually been
    665     // read. This is okay: they are zero.
    666     ByteSwap(&attr->type);
    667     ByteSwap(&attr->size);
    668     ByteSwap(&attr->config);
    669     ByteSwap(&attr->sample_period);
    670     ByteSwap(&attr->sample_type);
    671     ByteSwap(&attr->read_format);
    672 
    673     // NB: This will also reverse precise_ip : 2 as if it was two fields:
    674     auto* const bitfield_start = &attr->read_format + 1;
    675     SwapBitfieldOfBits(reinterpret_cast<u8*>(bitfield_start), sizeof(u64));
    676     // ... So swap it back:
    677     const auto tmp = attr->precise_ip;
    678     attr->precise_ip = (tmp & 0x2) >> 1 | (tmp & 0x1) << 1;
    679 
    680     ByteSwap(&attr->wakeup_events);  // union with wakeup_watermark
    681     ByteSwap(&attr->bp_type);
    682     ByteSwap(&attr->bp_addr);  // union with config1
    683     ByteSwap(&attr->bp_len);   // union with config2
    684     ByteSwap(&attr->branch_sample_type);
    685     ByteSwap(&attr->sample_regs_user);
    686     ByteSwap(&attr->sample_stack_user);
    687   }
    688 
    689   // The actual perf_event_attr data size might be different from the size of
    690   // the struct definition.  Check against perf_event_attr's |size| field.
    691   attr->size = sizeof(*attr);
    692 
    693   return true;
    694 }
    695 
    696 bool PerfReader::ReadUniqueIDs(DataReader* data, size_t num_ids,
    697                                std::vector<u64>* ids) {
    698   ids->resize(num_ids);
    699   for (u64& id : *ids) {
    700     if (!data->ReadUint64(&id)) {
    701       LOG(ERROR) << "Error reading unique ID.";
    702       return false;
    703     }
    704   }
    705   return true;
    706 }
    707 
    708 bool PerfReader::ReadEventTypesSection(DataReader* data) {
    709   int num_event_types =
    710       header_.event_types.size / sizeof(struct perf_trace_event_type);
    711   if (num_event_types == 0) {
    712     // Not available.
    713     return true;
    714   }
    715   CHECK_EQ(proto_->file_attrs().size(), num_event_types);
    716   CHECK_EQ(sizeof(perf_trace_event_type) * num_event_types,
    717            header_.event_types.size);
    718   data->SeekSet(header_.event_types.offset);
    719   for (int i = 0; i < num_event_types; ++i) {
    720     if (!ReadEventType(data, i, 0)) return false;
    721   }
    722   return true;
    723 }
    724 
    725 bool PerfReader::ReadEventType(DataReader* data, int attr_idx,
    726                                size_t event_size) {
    727   CheckNoEventTypePadding();
    728   decltype(perf_trace_event_type::event_id) event_id;
    729 
    730   if (!data->ReadUint64(&event_id)) {
    731     LOG(ERROR) << "Error reading event ID.";
    732     return false;
    733   }
    734 
    735   size_t event_name_len;
    736   if (event_size == 0) {  // Not in an event.
    737     event_name_len = sizeof(perf_trace_event_type::name);
    738   } else {
    739     event_name_len = event_size - sizeof(perf_event_header) - sizeof(event_id);
    740   }
    741 
    742   PerfFileAttr attr;
    743   if (!data->ReadString(event_name_len, &attr.name)) {
    744     LOG(ERROR) << "Not enough data left in data to read event name.";
    745     return false;
    746   }
    747 
    748   if (attr_idx >= proto_->file_attrs().size()) {
    749     LOG(ERROR) << "Too many event types, or attrs not read yet!";
    750     return false;
    751   }
    752   if (event_id != proto_->file_attrs(attr_idx).attr().config()) {
    753     LOG(ERROR) << "event_id for perf_trace_event_type (" << event_id << ") "
    754                << "does not match attr.config ("
    755                << proto_->file_attrs(attr_idx).attr().config() << ")";
    756     return false;
    757   }
    758   attr.attr.config = proto_->file_attrs(attr_idx).attr().config();
    759 
    760   serializer_.SerializePerfEventType(attr, proto_->add_event_types());
    761   return true;
    762 }
    763 
    764 bool PerfReader::ReadDataSection(DataReader* data) {
    765   u64 data_remaining_bytes = header_.data.size;
    766   data->SeekSet(header_.data.offset);
    767   while (data_remaining_bytes != 0) {
    768     // Read the header to determine the size of the event.
    769     perf_event_header header;
    770     if (!ReadPerfEventHeader(data, &header)) {
    771       LOG(ERROR) << "Error reading event header from data section.";
    772       return false;
    773     }
    774 
    775     // Read the rest of the event data.
    776     malloced_unique_ptr<event_t> event(CallocMemoryForEvent(header.size));
    777     event->header = header;
    778     if (!data->ReadDataValue(event->header.size - sizeof(event->header),
    779                              "rest of event", &event->header + 1)) {
    780       return false;
    781     }
    782     MaybeSwapEventFields(event.get(), data->is_cross_endian());
    783 
    784     // We must have a valid way to read sample info before reading perf events.
    785     CHECK(serializer_.SampleInfoReaderAvailable());
    786 
    787     // Serialize the event to protobuf form.
    788     PerfEvent* proto_event = proto_->add_events();
    789     if (!serializer_.SerializeEvent(event, proto_event)) return false;
    790 
    791     if (proto_event->header().type() == PERF_RECORD_AUXTRACE) {
    792       if (!ReadAuxtraceTraceData(data, proto_event)) return false;
    793       data_remaining_bytes -= proto_event->auxtrace_event().size();
    794     }
    795     data_remaining_bytes -= event->header.size;
    796   }
    797 
    798   DLOG(INFO) << "Number of events stored: " << proto_->events_size();
    799   return true;
    800 }
    801 
    802 bool PerfReader::ReadMetadata(DataReader* data) {
    803   // Metadata comes after the event data.
    804   data->SeekSet(header_.data.offset + header_.data.size);
    805 
    806   // Read the (offset, size) pairs of all the metadata elements. Note that this
    807   // takes into account all present metadata types, not just the ones included
    808   // in |kSupportedMetadataMask|. If a metadata type is not supported, it is
    809   // skipped over.
    810   std::vector<struct perf_file_section> sections(GetNumBits(metadata_mask()));
    811   for (struct perf_file_section& section : sections) {
    812     if (!ReadPerfFileSection(data, &section)) {
    813       LOG(ERROR) << "Error reading metadata entry info.";
    814       return false;
    815     }
    816   }
    817 
    818   auto section_iter = sections.begin();
    819   for (u32 type = HEADER_FIRST_FEATURE; type != HEADER_LAST_FEATURE; ++type) {
    820     if (!get_metadata_mask_bit(type)) continue;
    821     data->SeekSet(section_iter->offset);
    822     u64 size = section_iter->size;
    823 
    824     switch (type) {
    825       case HEADER_TRACING_DATA:
    826         if (!ReadTracingMetadata(data, size)) return false;
    827         break;
    828       case HEADER_BUILD_ID:
    829         if (!ReadBuildIDMetadata(data, size)) return false;
    830         break;
    831       case HEADER_HOSTNAME:
    832         if (!ReadSingleStringMetadata(
    833                 data, size,
    834                 proto_->mutable_string_metadata()->mutable_hostname())) {
    835           return false;
    836         }
    837         break;
    838       case HEADER_OSRELEASE:
    839         if (!ReadSingleStringMetadata(
    840                 data, size,
    841                 proto_->mutable_string_metadata()->mutable_kernel_version())) {
    842           return false;
    843         }
    844         break;
    845       case HEADER_VERSION:
    846         if (!ReadSingleStringMetadata(
    847                 data, size,
    848                 proto_->mutable_string_metadata()->mutable_perf_version())) {
    849           return false;
    850         }
    851         break;
    852       case HEADER_ARCH:
    853         if (!ReadSingleStringMetadata(
    854                 data, size,
    855                 proto_->mutable_string_metadata()->mutable_architecture())) {
    856           return false;
    857         }
    858         break;
    859       case HEADER_CPUDESC:
    860         if (!ReadSingleStringMetadata(
    861                 data, size,
    862                 proto_->mutable_string_metadata()->mutable_cpu_description())) {
    863           return false;
    864         }
    865         break;
    866       case HEADER_CPUID:
    867         if (!ReadSingleStringMetadata(
    868                 data, size,
    869                 proto_->mutable_string_metadata()->mutable_cpu_id())) {
    870           return false;
    871         }
    872         break;
    873       case HEADER_CMDLINE: {
    874         auto* string_metadata = proto_->mutable_string_metadata();
    875         if (!ReadRepeatedStringMetadata(
    876                 data, size, string_metadata->mutable_perf_command_line_token(),
    877                 string_metadata->mutable_perf_command_line_whole())) {
    878           return false;
    879         }
    880         break;
    881       }
    882       case HEADER_NRCPUS:
    883         if (!ReadUint32Metadata(data, type, size)) return false;
    884         break;
    885       case HEADER_TOTAL_MEM:
    886         if (!ReadUint64Metadata(data, type, size)) return false;
    887         break;
    888       case HEADER_EVENT_DESC:
    889         if (!ReadEventDescMetadata(data)) return false;
    890         break;
    891       case HEADER_CPU_TOPOLOGY:
    892         if (!ReadCPUTopologyMetadata(data)) return false;
    893         break;
    894       case HEADER_NUMA_TOPOLOGY:
    895         if (!ReadNUMATopologyMetadata(data)) return false;
    896         break;
    897       case HEADER_BRANCH_STACK:
    898         break;
    899       case HEADER_PMU_MAPPINGS:
    900         if (!ReadPMUMappingsMetadata(data, size)) return false;
    901         break;
    902       case HEADER_GROUP_DESC:
    903         if (!ReadGroupDescMetadata(data)) return false;
    904         break;
    905       default:
    906         LOG(INFO) << "Unsupported metadata type, skipping: " << type;
    907         break;
    908     }
    909     ++section_iter;
    910   }
    911 
    912   return true;
    913 }
    914 
    915 bool PerfReader::ReadBuildIDMetadata(DataReader* data, size_t size) {
    916   CheckNoBuildIDEventPadding();
    917   while (size > 0) {
    918     // Make sure there is enough data for everything but the filename.
    919     perf_event_header build_id_header;
    920     if (!ReadPerfEventHeader(data, &build_id_header)) {
    921       LOG(ERROR) << "Error reading build ID header.";
    922       return false;
    923     }
    924 
    925     if (!ReadBuildIDMetadataWithoutHeader(data, build_id_header)) return false;
    926     size -= build_id_header.size;
    927   }
    928 
    929   return true;
    930 }
    931 
    932 bool PerfReader::ReadBuildIDMetadataWithoutHeader(
    933     DataReader* data, const perf_event_header& header) {
    934   // Allocate memory for the event.
    935   malloced_unique_ptr<build_id_event> event(
    936       CallocMemoryForBuildID(header.size));
    937   event->header = header;
    938 
    939   // Make sure there is enough data for the rest of the event.
    940   if (!data->ReadDataValue(header.size - sizeof(header),
    941                            "rest of build ID event", &event->header + 1)) {
    942     LOG(ERROR) << "Not enough bytes to read build id event";
    943     return false;
    944   }
    945   if (data->is_cross_endian()) ByteSwap(&event->pid);
    946 
    947   // Perf tends to use more space than necessary, so fix the size.
    948   event->header.size =
    949       sizeof(*event) + GetUint64AlignedStringLength(event->filename);
    950 
    951   if (!serializer_.SerializeBuildIDEvent(event, proto_->add_build_ids())) {
    952     LOG(ERROR) << "Could not serialize build ID event with ID "
    953                << RawDataToHexString(event->build_id, sizeof(event->build_id));
    954     return false;
    955   }
    956   return true;
    957 }
    958 
    959 bool PerfReader::ReadSingleStringMetadata(DataReader* data,
    960                                           size_t max_readable_size,
    961                                           StringAndMd5sumPrefix* dest) const {
    962   // If a string metadata field is present but empty, it can have a size of 0,
    963   // in which case there is nothing to be read.
    964   string single_string;
    965   if (max_readable_size && !data->ReadStringWithSizeFromData(&single_string))
    966     return false;
    967   dest->set_value(single_string);
    968   dest->set_value_md5_prefix(Md5Prefix(single_string));
    969   return true;
    970 }
    971 
    972 bool PerfReader::ReadRepeatedStringMetadata(
    973     DataReader* data, size_t max_readable_size,
    974     RepeatedPtrField<StringAndMd5sumPrefix>* dest_array,
    975     StringAndMd5sumPrefix* dest_single) const {
    976   num_string_data_type count = 1;
    977   if (!data->ReadUint32(&count)) {
    978     LOG(ERROR) << "Error reading string count.";
    979     return false;
    980   }
    981   size_t size_read = sizeof(count);
    982 
    983   string full_string;
    984   while (count-- > 0 && size_read < max_readable_size) {
    985     StringAndMd5sumPrefix* new_entry = dest_array->Add();
    986     size_t offset = data->Tell();
    987     if (!ReadSingleStringMetadata(data, max_readable_size - size_read,
    988                                   new_entry)) {
    989       return false;
    990     }
    991 
    992     if (!full_string.empty()) full_string += " ";
    993     full_string += new_entry->value();
    994 
    995     size_read += data->Tell() - offset;
    996   }
    997 
    998   dest_single->set_value(full_string);
    999   dest_single->set_value_md5_prefix(Md5Prefix(full_string));
   1000   return true;
   1001 }
   1002 
   1003 bool PerfReader::ReadUint32Metadata(DataReader* data, u32 type, size_t size) {
   1004   PerfUint32Metadata uint32_data;
   1005   uint32_data.type = type;
   1006 
   1007   while (size > 0) {
   1008     uint32_t item;
   1009     if (!data->ReadUint32(&item)) {
   1010       LOG(ERROR) << "Error reading uint32 metadata";
   1011       return false;
   1012     }
   1013 
   1014     uint32_data.data.push_back(item);
   1015     size -= sizeof(item);
   1016   }
   1017 
   1018   serializer_.SerializeSingleUint32Metadata(uint32_data,
   1019                                             proto_->add_uint32_metadata());
   1020   return true;
   1021 }
   1022 
   1023 bool PerfReader::ReadUint64Metadata(DataReader* data, u32 type, size_t size) {
   1024   PerfUint64Metadata uint64_data;
   1025   uint64_data.type = type;
   1026 
   1027   while (size > 0) {
   1028     uint64_t item;
   1029     if (!data->ReadUint64(&item)) {
   1030       LOG(ERROR) << "Error reading uint64 metadata";
   1031       return false;
   1032     }
   1033 
   1034     uint64_data.data.push_back(item);
   1035     size -= sizeof(item);
   1036   }
   1037 
   1038   serializer_.SerializeSingleUint64Metadata(uint64_data,
   1039                                             proto_->add_uint64_metadata());
   1040   return true;
   1041 }
   1042 bool PerfReader::ReadEventDescMetadata(DataReader* data) {
   1043   // Structure:
   1044   // u32 nr_events
   1045   // u32 sizeof(perf_event_attr)
   1046   // foreach event (nr_events):
   1047   //   struct perf_event_attr
   1048   //   u32 nr_ids
   1049   //   event name (len & string, 64-bit padded)
   1050   //   u64 ids[nr_ids]
   1051 
   1052   u32 nr_events;
   1053   if (!data->ReadUint32(&nr_events)) {
   1054     LOG(ERROR) << "Error reading event_desc nr_events.";
   1055     return false;
   1056   }
   1057 
   1058   u32 attr_size;
   1059   if (!data->ReadUint32(&attr_size)) {
   1060     LOG(ERROR) << "Error reading event_desc attr_size.";
   1061     return false;
   1062   }
   1063 
   1064   file_attrs_seen_.clear();
   1065   proto_->clear_file_attrs();
   1066   proto_->mutable_file_attrs()->Reserve(nr_events);
   1067 
   1068   for (u32 i = 0; i < nr_events; i++) {
   1069     PerfFileAttr attr;
   1070     if (!ReadEventAttr(data, &attr.attr)) return false;
   1071 
   1072     u32 nr_ids;
   1073     if (!data->ReadUint32(&nr_ids)) {
   1074       LOG(ERROR) << "Error reading event_desc nr_ids.";
   1075       return false;
   1076     }
   1077 
   1078     if (!data->ReadStringWithSizeFromData(&attr.name)) return false;
   1079     std::vector<u64>& ids = attr.ids;
   1080     ids.resize(nr_ids);
   1081     for (u64& id : ids) {
   1082       if (!data->ReadUint64(&id)) {
   1083         LOG(ERROR) << "Error reading ID value for attr #" << i;
   1084         return false;
   1085       }
   1086     }
   1087     AddPerfFileAttr(attr);
   1088     // The EVENT_DESC metadata is the newer replacement for the older event type
   1089     // fields. In the protobuf, both types of data are stored in the
   1090     // |event_types| field.
   1091     serializer_.SerializePerfEventType(attr, proto_->add_event_types());
   1092   }
   1093   return true;
   1094 }
   1095 
   1096 bool PerfReader::ReadCPUTopologyMetadata(DataReader* data) {
   1097   num_siblings_type num_core_siblings;
   1098   if (!data->ReadUint32(&num_core_siblings)) {
   1099     LOG(ERROR) << "Error reading num core siblings.";
   1100     return false;
   1101   }
   1102 
   1103   PerfCPUTopologyMetadata cpu_topology;
   1104   cpu_topology.core_siblings.resize(num_core_siblings);
   1105   for (size_t i = 0; i < num_core_siblings; ++i) {
   1106     if (!data->ReadStringWithSizeFromData(&cpu_topology.core_siblings[i]))
   1107       return false;
   1108   }
   1109 
   1110   num_siblings_type num_thread_siblings;
   1111   if (!data->ReadUint32(&num_thread_siblings)) {
   1112     LOG(ERROR) << "Error reading num core siblings.";
   1113     return false;
   1114   }
   1115 
   1116   cpu_topology.thread_siblings.resize(num_thread_siblings);
   1117   for (size_t i = 0; i < num_thread_siblings; ++i) {
   1118     if (!data->ReadStringWithSizeFromData(&cpu_topology.thread_siblings[i]))
   1119       return false;
   1120   }
   1121 
   1122   serializer_.SerializeCPUTopologyMetadata(cpu_topology,
   1123                                            proto_->mutable_cpu_topology());
   1124   return true;
   1125 }
   1126 
   1127 bool PerfReader::ReadNUMATopologyMetadata(DataReader* data) {
   1128   numa_topology_num_nodes_type num_nodes;
   1129   if (!data->ReadUint32(&num_nodes)) {
   1130     LOG(ERROR) << "Error reading NUMA topology num nodes.";
   1131     return false;
   1132   }
   1133 
   1134   for (size_t i = 0; i < num_nodes; ++i) {
   1135     PerfNodeTopologyMetadata node;
   1136     if (!data->ReadUint32(&node.id) || !data->ReadUint64(&node.total_memory) ||
   1137         !data->ReadUint64(&node.free_memory) ||
   1138         !data->ReadStringWithSizeFromData(&node.cpu_list)) {
   1139       LOG(ERROR) << "Error reading NUMA topology info for node #" << i;
   1140       return false;
   1141     }
   1142     serializer_.SerializeNodeTopologyMetadata(node,
   1143                                               proto_->add_numa_topology());
   1144   }
   1145   return true;
   1146 }
   1147 
   1148 bool PerfReader::ReadPMUMappingsMetadata(DataReader* data, size_t size) {
   1149   pmu_mappings_num_mappings_type num_mappings;
   1150   auto begin_offset = data->Tell();
   1151   if (!data->ReadUint32(&num_mappings)) {
   1152     LOG(ERROR) << "Error reading the number of PMU mappings.";
   1153     return false;
   1154   }
   1155 
   1156   // Check size of the data read in addition to the iteration based on the
   1157   // number of PMU mappings because the number of pmu mappings is always zero
   1158   // in piped perf.data file.
   1159   //
   1160   // The number of PMU mappings is initialized to zero and after all the
   1161   // mappings are wirtten to the perf.data files, this value is set to the
   1162   // number of PMU mappings written. This logic doesn't work in pipe mode. So,
   1163   // the number of PMU mappings is always zero.
   1164   // Fix to write the number of PMU mappings before writing the actual PMU
   1165   // mappings landed upstream in 4.14. But the check for size is required as
   1166   // long as there are machines with older version of perf.
   1167   for (u32 i = 0; i < num_mappings || data->Tell() - begin_offset < size; ++i) {
   1168     PerfPMUMappingsMetadata mapping;
   1169     if (!data->ReadUint32(&mapping.type) ||
   1170         !data->ReadStringWithSizeFromData(&mapping.name)) {
   1171       LOG(ERROR) << "Error reading PMU mapping info for mapping #" << i;
   1172       return false;
   1173     }
   1174     serializer_.SerializePMUMappingsMetadata(mapping,
   1175                                              proto_->add_pmu_mappings());
   1176   }
   1177   if (data->Tell() - begin_offset != size) {
   1178     LOG(ERROR) << "Size from the header doesn't match the read size";
   1179     return false;
   1180   }
   1181   return true;
   1182 }
   1183 
   1184 bool PerfReader::ReadGroupDescMetadata(DataReader* data) {
   1185   group_desc_num_groups_type num_groups;
   1186   if (!data->ReadUint32(&num_groups)) {
   1187     LOG(ERROR) << "Error reading group desc num groups.";
   1188     return false;
   1189   }
   1190 
   1191   for (u32 i = 0; i < num_groups; ++i) {
   1192     PerfGroupDescMetadata group;
   1193     if (!data->ReadStringWithSizeFromData(&group.name) ||
   1194         !data->ReadUint32(&group.leader_idx) ||
   1195         !data->ReadUint32(&group.num_members)) {
   1196       LOG(ERROR) << "Error reading group desc info for group #" << i;
   1197       return false;
   1198     }
   1199     serializer_.SerializeGroupDescMetadata(group, proto_->add_group_desc());
   1200   }
   1201   return true;
   1202 }
   1203 bool PerfReader::ReadTracingMetadata(DataReader* data, size_t size) {
   1204   std::vector<char> tracing_data(size);
   1205   if (!data->ReadDataValue(tracing_data.size(), "tracing_data",
   1206                            tracing_data.data())) {
   1207     return false;
   1208   }
   1209   serializer_.SerializeTracingMetadata(tracing_data, proto_);
   1210   return true;
   1211 }
   1212 
   1213 bool PerfReader::ReadFileData(DataReader* data) {
   1214   // Make sure sections are within the size of the file. This check prevents
   1215   // more obscure messages later when attempting to read from one of these
   1216   // sections.
   1217   if (header_.attrs.offset + header_.attrs.size > data->size()) {
   1218     LOG(ERROR) << "Header says attrs section ends at "
   1219                << header_.attrs.offset + header_.attrs.size
   1220                << " bytes, which is larger than perf data size of "
   1221                << data->size() << " bytes.";
   1222     return false;
   1223   }
   1224   if (header_.data.offset + header_.data.size > data->size()) {
   1225     LOG(ERROR) << "Header says data section ends at "
   1226                << header_.data.offset + header_.data.size
   1227                << " bytes, which is larger than perf data size of "
   1228                << data->size() << " bytes.";
   1229     return false;
   1230   }
   1231   if (header_.event_types.offset + header_.event_types.size > data->size()) {
   1232     LOG(ERROR) << "Header says event_types section ends at "
   1233                << header_.event_types.offset + header_.event_types.size
   1234                << " bytes, which is larger than perf data size of "
   1235                << data->size() << " bytes.";
   1236     return false;
   1237   }
   1238 
   1239   if (!get_metadata_mask_bit(HEADER_EVENT_DESC)) {
   1240     // Prefer to read attrs and event names from HEADER_EVENT_DESC metadata if
   1241     // available. event_types section of perf.data is obsolete, but use it as
   1242     // a fallback:
   1243     if (!(ReadAttrsSection(data) && ReadEventTypesSection(data))) return false;
   1244   }
   1245 
   1246   if (!(ReadMetadata(data) && ReadDataSection(data))) return false;
   1247 
   1248   // We can construct HEADER_EVENT_DESC from attrs and event types.
   1249   // NB: Can't set this before ReadMetadata(), or it may misread the metadata.
   1250   if (!event_types().empty()) set_metadata_mask_bit(HEADER_EVENT_DESC);
   1251 
   1252   return true;
   1253 }
   1254 
   1255 bool PerfReader::ReadPipedData(DataReader* data) {
   1256   // The piped data comes right after the file header.
   1257   CHECK_EQ(piped_header_.size, data->Tell());
   1258   bool result = true;
   1259   int num_event_types = 0;
   1260 
   1261   CheckNoEventHeaderPadding();
   1262 
   1263   while (result && data->Tell() < data->size()) {
   1264     perf_event_header header;
   1265     if (!ReadPerfEventHeader(data, &header)) {
   1266       LOG(ERROR) << "Error reading event header.";
   1267       break;
   1268     }
   1269 
   1270     if (header.size == 0) {
   1271       // Avoid an infinite loop.
   1272       LOG(ERROR) << "Event size is zero. Type: " << header.type;
   1273       return false;
   1274     }
   1275 
   1276     // Compute the size of the post-header part of the event data.
   1277     size_t size_without_header = header.size - sizeof(header);
   1278 
   1279     bool isHeaderEventType = [&] {
   1280       switch (header.type) {
   1281         case PERF_RECORD_HEADER_ATTR:
   1282         case PERF_RECORD_HEADER_EVENT_TYPE:
   1283         case PERF_RECORD_HEADER_TRACING_DATA:
   1284         case PERF_RECORD_HEADER_BUILD_ID:
   1285           return true;
   1286         default:
   1287           return false;
   1288       }
   1289     }();
   1290 
   1291     if (!isHeaderEventType) {
   1292       // Allocate space for an event struct based on the size in the header.
   1293       // Don't blindly allocate the entire event_t because it is a
   1294       // variable-sized type that may include data beyond what's nominally
   1295       // declared in its definition.
   1296       malloced_unique_ptr<event_t> event(CallocMemoryForEvent(header.size));
   1297       event->header = header;
   1298 
   1299       // Read the rest of the event data.
   1300       if (!data->ReadDataValue(size_without_header, "rest of piped event",
   1301                                &event->header + 1)) {
   1302         break;
   1303       }
   1304       MaybeSwapEventFields(event.get(), data->is_cross_endian());
   1305 
   1306       // Serialize the event to protobuf form.
   1307       PerfEvent* proto_event = proto_->add_events();
   1308       if (!serializer_.SerializeEvent(event, proto_event)) return false;
   1309 
   1310       if (proto_event->header().type() == PERF_RECORD_AUXTRACE) {
   1311         if (!ReadAuxtraceTraceData(data, proto_event)) return false;
   1312       }
   1313       continue;
   1314     }
   1315 
   1316     result = [&] {
   1317       switch (header.type) {
   1318         case PERF_RECORD_HEADER_ATTR:
   1319           return ReadAttrEventBlock(data, size_without_header);
   1320         case PERF_RECORD_HEADER_EVENT_TYPE:
   1321           return ReadEventType(data, num_event_types++, header.size);
   1322         case PERF_RECORD_HEADER_TRACING_DATA:
   1323           set_metadata_mask_bit(HEADER_TRACING_DATA);
   1324           {
   1325             // TRACING_DATA's header.size is a lie. It is the size of only the
   1326             // event struct. The size of the data is in the event struct, and
   1327             // followed immediately by the tracing header data.
   1328             decltype(tracing_data_event::size) size = 0;
   1329             if (!data->ReadUint32(&size)) {
   1330               LOG(ERROR) << "Error reading tracing data size.";
   1331               return false;
   1332             }
   1333             return ReadTracingMetadata(data, size);
   1334           }
   1335         case PERF_RECORD_HEADER_BUILD_ID:
   1336           set_metadata_mask_bit(HEADER_BUILD_ID);
   1337           return ReadBuildIDMetadataWithoutHeader(data, header);
   1338         default:
   1339           // For unsupported event types, log a warning only if the type is an
   1340           // unknown type.
   1341           if (header.type < PERF_RECORD_USER_TYPE_START ||
   1342               header.type >= PERF_RECORD_HEADER_MAX) {
   1343             LOG(WARNING) << "Unknown event type: " << header.type;
   1344           }
   1345           // Skip over the data in this event.
   1346           data->SeekSet(data->Tell() + size_without_header);
   1347           return true;
   1348       }
   1349     }();
   1350   }
   1351 
   1352   if (!result) return false;
   1353 
   1354   // The PERF_RECORD_HEADER_EVENT_TYPE events are obsolete, but if present
   1355   // and PERF_RECORD_HEADER_EVENT_DESC metadata events are not, we should use
   1356   // them. Otherwise, we should use prefer the _EVENT_DESC data.
   1357   if (!get_metadata_mask_bit(HEADER_EVENT_DESC) &&
   1358       num_event_types == proto_->file_attrs().size()) {
   1359     // We can construct HEADER_EVENT_DESC:
   1360     set_metadata_mask_bit(HEADER_EVENT_DESC);
   1361   }
   1362 
   1363   return result;
   1364 }
   1365 
   1366 bool PerfReader::ReadAuxtraceTraceData(DataReader* data,
   1367                                        PerfEvent* proto_event) {
   1368   std::vector<char> trace_data(proto_event->auxtrace_event().size());
   1369   if (!data->ReadDataValue(trace_data.size(),
   1370                            "trace date from PERF_RECORD_AUXTRACE event",
   1371                            trace_data.data())) {
   1372     return false;
   1373   }
   1374   if (data->is_cross_endian()) {
   1375     LOG(ERROR) << "Cannot byteswap trace data from PERF_RECORD_AUXTRACE";
   1376   }
   1377   if (!serializer_.SerializeAuxtraceEventTraceData(
   1378           trace_data, proto_event->mutable_auxtrace_event())) {
   1379     return false;
   1380   }
   1381   return true;
   1382 }
   1383 
   1384 bool PerfReader::WriteHeader(const struct perf_file_header& header,
   1385                              DataWriter* data) const {
   1386   CheckNoEventHeaderPadding();
   1387   size_t size = sizeof(header);
   1388   return data->WriteDataValue(&header, size, "file header");
   1389 }
   1390 
   1391 bool PerfReader::WriteAttrs(const struct perf_file_header& header,
   1392                             DataWriter* data) const {
   1393   CheckNoPerfEventAttrPadding();
   1394   const size_t id_offset = header.size;
   1395   CHECK_EQ(id_offset, data->Tell());
   1396 
   1397   std::vector<struct perf_file_section> id_sections;
   1398   id_sections.reserve(attrs().size());
   1399   for (const auto& attr : proto_->file_attrs()) {
   1400     size_t section_size =
   1401         attr.ids_size() * sizeof(decltype(PerfFileAttr::ids)::value_type);
   1402     id_sections.push_back(perf_file_section{data->Tell(), section_size});
   1403     for (const uint64_t& id : attr.ids()) {
   1404       if (!data->WriteDataValue(&id, sizeof(id), "ID info")) return false;
   1405     }
   1406   }
   1407 
   1408   CHECK_EQ(header.attrs.offset, data->Tell());
   1409   for (int i = 0; i < attrs().size(); i++) {
   1410     const struct perf_file_section& id_section = id_sections[i];
   1411     PerfFileAttr attr;
   1412     serializer_.DeserializePerfFileAttr(proto_->file_attrs(i), &attr);
   1413     if (!data->WriteDataValue(&attr.attr, sizeof(attr.attr), "attribute") ||
   1414         !data->WriteDataValue(&id_section, sizeof(id_section), "ID section")) {
   1415       return false;
   1416     }
   1417   }
   1418   return true;
   1419 }
   1420 
   1421 bool PerfReader::WriteData(const struct perf_file_header& header,
   1422                            DataWriter* data) const {
   1423   // No need to CHECK anything if no event data is being written.
   1424   if (proto_->events().empty()) return true;
   1425 
   1426   CHECK(serializer_.SampleInfoReaderAvailable());
   1427   CHECK_EQ(header.data.offset, data->Tell());
   1428   for (const PerfEvent& proto_event : proto_->events()) {
   1429     malloced_unique_ptr<event_t> event;
   1430     // The nominal size given by |proto_event| may not be correct, as the
   1431     // contents may have changed since the PerfEvent was created. Use the size
   1432     // in the event_t returned by PerfSerializer::DeserializeEvent().
   1433     if (!serializer_.DeserializeEvent(proto_event, &event) ||
   1434         !data->WriteDataValue(event.get(), event->header.size, "event data")) {
   1435       return false;
   1436     }
   1437     // PERF_RECORD_AUXTRACE contains trace data that is written after writing
   1438     // the actual event data.
   1439     if (proto_event.header().type() == PERF_RECORD_AUXTRACE &&
   1440         proto_event.auxtrace_event().size() > 0) {
   1441       std::vector<char> trace_data;
   1442       if (!serializer_.DeserializeAuxtraceEventTraceData(
   1443               proto_event.auxtrace_event(), &trace_data) ||
   1444           !data->WriteDataValue(reinterpret_cast<void*>(trace_data.data()),
   1445                                 trace_data.size(),
   1446                                 "trace data from PERF_RECORD_AUXTRACE event")) {
   1447         return false;
   1448       }
   1449     }
   1450   }
   1451   return true;
   1452 }
   1453 
   1454 bool PerfReader::WriteMetadata(const struct perf_file_header& header,
   1455                                DataWriter* data) const {
   1456   const size_t header_offset = header.data.offset + header.data.size;
   1457   CHECK_EQ(header_offset, data->Tell());
   1458 
   1459   // There is one header for each feature pointing to the metadata for that
   1460   // feature. If a feature has no metadata, the size field is zero.
   1461   const size_t headers_size =
   1462       GetNumSupportedMetadata() * sizeof(perf_file_section);
   1463   const size_t metadata_offset = header_offset + headers_size;
   1464   data->SeekSet(metadata_offset);
   1465 
   1466   // Record the new metadata offsets and sizes in this vector of info entries.
   1467   std::vector<struct perf_file_section> metadata_sections;
   1468   metadata_sections.reserve(GetNumSupportedMetadata());
   1469 
   1470   // For less verbose access to string metadata fields.
   1471   const auto& string_metadata = proto_->string_metadata();
   1472 
   1473   for (u32 type = HEADER_FIRST_FEATURE; type != HEADER_LAST_FEATURE; ++type) {
   1474     if ((header.adds_features[0] & (1 << type)) == 0) continue;
   1475 
   1476     struct perf_file_section header_entry;
   1477     header_entry.offset = data->Tell();
   1478     // Write actual metadata to address metadata_offset
   1479     switch (type) {
   1480       case HEADER_TRACING_DATA:
   1481         if (!data->WriteDataValue(tracing_data().data(), tracing_data().size(),
   1482                                   "tracing data")) {
   1483           return false;
   1484         }
   1485         break;
   1486       case HEADER_BUILD_ID:
   1487         if (!WriteBuildIDMetadata(type, data)) return false;
   1488         break;
   1489       case HEADER_HOSTNAME:
   1490         if (!WriteSingleStringMetadata(string_metadata.hostname(), data))
   1491           return false;
   1492         break;
   1493       case HEADER_OSRELEASE:
   1494         if (!WriteSingleStringMetadata(string_metadata.kernel_version(), data))
   1495           return false;
   1496         break;
   1497       case HEADER_VERSION:
   1498         if (!WriteSingleStringMetadata(string_metadata.perf_version(), data))
   1499           return false;
   1500         break;
   1501       case HEADER_ARCH:
   1502         if (!WriteSingleStringMetadata(string_metadata.architecture(), data))
   1503           return false;
   1504         break;
   1505       case HEADER_CPUDESC:
   1506         if (!WriteSingleStringMetadata(string_metadata.cpu_description(), data))
   1507           return false;
   1508         break;
   1509       case HEADER_CPUID:
   1510         if (!WriteSingleStringMetadata(string_metadata.cpu_id(), data))
   1511           return false;
   1512         break;
   1513       case HEADER_CMDLINE:
   1514         if (!WriteRepeatedStringMetadata(
   1515                 string_metadata.perf_command_line_token(), data)) {
   1516           return false;
   1517         }
   1518         break;
   1519       case HEADER_NRCPUS:
   1520         if (!WriteUint32Metadata(type, data)) return false;
   1521         break;
   1522       case HEADER_TOTAL_MEM:
   1523         if (!WriteUint64Metadata(type, data)) return false;
   1524         break;
   1525       case HEADER_EVENT_DESC:
   1526         if (!WriteEventDescMetadata(data)) return false;
   1527         break;
   1528       case HEADER_CPU_TOPOLOGY:
   1529         if (!WriteCPUTopologyMetadata(data)) return false;
   1530         break;
   1531       case HEADER_NUMA_TOPOLOGY:
   1532         if (!WriteNUMATopologyMetadata(data)) return false;
   1533         break;
   1534       case HEADER_BRANCH_STACK:
   1535         break;
   1536       case HEADER_PMU_MAPPINGS:
   1537         if (!WritePMUMappingsMetadata(data)) return false;
   1538         break;
   1539       case HEADER_GROUP_DESC:
   1540         if (!WriteGroupDescMetadata(data)) return false;
   1541         break;
   1542       default:
   1543         LOG(ERROR) << "Unsupported metadata type: " << type;
   1544         return false;
   1545     }
   1546 
   1547     // Compute the size of the metadata that was just written. This is reflected
   1548     // in how much the data write pointer has moved.
   1549     header_entry.size = data->Tell() - header_entry.offset;
   1550     metadata_sections.push_back(header_entry);
   1551   }
   1552   // Make sure we have recorded the right number of entries.
   1553   CHECK_EQ(GetNumSupportedMetadata(), metadata_sections.size());
   1554 
   1555   // Now write the metadata offset and size info back to the metadata headers.
   1556   size_t old_offset = data->Tell();
   1557   data->SeekSet(header_offset);
   1558   if (!data->WriteDataValue(metadata_sections.data(), headers_size,
   1559                             "metadata section info")) {
   1560     return false;
   1561   }
   1562   // Make sure the write pointer now points to the end of the metadata headers
   1563   // and hence the beginning of the actual metadata.
   1564   CHECK_EQ(metadata_offset, data->Tell());
   1565   data->SeekSet(old_offset);
   1566 
   1567   return true;
   1568 }
   1569 
   1570 bool PerfReader::WriteBuildIDMetadata(u32 type, DataWriter* data) const {
   1571   CheckNoBuildIDEventPadding();
   1572   for (const auto& build_id : proto_->build_ids()) {
   1573     malloced_unique_ptr<build_id_event> event;
   1574     if (!serializer_.DeserializeBuildIDEvent(build_id, &event)) {
   1575       LOG(ERROR) << "Could not deserialize build ID event with build ID "
   1576                  << RawDataToHexString(build_id.build_id_hash());
   1577       return false;
   1578     }
   1579     if (!data->WriteDataValue(event.get(), event->header.size,
   1580                               "Build ID metadata")) {
   1581       return false;
   1582     }
   1583   }
   1584   return true;
   1585 }
   1586 
   1587 bool PerfReader::WriteSingleStringMetadata(const StringAndMd5sumPrefix& src,
   1588                                            DataWriter* data) const {
   1589   return data->WriteStringWithSizeToData(src.value());
   1590 }
   1591 
   1592 bool PerfReader::WriteRepeatedStringMetadata(
   1593     const RepeatedPtrField<StringAndMd5sumPrefix>& src_array,
   1594     DataWriter* data) const {
   1595   num_string_data_type num_strings = src_array.size();
   1596   if (!data->WriteDataValue(&num_strings, sizeof(num_strings),
   1597                             "number of string metadata")) {
   1598     return false;
   1599   }
   1600   for (const auto& src_entry : src_array) {
   1601     if (!data->WriteStringWithSizeToData(src_entry.value())) return false;
   1602   }
   1603   return true;
   1604 }
   1605 
   1606 bool PerfReader::WriteUint32Metadata(u32 type, DataWriter* data) const {
   1607   for (const auto& metadata : proto_->uint32_metadata()) {
   1608     if (metadata.type() != type) continue;
   1609     PerfUint32Metadata local_metadata;
   1610     serializer_.DeserializeSingleUint32Metadata(metadata, &local_metadata);
   1611     const std::vector<uint32_t>& raw_data = local_metadata.data;
   1612     return data->WriteDataValue(raw_data.data(),
   1613                                 raw_data.size() * sizeof(uint32_t),
   1614                                 "uint32_t metadata");
   1615   }
   1616   LOG(ERROR) << "Uint32 metadata of type " << type << " not present";
   1617   return false;
   1618 }
   1619 
   1620 bool PerfReader::WriteUint64Metadata(u32 type, DataWriter* data) const {
   1621   for (const auto& metadata : proto_->uint64_metadata()) {
   1622     if (metadata.type() != type) continue;
   1623     PerfUint64Metadata local_metadata;
   1624     serializer_.DeserializeSingleUint64Metadata(metadata, &local_metadata);
   1625     const std::vector<uint64_t>& raw_data = local_metadata.data;
   1626     return data->WriteDataValue(raw_data.data(),
   1627                                 raw_data.size() * sizeof(uint64_t),
   1628                                 "uint32_t metadata");
   1629   }
   1630   LOG(ERROR) << "Uint64 metadata of type " << type << " not present";
   1631   return false;
   1632 }
   1633 
   1634 bool PerfReader::WriteEventDescMetadata(DataWriter* data) const {
   1635   CheckNoPerfEventAttrPadding();
   1636 
   1637   if (attrs().size() > event_types().size()) {
   1638     LOG(ERROR) << "Number of attrs (" << attrs().size() << ") cannot exceed "
   1639                << "number of event types (" << event_types().size() << ")";
   1640     return false;
   1641   }
   1642 
   1643   event_desc_num_events num_events = proto_->file_attrs().size();
   1644   if (!data->WriteDataValue(&num_events, sizeof(num_events),
   1645                             "event_desc num_events")) {
   1646     return false;
   1647   }
   1648   event_desc_attr_size attr_size = sizeof(perf_event_attr);
   1649   if (!data->WriteDataValue(&attr_size, sizeof(attr_size),
   1650                             "event_desc attr_size")) {
   1651     return false;
   1652   }
   1653 
   1654   for (int i = 0; i < attrs().size(); ++i) {
   1655     const auto& stored_attr = attrs().Get(i);
   1656     PerfFileAttr attr;
   1657     serializer_.DeserializePerfFileAttr(stored_attr, &attr);
   1658     if (!serializer_.DeserializePerfEventType(proto_->event_types(i), &attr))
   1659       return false;
   1660 
   1661     if (!data->WriteDataValue(&attr.attr, sizeof(attr.attr),
   1662                               "event_desc attribute")) {
   1663       return false;
   1664     }
   1665 
   1666     event_desc_num_unique_ids num_ids = attr.ids.size();
   1667     if (!data->WriteDataValue(&num_ids, sizeof(num_ids),
   1668                               "event_desc num_unique_ids")) {
   1669       return false;
   1670     }
   1671 
   1672     if (!data->WriteStringWithSizeToData(attr.name)) return false;
   1673 
   1674     if (!data->WriteDataValue(attr.ids.data(), num_ids * sizeof(attr.ids[0]),
   1675                               "event_desc unique_ids")) {
   1676       return false;
   1677     }
   1678   }
   1679   return true;
   1680 }
   1681 
   1682 bool PerfReader::WriteCPUTopologyMetadata(DataWriter* data) const {
   1683   PerfCPUTopologyMetadata cpu_topology;
   1684   serializer_.DeserializeCPUTopologyMetadata(proto_->cpu_topology(),
   1685                                              &cpu_topology);
   1686 
   1687   std::vector<string>& cores = cpu_topology.core_siblings;
   1688   num_siblings_type num_cores = cores.size();
   1689   if (!data->WriteDataValue(&num_cores, sizeof(num_cores), "num cores"))
   1690     return false;
   1691   for (string& core_name : cores) {
   1692     if (!data->WriteStringWithSizeToData(core_name)) return false;
   1693   }
   1694 
   1695   std::vector<string>& threads = cpu_topology.thread_siblings;
   1696   num_siblings_type num_threads = threads.size();
   1697   if (!data->WriteDataValue(&num_threads, sizeof(num_threads), "num threads"))
   1698     return false;
   1699   for (string& thread_name : threads) {
   1700     if (!data->WriteStringWithSizeToData(thread_name)) return false;
   1701   }
   1702 
   1703   return true;
   1704 }
   1705 
   1706 bool PerfReader::WriteNUMATopologyMetadata(DataWriter* data) const {
   1707   numa_topology_num_nodes_type num_nodes = proto_->numa_topology().size();
   1708   if (!data->WriteDataValue(&num_nodes, sizeof(num_nodes), "num nodes"))
   1709     return false;
   1710 
   1711   for (const auto& node_proto : proto_->numa_topology()) {
   1712     PerfNodeTopologyMetadata node;
   1713     serializer_.DeserializeNodeTopologyMetadata(node_proto, &node);
   1714 
   1715     if (!data->WriteDataValue(&node.id, sizeof(node.id), "node id") ||
   1716         !data->WriteDataValue(&node.total_memory, sizeof(node.total_memory),
   1717                               "node total memory") ||
   1718         !data->WriteDataValue(&node.free_memory, sizeof(node.free_memory),
   1719                               "node free memory") ||
   1720         !data->WriteStringWithSizeToData(node.cpu_list)) {
   1721       return false;
   1722     }
   1723   }
   1724   return true;
   1725 }
   1726 
   1727 bool PerfReader::WritePMUMappingsMetadata(DataWriter* data) const {
   1728   pmu_mappings_num_mappings_type num_mappings = proto_->pmu_mappings().size();
   1729   if (!data->WriteDataValue(&num_mappings, sizeof(num_mappings),
   1730                             "num mappings"))
   1731     return false;
   1732 
   1733   for (const auto& mapping_proto : proto_->pmu_mappings()) {
   1734     PerfPMUMappingsMetadata mapping;
   1735     serializer_.DeserializePMUMappingsMetadata(mapping_proto, &mapping);
   1736 
   1737     if (!data->WriteDataValue(&mapping.type, sizeof(mapping.type),
   1738                               "mapping type") ||
   1739         !data->WriteStringWithSizeToData(mapping.name)) {
   1740       return false;
   1741     }
   1742   }
   1743   return true;
   1744 }
   1745 
   1746 bool PerfReader::WriteGroupDescMetadata(DataWriter* data) const {
   1747   group_desc_num_groups_type num_groups = proto_->group_desc().size();
   1748   if (!data->WriteDataValue(&num_groups, sizeof(num_groups), "num groups"))
   1749     return false;
   1750 
   1751   for (const auto& group_proto : proto_->group_desc()) {
   1752     PerfGroupDescMetadata group;
   1753     serializer_.DeserializeGroupDescMetadata(group_proto, &group);
   1754 
   1755     if (!data->WriteStringWithSizeToData(group.name) ||
   1756         !data->WriteDataValue(&group.leader_idx, sizeof(group.leader_idx),
   1757                               "group leader index") ||
   1758         !data->WriteDataValue(&group.num_members, sizeof(group.num_members),
   1759                               "group num members")) {
   1760       return false;
   1761     }
   1762   }
   1763   return true;
   1764 }
   1765 
   1766 bool PerfReader::ReadAttrEventBlock(DataReader* data, size_t size) {
   1767   const size_t initial_offset = data->Tell();
   1768   PerfFileAttr attr;
   1769   if (!ReadEventAttr(data, &attr.attr)) return false;
   1770 
   1771   // attr.attr.size has been upgraded to the current size of perf_event_attr.
   1772   const size_t actual_attr_size = data->Tell() - initial_offset;
   1773 
   1774   const size_t num_ids =
   1775       (size - actual_attr_size) / sizeof(decltype(attr.ids)::value_type);
   1776   if (!ReadUniqueIDs(data, num_ids, &attr.ids)) return false;
   1777 
   1778   // Event types are found many times in the perf data file.
   1779   // Only add this event type if it is not already present.
   1780   if (!attr.ids.empty() &&
   1781       file_attrs_seen_.find(attr.ids[0]) != file_attrs_seen_.end()) {
   1782     return true;
   1783   }
   1784 
   1785   AddPerfFileAttr(attr);
   1786   return true;
   1787 }
   1788 
   1789 void PerfReader::MaybeSwapEventFields(event_t* event, bool is_cross_endian) {
   1790   if (!is_cross_endian) return;
   1791   uint32_t type = event->header.type;
   1792   switch (type) {
   1793     case PERF_RECORD_SAMPLE:
   1794       break;
   1795     case PERF_RECORD_MMAP:
   1796       ByteSwap(&event->mmap.pid);
   1797       ByteSwap(&event->mmap.tid);
   1798       ByteSwap(&event->mmap.start);
   1799       ByteSwap(&event->mmap.len);
   1800       ByteSwap(&event->mmap.pgoff);
   1801       break;
   1802     case PERF_RECORD_MMAP2:
   1803       ByteSwap(&event->mmap2.pid);
   1804       ByteSwap(&event->mmap2.tid);
   1805       ByteSwap(&event->mmap2.start);
   1806       ByteSwap(&event->mmap2.len);
   1807       ByteSwap(&event->mmap2.pgoff);
   1808       ByteSwap(&event->mmap2.maj);
   1809       ByteSwap(&event->mmap2.min);
   1810       ByteSwap(&event->mmap2.ino);
   1811       ByteSwap(&event->mmap2.ino_generation);
   1812       ByteSwap(&event->mmap2.prot);
   1813       ByteSwap(&event->mmap2.flags);
   1814       break;
   1815     case PERF_RECORD_FORK:
   1816     case PERF_RECORD_EXIT:
   1817       ByteSwap(&event->fork.pid);
   1818       ByteSwap(&event->fork.tid);
   1819       ByteSwap(&event->fork.ppid);
   1820       ByteSwap(&event->fork.ptid);
   1821       ByteSwap(&event->fork.time);
   1822       break;
   1823     case PERF_RECORD_COMM:
   1824       ByteSwap(&event->comm.pid);
   1825       ByteSwap(&event->comm.tid);
   1826       break;
   1827     case PERF_RECORD_LOST:
   1828       ByteSwap(&event->lost.id);
   1829       ByteSwap(&event->lost.lost);
   1830       break;
   1831     case PERF_RECORD_THROTTLE:
   1832     case PERF_RECORD_UNTHROTTLE:
   1833       ByteSwap(&event->throttle.time);
   1834       ByteSwap(&event->throttle.id);
   1835       ByteSwap(&event->throttle.stream_id);
   1836       break;
   1837     case PERF_RECORD_READ:
   1838       ByteSwap(&event->read.pid);
   1839       ByteSwap(&event->read.tid);
   1840       ByteSwap(&event->read.value);
   1841       ByteSwap(&event->read.time_enabled);
   1842       ByteSwap(&event->read.time_running);
   1843       ByteSwap(&event->read.id);
   1844       break;
   1845     case PERF_RECORD_AUX:
   1846       ByteSwap(&event->aux.aux_offset);
   1847       ByteSwap(&event->aux.aux_size);
   1848       ByteSwap(&event->aux.flags);
   1849       break;
   1850     case PERF_RECORD_AUXTRACE:
   1851       ByteSwap(&event->auxtrace.size);
   1852       ByteSwap(&event->auxtrace.offset);
   1853       ByteSwap(&event->auxtrace.reference);
   1854       ByteSwap(&event->auxtrace.idx);
   1855       ByteSwap(&event->auxtrace.tid);
   1856       ByteSwap(&event->auxtrace.cpu);
   1857       break;
   1858     default:
   1859       LOG(FATAL) << "Unknown event type: " << type;
   1860   }
   1861 
   1862   // Do not swap the sample info fields that are not explicitly listed in the
   1863   // struct definition of each event type. Leave that up to SampleInfoReader
   1864   // within |serializer_|.
   1865 }
   1866 
   1867 size_t PerfReader::GetNumSupportedMetadata() const {
   1868   return GetNumBits(metadata_mask() & kSupportedMetadataMask);
   1869 }
   1870 
   1871 size_t PerfReader::GetEventDescMetadataSize() const {
   1872   if (attrs().size() > event_types().size()) {
   1873     LOG(ERROR) << "Number of attrs (" << attrs().size() << ") cannot exceed "
   1874                << "number of event types (" << event_types().size() << ")";
   1875     return 0;
   1876   }
   1877 
   1878   size_t size = 0;
   1879   if (get_metadata_mask_bit(HEADER_EVENT_DESC)) {
   1880     size += sizeof(event_desc_num_events) + sizeof(event_desc_attr_size);
   1881     for (int i = 0; i < attrs().size(); ++i) {
   1882       size += sizeof(perf_event_attr);
   1883       size += sizeof(event_desc_num_unique_ids);
   1884       size += ExpectedStorageSizeOf(event_types().Get(i).name());
   1885       size += attrs().Get(i).ids_size() *
   1886               sizeof(decltype(PerfFileAttr::ids)::value_type);
   1887     }
   1888   }
   1889   return size;
   1890 }
   1891 
   1892 size_t PerfReader::GetBuildIDMetadataSize() const {
   1893   size_t size = 0;
   1894   for (const auto& build_id : proto_->build_ids()) {
   1895     size += sizeof(build_id_event) +
   1896             GetUint64AlignedStringLength(build_id.filename());
   1897   }
   1898   return size;
   1899 }
   1900 
   1901 size_t PerfReader::GetStringMetadataSize() const {
   1902   size_t size = 0;
   1903   if (string_metadata().has_hostname())
   1904     size += ExpectedStorageSizeOf(string_metadata().hostname().value());
   1905   if (string_metadata().has_kernel_version())
   1906     size += ExpectedStorageSizeOf(string_metadata().kernel_version().value());
   1907   if (string_metadata().has_perf_version())
   1908     size += ExpectedStorageSizeOf(string_metadata().perf_version().value());
   1909   if (string_metadata().has_architecture())
   1910     size += ExpectedStorageSizeOf(string_metadata().architecture().value());
   1911   if (string_metadata().has_cpu_description())
   1912     size += ExpectedStorageSizeOf(string_metadata().cpu_description().value());
   1913   if (string_metadata().has_cpu_id())
   1914     size += ExpectedStorageSizeOf(string_metadata().cpu_id().value());
   1915 
   1916   if (!string_metadata().perf_command_line_token().empty()) {
   1917     size += sizeof(num_string_data_type);
   1918     for (const auto& token : string_metadata().perf_command_line_token())
   1919       size += ExpectedStorageSizeOf(token.value());
   1920   }
   1921   return size;
   1922 }
   1923 
   1924 size_t PerfReader::GetUint32MetadataSize() const {
   1925   size_t size = 0;
   1926   for (const auto& metadata : proto_->uint32_metadata())
   1927     size += metadata.data().size() * sizeof(uint32_t);
   1928   return size;
   1929 }
   1930 
   1931 size_t PerfReader::GetUint64MetadataSize() const {
   1932   size_t size = 0;
   1933   for (const auto& metadata : proto_->uint64_metadata())
   1934     size += metadata.data().size() * sizeof(uint64_t);
   1935   return size;
   1936 }
   1937 
   1938 size_t PerfReader::GetCPUTopologyMetadataSize() const {
   1939   // Core siblings.
   1940   size_t size = sizeof(num_siblings_type);
   1941   for (const string& core_sibling : proto_->cpu_topology().core_siblings())
   1942     size += ExpectedStorageSizeOf(core_sibling);
   1943 
   1944   // Thread siblings.
   1945   size += sizeof(num_siblings_type);
   1946   for (const string& thread_sibling : proto_->cpu_topology().thread_siblings())
   1947     size += ExpectedStorageSizeOf(thread_sibling);
   1948 
   1949   return size;
   1950 }
   1951 
   1952 size_t PerfReader::GetNUMATopologyMetadataSize() const {
   1953   size_t size = sizeof(numa_topology_num_nodes_type);
   1954   for (const auto& node : proto_->numa_topology()) {
   1955     size += sizeof(node.id());
   1956     size += sizeof(node.total_memory()) + sizeof(node.free_memory());
   1957     size += ExpectedStorageSizeOf(node.cpu_list());
   1958   }
   1959   return size;
   1960 }
   1961 
   1962 size_t PerfReader::GetPMUMappingsMetadataSize() const {
   1963   size_t size = sizeof(pmu_mappings_num_mappings_type);
   1964   for (const auto& node : proto_->pmu_mappings()) {
   1965     size += sizeof(node.type());
   1966     size += ExpectedStorageSizeOf(node.name());
   1967   }
   1968   return size;
   1969 }
   1970 
   1971 size_t PerfReader::GetGroupDescMetadataSize() const {
   1972   size_t size = sizeof(group_desc_num_groups_type);
   1973   for (const auto& group : proto_->group_desc()) {
   1974     size += ExpectedStorageSizeOf(group.name());
   1975     size += sizeof(group.leader_idx());
   1976     size += sizeof(group.num_members());
   1977   }
   1978   return size;
   1979 }
   1980 
   1981 bool PerfReader::NeedsNumberOfStringData(u32 type) const {
   1982   return type == HEADER_CMDLINE;
   1983 }
   1984 
   1985 bool PerfReader::LocalizeMMapFilenames(
   1986     const std::map<string, string>& filename_map) {
   1987   CHECK(serializer_.SampleInfoReaderAvailable());
   1988 
   1989   // Search for mmap/mmap2 events for which the filename needs to be updated.
   1990   for (PerfEvent& event : *proto_->mutable_events()) {
   1991     if (event.header().type() != PERF_RECORD_MMAP &&
   1992         event.header().type() != PERF_RECORD_MMAP2) {
   1993       continue;
   1994     }
   1995     const string& filename = event.mmap_event().filename();
   1996     const auto it = filename_map.find(filename);
   1997     if (it == filename_map.end())  // not found
   1998       continue;
   1999 
   2000     const string& new_filename = it->second;
   2001     size_t old_len = GetUint64AlignedStringLength(filename);
   2002     size_t new_len = GetUint64AlignedStringLength(new_filename);
   2003     size_t new_size = event.header().size() - old_len + new_len;
   2004 
   2005     event.mutable_mmap_event()->set_filename(new_filename);
   2006     event.mutable_header()->set_size(new_size);
   2007   }
   2008 
   2009   return true;
   2010 }
   2011 
   2012 void PerfReader::AddPerfFileAttr(const PerfFileAttr& attr) {
   2013   serializer_.SerializePerfFileAttr(attr, proto_->add_file_attrs());
   2014 
   2015   // Generate a new SampleInfoReader with the new attr.
   2016   serializer_.CreateSampleInfoReader(attr, is_cross_endian_);
   2017   if (!attr.ids.empty()) {
   2018     file_attrs_seen_.insert(attr.ids[0]);
   2019   }
   2020 }
   2021 
   2022 }  // namespace quipper
   2023