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 
GetSchema()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 
ParsePTCPU(const JSONTraceIntelPTCPUInfo & cpu_info)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 
CreateTraceIntelPTInstance(const pt_cpu & cpu_info,std::vector<ParsedProcess> & parsed_processes)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 
Parse()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 
fromJSON(const Value & value,TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings & plugin_settings,Path path)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 
fromJSON(const json::Value & value,TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo & cpu_info,Path path)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 
toJSON(const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo & cpu_info)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