126 lines · cpp
1//===-- TraceIntelPTGDBRemotePackets.cpp ------------------------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"10 11using namespace llvm;12using namespace llvm::json;13 14namespace lldb_private {15 16const char *IntelPTDataKinds::kProcFsCpuInfo = "procfsCpuInfo";17const char *IntelPTDataKinds::kIptTrace = "iptTrace";18const char *IntelPTDataKinds::kPerfContextSwitchTrace =19 "perfContextSwitchTrace";20 21bool TraceIntelPTStartRequest::IsPerCpuTracing() const {22 return per_cpu_tracing.value_or(false);23}24 25json::Value toJSON(const JSONUINT64 &uint64, bool hex) {26 if (hex)27 return json::Value(formatv("{0:x+}", uint64.value));28 else29 return json::Value(formatv("{0}", uint64.value));30}31 32bool fromJSON(const json::Value &value, JSONUINT64 &uint64, Path path) {33 if (std::optional<uint64_t> val = value.getAsUINT64()) {34 uint64.value = *val;35 return true;36 } else if (std::optional<StringRef> val = value.getAsString()) {37 if (!val->getAsInteger(/*radix=*/0, uint64.value))38 return true;39 path.report("invalid string number");40 }41 path.report("invalid number or string number");42 return false;43}44 45bool fromJSON(const json::Value &value, TraceIntelPTStartRequest &packet,46 Path path) {47 ObjectMapper o(value, path);48 if (!(o && fromJSON(value, (TraceStartRequest &)packet, path) &&49 o.map("enableTsc", packet.enable_tsc) &&50 o.map("psbPeriod", packet.psb_period) &&51 o.map("iptTraceSize", packet.ipt_trace_size)))52 return false;53 54 if (packet.IsProcessTracing()) {55 if (!o.map("processBufferSizeLimit", packet.process_buffer_size_limit) ||56 !o.map("perCpuTracing", packet.per_cpu_tracing) ||57 !o.map("disableCgroupTracing", packet.disable_cgroup_filtering))58 return false;59 }60 return true;61}62 63json::Value toJSON(const TraceIntelPTStartRequest &packet) {64 json::Value base = toJSON((const TraceStartRequest &)packet);65 json::Object &obj = *base.getAsObject();66 obj.try_emplace("iptTraceSize", packet.ipt_trace_size);67 obj.try_emplace("processBufferSizeLimit", packet.process_buffer_size_limit);68 obj.try_emplace("psbPeriod", packet.psb_period);69 obj.try_emplace("enableTsc", packet.enable_tsc);70 obj.try_emplace("perCpuTracing", packet.per_cpu_tracing);71 obj.try_emplace("disableCgroupTracing", packet.disable_cgroup_filtering);72 return base;73}74 75uint64_t LinuxPerfZeroTscConversion::ToNanos(uint64_t tsc) const {76 uint64_t quot = tsc >> time_shift;77 uint64_t rem_flag = (((uint64_t)1 << time_shift) - 1);78 uint64_t rem = tsc & rem_flag;79 return time_zero.value + quot * time_mult + ((rem * time_mult) >> time_shift);80}81 82uint64_t LinuxPerfZeroTscConversion::ToTSC(uint64_t nanos) const {83 uint64_t time = nanos - time_zero.value;84 uint64_t quot = time / time_mult;85 uint64_t rem = time % time_mult;86 return (quot << time_shift) + (rem << time_shift) / time_mult;87}88 89json::Value toJSON(const LinuxPerfZeroTscConversion &packet) {90 return json::Value(json::Object{91 {"timeMult", packet.time_mult},92 {"timeShift", packet.time_shift},93 {"timeZero", toJSON(packet.time_zero, /*hex=*/false)},94 });95}96 97bool fromJSON(const json::Value &value, LinuxPerfZeroTscConversion &packet,98 json::Path path) {99 ObjectMapper o(value, path);100 uint64_t time_mult, time_shift;101 if (!(o && o.map("timeMult", time_mult) && o.map("timeShift", time_shift) &&102 o.map("timeZero", packet.time_zero)))103 return false;104 packet.time_mult = time_mult;105 packet.time_shift = time_shift;106 return true;107}108 109bool fromJSON(const json::Value &value, TraceIntelPTGetStateResponse &packet,110 json::Path path) {111 ObjectMapper o(value, path);112 return o && fromJSON(value, (TraceGetStateResponse &)packet, path) &&113 o.map("tscPerfZeroConversion", packet.tsc_perf_zero_conversion) &&114 o.map("usingCgroupFiltering", packet.using_cgroup_filtering);115}116 117json::Value toJSON(const TraceIntelPTGetStateResponse &packet) {118 json::Value base = toJSON((const TraceGetStateResponse &)packet);119 json::Object &obj = *base.getAsObject();120 obj.insert({"tscPerfZeroConversion", packet.tsc_perf_zero_conversion});121 obj.insert({"usingCgroupFiltering", packet.using_cgroup_filtering});122 return base;123}124 125} // namespace lldb_private126