1343181Sdim//===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===// 2343181Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343181Sdim// 7343181Sdim//===----------------------------------------------------------------------===// 8343181Sdim 9343181Sdim#ifndef liblldb_GDBRemoteCommunicationHistory_h_ 10343181Sdim#define liblldb_GDBRemoteCommunicationHistory_h_ 11343181Sdim 12343181Sdim#include <string> 13343181Sdim#include <vector> 14343181Sdim 15360784Sdim#include "lldb/Utility/GDBRemote.h" 16360784Sdim#include "lldb/Utility/Reproducer.h" 17343181Sdim#include "lldb/lldb-public.h" 18343181Sdim#include "llvm/Support/YAMLTraits.h" 19343181Sdim#include "llvm/Support/raw_ostream.h" 20343181Sdim 21343181Sdimnamespace lldb_private { 22360784Sdimnamespace repro { 23360784Sdimclass PacketRecorder; 24360784Sdim} 25343181Sdimnamespace process_gdb_remote { 26343181Sdim 27343181Sdim/// The history keeps a circular buffer of GDB remote packets. The history is 28343181Sdim/// used for logging and replaying GDB remote packets. 29343181Sdimclass GDBRemoteCommunicationHistory { 30343181Sdimpublic: 31343181Sdim friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>; 32343181Sdim 33343181Sdim GDBRemoteCommunicationHistory(uint32_t size = 0); 34343181Sdim 35343181Sdim ~GDBRemoteCommunicationHistory(); 36343181Sdim 37343181Sdim // For single char packets for ack, nack and /x03 38360784Sdim void AddPacket(char packet_char, GDBRemotePacket::Type type, 39343181Sdim uint32_t bytes_transmitted); 40343181Sdim 41360784Sdim void AddPacket(const std::string &src, uint32_t src_len, 42360784Sdim GDBRemotePacket::Type type, uint32_t bytes_transmitted); 43360784Sdim 44343181Sdim void Dump(Stream &strm) const; 45343181Sdim void Dump(Log *log) const; 46343181Sdim bool DidDumpToLog() const { return m_dumped_to_log; } 47343181Sdim 48360784Sdim void SetRecorder(repro::PacketRecorder *recorder) { m_recorder = recorder; } 49343181Sdim 50343181Sdimprivate: 51343181Sdim uint32_t GetFirstSavedPacketIndex() const { 52343181Sdim if (m_total_packet_count < m_packets.size()) 53343181Sdim return 0; 54343181Sdim else 55343181Sdim return m_curr_idx + 1; 56343181Sdim } 57343181Sdim 58343181Sdim uint32_t GetNumPacketsInHistory() const { 59343181Sdim if (m_total_packet_count < m_packets.size()) 60343181Sdim return m_total_packet_count; 61343181Sdim else 62343181Sdim return (uint32_t)m_packets.size(); 63343181Sdim } 64343181Sdim 65343181Sdim uint32_t GetNextIndex() { 66343181Sdim ++m_total_packet_count; 67343181Sdim const uint32_t idx = m_curr_idx; 68343181Sdim m_curr_idx = NormalizeIndex(idx + 1); 69343181Sdim return idx; 70343181Sdim } 71343181Sdim 72343181Sdim uint32_t NormalizeIndex(uint32_t i) const { 73343181Sdim return m_packets.empty() ? 0 : i % m_packets.size(); 74343181Sdim } 75343181Sdim 76360784Sdim std::vector<GDBRemotePacket> m_packets; 77343181Sdim uint32_t m_curr_idx; 78343181Sdim uint32_t m_total_packet_count; 79343181Sdim mutable bool m_dumped_to_log; 80360784Sdim repro::PacketRecorder *m_recorder = nullptr; 81343181Sdim}; 82343181Sdim 83343181Sdim} // namespace process_gdb_remote 84343181Sdim} // namespace lldb_private 85343181Sdim 86343181Sdim#endif // liblldb_GDBRemoteCommunicationHistory_h_ 87