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 "TraceIntelPT.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 using namespace lldb_private::trace_intel_pt;
17 using namespace llvm;
18 
GetSchema()19 StringRef TraceIntelPTSessionFileParser::GetSchema() {
20   static std::string schema;
21   if (schema.empty()) {
22     schema = TraceSessionFileParser::BuildSchema(R"({
23     "type": "intel-pt",
24     "cpuInfo": {
25       "vendor": "intel" | "unknown",
26       "family": integer,
27       "model": integer,
28       "stepping": integer
29     }
30   })");
31   }
32   return schema;
33 }
34 
ParsePTCPU(const JSONTraceIntelPTCPUInfo & cpu_info)35 pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(
36     const JSONTraceIntelPTCPUInfo &cpu_info) {
37   return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
38           static_cast<uint16_t>(cpu_info.family),
39           static_cast<uint8_t>(cpu_info.model),
40           static_cast<uint8_t>(cpu_info.stepping)};
41 }
42 
CreateTraceIntelPTInstance(const pt_cpu & cpu_info,std::vector<ParsedProcess> & parsed_processes)43 TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
44     const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes) {
45   std::vector<ThreadPostMortemTraceSP> threads;
46   for (const ParsedProcess &parsed_process : parsed_processes)
47     threads.insert(threads.end(), parsed_process.threads.begin(),
48                    parsed_process.threads.end());
49 
50   TraceSP trace_instance(new TraceIntelPT(cpu_info, threads));
51   for (const ParsedProcess &parsed_process : parsed_processes)
52     parsed_process.target_sp->SetTrace(trace_instance);
53 
54   return trace_instance;
55 }
56 
Parse()57 Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
58   json::Path::Root root("traceSession");
59   JSONTraceSession<JSONTraceIntelPTSettings> session;
60   if (!json::fromJSON(m_trace_session_file, session, root))
61     return CreateJSONError(root, m_trace_session_file);
62 
63   if (Expected<std::vector<ParsedProcess>> parsed_processes =
64           ParseCommonSessionFile(session))
65     return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo),
66                                       *parsed_processes);
67   else
68     return parsed_processes.takeError();
69 }
70