15ffd83dbSDimitry Andric //===-- GDBRemoteCommunicationHistory.cpp ---------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "GDBRemoteCommunicationHistory.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric // Other libraries and framework includes
120b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h"
130b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric using namespace llvm;
160b57cec5SDimitry Andric using namespace lldb;
170b57cec5SDimitry Andric using namespace lldb_private;
180b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote;
190b57cec5SDimitry Andric 
GDBRemoteCommunicationHistory(uint32_t size)200b57cec5SDimitry Andric GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
21*fe6060f1SDimitry Andric     : m_packets() {
220b57cec5SDimitry Andric   if (size)
230b57cec5SDimitry Andric     m_packets.resize(size);
240b57cec5SDimitry Andric }
250b57cec5SDimitry Andric 
26*fe6060f1SDimitry Andric GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() = default;
270b57cec5SDimitry Andric 
AddPacket(char packet_char,GDBRemotePacket::Type type,uint32_t bytes_transmitted)289dba64beSDimitry Andric void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
299dba64beSDimitry Andric                                               GDBRemotePacket::Type type,
300b57cec5SDimitry Andric                                               uint32_t bytes_transmitted) {
310b57cec5SDimitry Andric   const size_t size = m_packets.size();
320b57cec5SDimitry Andric   if (size == 0)
330b57cec5SDimitry Andric     return;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   const uint32_t idx = GetNextIndex();
360b57cec5SDimitry Andric   m_packets[idx].packet.data.assign(1, packet_char);
370b57cec5SDimitry Andric   m_packets[idx].type = type;
380b57cec5SDimitry Andric   m_packets[idx].bytes_transmitted = bytes_transmitted;
390b57cec5SDimitry Andric   m_packets[idx].packet_idx = m_total_packet_count;
400b57cec5SDimitry Andric   m_packets[idx].tid = llvm::get_threadid();
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric 
AddPacket(const std::string & src,uint32_t src_len,GDBRemotePacket::Type type,uint32_t bytes_transmitted)430b57cec5SDimitry Andric void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
449dba64beSDimitry Andric                                               uint32_t src_len,
459dba64beSDimitry Andric                                               GDBRemotePacket::Type type,
460b57cec5SDimitry Andric                                               uint32_t bytes_transmitted) {
470b57cec5SDimitry Andric   const size_t size = m_packets.size();
480b57cec5SDimitry Andric   if (size == 0)
490b57cec5SDimitry Andric     return;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   const uint32_t idx = GetNextIndex();
520b57cec5SDimitry Andric   m_packets[idx].packet.data.assign(src, 0, src_len);
530b57cec5SDimitry Andric   m_packets[idx].type = type;
540b57cec5SDimitry Andric   m_packets[idx].bytes_transmitted = bytes_transmitted;
550b57cec5SDimitry Andric   m_packets[idx].packet_idx = m_total_packet_count;
560b57cec5SDimitry Andric   m_packets[idx].tid = llvm::get_threadid();
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
Dump(Stream & strm) const590b57cec5SDimitry Andric void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
600b57cec5SDimitry Andric   const uint32_t size = GetNumPacketsInHistory();
610b57cec5SDimitry Andric   const uint32_t first_idx = GetFirstSavedPacketIndex();
620b57cec5SDimitry Andric   const uint32_t stop_idx = m_curr_idx + size;
630b57cec5SDimitry Andric   for (uint32_t i = first_idx; i < stop_idx; ++i) {
640b57cec5SDimitry Andric     const uint32_t idx = NormalizeIndex(i);
659dba64beSDimitry Andric     const GDBRemotePacket &entry = m_packets[idx];
669dba64beSDimitry Andric     if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
679dba64beSDimitry Andric         entry.packet.data.empty())
680b57cec5SDimitry Andric       break;
699dba64beSDimitry Andric     strm.Printf("history[%u] ", entry.packet_idx);
709dba64beSDimitry Andric     entry.Dump(strm);
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
Dump(Log * log) const740b57cec5SDimitry Andric void GDBRemoteCommunicationHistory::Dump(Log *log) const {
750b57cec5SDimitry Andric   if (!log || m_dumped_to_log)
760b57cec5SDimitry Andric     return;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   m_dumped_to_log = true;
790b57cec5SDimitry Andric   const uint32_t size = GetNumPacketsInHistory();
800b57cec5SDimitry Andric   const uint32_t first_idx = GetFirstSavedPacketIndex();
810b57cec5SDimitry Andric   const uint32_t stop_idx = m_curr_idx + size;
820b57cec5SDimitry Andric   for (uint32_t i = first_idx; i < stop_idx; ++i) {
830b57cec5SDimitry Andric     const uint32_t idx = NormalizeIndex(i);
849dba64beSDimitry Andric     const GDBRemotePacket &entry = m_packets[idx];
859dba64beSDimitry Andric     if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
869dba64beSDimitry Andric         entry.packet.data.empty())
870b57cec5SDimitry Andric       break;
889dba64beSDimitry Andric     LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
890b57cec5SDimitry Andric               entry.packet_idx, entry.tid, entry.bytes_transmitted,
909dba64beSDimitry Andric               (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
919dba64beSDimitry Andric                                                                : "read",
920b57cec5SDimitry Andric               entry.packet.data.c_str());
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
96