Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp
39645 views
//===-- TraceIntelPTJSONStructs.cpp ---------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "TraceIntelPTJSONStructs.h"9#include "llvm/Support/JSON.h"10#include <optional>11#include <string>1213using namespace lldb;14using namespace lldb_private;15using namespace lldb_private::trace_intel_pt;16using namespace llvm;17using namespace llvm::json;1819namespace lldb_private {20namespace trace_intel_pt {2122std::optional<std::vector<lldb::cpu_id_t>>23JSONTraceBundleDescription::GetCpuIds() {24if (!cpus)25return std::nullopt;26std::vector<lldb::cpu_id_t> cpu_ids;27for (const JSONCpu &cpu : *cpus)28cpu_ids.push_back(cpu.id);29return cpu_ids;30}3132json::Value toJSON(const JSONModule &module) {33json::Object json_module;34json_module["systemPath"] = module.system_path;35if (module.file)36json_module["file"] = *module.file;37json_module["loadAddress"] = toJSON(module.load_address, true);38if (module.uuid)39json_module["uuid"] = *module.uuid;40return std::move(json_module);41}4243bool fromJSON(const json::Value &value, JSONModule &module, Path path) {44ObjectMapper o(value, path);45return o && o.map("systemPath", module.system_path) &&46o.map("file", module.file) &&47o.map("loadAddress", module.load_address) &&48o.map("uuid", module.uuid);49}5051json::Value toJSON(const JSONThread &thread) {52json::Object obj{{"tid", thread.tid}};53if (thread.ipt_trace)54obj["iptTrace"] = *thread.ipt_trace;55return obj;56}5758bool fromJSON(const json::Value &value, JSONThread &thread, Path path) {59ObjectMapper o(value, path);60return o && o.map("tid", thread.tid) && o.map("iptTrace", thread.ipt_trace);61}6263json::Value toJSON(const JSONProcess &process) {64return Object{65{"pid", process.pid},66{"triple", process.triple},67{"threads", process.threads},68{"modules", process.modules},69};70}7172bool fromJSON(const json::Value &value, JSONProcess &process, Path path) {73ObjectMapper o(value, path);74return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&75o.map("threads", process.threads) && o.map("modules", process.modules);76}7778json::Value toJSON(const JSONCpu &cpu) {79return Object{80{"id", cpu.id},81{"iptTrace", cpu.ipt_trace},82{"contextSwitchTrace", cpu.context_switch_trace},83};84}8586bool fromJSON(const json::Value &value, JSONCpu &cpu, Path path) {87ObjectMapper o(value, path);88uint64_t cpu_id;89if (!(o && o.map("id", cpu_id) && o.map("iptTrace", cpu.ipt_trace) &&90o.map("contextSwitchTrace", cpu.context_switch_trace)))91return false;92cpu.id = cpu_id;93return true;94}9596json::Value toJSON(const pt_cpu &cpu_info) {97return Object{98{"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"},99{"family", cpu_info.family},100{"model", cpu_info.model},101{"stepping", cpu_info.stepping},102};103}104105bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {106ObjectMapper o(value, path);107std::string vendor;108uint64_t family, model, stepping;109if (!(o && o.map("vendor", vendor) && o.map("family", family) &&110o.map("model", model) && o.map("stepping", stepping)))111return false;112cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown;113cpu_info.family = family;114cpu_info.model = model;115cpu_info.stepping = stepping;116return true;117}118119json::Value toJSON(const JSONKernel &kernel) {120json::Object json_module;121if (kernel.load_address)122json_module["loadAddress"] = toJSON(*kernel.load_address, true);123json_module["file"] = kernel.file;124return std::move(json_module);125}126127bool fromJSON(const json::Value &value, JSONKernel &kernel, Path path) {128ObjectMapper o(value, path);129return o && o.map("loadAddress", kernel.load_address) &&130o.map("file", kernel.file);131}132133json::Value toJSON(const JSONTraceBundleDescription &bundle_description) {134return Object{135{"type", bundle_description.type},136{"processes", bundle_description.processes},137// We have to do this because the compiler fails at doing it138// automatically because pt_cpu is not in a namespace139{"cpuInfo", toJSON(bundle_description.cpu_info)},140{"cpus", bundle_description.cpus},141{"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion},142{"kernel", bundle_description.kernel}};143}144145bool fromJSON(const json::Value &value,146JSONTraceBundleDescription &bundle_description, Path path) {147ObjectMapper o(value, path);148if (!(o && o.map("processes", bundle_description.processes) &&149o.map("type", bundle_description.type) &&150o.map("cpus", bundle_description.cpus) &&151o.map("tscPerfZeroConversion",152bundle_description.tsc_perf_zero_conversion) &&153o.map("kernel", bundle_description.kernel)))154return false;155if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) {156path.report(157"\"tscPerfZeroConversion\" is required when \"cpus\" is provided");158return false;159}160// We have to do this because the compiler fails at doing it automatically161// because pt_cpu is not in a namespace162if (!fromJSON(*value.getAsObject()->get("cpuInfo"),163bundle_description.cpu_info, path.field("cpuInfo")))164return false;165166// When kernel section is present, this is kernel-only tracing. Thus, throw an167// error if the "processes" section is non-empty or the "cpus" section is not168// present.169if (bundle_description.kernel) {170if (bundle_description.processes &&171!bundle_description.processes->empty()) {172path.report("\"processes\" must be empty when \"kernel\" is provided");173return false;174}175if (!bundle_description.cpus) {176path.report("\"cpus\" is required when \"kernel\" is provided");177return false;178}179} else if (!bundle_description.processes) {180// Usermode tracing requires processes section.181path.report("\"processes\" is required when \"kernel\" is not provided");182return false;183}184return true;185}186187} // namespace trace_intel_pt188} // namespace lldb_private189190191