brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 52ca694 Raw
190 lines · cpp
1//===-- TraceIntelPTJSONStructs.cpp ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "TraceIntelPTJSONStructs.h"10#include "llvm/Support/JSON.h"11#include <optional>12#include <string>13 14using namespace lldb;15using namespace lldb_private;16using namespace lldb_private::trace_intel_pt;17using namespace llvm;18using namespace llvm::json;19 20namespace lldb_private {21namespace trace_intel_pt {22 23std::optional<std::vector<lldb::cpu_id_t>>24JSONTraceBundleDescription::GetCpuIds() {25  if (!cpus)26    return std::nullopt;27  std::vector<lldb::cpu_id_t> cpu_ids;28  for (const JSONCpu &cpu : *cpus)29    cpu_ids.push_back(cpu.id);30  return cpu_ids;31}32 33json::Value toJSON(const JSONModule &module) {34  json::Object json_module;35  json_module["systemPath"] = module.system_path;36  if (module.file)37    json_module["file"] = *module.file;38  json_module["loadAddress"] = toJSON(module.load_address, true);39  if (module.uuid)40    json_module["uuid"] = *module.uuid;41  return std::move(json_module);42}43 44bool fromJSON(const json::Value &value, JSONModule &module, Path path) {45  ObjectMapper o(value, path);46  return o && o.map("systemPath", module.system_path) &&47         o.map("file", module.file) &&48         o.map("loadAddress", module.load_address) &&49         o.map("uuid", module.uuid);50}51 52json::Value toJSON(const JSONThread &thread) {53  json::Object obj{{"tid", thread.tid}};54  if (thread.ipt_trace)55    obj["iptTrace"] = *thread.ipt_trace;56  return obj;57}58 59bool fromJSON(const json::Value &value, JSONThread &thread, Path path) {60  ObjectMapper o(value, path);61  return o && o.map("tid", thread.tid) && o.map("iptTrace", thread.ipt_trace);62}63 64json::Value toJSON(const JSONProcess &process) {65  return Object{66      {"pid", process.pid},67      {"triple", process.triple},68      {"threads", process.threads},69      {"modules", process.modules},70  };71}72 73bool fromJSON(const json::Value &value, JSONProcess &process, Path path) {74  ObjectMapper o(value, path);75  return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&76         o.map("threads", process.threads) && o.map("modules", process.modules);77}78 79json::Value toJSON(const JSONCpu &cpu) {80  return Object{81      {"id", cpu.id},82      {"iptTrace", cpu.ipt_trace},83      {"contextSwitchTrace", cpu.context_switch_trace},84  };85}86 87bool fromJSON(const json::Value &value, JSONCpu &cpu, Path path) {88  ObjectMapper o(value, path);89  uint64_t cpu_id;90  if (!(o && o.map("id", cpu_id) && o.map("iptTrace", cpu.ipt_trace) &&91        o.map("contextSwitchTrace", cpu.context_switch_trace)))92    return false;93  cpu.id = cpu_id;94  return true;95}96 97json::Value toJSON(const pt_cpu &cpu_info) {98  return Object{99      {"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"},100      {"family", cpu_info.family},101      {"model", cpu_info.model},102      {"stepping", cpu_info.stepping},103  };104}105 106bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {107  ObjectMapper o(value, path);108  std::string vendor;109  uint64_t family, model, stepping;110  if (!(o && o.map("vendor", vendor) && o.map("family", family) &&111        o.map("model", model) && o.map("stepping", stepping)))112    return false;113  cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown;114  cpu_info.family = family;115  cpu_info.model = model;116  cpu_info.stepping = stepping;117  return true;118}119 120json::Value toJSON(const JSONKernel &kernel) {121  json::Object json_module;122  if (kernel.load_address)123    json_module["loadAddress"] = toJSON(*kernel.load_address, true);124  json_module["file"] = kernel.file;125  return std::move(json_module);126}127 128bool fromJSON(const json::Value &value, JSONKernel &kernel, Path path) {129  ObjectMapper o(value, path);130  return o && o.map("loadAddress", kernel.load_address) &&131         o.map("file", kernel.file);132}133 134json::Value toJSON(const JSONTraceBundleDescription &bundle_description) {135  return Object{136      {"type", bundle_description.type},137      {"processes", bundle_description.processes},138      // We have to do this because the compiler fails at doing it139      // automatically because pt_cpu is not in a namespace140      {"cpuInfo", toJSON(bundle_description.cpu_info)},141      {"cpus", bundle_description.cpus},142      {"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion},143      {"kernel", bundle_description.kernel}};144}145 146bool fromJSON(const json::Value &value,147              JSONTraceBundleDescription &bundle_description, Path path) {148  ObjectMapper o(value, path);149  if (!(o && o.map("processes", bundle_description.processes) &&150        o.map("type", bundle_description.type) &&151        o.map("cpus", bundle_description.cpus) &&152        o.map("tscPerfZeroConversion",153              bundle_description.tsc_perf_zero_conversion) &&154        o.map("kernel", bundle_description.kernel)))155    return false;156  if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) {157    path.report(158        "\"tscPerfZeroConversion\" is required when \"cpus\" is provided");159    return false;160  }161  // We have to do this because the compiler fails at doing it automatically162  // because pt_cpu is not in a namespace163  if (!fromJSON(*value.getAsObject()->get("cpuInfo"),164                bundle_description.cpu_info, path.field("cpuInfo")))165    return false;166 167  // When kernel section is present, this is kernel-only tracing. Thus, throw an168  // error if the "processes" section is non-empty or the "cpus" section is not169  // present.170  if (bundle_description.kernel) {171    if (bundle_description.processes &&172        !bundle_description.processes->empty()) {173      path.report("\"processes\" must be empty when \"kernel\" is provided");174      return false;175    }176    if (!bundle_description.cpus) {177      path.report("\"cpus\" is required when \"kernel\" is provided");178      return false;179    }180  } else if (!bundle_description.processes) {181    // Usermode tracing requires processes section.182    path.report("\"processes\" is required when \"kernel\" is not provided");183    return false;184  }185  return true;186}187 188} // namespace trace_intel_pt189} // namespace lldb_private190