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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TraceIntelPTJSONStructs.h"
10 
11 #include "llvm/Support/JSON.h"
12 #include <string>
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 using namespace lldb_private::trace_intel_pt;
17 using namespace llvm;
18 using namespace llvm::json;
19 
20 namespace lldb_private {
21 namespace trace_intel_pt {
22 
23 Optional<std::vector<lldb::core_id_t>> JSONTraceSession::GetCoreIds() {
24   if (!cores)
25     return None;
26   std::vector<lldb::core_id_t> core_ids;
27   for (const JSONCore &core : *cores)
28     core_ids.push_back(core.core_id);
29   return core_ids;
30 }
31 
32 json::Value toJSON(const JSONModule &module) {
33   json::Object json_module;
34   json_module["systemPath"] = module.system_path;
35   if (module.file)
36     json_module["file"] = *module.file;
37   json_module["loadAddress"] = module.load_address;
38   if (module.uuid)
39     json_module["uuid"] = *module.uuid;
40   return std::move(json_module);
41 }
42 
43 bool fromJSON(const json::Value &value, JSONModule &module, Path path) {
44   ObjectMapper o(value, path);
45   return o && o.map("systemPath", module.system_path) &&
46          o.map("file", module.file) &&
47          o.map("loadAddress", module.load_address) &&
48          o.map("uuid", module.uuid);
49 }
50 
51 json::Value toJSON(const JSONThread &thread) {
52   return json::Object{{"tid", thread.tid},
53                       {"traceBuffer", thread.trace_buffer}};
54 }
55 
56 bool fromJSON(const json::Value &value, JSONThread &thread, Path path) {
57   ObjectMapper o(value, path);
58   return o && o.map("tid", thread.tid) &&
59          o.map("traceBuffer", thread.trace_buffer);
60 }
61 
62 json::Value toJSON(const JSONProcess &process) {
63   return Object{
64       {"pid", process.pid},
65       {"triple", process.triple},
66       {"threads", process.threads},
67       {"modules", process.modules},
68   };
69 }
70 
71 bool fromJSON(const json::Value &value, JSONProcess &process, Path path) {
72   ObjectMapper o(value, path);
73   return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
74          o.map("threads", process.threads) && o.map("modules", process.modules);
75 }
76 
77 json::Value toJSON(const JSONCore &core) {
78   return Object{
79       {"coreId", core.core_id},
80       {"traceBuffer", core.trace_buffer},
81       {"contextSwitchTrace", core.context_switch_trace},
82   };
83 }
84 
85 bool fromJSON(const json::Value &value, JSONCore &core, Path path) {
86   ObjectMapper o(value, path);
87   uint64_t core_id;
88   if (!o || !o.map("coreId", core_id) ||
89       !o.map("traceBuffer", core.trace_buffer) ||
90       !o.map("contextSwitchTrace", core.context_switch_trace))
91     return false;
92   core.core_id = core_id;
93   return true;
94 }
95 
96 json::Value toJSON(const pt_cpu &cpu_info) {
97   return 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 }
104 
105 bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) {
106   ObjectMapper o(value, path);
107   std::string vendor;
108   uint64_t family, model, stepping;
109   if (!o || !o.map("vendor", vendor) || !o.map("family", family) ||
110       !o.map("model", model) || !o.map("stepping", stepping))
111     return false;
112   cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown;
113   cpu_info.family = family;
114   cpu_info.model = model;
115   cpu_info.stepping = stepping;
116   return true;
117 }
118 
119 json::Value toJSON(const JSONTraceSession &session) {
120   return Object{{"type", session.type},
121                 {"processes", session.processes},
122                 // We have to do this because the compiler fails at doing it
123                 // automatically because pt_cpu is not in a namespace
124                 {"cpuInfo", toJSON(session.cpu_info)},
125                 {"cores", session.cores},
126                 {"tscPerfZeroConversion", session.tsc_perf_zero_conversion}};
127 }
128 
129 bool fromJSON(const json::Value &value, JSONTraceSession &session, Path path) {
130   ObjectMapper o(value, path);
131   if (!o || !o.map("processes", session.processes) ||
132       !o.map("type", session.type) || !o.map("cores", session.cores) ||
133       !o.map("tscPerfZeroConversion", session.tsc_perf_zero_conversion))
134     return false;
135   // We have to do this because the compiler fails at doing it automatically
136   // because pt_cpu is not in a namespace
137   if (!fromJSON(*value.getAsObject()->get("cpuInfo"), session.cpu_info,
138                 path.field("cpuInfo")))
139     return false;
140   return true;
141 }
142 
143 } // namespace trace_intel_pt
144 } // namespace lldb_private
145