xref: /freebsd-src/contrib/llvm-project/lldb/source/Utility/TraceIntelPTGDBRemotePackets.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1fe6060f1SDimitry Andric //===-- TraceIntelPTGDBRemotePackets.cpp ------------------------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric 
9fe6060f1SDimitry Andric #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
10fe6060f1SDimitry Andric 
11fe6060f1SDimitry Andric using namespace llvm;
12fe6060f1SDimitry Andric using namespace llvm::json;
13fe6060f1SDimitry Andric 
14fe6060f1SDimitry Andric namespace lldb_private {
15fe6060f1SDimitry Andric 
1681ad6265SDimitry Andric const char *IntelPTDataKinds::kProcFsCpuInfo = "procfsCpuInfo";
1781ad6265SDimitry Andric const char *IntelPTDataKinds::kIptTrace = "iptTrace";
1881ad6265SDimitry Andric const char *IntelPTDataKinds::kPerfContextSwitchTrace =
1981ad6265SDimitry Andric     "perfContextSwitchTrace";
2081ad6265SDimitry Andric 
IsPerCpuTracing() const2181ad6265SDimitry Andric bool TraceIntelPTStartRequest::IsPerCpuTracing() const {
2281ad6265SDimitry Andric   return per_cpu_tracing.value_or(false);
2381ad6265SDimitry Andric }
2481ad6265SDimitry Andric 
toJSON(const JSONUINT64 & uint64,bool hex)2581ad6265SDimitry Andric json::Value toJSON(const JSONUINT64 &uint64, bool hex) {
2681ad6265SDimitry Andric   if (hex)
2781ad6265SDimitry Andric     return json::Value(formatv("{0:x+}", uint64.value));
2881ad6265SDimitry Andric   else
2981ad6265SDimitry Andric     return json::Value(formatv("{0}", uint64.value));
3081ad6265SDimitry Andric }
3181ad6265SDimitry Andric 
fromJSON(const json::Value & value,JSONUINT64 & uint64,Path path)3281ad6265SDimitry Andric bool fromJSON(const json::Value &value, JSONUINT64 &uint64, Path path) {
33*bdd1243dSDimitry Andric   if (std::optional<uint64_t> val = value.getAsUINT64()) {
3481ad6265SDimitry Andric     uint64.value = *val;
3581ad6265SDimitry Andric     return true;
36*bdd1243dSDimitry Andric   } else if (std::optional<StringRef> val = value.getAsString()) {
3781ad6265SDimitry Andric     if (!val->getAsInteger(/*radix=*/0, uint64.value))
3881ad6265SDimitry Andric       return true;
3981ad6265SDimitry Andric     path.report("invalid string number");
4081ad6265SDimitry Andric   }
4181ad6265SDimitry Andric   path.report("invalid number or string number");
4281ad6265SDimitry Andric   return false;
4381ad6265SDimitry Andric }
4481ad6265SDimitry Andric 
fromJSON(const json::Value & value,TraceIntelPTStartRequest & packet,Path path)45fe6060f1SDimitry Andric bool fromJSON(const json::Value &value, TraceIntelPTStartRequest &packet,
46fe6060f1SDimitry Andric               Path path) {
47fe6060f1SDimitry Andric   ObjectMapper o(value, path);
4881ad6265SDimitry Andric   if (!(o && fromJSON(value, (TraceStartRequest &)packet, path) &&
4981ad6265SDimitry Andric         o.map("enableTsc", packet.enable_tsc) &&
5081ad6265SDimitry Andric         o.map("psbPeriod", packet.psb_period) &&
5181ad6265SDimitry Andric         o.map("iptTraceSize", packet.ipt_trace_size)))
52fe6060f1SDimitry Andric     return false;
5381ad6265SDimitry Andric 
5481ad6265SDimitry Andric   if (packet.IsProcessTracing()) {
5581ad6265SDimitry Andric     if (!o.map("processBufferSizeLimit", packet.process_buffer_size_limit) ||
56753f127fSDimitry Andric         !o.map("perCpuTracing", packet.per_cpu_tracing) ||
57753f127fSDimitry Andric         !o.map("disableCgroupTracing", packet.disable_cgroup_filtering))
58fe6060f1SDimitry Andric       return false;
59fe6060f1SDimitry Andric   }
60fe6060f1SDimitry Andric   return true;
61fe6060f1SDimitry Andric }
62fe6060f1SDimitry Andric 
toJSON(const TraceIntelPTStartRequest & packet)63fe6060f1SDimitry Andric json::Value toJSON(const TraceIntelPTStartRequest &packet) {
64fe6060f1SDimitry Andric   json::Value base = toJSON((const TraceStartRequest &)packet);
6581ad6265SDimitry Andric   json::Object &obj = *base.getAsObject();
6681ad6265SDimitry Andric   obj.try_emplace("iptTraceSize", packet.ipt_trace_size);
6781ad6265SDimitry Andric   obj.try_emplace("processBufferSizeLimit", packet.process_buffer_size_limit);
6881ad6265SDimitry Andric   obj.try_emplace("psbPeriod", packet.psb_period);
6981ad6265SDimitry Andric   obj.try_emplace("enableTsc", packet.enable_tsc);
7081ad6265SDimitry Andric   obj.try_emplace("perCpuTracing", packet.per_cpu_tracing);
71753f127fSDimitry Andric   obj.try_emplace("disableCgroupTracing", packet.disable_cgroup_filtering);
7281ad6265SDimitry Andric   return base;
7381ad6265SDimitry Andric }
7481ad6265SDimitry Andric 
ToNanos(uint64_t tsc) const7581ad6265SDimitry Andric uint64_t LinuxPerfZeroTscConversion::ToNanos(uint64_t tsc) const {
7681ad6265SDimitry Andric   uint64_t quot = tsc >> time_shift;
7781ad6265SDimitry Andric   uint64_t rem_flag = (((uint64_t)1 << time_shift) - 1);
7881ad6265SDimitry Andric   uint64_t rem = tsc & rem_flag;
7981ad6265SDimitry Andric   return time_zero.value + quot * time_mult + ((rem * time_mult) >> time_shift);
8081ad6265SDimitry Andric }
8181ad6265SDimitry Andric 
ToTSC(uint64_t nanos) const8281ad6265SDimitry Andric uint64_t LinuxPerfZeroTscConversion::ToTSC(uint64_t nanos) const {
8381ad6265SDimitry Andric   uint64_t time = nanos - time_zero.value;
8481ad6265SDimitry Andric   uint64_t quot = time / time_mult;
8581ad6265SDimitry Andric   uint64_t rem = time % time_mult;
8681ad6265SDimitry Andric   return (quot << time_shift) + (rem << time_shift) / time_mult;
8781ad6265SDimitry Andric }
8881ad6265SDimitry Andric 
toJSON(const LinuxPerfZeroTscConversion & packet)8981ad6265SDimitry Andric json::Value toJSON(const LinuxPerfZeroTscConversion &packet) {
9081ad6265SDimitry Andric   return json::Value(json::Object{
9181ad6265SDimitry Andric       {"timeMult", packet.time_mult},
9281ad6265SDimitry Andric       {"timeShift", packet.time_shift},
9381ad6265SDimitry Andric       {"timeZero", toJSON(packet.time_zero, /*hex=*/false)},
9481ad6265SDimitry Andric   });
9581ad6265SDimitry Andric }
9681ad6265SDimitry Andric 
fromJSON(const json::Value & value,LinuxPerfZeroTscConversion & packet,json::Path path)9781ad6265SDimitry Andric bool fromJSON(const json::Value &value, LinuxPerfZeroTscConversion &packet,
9881ad6265SDimitry Andric               json::Path path) {
9981ad6265SDimitry Andric   ObjectMapper o(value, path);
10081ad6265SDimitry Andric   uint64_t time_mult, time_shift;
10181ad6265SDimitry Andric   if (!(o && o.map("timeMult", time_mult) && o.map("timeShift", time_shift) &&
10281ad6265SDimitry Andric         o.map("timeZero", packet.time_zero)))
10381ad6265SDimitry Andric     return false;
10481ad6265SDimitry Andric   packet.time_mult = time_mult;
10581ad6265SDimitry Andric   packet.time_shift = time_shift;
10681ad6265SDimitry Andric   return true;
10781ad6265SDimitry Andric }
10881ad6265SDimitry Andric 
fromJSON(const json::Value & value,TraceIntelPTGetStateResponse & packet,json::Path path)10981ad6265SDimitry Andric bool fromJSON(const json::Value &value, TraceIntelPTGetStateResponse &packet,
11081ad6265SDimitry Andric               json::Path path) {
11181ad6265SDimitry Andric   ObjectMapper o(value, path);
11281ad6265SDimitry Andric   return o && fromJSON(value, (TraceGetStateResponse &)packet, path) &&
113753f127fSDimitry Andric          o.map("tscPerfZeroConversion", packet.tsc_perf_zero_conversion) &&
114753f127fSDimitry Andric          o.map("usingCgroupFiltering", packet.using_cgroup_filtering);
11581ad6265SDimitry Andric }
11681ad6265SDimitry Andric 
toJSON(const TraceIntelPTGetStateResponse & packet)11781ad6265SDimitry Andric json::Value toJSON(const TraceIntelPTGetStateResponse &packet) {
11881ad6265SDimitry Andric   json::Value base = toJSON((const TraceGetStateResponse &)packet);
119753f127fSDimitry Andric   json::Object &obj = *base.getAsObject();
120753f127fSDimitry Andric   obj.insert({"tscPerfZeroConversion", packet.tsc_perf_zero_conversion});
121753f127fSDimitry Andric   obj.insert({"usingCgroupFiltering", packet.using_cgroup_filtering});
122fe6060f1SDimitry Andric   return base;
123fe6060f1SDimitry Andric }
124fe6060f1SDimitry Andric 
125fe6060f1SDimitry Andric } // namespace lldb_private
126