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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" 10 11 using namespace llvm; 12 using namespace llvm::json; 13 14 namespace lldb_private { 15 16 const char *IntelPTDataKinds::kProcFsCpuInfo = "procfsCpuInfo"; 17 const char *IntelPTDataKinds::kIptTrace = "iptTrace"; 18 const char *IntelPTDataKinds::kPerfContextSwitchTrace = 19 "perfContextSwitchTrace"; 20 21 bool TraceIntelPTStartRequest::IsPerCpuTracing() const { 22 return per_cpu_tracing.value_or(false); 23 } 24 25 json::Value toJSON(const JSONUINT64 &uint64, bool hex) { 26 if (hex) 27 return json::Value(formatv("{0:x+}", uint64.value)); 28 else 29 return json::Value(formatv("{0}", uint64.value)); 30 } 31 32 bool fromJSON(const json::Value &value, JSONUINT64 &uint64, Path path) { 33 if (Optional<uint64_t> val = value.getAsUINT64()) { 34 uint64.value = *val; 35 return true; 36 } else if (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 45 bool 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 63 json::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 75 uint64_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 82 uint64_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 89 json::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 97 bool 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 109 bool 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 117 json::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_private 126