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(§ion->offset); 173 ByteSwap(§ion->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(×tamp_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, §ion)) { 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