1602497d6SWalter Erquinigo //===-- TraceIntelPTJSONStructs.cpp ---------------------------------------===//
2602497d6SWalter Erquinigo //
3602497d6SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4602497d6SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
5602497d6SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6602497d6SWalter Erquinigo //
7602497d6SWalter Erquinigo //===----------------------------------------------------------------------===//
8602497d6SWalter Erquinigo
9602497d6SWalter Erquinigo #include "TraceIntelPTJSONStructs.h"
10602497d6SWalter Erquinigo
11602497d6SWalter Erquinigo #include "llvm/Support/JSON.h"
12602497d6SWalter Erquinigo #include <string>
13602497d6SWalter Erquinigo
14602497d6SWalter Erquinigo using namespace lldb;
15602497d6SWalter Erquinigo using namespace lldb_private;
16602497d6SWalter Erquinigo using namespace lldb_private::trace_intel_pt;
17602497d6SWalter Erquinigo using namespace llvm;
18fc5ef57cSWalter Erquinigo using namespace llvm::json;
19602497d6SWalter Erquinigo
20fc5ef57cSWalter Erquinigo namespace lldb_private {
21fc5ef57cSWalter Erquinigo namespace trace_intel_pt {
22602497d6SWalter Erquinigo
GetCpuIds()23*b8dcd0baSWalter Erquinigo Optional<std::vector<lldb::cpu_id_t>> JSONTraceBundleDescription::GetCpuIds() {
246a5355e8SWalter Erquinigo if (!cpus)
25fc5ef57cSWalter Erquinigo return None;
266a5355e8SWalter Erquinigo std::vector<lldb::cpu_id_t> cpu_ids;
276a5355e8SWalter Erquinigo for (const JSONCpu &cpu : *cpus)
286a5355e8SWalter Erquinigo cpu_ids.push_back(cpu.id);
296a5355e8SWalter Erquinigo return cpu_ids;
30602497d6SWalter Erquinigo }
31602497d6SWalter Erquinigo
toJSON(const JSONModule & module)32fc5ef57cSWalter Erquinigo json::Value toJSON(const JSONModule &module) {
33fc5ef57cSWalter Erquinigo json::Object json_module;
34fc5ef57cSWalter Erquinigo json_module["systemPath"] = module.system_path;
35fc5ef57cSWalter Erquinigo if (module.file)
36fc5ef57cSWalter Erquinigo json_module["file"] = *module.file;
379f45f23dSWalter Erquinigo json_module["loadAddress"] = toJSON(module.load_address, true);
38fc5ef57cSWalter Erquinigo if (module.uuid)
39fc5ef57cSWalter Erquinigo json_module["uuid"] = *module.uuid;
40fc5ef57cSWalter Erquinigo return std::move(json_module);
41602497d6SWalter Erquinigo }
42602497d6SWalter Erquinigo
fromJSON(const json::Value & value,JSONModule & module,Path path)43fc5ef57cSWalter Erquinigo bool fromJSON(const json::Value &value, JSONModule &module, Path path) {
44fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
45fc5ef57cSWalter Erquinigo return o && o.map("systemPath", module.system_path) &&
46fc5ef57cSWalter Erquinigo o.map("file", module.file) &&
47fc5ef57cSWalter Erquinigo o.map("loadAddress", module.load_address) &&
48fc5ef57cSWalter Erquinigo o.map("uuid", module.uuid);
49fc5ef57cSWalter Erquinigo }
50fc5ef57cSWalter Erquinigo
toJSON(const JSONThread & thread)51fc5ef57cSWalter Erquinigo json::Value toJSON(const JSONThread &thread) {
52a19fcc2bSWalter Erquinigo json::Object obj{{"tid", thread.tid}};
536a5355e8SWalter Erquinigo if (thread.ipt_trace)
546a5355e8SWalter Erquinigo obj["iptTrace"] = *thread.ipt_trace;
55a19fcc2bSWalter Erquinigo return obj;
56fc5ef57cSWalter Erquinigo }
57fc5ef57cSWalter Erquinigo
fromJSON(const json::Value & value,JSONThread & thread,Path path)58fc5ef57cSWalter Erquinigo bool fromJSON(const json::Value &value, JSONThread &thread, Path path) {
59fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
606a5355e8SWalter Erquinigo return o && o.map("tid", thread.tid) && o.map("iptTrace", thread.ipt_trace);
61fc5ef57cSWalter Erquinigo }
62fc5ef57cSWalter Erquinigo
toJSON(const JSONProcess & process)63fc5ef57cSWalter Erquinigo json::Value toJSON(const JSONProcess &process) {
64fc5ef57cSWalter Erquinigo return Object{
65fc5ef57cSWalter Erquinigo {"pid", process.pid},
66fc5ef57cSWalter Erquinigo {"triple", process.triple},
67fc5ef57cSWalter Erquinigo {"threads", process.threads},
68fc5ef57cSWalter Erquinigo {"modules", process.modules},
69fc5ef57cSWalter Erquinigo };
70fc5ef57cSWalter Erquinigo }
71fc5ef57cSWalter Erquinigo
fromJSON(const json::Value & value,JSONProcess & process,Path path)72fc5ef57cSWalter Erquinigo bool fromJSON(const json::Value &value, JSONProcess &process, Path path) {
73fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
74fc5ef57cSWalter Erquinigo return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
75fc5ef57cSWalter Erquinigo o.map("threads", process.threads) && o.map("modules", process.modules);
76fc5ef57cSWalter Erquinigo }
77fc5ef57cSWalter Erquinigo
toJSON(const JSONCpu & cpu)786a5355e8SWalter Erquinigo json::Value toJSON(const JSONCpu &cpu) {
79fc5ef57cSWalter Erquinigo return Object{
806a5355e8SWalter Erquinigo {"id", cpu.id},
816a5355e8SWalter Erquinigo {"iptTrace", cpu.ipt_trace},
826a5355e8SWalter Erquinigo {"contextSwitchTrace", cpu.context_switch_trace},
83fc5ef57cSWalter Erquinigo };
84fc5ef57cSWalter Erquinigo }
85fc5ef57cSWalter Erquinigo
fromJSON(const json::Value & value,JSONCpu & cpu,Path path)866a5355e8SWalter Erquinigo bool fromJSON(const json::Value &value, JSONCpu &cpu, Path path) {
87fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
886a5355e8SWalter Erquinigo uint64_t cpu_id;
896a5355e8SWalter Erquinigo if (!(o && o.map("id", cpu_id) && o.map("iptTrace", cpu.ipt_trace) &&
906a5355e8SWalter Erquinigo o.map("contextSwitchTrace", cpu.context_switch_trace)))
91fc5ef57cSWalter Erquinigo return false;
926a5355e8SWalter Erquinigo cpu.id = cpu_id;
93fc5ef57cSWalter Erquinigo return true;
94fc5ef57cSWalter Erquinigo }
95fc5ef57cSWalter Erquinigo
toJSON(const pt_cpu & cpu_info)96fc5ef57cSWalter Erquinigo json::Value toJSON(const pt_cpu &cpu_info) {
97fc5ef57cSWalter Erquinigo return Object{
98fc5ef57cSWalter Erquinigo {"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"},
99fc5ef57cSWalter Erquinigo {"family", cpu_info.family},
100602497d6SWalter Erquinigo {"model", cpu_info.model},
101602497d6SWalter Erquinigo {"stepping", cpu_info.stepping},
102fc5ef57cSWalter Erquinigo };
103602497d6SWalter Erquinigo }
104602497d6SWalter Erquinigo
fromJSON(const json::Value & value,pt_cpu & cpu_info,Path path)105fc5ef57cSWalter Erquinigo bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {
106fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
107fc5ef57cSWalter Erquinigo std::string vendor;
108fc5ef57cSWalter Erquinigo uint64_t family, model, stepping;
109561a61fbSWalter Erquinigo if (!(o && o.map("vendor", vendor) && o.map("family", family) &&
110561a61fbSWalter Erquinigo o.map("model", model) && o.map("stepping", stepping)))
111fc5ef57cSWalter Erquinigo return false;
112fc5ef57cSWalter Erquinigo cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown;
113fc5ef57cSWalter Erquinigo cpu_info.family = family;
114fc5ef57cSWalter Erquinigo cpu_info.model = model;
115fc5ef57cSWalter Erquinigo cpu_info.stepping = stepping;
116fc5ef57cSWalter Erquinigo return true;
117602497d6SWalter Erquinigo }
118602497d6SWalter Erquinigo
toJSON(const JSONTraceBundleDescription & bundle_description)119*b8dcd0baSWalter Erquinigo json::Value toJSON(const JSONTraceBundleDescription &bundle_description) {
120*b8dcd0baSWalter Erquinigo return Object{{"type", bundle_description.type},
121*b8dcd0baSWalter Erquinigo {"processes", bundle_description.processes},
122fc5ef57cSWalter Erquinigo // We have to do this because the compiler fails at doing it
123fc5ef57cSWalter Erquinigo // automatically because pt_cpu is not in a namespace
124*b8dcd0baSWalter Erquinigo {"cpuInfo", toJSON(bundle_description.cpu_info)},
125*b8dcd0baSWalter Erquinigo {"cpus", bundle_description.cpus},
126*b8dcd0baSWalter Erquinigo {"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion}};
127602497d6SWalter Erquinigo }
128602497d6SWalter Erquinigo
fromJSON(const json::Value & value,JSONTraceBundleDescription & bundle_description,Path path)129*b8dcd0baSWalter Erquinigo bool fromJSON(const json::Value &value, JSONTraceBundleDescription &bundle_description, Path path) {
130fc5ef57cSWalter Erquinigo ObjectMapper o(value, path);
131*b8dcd0baSWalter Erquinigo if (!(o && o.map("processes", bundle_description.processes) &&
132*b8dcd0baSWalter Erquinigo o.map("type", bundle_description.type) && o.map("cpus", bundle_description.cpus) &&
133*b8dcd0baSWalter Erquinigo o.map("tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion)))
134fc5ef57cSWalter Erquinigo return false;
135*b8dcd0baSWalter Erquinigo if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) {
1361a3f9969SWalter Erquinigo path.report(
1376a5355e8SWalter Erquinigo "\"tscPerfZeroConversion\" is required when \"cpus\" is provided");
1381a3f9969SWalter Erquinigo return false;
1391a3f9969SWalter Erquinigo }
140fc5ef57cSWalter Erquinigo // We have to do this because the compiler fails at doing it automatically
141fc5ef57cSWalter Erquinigo // because pt_cpu is not in a namespace
142*b8dcd0baSWalter Erquinigo if (!fromJSON(*value.getAsObject()->get("cpuInfo"), bundle_description.cpu_info,
143fc5ef57cSWalter Erquinigo path.field("cpuInfo")))
144fc5ef57cSWalter Erquinigo return false;
145fc5ef57cSWalter Erquinigo return true;
146fc5ef57cSWalter Erquinigo }
147fc5ef57cSWalter Erquinigo
148fc5ef57cSWalter Erquinigo } // namespace trace_intel_pt
149fc5ef57cSWalter Erquinigo } // namespace lldb_private
150