15d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
25d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Use of this source code is governed by a BSD-style license that can be
35d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// found in the LICENSE file.
45d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
55d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "perf_serializer.h"
65d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
75d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <stdint.h>
85d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <stdio.h>
95d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <sys/time.h>
105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <algorithm>  // for std::copy
125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "base/logging.h"
145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "binary_data_utils.h"
165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "compat/proto.h"
175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "compat/string.h"
185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "kernel/perf_event.h"
195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "perf_data_structures.h"
205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "perf_data_utils.h"
215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "perf_parser.h"
225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "perf_reader.h"
235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmananamespace quipper {
255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
263fa0a5f4b88119fac65f86971738ea0202797b6elakshmanaPerfSerializer::PerfSerializer() {}
275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
283fa0a5f4b88119fac65f86971738ea0202797b6elakshmanaPerfSerializer::~PerfSerializer() {}
295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializePerfFileAttr(
315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfFileAttr& perf_file_attr,
325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfFileAttr* perf_file_attr_proto) const {
335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!SerializePerfEventAttr(perf_file_attr.attr,
345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                              perf_file_attr_proto->mutable_attr())) {
355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
383fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  for (size_t i = 0; i < perf_file_attr.ids.size(); i++)
395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    perf_file_attr_proto->add_ids(perf_file_attr.ids[i]);
405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializePerfFileAttr(
445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfFileAttr& perf_file_attr_proto,
455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfFileAttr* perf_file_attr) const {
465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!DeserializePerfEventAttr(perf_file_attr_proto.attr(),
475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                &perf_file_attr->attr)) {
485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
513fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  for (int i = 0; i < perf_file_attr_proto.ids_size(); i++)
525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    perf_file_attr->ids.push_back(perf_file_attr_proto.ids(i));
535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializePerfEventAttr(
575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const perf_event_attr& perf_event_attr,
585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfEventAttr* perf_event_attr_proto) const {
595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#define S(x) perf_event_attr_proto->set_##x(perf_event_attr.x)
605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(type);
615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(size);
625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(config);
635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (perf_event_attr_proto->freq())
645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(sample_freq);
655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  else
665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(sample_period);
675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_type);
685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(read_format);
695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(disabled);
705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(inherit);
715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(pinned);
725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclusive);
735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_user);
745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_kernel);
755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_hv);
765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_idle);
775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap);
785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(comm);
795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(freq);
805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(inherit_stat);
815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(enable_on_exec);
825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(task);
835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(watermark);
845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(precise_ip);
855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap_data);
865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_id_all);
875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_host);
885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_guest);
895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_callchain_kernel);
905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_callchain_user);
915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap2);
925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(comm_exec);
935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (perf_event_attr_proto->watermark())
945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(wakeup_watermark);
955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  else
965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(wakeup_events);
975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_type);
985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_addr);
995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_len);
1005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(branch_sample_type);
1015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_regs_user);
1025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_stack_user);
1035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#undef S
1045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
1055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
1065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializePerfEventAttr(
1085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfEventAttr& perf_event_attr_proto,
1095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    perf_event_attr* perf_event_attr) const {
1105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  memset(perf_event_attr, 0, sizeof(*perf_event_attr));
1115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#define S(x) perf_event_attr->x = perf_event_attr_proto.x()
1125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(type);
1135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(size);
1145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(config);
1155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (perf_event_attr->freq)
1165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(sample_freq);
1175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  else
1185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(sample_period);
1195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_type);
1205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(read_format);
1215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(disabled);
1225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(inherit);
1235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(pinned);
1245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclusive);
1255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_user);
1265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_kernel);
1275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_hv);
1285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_idle);
1295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap);
1305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(comm);
1315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(freq);
1325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(inherit_stat);
1335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(enable_on_exec);
1345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(task);
1355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(watermark);
1365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(precise_ip);
1375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap_data);
1385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_id_all);
1395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_host);
1405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_guest);
1415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_callchain_kernel);
1425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(exclude_callchain_user);
1435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(mmap2);
1445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(comm_exec);
1455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (perf_event_attr->watermark)
1465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(wakeup_watermark);
1475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  else
1485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    S(wakeup_events);
1495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_type);
1505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_addr);
1515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(bp_len);
1525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(branch_sample_type);
1535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_regs_user);
1545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  S(sample_stack_user);
1555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#undef S
1565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
1575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
1585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializePerfEventType(
1605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfFileAttr& event_attr,
1615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    quipper::PerfDataProto_PerfEventType* event_type_proto) const {
1625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_type_proto->set_id(event_attr.attr.config);
1635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_type_proto->set_name(event_attr.name);
1645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_type_proto->set_name_md5_prefix(Md5Prefix(event_attr.name));
1655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
1665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
1675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializePerfEventType(
1695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const quipper::PerfDataProto_PerfEventType& event_type_proto,
1705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfFileAttr* event_attr) const {
1715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Attr should have already been deserialized.
1725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (event_attr->attr.config != event_type_proto.id()) {
1735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    LOG(ERROR) << "Event type ID " << event_type_proto.id()
1745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana               << " does not match attr.config " << event_attr->attr.config
1755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana               << ". Not deserializing the event name!";
1765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
1775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_attr->name = event_type_proto.name();
1795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
1805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
1815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeEvent(
1835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const malloced_unique_ptr<event_t>& event_ptr,
1845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfEvent* event_proto) const {
1855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const event_t& event = *event_ptr;
1865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!SerializeEventHeader(event.header, event_proto->mutable_header()))
1885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
1895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
19098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  if (event.header.type >= PERF_RECORD_USER_TYPE_START) {
19198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    if (!SerializeUserEvent(event, event_proto)) {
19298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return false;
19398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    }
19498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  } else if (!SerializeKernelEvent(event, event_proto)) {
19598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    return false;
19698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
19798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
19898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  event_proto->set_timestamp(GetTimeFromPerfEvent(*event_proto));
19998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
20098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
20198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
20298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::SerializeKernelEvent(
20398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const event_t& event, PerfDataProto_PerfEvent* event_proto) const {
2045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  switch (event.header.type) {
2055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_SAMPLE:
20698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeSampleEvent(event, event_proto->mutable_sample_event());
2075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_MMAP:
20898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeMMapEvent(event, event_proto->mutable_mmap_event());
2095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_MMAP2:
21098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeMMap2Event(event, event_proto->mutable_mmap_event());
2115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_COMM:
21298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeCommEvent(event, event_proto->mutable_comm_event());
2135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_EXIT:
21498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeForkExitEvent(event, event_proto->mutable_exit_event());
2155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_FORK:
21698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeForkExitEvent(event, event_proto->mutable_fork_event());
2175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_LOST:
21898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeLostEvent(event, event_proto->mutable_lost_event());
2195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_THROTTLE:
2205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_UNTHROTTLE:
22198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeThrottleEvent(event,
22298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                                    event_proto->mutable_throttle_event());
2235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_READ:
22498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeReadEvent(event, event_proto->mutable_read_event());
22598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_AUX:
22698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeAuxEvent(event, event_proto->mutable_aux_event());
22798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    default:
22898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      LOG(ERROR) << "Unknown event type: " << event.header.type;
22998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
23098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
23198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
23298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
23398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::SerializeUserEvent(
23498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const event_t& event, PerfDataProto_PerfEvent* event_proto) const {
23598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  switch (event.header.type) {
23698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_AUXTRACE:
23798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return SerializeAuxtraceEvent(event,
23898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                                    event_proto->mutable_auxtrace_event());
2395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    default:
24098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      if (event.header.type >= PERF_RECORD_HEADER_MAX) {
2415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        LOG(ERROR) << "Unknown event type: " << event.header.type;
2425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      }
2435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
2455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
2465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeEvent(
2485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfEvent& event_proto,
2495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    malloced_unique_ptr<event_t>* event_ptr) const {
2505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_ptr->reset(CallocMemoryForEvent(event_proto.header().size()));
2515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event_t* event = event_ptr->get();
2525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!DeserializeEventHeader(event_proto.header(), &event->header))
2545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
2555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  bool event_deserialized = false;
25798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  if (event_proto.header().type() >= PERF_RECORD_USER_TYPE_START) {
25898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    event_deserialized = DeserializeUserEvent(event_proto, event);
25998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  } else {
26098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    event_deserialized = DeserializeKernelEvent(event_proto, event);
26198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
26298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
26398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  if (!event_deserialized) {
26498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    LOG(ERROR) << "Could not deserialize event of type "
26598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana               << event_proto.header().type();
26698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    return false;
26798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
26898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
26998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
27098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
27198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
27298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::DeserializeKernelEvent(
27398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const PerfDataProto_PerfEvent& event_proto, event_t* event) const {
2745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  switch (event_proto.header().type()) {
2755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_SAMPLE:
27698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeSampleEvent(event_proto.sample_event(), event);
2775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_MMAP:
27898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeMMapEvent(event_proto.mmap_event(), event);
2795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_MMAP2:
28098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeMMap2Event(event_proto.mmap_event(), event);
2815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_COMM:
28298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeCommEvent(event_proto.comm_event(), event);
2835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_EXIT:
28498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return (event_proto.has_exit_event() &&
28598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana              DeserializeForkExitEvent(event_proto.exit_event(), event)) ||
28698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana             (event_proto.has_fork_event() &&
28798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana              DeserializeForkExitEvent(event_proto.fork_event(), event));
28898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    // Some older protobufs use the |fork_event| field to store exit
28998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    // events.
2905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_FORK:
29198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeForkExitEvent(event_proto.fork_event(), event);
2925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_LOST:
29398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeLostEvent(event_proto.lost_event(), event);
2945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_THROTTLE:
2955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_UNTHROTTLE:
29698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeThrottleEvent(event_proto.throttle_event(), event);
2975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    case PERF_RECORD_READ:
29898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeReadEvent(event_proto.read_event(), event);
29998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_AUX:
30098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeAuxEvent(event_proto.aux_event(), event);
30198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_ITRACE_START:
30298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_LOST_SAMPLES:
30398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_SWITCH:
30498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_SWITCH_CPU_WIDE:
30598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_NAMESPACES:
30698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      LOG(ERROR) << "Event type: " << event_proto.header().type()
30798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                 << ". Not yet supported.";
30898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return true;
3095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      break;
31098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
31198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return false;
31298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
31398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
31498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::DeserializeUserEvent(
31598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const PerfDataProto_PerfEvent& event_proto, event_t* event) const {
31698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  switch (event_proto.header().type()) {
31798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    case PERF_RECORD_AUXTRACE:
31898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      return DeserializeAuxtraceEvent(event_proto.auxtrace_event(), event);
3195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    default:
3202abc932b46e3e8fdb38710d37200ee8a59ff45cdlakshmana      // User type events are marked as deserialized because they don't
3212abc932b46e3e8fdb38710d37200ee8a59ff45cdlakshmana      // have non-header data in perf.data proto.
32298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      if (event_proto.header().type() >= PERF_RECORD_HEADER_MAX) {
32398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        return false;
3242abc932b46e3e8fdb38710d37200ee8a59ff45cdlakshmana      }
3255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
3265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
3275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
3285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeEventHeader(
3305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const perf_event_header& header,
3315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_EventHeader* header_proto) const {
3325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header_proto->set_type(header.type);
3335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header_proto->set_misc(header.misc);
3345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header_proto->set_size(header.size);
3355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
3365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
3375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeEventHeader(
3395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_EventHeader& header_proto,
3405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    perf_event_header* header) const {
3415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header->type = header_proto.type();
3425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header->misc = header_proto.misc();
3435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  header->size = header_proto.size();
3445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
3455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
3465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeSampleEvent(
3483fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const event_t& event, PerfDataProto_SampleEvent* sample) const {
3495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_sample sample_info;
3505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  uint64_t sample_type = 0;
3515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!ReadPerfSampleInfoAndType(event, &sample_info, &sample_type))
3525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
3535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3543fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_IP) sample->set_ip(sample_info.ip);
3555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_TID) {
3565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_pid(sample_info.pid);
3575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_tid(sample_info.tid);
3585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
3595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_TIME)
3605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_sample_time_ns(sample_info.time);
3613fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_ADDR) sample->set_addr(sample_info.addr);
3625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if ((sample_type & PERF_SAMPLE_ID) || (sample_type & PERF_SAMPLE_IDENTIFIER))
3635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_id(sample_info.id);
3645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_STREAM_ID)
3655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_stream_id(sample_info.stream_id);
3663fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_CPU) sample->set_cpu(sample_info.cpu);
3673fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_PERIOD) sample->set_period(sample_info.period);
3683fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_RAW) sample->set_raw_size(sample_info.raw_size);
3695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_READ) {
3705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const SampleInfoReader* reader = GetSampleInfoReaderForEvent(event);
3715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (reader) {
3725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      PerfDataProto_ReadInfo* read_info = sample->mutable_read_info();
3737e11b0133d3e6557027b92b1f7faddc13aa15571skanev      if (reader->event_attr().read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
3747e11b0133d3e6557027b92b1f7faddc13aa15571skanev        read_info->set_time_enabled(sample_info.read.time_enabled);
3757e11b0133d3e6557027b92b1f7faddc13aa15571skanev      if (reader->event_attr().read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
3767e11b0133d3e6557027b92b1f7faddc13aa15571skanev        read_info->set_time_running(sample_info.read.time_running);
3775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      if (reader->event_attr().read_format & PERF_FORMAT_GROUP) {
37892657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        for (size_t i = 0; i < sample_info.read.group.nr; i++) {
37992657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev          auto read_value = read_info->add_read_value();
38092657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev          read_value->set_value(sample_info.read.group.values[i].value);
38192657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev          read_value->set_id(sample_info.read.group.values[i].id);
38292657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        }
3835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      } else {
3845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        auto read_value = read_info->add_read_value();
3855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        read_value->set_value(sample_info.read.one.value);
3865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        read_value->set_id(sample_info.read.one.id);
3875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      }
3885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    }
3895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
3905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_CALLCHAIN) {
3915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->mutable_callchain()->Reserve(sample_info.callchain->nr);
3925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    for (size_t i = 0; i < sample_info.callchain->nr; ++i)
3935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample->add_callchain(sample_info.callchain->ips[i]);
3945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
3955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
3965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    for (size_t i = 0; i < sample_info.branch_stack->nr; ++i) {
3975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample->add_branch_stack();
3985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      const struct branch_entry& entry = sample_info.branch_stack->entries[i];
3995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample->mutable_branch_stack(i)->set_from_ip(entry.from);
4005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample->mutable_branch_stack(i)->set_to_ip(entry.to);
4015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample->mutable_branch_stack(i)->set_mispredicted(entry.flags.mispred);
4025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    }
4035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4053fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_WEIGHT) sample->set_weight(sample_info.weight);
4065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_DATA_SRC)
4075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_data_src(sample_info.data_src);
4085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_TRANSACTION)
4095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_transaction(sample_info.transaction);
4105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
4125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
4135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeSampleEvent(
4153fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto_SampleEvent& sample, event_t* event) const {
4165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_sample sample_info;
4173fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_ip()) sample_info.ip = sample.ip();
4185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.has_pid()) {
4195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    CHECK(sample.has_tid()) << "Cannot have PID without TID.";
4205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.pid = sample.pid();
4215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.tid = sample.tid();
4225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4233fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_sample_time_ns()) sample_info.time = sample.sample_time_ns();
4243fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_addr()) sample_info.addr = sample.addr();
4253fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_id()) sample_info.id = sample.id();
4263fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_stream_id()) sample_info.stream_id = sample.stream_id();
4273fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_cpu()) sample_info.cpu = sample.cpu();
4283fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_period()) sample_info.period = sample.period();
4295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.has_read_info()) {
4305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const SampleInfoReader* reader = GetSampleInfoReaderForEvent(*event);
4315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (reader) {
4325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      const PerfDataProto_ReadInfo& read_info = sample.read_info();
4337e11b0133d3e6557027b92b1f7faddc13aa15571skanev      if (reader->event_attr().read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
4347e11b0133d3e6557027b92b1f7faddc13aa15571skanev        sample_info.read.time_enabled = read_info.time_enabled();
4357e11b0133d3e6557027b92b1f7faddc13aa15571skanev      if (reader->event_attr().read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
4367e11b0133d3e6557027b92b1f7faddc13aa15571skanev        sample_info.read.time_running = read_info.time_running();
4375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      if (reader->event_attr().read_format & PERF_FORMAT_GROUP) {
43892657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        sample_info.read.group.nr = read_info.read_value_size();
43992657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        sample_info.read.group.values =
44092657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev            new sample_read_value[read_info.read_value_size()];
44192657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        for (size_t i = 0; i < sample_info.read.group.nr; i++) {
44292657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev          sample_info.read.group.values[i].value =
44392657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev              read_info.read_value(i).value();
44492657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev          sample_info.read.group.values[i].id = read_info.read_value(i).id();
44592657d3e7e7551bb09af158475d5f62d9f022e3aSvilen Kanev        }
4465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      } else if (read_info.read_value_size() == 1) {
4475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_info.read.one.value = read_info.read_value(0).value();
4485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_info.read.one.id = read_info.read_value(0).id();
4495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      } else {
4505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        LOG(ERROR) << "Expected read_value array size of 1 but got "
4515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                   << read_info.read_value_size();
4525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      }
4535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    }
4545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.callchain_size() > 0) {
4565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    uint64_t callchain_size = sample.callchain_size();
4575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.callchain = reinterpret_cast<struct ip_callchain*>(
4585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        new uint64_t[callchain_size + 1]);
4595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.callchain->nr = callchain_size;
4605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    for (size_t i = 0; i < callchain_size; ++i)
4615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      sample_info.callchain->ips[i] = sample.callchain(i);
4625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.raw_size() > 0) {
4645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.raw_size = sample.raw_size();
4655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.raw_data = new uint8_t[sample.raw_size()];
4665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    memset(sample_info.raw_data, 0, sample.raw_size());
4675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.branch_stack_size() > 0) {
4695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    uint64_t branch_stack_size = sample.branch_stack_size();
4703fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    sample_info.branch_stack = reinterpret_cast<struct branch_stack*>(
4713fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        new uint8_t[sizeof(uint64_t) +
4723fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                    branch_stack_size * sizeof(struct branch_entry)]);
4735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.branch_stack->nr = branch_stack_size;
4745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    for (size_t i = 0; i < branch_stack_size; ++i) {
4755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      struct branch_entry& entry = sample_info.branch_stack->entries[i];
4765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      memset(&entry, 0, sizeof(entry));
4775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      entry.from = sample.branch_stack(i).from_ip();
4785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      entry.to = sample.branch_stack(i).to_ip();
4795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      entry.flags.mispred = sample.branch_stack(i).mispredicted();
4805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      entry.flags.predicted = !entry.flags.mispred;
4815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    }
4825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4843fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_weight()) sample_info.weight = sample.weight();
4853fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_data_src()) sample_info.data_src = sample.data_src();
4863fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_transaction()) sample_info.transaction = sample.transaction();
4875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfoReader* writer = GetSampleInfoReaderForId(sample.id());
4895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  CHECK(writer);
4905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return writer->WritePerfSampleInfo(sample_info, event);
4915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
4925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4933fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::SerializeMMapEvent(const event_t& event,
4943fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                        PerfDataProto_MMapEvent* sample) const {
4955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct mmap_event& mmap = event.mmap;
4965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pid(mmap.pid);
4975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_tid(mmap.tid);
4985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_start(mmap.start);
4995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_len(mmap.len);
5005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pgoff(mmap.pgoff);
5015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_filename(mmap.filename);
5025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_filename_md5_prefix(Md5Prefix(mmap.filename));
5035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
5055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5073fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::DeserializeMMapEvent(const PerfDataProto_MMapEvent& sample,
5083fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                          event_t* event) const {
5095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct mmap_event& mmap = event->mmap;
5105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.pid = sample.pid();
5115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.tid = sample.tid();
5125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.start = sample.start();
5135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.len = sample.len();
5145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.pgoff = sample.pgoff();
5155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  snprintf(mmap.filename, PATH_MAX, "%s", sample.filename().c_str());
5165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
5185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeMMap2Event(
5213fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const event_t& event, PerfDataProto_MMapEvent* sample) const {
5225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct mmap2_event& mmap = event.mmap2;
5235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pid(mmap.pid);
5245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_tid(mmap.tid);
5255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_start(mmap.start);
5265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_len(mmap.len);
5275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pgoff(mmap.pgoff);
5285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_maj(mmap.maj);
5295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_min(mmap.min);
5305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_ino(mmap.ino);
5315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_ino_generation(mmap.ino_generation);
5325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_prot(mmap.prot);
5335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_flags(mmap.flags);
5345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_filename(mmap.filename);
5355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_filename_md5_prefix(Md5Prefix(mmap.filename));
5365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
5385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeMMap2Event(
5413fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto_MMapEvent& sample, event_t* event) const {
5425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct mmap2_event& mmap = event->mmap2;
5435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.pid = sample.pid();
5445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.tid = sample.tid();
5455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.start = sample.start();
5465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.len = sample.len();
5475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.pgoff = sample.pgoff();
5485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.maj = sample.maj();
5495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.min = sample.min();
5505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.ino = sample.ino();
5515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.ino_generation = sample.ino_generation();
5525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.prot = sample.prot();
5535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  mmap.flags = sample.flags();
5545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  snprintf(mmap.filename, PATH_MAX, "%s", sample.filename().c_str());
5555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
5575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5593fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::SerializeCommEvent(const event_t& event,
5603fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                        PerfDataProto_CommEvent* sample) const {
5615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct comm_event& comm = event.comm;
5625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pid(comm.pid);
5635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_tid(comm.tid);
5645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_comm(comm.comm);
5655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_comm_md5_prefix(Md5Prefix(comm.comm));
5665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
5685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5703fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::DeserializeCommEvent(const PerfDataProto_CommEvent& sample,
5713fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                          event_t* event) const {
5725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct comm_event& comm = event->comm;
5735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  comm.pid = sample.pid();
5745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  comm.tid = sample.tid();
5755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  snprintf(comm.comm, sizeof(comm.comm), "%s", sample.comm().c_str());
5765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Sometimes the command string will be modified.  e.g. if the original comm
5785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // string is not recoverable from the Md5sum prefix, then use the latter as a
5795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // replacement comm string.  However, if the original was < 8 bytes (fit into
5805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // |sizeof(uint64_t)|), then the size is no longer correct.  This section
5815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // checks for the size difference and updates the size in the header.
5825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfoReader* reader =
5835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      GetSampleInfoReaderForId(sample.sample_info().id());
5845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  CHECK(reader);
5853fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  uint64_t sample_fields = SampleInfoReader::GetSampleFieldsForEventType(
5863fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      comm.header.type, reader->event_attr().sample_type);
5875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  comm.header.size = SampleInfoReader::GetPerfSampleDataOffset(*event) +
5885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                     GetNumBits(sample_fields) * sizeof(uint64_t);
5895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
5915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
5925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeForkExitEvent(
5943fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const event_t& event, PerfDataProto_ForkEvent* sample) const {
5955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct fork_event& fork = event.fork;
5965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pid(fork.pid);
5975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_ppid(fork.ppid);
5985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_tid(fork.tid);
5995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_ptid(fork.ptid);
6005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_fork_time_ns(fork.time);
6015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
6035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeForkExitEvent(
6063fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto_ForkEvent& sample, event_t* event) const {
6075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct fork_event& fork = event->fork;
6085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  fork.pid = sample.pid();
6095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  fork.ppid = sample.ppid();
6105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  fork.tid = sample.tid();
6115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  fork.ptid = sample.ptid();
6125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  fork.time = sample.fork_time_ns();
6135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
6155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6173fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::SerializeLostEvent(const event_t& event,
6183fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                        PerfDataProto_LostEvent* sample) const {
6195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct lost_event& lost = event.lost;
6205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_id(lost.id);
6215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_lost(lost.lost);
6225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
6245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6263fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::DeserializeLostEvent(const PerfDataProto_LostEvent& sample,
6273fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                          event_t* event) const {
6285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct lost_event& lost = event->lost;
6295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  lost.id = sample.id();
6305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  lost.lost = sample.lost();
6315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
6335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeThrottleEvent(
6363fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const event_t& event, PerfDataProto_ThrottleEvent* sample) const {
6375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct throttle_event& throttle = event.throttle;
6385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_time_ns(throttle.time);
6395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_id(throttle.id);
6405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_stream_id(throttle.stream_id);
6415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
6435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeThrottleEvent(
6463fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto_ThrottleEvent& sample, event_t* event) const {
6475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct throttle_event& throttle = event->throttle;
6485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  throttle.time = sample.time_ns();
6495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  throttle.id = sample.id();
6505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  throttle.stream_id = sample.stream_id();
6515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
6535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6553fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::SerializeReadEvent(const event_t& event,
6563fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                        PerfDataProto_ReadEvent* sample) const {
6575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const struct read_event& read = event.read;
6585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_pid(read.pid);
6595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_tid(read.tid);
6605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_value(read.value);
6615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_time_enabled(read.time_enabled);
6625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_time_running(read.time_running);
6635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  sample->set_id(read.id);
6645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
6665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6683fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::DeserializeReadEvent(const PerfDataProto_ReadEvent& sample,
6693fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                          event_t* event) const {
6705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct read_event& read = event->read;
6715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.pid = sample.pid();
6725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.tid = sample.tid();
6735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.value = sample.value();
6745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.time_enabled = sample.time_enabled();
6755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.time_running = sample.time_running();
6765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  read.id = sample.id();
6775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
6785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
6795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
6805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
68198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::SerializeAuxEvent(const event_t& event,
68298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                                       PerfDataProto_AuxEvent* sample) const {
68398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const struct aux_event& aux = event.aux;
68498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_aux_offset(aux.aux_offset);
68598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_aux_size(aux.aux_size);
68698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_is_truncated(aux.flags & PERF_AUX_FLAG_TRUNCATED ? true : false);
68798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_is_overwrite(aux.flags & PERF_AUX_FLAG_OVERWRITE ? true : false);
68898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_is_partial(aux.flags & PERF_AUX_FLAG_PARTIAL ? true : false);
68998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  if (aux.flags & ~(PERF_AUX_FLAG_TRUNCATED | PERF_AUX_FLAG_OVERWRITE |
69098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                    PERF_AUX_FLAG_PARTIAL)) {
69198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    LOG(WARNING) << "Ignoring unknown PERF_RECORD_AUX flag: " << aux.flags;
69298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
69398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
69498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return SerializeSampleInfo(event, sample->mutable_sample_info());
69598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
69698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
69798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::DeserializeAuxEvent(const PerfDataProto_AuxEvent& sample,
69898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                                         event_t* event) const {
69998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  struct aux_event& aux = event->aux;
70098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  aux.aux_offset = sample.aux_offset();
70198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  aux.aux_size = sample.aux_size();
70298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  aux.flags |= sample.is_truncated() ? PERF_AUX_FLAG_TRUNCATED : 0;
70398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  aux.flags |= sample.is_overwrite() ? PERF_AUX_FLAG_OVERWRITE : 0;
70498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  aux.flags |= sample.is_partial() ? PERF_AUX_FLAG_PARTIAL : 0;
70598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
70698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return DeserializeSampleInfo(sample.sample_info(), event);
70798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
70898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
7095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeSampleInfo(
7103fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const event_t& event, PerfDataProto_SampleInfo* sample) const {
7113fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (!SampleIdAll()) return true;
7125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_sample sample_info;
7145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  uint64_t sample_type = 0;
7155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!ReadPerfSampleInfoAndType(event, &sample_info, &sample_type))
7165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
7175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_TID) {
7195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_pid(sample_info.pid);
7205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_tid(sample_info.tid);
7215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
7225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_TIME)
7235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_sample_time_ns(sample_info.time);
7245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if ((sample_type & PERF_SAMPLE_ID) || (sample_type & PERF_SAMPLE_IDENTIFIER))
7255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_id(sample_info.id);
7263fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_type & PERF_SAMPLE_CPU) sample->set_cpu(sample_info.cpu);
7275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_STREAM_ID)
7285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample->set_stream_id(sample_info.stream_id);
7295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
7305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
7315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeSampleInfo(
7333fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto_SampleInfo& sample, event_t* event) const {
7343fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (!SampleIdAll()) return true;
7355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_sample sample_info;
7375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample.has_tid()) {
7385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.pid = sample.pid();
7395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info.tid = sample.tid();
7405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
7413fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_sample_time_ns()) sample_info.time = sample.sample_time_ns();
7423fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_id()) sample_info.id = sample.id();
7433fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_cpu()) sample_info.cpu = sample.cpu();
7443fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample.has_stream_id()) sample_info.stream_id = sample.stream_id();
7455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfoReader* writer = GetSampleInfoReaderForId(sample.id());
7475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  CHECK(writer);
7485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return writer->WritePerfSampleInfo(sample_info, event);
7495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
7505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7513fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::SerializeTracingMetadata(const std::vector<char>& from,
7523fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                              PerfDataProto* to) const {
7535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (from.empty()) {
7545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return true;
7555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
7565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  PerfDataProto_PerfTracingMetadata* data = to->mutable_tracing_data();
7575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  data->set_tracing_data(from.data(), from.size());
7585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  data->set_tracing_data_md5_prefix(Md5Prefix(from));
7595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
7615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
7625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7633fa0a5f4b88119fac65f86971738ea0202797b6elakshmanabool PerfSerializer::DeserializeTracingMetadata(const PerfDataProto& from,
7643fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                                                std::vector<char>* to) const {
7655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!from.has_tracing_data()) {
7665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    to->clear();
7675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return true;
7685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
7695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7703fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  const PerfDataProto_PerfTracingMetadata& data = from.tracing_data();
7715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->assign(data.tracing_data().begin(), data.tracing_data().end());
7725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
7735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
7745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeBuildIDEvent(
7765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const malloced_unique_ptr<build_id_event>& from,
7775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfBuildID* to) const {
7785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->set_misc(from->header.misc);
7795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->set_pid(from->pid);
7805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->set_filename(from->filename);
7815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->set_filename_md5_prefix(Md5Prefix(from->filename));
7825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Trim out trailing zeroes from the build ID.
7845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  string build_id = RawDataToHexString(from->build_id, kBuildIDArraySize);
7855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  TrimZeroesFromBuildIDString(&build_id);
7865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  uint8_t build_id_bytes[kBuildIDArraySize];
7885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!HexStringToRawData(build_id, build_id_bytes, sizeof(build_id_bytes)))
7895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
7905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Used to convert build IDs (and possibly other hashes) between raw data
7925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // format and as string of hex digits.
7935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const int kHexCharsPerByte = 2;
7945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  to->set_build_id_hash(build_id_bytes, build_id.size() / kHexCharsPerByte);
7955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
7975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
7985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
7995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeBuildIDEvent(
8005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfBuildID& from,
8015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    malloced_unique_ptr<build_id_event>* to) const {
8025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const string& filename = from.filename();
8035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  size_t size = sizeof(build_id_event) + GetUint64AlignedStringLength(filename);
8045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
8055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  malloced_unique_ptr<build_id_event>& event = *to;
8065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event.reset(CallocMemoryForBuildID(size));
8075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event->header.type = PERF_RECORD_HEADER_BUILD_ID;
8085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event->header.size = size;
8095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event->header.misc = from.misc();
8105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  event->pid = from.pid();
8115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  memcpy(event->build_id, from.build_id_hash().c_str(),
8125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana         from.build_id_hash().size());
8135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
8145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (from.has_filename() && !filename.empty()) {
8153fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    CHECK_GT(
8163fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        snprintf(event->filename, filename.size() + 1, "%s", filename.c_str()),
8173fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        0);
8185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
8195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
8205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
8215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
82298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::SerializeAuxtraceEvent(
82398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const event_t& event, PerfDataProto_AuxtraceEvent* sample) const {
82498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const struct auxtrace_event& auxtrace = event.auxtrace;
82598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_size(auxtrace.size);
82698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_offset(auxtrace.offset);
82798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_reference(auxtrace.reference);
82898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_idx(auxtrace.idx);
82998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_tid(auxtrace.tid);
83098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  sample->set_cpu(auxtrace.cpu);
83198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
83298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
83398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
83498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
83598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::SerializeAuxtraceEventTraceData(
83698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const std::vector<char>& from, PerfDataProto_AuxtraceEvent* to) const {
83798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  if (from.empty()) {
83898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    return true;
83998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  }
84098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  to->set_trace_data(from.data(), from.size());
84198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
84298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
84398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
84498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
84598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::DeserializeAuxtraceEvent(
84698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const PerfDataProto_AuxtraceEvent& sample, event_t* event) const {
84798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  struct auxtrace_event& auxtrace = event->auxtrace;
84898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.size = sample.size();
84998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.offset = sample.offset();
85098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.reference = sample.reference();
85198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.idx = sample.idx();
85298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.tid = sample.tid();
85398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  auxtrace.cpu = sample.cpu();
85498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
85598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
85698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
85798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
85898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanabool PerfSerializer::DeserializeAuxtraceEventTraceData(
85998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana    const PerfDataProto_AuxtraceEvent& from, std::vector<char>* to) const {
86098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  to->assign(from.trace_data().begin(), from.trace_data().end());
86198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  return true;
86298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana}
86398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
8645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeSingleUint32Metadata(
8655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfUint32Metadata& metadata,
8665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfUint32Metadata* proto_metadata) const {
8675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_type(metadata.type);
8685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (size_t i = 0; i < metadata.data.size(); ++i)
8695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_data(metadata.data[i]);
8705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
8715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
8725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
8735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeSingleUint32Metadata(
8745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfUint32Metadata& proto_metadata,
8755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfUint32Metadata* metadata) const {
8765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->type = proto_metadata.type();
8775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (int i = 0; i < proto_metadata.data_size(); ++i)
8785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    metadata->data.push_back(proto_metadata.data(i));
8795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
8805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
8815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
8825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeSingleUint64Metadata(
8835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfUint64Metadata& metadata,
8845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfUint64Metadata* proto_metadata) const {
8855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_type(metadata.type);
8865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (size_t i = 0; i < metadata.data.size(); ++i)
8875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_data(metadata.data[i]);
8885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
8895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
8905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
8915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeSingleUint64Metadata(
8925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfUint64Metadata& proto_metadata,
8935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfUint64Metadata* metadata) const {
8945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->type = proto_metadata.type();
8955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (int i = 0; i < proto_metadata.data_size(); ++i)
8965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    metadata->data.push_back(proto_metadata.data(i));
8975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
8985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
8995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
9005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeCPUTopologyMetadata(
9015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfCPUTopologyMetadata& metadata,
9025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfCPUTopologyMetadata* proto_metadata) const {
9035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (const string& core_name : metadata.core_siblings) {
9045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_core_siblings(core_name);
9055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_core_siblings_md5_prefix(Md5Prefix(core_name));
9065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
9075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (const string& thread_name : metadata.thread_siblings) {
9085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_thread_siblings(thread_name);
9095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    proto_metadata->add_thread_siblings_md5_prefix(Md5Prefix(thread_name));
9105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
9115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
9125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
9135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
9145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeCPUTopologyMetadata(
9155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfCPUTopologyMetadata& proto_metadata,
9165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfCPUTopologyMetadata* metadata) const {
9175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->core_siblings.clear();
9185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->core_siblings.reserve(proto_metadata.core_siblings().size());
9195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  std::copy(proto_metadata.core_siblings().begin(),
9205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana            proto_metadata.core_siblings().end(),
9215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana            std::back_inserter(metadata->core_siblings));
9225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
9235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->thread_siblings.clear();
9245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->thread_siblings.reserve(proto_metadata.thread_siblings().size());
9255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  std::copy(proto_metadata.thread_siblings().begin(),
9265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana            proto_metadata.thread_siblings().end(),
9275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana            std::back_inserter(metadata->thread_siblings));
9285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
9295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
9305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
9315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SerializeNodeTopologyMetadata(
9325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfNodeTopologyMetadata& metadata,
9335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfDataProto_PerfNodeTopologyMetadata* proto_metadata) const {
9345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_id(metadata.id);
9355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_total_memory(metadata.total_memory);
9365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_free_memory(metadata.free_memory);
9375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_cpu_list(metadata.cpu_list);
9385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  proto_metadata->set_cpu_list_md5_prefix(Md5Prefix(metadata.cpu_list));
9395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
9405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
9415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
9425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::DeserializeNodeTopologyMetadata(
9435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const PerfDataProto_PerfNodeTopologyMetadata& proto_metadata,
9445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    PerfNodeTopologyMetadata* metadata) const {
9455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->id = proto_metadata.id();
9465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->total_memory = proto_metadata.total_memory();
9475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->free_memory = proto_metadata.free_memory();
9485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  metadata->cpu_list = proto_metadata.cpu_list();
9495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
9505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
9515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
952b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmanabool PerfSerializer::SerializePMUMappingsMetadata(
953b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    const PerfPMUMappingsMetadata& metadata,
954b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    PerfDataProto_PerfPMUMappingsMetadata* proto_metadata) const {
955b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_type(metadata.type);
956b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_name(metadata.name);
957b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_name_md5_prefix(Md5Prefix(metadata.name));
958b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  return true;
959b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana}
960b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana
961b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmanabool PerfSerializer::DeserializePMUMappingsMetadata(
962b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    const PerfDataProto_PerfPMUMappingsMetadata& proto_metadata,
963b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    PerfPMUMappingsMetadata* metadata) const {
964b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  metadata->type = proto_metadata.type();
965b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  metadata->name = proto_metadata.name();
966b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  return true;
967b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana}
968b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana
969b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmanabool PerfSerializer::SerializeGroupDescMetadata(
970b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    const PerfGroupDescMetadata& metadata,
971b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    PerfDataProto_PerfGroupDescMetadata* proto_metadata) const {
972b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_name(metadata.name);
973b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_name_md5_prefix(Md5Prefix(metadata.name));
974b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_leader_idx(metadata.leader_idx);
975b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  proto_metadata->set_num_members(metadata.num_members);
976b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  return true;
977b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana}
978b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana
979b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmanabool PerfSerializer::DeserializeGroupDescMetadata(
980b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    const PerfDataProto_PerfGroupDescMetadata& proto_metadata,
981b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana    PerfGroupDescMetadata* metadata) const {
982b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  metadata->name = proto_metadata.name();
983b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  metadata->leader_idx = proto_metadata.leader_idx();
984b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  metadata->num_members = proto_metadata.num_members();
985b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana  return true;
986b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana}
987b86dd5276ecdba751d56be4f1bafca7065b78ea4lakshmana
9885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// static
9895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanavoid PerfSerializer::SerializeParserStats(const PerfEventStats& stats,
9905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                          PerfDataProto* perf_data_proto) {
9915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  PerfDataProto_PerfEventStats* stats_pb = perf_data_proto->mutable_stats();
9925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_num_sample_events(stats.num_sample_events);
9935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_num_mmap_events(stats.num_mmap_events);
9945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_num_fork_events(stats.num_fork_events);
9955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_num_exit_events(stats.num_exit_events);
9965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_did_remap(stats.did_remap);
9975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats_pb->set_num_sample_events_mapped(stats.num_sample_events_mapped);
9985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
9995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// static
10015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanavoid PerfSerializer::DeserializeParserStats(
10023fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    const PerfDataProto& perf_data_proto, PerfEventStats* stats) {
10035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const PerfDataProto_PerfEventStats& stats_pb = perf_data_proto.stats();
10045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->num_sample_events = stats_pb.num_sample_events();
10055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->num_mmap_events = stats_pb.num_mmap_events();
10065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->num_fork_events = stats_pb.num_fork_events();
10075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->num_exit_events = stats_pb.num_exit_events();
10085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->did_remap = stats_pb.did_remap();
10095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  stats->num_sample_events_mapped = stats_pb.num_sample_events_mapped();
10105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
10115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanavoid PerfSerializer::CreateSampleInfoReader(const PerfFileAttr& attr,
10135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                            bool read_cross_endian) {
10145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  for (const auto& id :
10155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana       (attr.ids.empty() ? std::initializer_list<u64>({0}) : attr.ids)) {
10165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_info_reader_map_[id].reset(
10175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        new SampleInfoReader(attr.attr, read_cross_endian));
10185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  UpdateEventIdPositions(attr.attr);
10205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
10215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanavoid PerfSerializer::UpdateEventIdPositions(
10235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const struct perf_event_attr& attr) {
10245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 sample_type = attr.sample_type;
10255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ssize_t new_sample_event_id_pos = EventIdPosition::NotPresent;
10265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ssize_t new_other_event_id_pos = EventIdPosition::NotPresent;
10275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_type & PERF_SAMPLE_IDENTIFIER) {
10285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    new_sample_event_id_pos = 0;
10295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    new_other_event_id_pos = 1;
10305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  } else if (sample_type & PERF_SAMPLE_ID) {
10315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    // Increment for IP, TID, TIME, ADDR
10325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    new_sample_event_id_pos = 0;
10335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_IP) new_sample_event_id_pos++;
10345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_TID) new_sample_event_id_pos++;
10355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_TIME) new_sample_event_id_pos++;
10365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_ADDR) new_sample_event_id_pos++;
10375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    // Increment for CPU, STREAM_ID
10395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    new_other_event_id_pos = 1;
10405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_CPU) new_other_event_id_pos++;
10415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    if (sample_type & PERF_SAMPLE_STREAM_ID) new_other_event_id_pos++;
10425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_event_id_pos_ == EventIdPosition::Uninitialized) {
10455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    sample_event_id_pos_ = new_sample_event_id_pos;
10465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  } else {
10475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    CHECK_EQ(new_sample_event_id_pos, sample_event_id_pos_)
10485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        << "Event ids must be in a consistent positition";
10495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (other_event_id_pos_ == EventIdPosition::Uninitialized) {
10515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    other_event_id_pos_ = new_other_event_id_pos;
10525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  } else {
10535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    CHECK_EQ(new_other_event_id_pos, other_event_id_pos_)
10545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        << "Event ids must be in a consistent positition";
10555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
10575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::SampleIdAll() const {
10595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (sample_info_reader_map_.empty()) {
10605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
10615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return sample_info_reader_map_.begin()->second->event_attr().sample_id_all;
10635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
10645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaconst SampleInfoReader* PerfSerializer::GetSampleInfoReaderForEvent(
10665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const event_t& event) const {
10675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Where is the event id?
10685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ssize_t event_id_pos = EventIdPosition::Uninitialized;
10695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (event.header.type == PERF_RECORD_SAMPLE) {
10705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    event_id_pos = sample_event_id_pos_;
10715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  } else if (SampleIdAll()) {
10725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    event_id_pos = other_event_id_pos_;
10735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  } else {
10745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    event_id_pos = EventIdPosition::NotPresent;
10755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
10775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // What is the event id?
10785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 event_id;
10795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  switch (event_id_pos) {
10803fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    case EventIdPosition::Uninitialized:
10813fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      LOG(FATAL) << "Position of the event id was not initialized!";
10823fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      return nullptr;
10833fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    case EventIdPosition::NotPresent:
10843fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      event_id = 0;
10853fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      break;
10863fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    default:
10873fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      if (event.header.type == PERF_RECORD_SAMPLE) {
10883fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        event_id = event.sample.array[event_id_pos];
10893fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      } else {
10903fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        // Pretend this is a sample event--ie, an array of u64. Find the length
10913fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        // of the array. The sample id is at the end of the array, and
10923fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        // event_id_pos (aka other_event_id_pos_) counts from the end.
10933fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        size_t event_end_pos =
10943fa0a5f4b88119fac65f86971738ea0202797b6elakshmana            (event.header.size - sizeof(event.header)) / sizeof(u64);
10953fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        event_id = event.sample.array[event_end_pos - event_id_pos];
10963fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      }
10973fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      break;
10985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
10995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return GetSampleInfoReaderForId(event_id);
11005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
11015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
11025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaconst SampleInfoReader* PerfSerializer::GetSampleInfoReaderForId(
11035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    uint64_t id) const {
11045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (id) {
11055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    auto iter = sample_info_reader_map_.find(id);
11063fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    if (iter == sample_info_reader_map_.end()) return nullptr;
11075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return iter->second.get();
11085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
11095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
11103fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (sample_info_reader_map_.empty()) return nullptr;
11115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return sample_info_reader_map_.begin()->second.get();
11125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
11135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
11145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanabool PerfSerializer::ReadPerfSampleInfoAndType(const event_t& event,
11155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                               perf_sample* sample_info,
11165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                               uint64_t* sample_type) const {
11175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfoReader* reader = GetSampleInfoReaderForEvent(event);
11185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  if (!reader) {
11195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    LOG(ERROR) << "No SampleInfoReader available";
11205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return false;
11215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
11225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
11233fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  if (!reader->ReadPerfSampleInfo(event, sample_info)) return false;
11245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  *sample_type = reader->event_attr().sample_type;
11255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  return true;
11265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}
11275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
11285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}  // namespace quipper
1129