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