xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1349cc55cSDimitry Andric //===-- TraceIntelPTJSONStructs.cpp ---------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "TraceIntelPTJSONStructs.h"
10349cc55cSDimitry Andric 
11349cc55cSDimitry Andric #include "llvm/Support/JSON.h"
12349cc55cSDimitry Andric #include <string>
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric using namespace lldb;
15349cc55cSDimitry Andric using namespace lldb_private;
16349cc55cSDimitry Andric using namespace lldb_private::trace_intel_pt;
17349cc55cSDimitry Andric using namespace llvm;
18*81ad6265SDimitry Andric using namespace llvm::json;
19349cc55cSDimitry Andric 
20*81ad6265SDimitry Andric namespace lldb_private {
21*81ad6265SDimitry Andric namespace trace_intel_pt {
22349cc55cSDimitry Andric 
23*81ad6265SDimitry Andric Optional<std::vector<lldb::cpu_id_t>> JSONTraceBundleDescription::GetCpuIds() {
24*81ad6265SDimitry Andric   if (!cpus)
25*81ad6265SDimitry Andric     return None;
26*81ad6265SDimitry Andric   std::vector<lldb::cpu_id_t> cpu_ids;
27*81ad6265SDimitry Andric   for (const JSONCpu &cpu : *cpus)
28*81ad6265SDimitry Andric     cpu_ids.push_back(cpu.id);
29*81ad6265SDimitry Andric   return cpu_ids;
30349cc55cSDimitry Andric }
31349cc55cSDimitry Andric 
32*81ad6265SDimitry Andric json::Value toJSON(const JSONModule &module) {
33*81ad6265SDimitry Andric   json::Object json_module;
34*81ad6265SDimitry Andric   json_module["systemPath"] = module.system_path;
35*81ad6265SDimitry Andric   if (module.file)
36*81ad6265SDimitry Andric     json_module["file"] = *module.file;
37*81ad6265SDimitry Andric   json_module["loadAddress"] = toJSON(module.load_address, true);
38*81ad6265SDimitry Andric   if (module.uuid)
39*81ad6265SDimitry Andric     json_module["uuid"] = *module.uuid;
40*81ad6265SDimitry Andric   return std::move(json_module);
41349cc55cSDimitry Andric }
42349cc55cSDimitry Andric 
43*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONModule &module, Path path) {
44*81ad6265SDimitry Andric   ObjectMapper o(value, path);
45*81ad6265SDimitry Andric   return o && o.map("systemPath", module.system_path) &&
46*81ad6265SDimitry Andric          o.map("file", module.file) &&
47*81ad6265SDimitry Andric          o.map("loadAddress", module.load_address) &&
48*81ad6265SDimitry Andric          o.map("uuid", module.uuid);
49*81ad6265SDimitry Andric }
50*81ad6265SDimitry Andric 
51*81ad6265SDimitry Andric json::Value toJSON(const JSONThread &thread) {
52*81ad6265SDimitry Andric   json::Object obj{{"tid", thread.tid}};
53*81ad6265SDimitry Andric   if (thread.ipt_trace)
54*81ad6265SDimitry Andric     obj["iptTrace"] = *thread.ipt_trace;
55*81ad6265SDimitry Andric   return obj;
56*81ad6265SDimitry Andric }
57*81ad6265SDimitry Andric 
58*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONThread &thread, Path path) {
59*81ad6265SDimitry Andric   ObjectMapper o(value, path);
60*81ad6265SDimitry Andric   return o && o.map("tid", thread.tid) && o.map("iptTrace", thread.ipt_trace);
61*81ad6265SDimitry Andric }
62*81ad6265SDimitry Andric 
63*81ad6265SDimitry Andric json::Value toJSON(const JSONProcess &process) {
64*81ad6265SDimitry Andric   return Object{
65*81ad6265SDimitry Andric       {"pid", process.pid},
66*81ad6265SDimitry Andric       {"triple", process.triple},
67*81ad6265SDimitry Andric       {"threads", process.threads},
68*81ad6265SDimitry Andric       {"modules", process.modules},
69*81ad6265SDimitry Andric   };
70*81ad6265SDimitry Andric }
71*81ad6265SDimitry Andric 
72*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONProcess &process, Path path) {
73*81ad6265SDimitry Andric   ObjectMapper o(value, path);
74*81ad6265SDimitry Andric   return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
75*81ad6265SDimitry Andric          o.map("threads", process.threads) && o.map("modules", process.modules);
76*81ad6265SDimitry Andric }
77*81ad6265SDimitry Andric 
78*81ad6265SDimitry Andric json::Value toJSON(const JSONCpu &cpu) {
79*81ad6265SDimitry Andric   return Object{
80*81ad6265SDimitry Andric       {"id", cpu.id},
81*81ad6265SDimitry Andric       {"iptTrace", cpu.ipt_trace},
82*81ad6265SDimitry Andric       {"contextSwitchTrace", cpu.context_switch_trace},
83*81ad6265SDimitry Andric   };
84*81ad6265SDimitry Andric }
85*81ad6265SDimitry Andric 
86*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONCpu &cpu, Path path) {
87*81ad6265SDimitry Andric   ObjectMapper o(value, path);
88*81ad6265SDimitry Andric   uint64_t cpu_id;
89*81ad6265SDimitry Andric   if (!(o && o.map("id", cpu_id) && o.map("iptTrace", cpu.ipt_trace) &&
90*81ad6265SDimitry Andric         o.map("contextSwitchTrace", cpu.context_switch_trace)))
91*81ad6265SDimitry Andric     return false;
92*81ad6265SDimitry Andric   cpu.id = cpu_id;
93*81ad6265SDimitry Andric   return true;
94*81ad6265SDimitry Andric }
95*81ad6265SDimitry Andric 
96*81ad6265SDimitry Andric json::Value toJSON(const pt_cpu &cpu_info) {
97*81ad6265SDimitry Andric   return Object{
98*81ad6265SDimitry Andric       {"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"},
99*81ad6265SDimitry Andric       {"family", cpu_info.family},
100349cc55cSDimitry Andric       {"model", cpu_info.model},
101349cc55cSDimitry Andric       {"stepping", cpu_info.stepping},
102*81ad6265SDimitry Andric   };
103349cc55cSDimitry Andric }
104349cc55cSDimitry Andric 
105*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {
106*81ad6265SDimitry Andric   ObjectMapper o(value, path);
107*81ad6265SDimitry Andric   std::string vendor;
108*81ad6265SDimitry Andric   uint64_t family, model, stepping;
109*81ad6265SDimitry Andric   if (!(o && o.map("vendor", vendor) && o.map("family", family) &&
110*81ad6265SDimitry Andric         o.map("model", model) && o.map("stepping", stepping)))
111*81ad6265SDimitry Andric     return false;
112*81ad6265SDimitry Andric   cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown;
113*81ad6265SDimitry Andric   cpu_info.family = family;
114*81ad6265SDimitry Andric   cpu_info.model = model;
115*81ad6265SDimitry Andric   cpu_info.stepping = stepping;
116*81ad6265SDimitry Andric   return true;
117349cc55cSDimitry Andric }
118349cc55cSDimitry Andric 
119*81ad6265SDimitry Andric json::Value toJSON(const JSONTraceBundleDescription &bundle_description) {
120*81ad6265SDimitry Andric   return Object{{"type", bundle_description.type},
121*81ad6265SDimitry Andric                 {"processes", bundle_description.processes},
122*81ad6265SDimitry Andric                 // We have to do this because the compiler fails at doing it
123*81ad6265SDimitry Andric                 // automatically because pt_cpu is not in a namespace
124*81ad6265SDimitry Andric                 {"cpuInfo", toJSON(bundle_description.cpu_info)},
125*81ad6265SDimitry Andric                 {"cpus", bundle_description.cpus},
126*81ad6265SDimitry Andric                 {"tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion}};
127349cc55cSDimitry Andric }
128349cc55cSDimitry Andric 
129*81ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONTraceBundleDescription &bundle_description, Path path) {
130*81ad6265SDimitry Andric   ObjectMapper o(value, path);
131*81ad6265SDimitry Andric   if (!(o && o.map("processes", bundle_description.processes) &&
132*81ad6265SDimitry Andric         o.map("type", bundle_description.type) && o.map("cpus", bundle_description.cpus) &&
133*81ad6265SDimitry Andric         o.map("tscPerfZeroConversion", bundle_description.tsc_perf_zero_conversion)))
134*81ad6265SDimitry Andric     return false;
135*81ad6265SDimitry Andric   if (bundle_description.cpus && !bundle_description.tsc_perf_zero_conversion) {
136*81ad6265SDimitry Andric     path.report(
137*81ad6265SDimitry Andric         "\"tscPerfZeroConversion\" is required when \"cpus\" is provided");
138*81ad6265SDimitry Andric     return false;
139*81ad6265SDimitry Andric   }
140*81ad6265SDimitry Andric   // We have to do this because the compiler fails at doing it automatically
141*81ad6265SDimitry Andric   // because pt_cpu is not in a namespace
142*81ad6265SDimitry Andric   if (!fromJSON(*value.getAsObject()->get("cpuInfo"), bundle_description.cpu_info,
143*81ad6265SDimitry Andric                 path.field("cpuInfo")))
144*81ad6265SDimitry Andric     return false;
145*81ad6265SDimitry Andric   return true;
146*81ad6265SDimitry Andric }
147*81ad6265SDimitry Andric 
148*81ad6265SDimitry Andric } // namespace trace_intel_pt
149*81ad6265SDimitry Andric } // namespace lldb_private
150