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 json::Object obj{{"tid", thread.tid}}; 53 if (thread.trace_buffer) 54 obj["traceBuffer"] = *thread.trace_buffer; 55 return obj; 56 } 57 58 bool fromJSON(const json::Value &value, JSONThread &thread, Path path) { 59 ObjectMapper o(value, path); 60 return o && o.map("tid", thread.tid) && 61 o.map("traceBuffer", thread.trace_buffer); 62 } 63 64 json::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 73 bool 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 79 json::Value toJSON(const JSONCore &core) { 80 return Object{ 81 {"coreId", core.core_id}, 82 {"traceBuffer", core.trace_buffer}, 83 {"contextSwitchTrace", core.context_switch_trace}, 84 }; 85 } 86 87 bool fromJSON(const json::Value &value, JSONCore &core, Path path) { 88 ObjectMapper o(value, path); 89 uint64_t core_id; 90 if (!o || !o.map("coreId", core_id) || 91 !o.map("traceBuffer", core.trace_buffer) || 92 !o.map("contextSwitchTrace", core.context_switch_trace)) 93 return false; 94 core.core_id = core_id; 95 return true; 96 } 97 98 json::Value toJSON(const pt_cpu &cpu_info) { 99 return Object{ 100 {"vendor", cpu_info.vendor == pcv_intel ? "GenuineIntel" : "Unknown"}, 101 {"family", cpu_info.family}, 102 {"model", cpu_info.model}, 103 {"stepping", cpu_info.stepping}, 104 }; 105 } 106 107 bool fromJSON(const json::Value &value, pt_cpu &cpu_info, Path path) { 108 ObjectMapper o(value, path); 109 std::string vendor; 110 uint64_t family, model, stepping; 111 if (!o || !o.map("vendor", vendor) || !o.map("family", family) || 112 !o.map("model", model) || !o.map("stepping", stepping)) 113 return false; 114 cpu_info.vendor = vendor == "GenuineIntel" ? pcv_intel : pcv_unknown; 115 cpu_info.family = family; 116 cpu_info.model = model; 117 cpu_info.stepping = stepping; 118 return true; 119 } 120 121 json::Value toJSON(const JSONTraceSession &session) { 122 return Object{{"type", session.type}, 123 {"processes", session.processes}, 124 // We have to do this because the compiler fails at doing it 125 // automatically because pt_cpu is not in a namespace 126 {"cpuInfo", toJSON(session.cpu_info)}, 127 {"cores", session.cores}, 128 {"tscPerfZeroConversion", session.tsc_perf_zero_conversion}}; 129 } 130 131 bool fromJSON(const json::Value &value, JSONTraceSession &session, Path path) { 132 ObjectMapper o(value, path); 133 if (!o || !o.map("processes", session.processes) || 134 !o.map("type", session.type) || !o.map("cores", session.cores) || 135 !o.map("tscPerfZeroConversion", session.tsc_perf_zero_conversion)) 136 return false; 137 if (session.cores && !session.tsc_perf_zero_conversion) { 138 path.report( 139 "\"tscPerfZeroConversion\" is required when \"cores\" is provided"); 140 return false; 141 } 142 // We have to do this because the compiler fails at doing it automatically 143 // because pt_cpu is not in a namespace 144 if (!fromJSON(*value.getAsObject()->get("cpuInfo"), session.cpu_info, 145 path.field("cpuInfo"))) 146 return false; 147 return true; 148 } 149 150 } // namespace trace_intel_pt 151 } // namespace lldb_private 152