1 //===-- TraceIntelPTSessionFileParser.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 "TraceIntelPTSessionFileParser.h" 10 11 #include "../common/ThreadPostMortemTrace.h" 12 #include "lldb/Core/Debugger.h" 13 #include "lldb/Target/Process.h" 14 #include "lldb/Target/Target.h" 15 #include "lldb/Target/ThreadList.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 using namespace lldb_private::trace_intel_pt; 20 using namespace llvm; 21 22 StringRef TraceIntelPTSessionFileParser::GetSchema() { 23 static std::string schema; 24 if (schema.empty()) { 25 schema = TraceSessionFileParser::BuildSchema(R"({ 26 "type": "intel-pt", 27 "cpuInfo": { 28 "vendor": "intel" | "unknown", 29 "family": integer, 30 "model": integer, 31 "stepping": integer 32 } 33 })"); 34 } 35 return schema; 36 } 37 38 pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU( 39 const JSONTraceIntelPTCPUInfo &cpu_info) { 40 return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown, 41 static_cast<uint16_t>(cpu_info.family), 42 static_cast<uint8_t>(cpu_info.model), 43 static_cast<uint8_t>(cpu_info.stepping)}; 44 } 45 46 TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance( 47 const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes) { 48 std::vector<ThreadPostMortemTraceSP> threads; 49 for (const ParsedProcess &parsed_process : parsed_processes) 50 threads.insert(threads.end(), parsed_process.threads.begin(), 51 parsed_process.threads.end()); 52 53 TraceSP trace_instance(new TraceIntelPT(cpu_info, threads)); 54 for (const ParsedProcess &parsed_process : parsed_processes) 55 parsed_process.target_sp->SetTrace(trace_instance); 56 57 return trace_instance; 58 } 59 60 Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { 61 json::Path::Root root("traceSession"); 62 TraceSessionFileParser::JSONTraceSession<JSONTraceIntelPTSettings> session; 63 if (!json::fromJSON(m_trace_session_file, session, root)) 64 return CreateJSONError(root, m_trace_session_file); 65 66 if (Expected<std::vector<ParsedProcess>> parsed_processes = 67 ParseCommonSessionFile(session)) 68 return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo), 69 *parsed_processes); 70 else 71 return parsed_processes.takeError(); 72 } 73 74 namespace llvm { 75 namespace json { 76 77 bool fromJSON( 78 const Value &value, 79 TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings, 80 Path path) { 81 ObjectMapper o(value, path); 82 return o && o.map("cpuInfo", plugin_settings.cpuInfo) && 83 fromJSON( 84 value, 85 (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings, 86 path); 87 } 88 89 bool fromJSON(const json::Value &value, 90 TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info, 91 Path path) { 92 ObjectMapper o(value, path); 93 return o && o.map("vendor", cpu_info.vendor) && 94 o.map("family", cpu_info.family) && o.map("model", cpu_info.model) && 95 o.map("stepping", cpu_info.stepping); 96 } 97 98 Value toJSON( 99 const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) { 100 return Value(Object{{"family", cpu_info.family}, 101 {"model", cpu_info.model}, 102 {"stepping", cpu_info.stepping}, 103 {"vendor", cpu_info.vendor}}); 104 } 105 106 } // namespace json 107 } // namespace llvm 108