1*9dba64beSDimitry Andric //===-- GDBRemote.cpp -----------------------------------------------------===// 2*9dba64beSDimitry Andric // 3*9dba64beSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*9dba64beSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*9dba64beSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*9dba64beSDimitry Andric // 7*9dba64beSDimitry Andric //===----------------------------------------------------------------------===// 8*9dba64beSDimitry Andric 9*9dba64beSDimitry Andric #include "lldb/Utility/GDBRemote.h" 10*9dba64beSDimitry Andric 11*9dba64beSDimitry Andric #include "lldb/Utility/Flags.h" 12*9dba64beSDimitry Andric #include "lldb/Utility/Stream.h" 13*9dba64beSDimitry Andric 14*9dba64beSDimitry Andric #include <stdio.h> 15*9dba64beSDimitry Andric 16*9dba64beSDimitry Andric using namespace lldb; 17*9dba64beSDimitry Andric using namespace lldb_private; 18*9dba64beSDimitry Andric using namespace llvm; 19*9dba64beSDimitry Andric 20*9dba64beSDimitry Andric StreamGDBRemote::StreamGDBRemote() : StreamString() {} 21*9dba64beSDimitry Andric 22*9dba64beSDimitry Andric StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size, 23*9dba64beSDimitry Andric ByteOrder byte_order) 24*9dba64beSDimitry Andric : StreamString(flags, addr_size, byte_order) {} 25*9dba64beSDimitry Andric 26*9dba64beSDimitry Andric StreamGDBRemote::~StreamGDBRemote() {} 27*9dba64beSDimitry Andric 28*9dba64beSDimitry Andric int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) { 29*9dba64beSDimitry Andric int bytes_written = 0; 30*9dba64beSDimitry Andric const uint8_t *src = static_cast<const uint8_t *>(s); 31*9dba64beSDimitry Andric bool binary_is_set = m_flags.Test(eBinary); 32*9dba64beSDimitry Andric m_flags.Clear(eBinary); 33*9dba64beSDimitry Andric while (src_len) { 34*9dba64beSDimitry Andric uint8_t byte = *src; 35*9dba64beSDimitry Andric src++; 36*9dba64beSDimitry Andric src_len--; 37*9dba64beSDimitry Andric if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) { 38*9dba64beSDimitry Andric bytes_written += PutChar(0x7d); 39*9dba64beSDimitry Andric byte ^= 0x20; 40*9dba64beSDimitry Andric } 41*9dba64beSDimitry Andric bytes_written += PutChar(byte); 42*9dba64beSDimitry Andric }; 43*9dba64beSDimitry Andric if (binary_is_set) 44*9dba64beSDimitry Andric m_flags.Set(eBinary); 45*9dba64beSDimitry Andric return bytes_written; 46*9dba64beSDimitry Andric } 47*9dba64beSDimitry Andric 48*9dba64beSDimitry Andric void GDBRemotePacket::Serialize(raw_ostream &strm) const { 49*9dba64beSDimitry Andric yaml::Output yout(strm); 50*9dba64beSDimitry Andric yout << const_cast<GDBRemotePacket &>(*this); 51*9dba64beSDimitry Andric strm.flush(); 52*9dba64beSDimitry Andric } 53*9dba64beSDimitry Andric 54*9dba64beSDimitry Andric llvm::StringRef GDBRemotePacket::GetTypeStr() const { 55*9dba64beSDimitry Andric switch (type) { 56*9dba64beSDimitry Andric case GDBRemotePacket::ePacketTypeSend: 57*9dba64beSDimitry Andric return "send"; 58*9dba64beSDimitry Andric case GDBRemotePacket::ePacketTypeRecv: 59*9dba64beSDimitry Andric return "read"; 60*9dba64beSDimitry Andric case GDBRemotePacket::ePacketTypeInvalid: 61*9dba64beSDimitry Andric return "invalid"; 62*9dba64beSDimitry Andric } 63*9dba64beSDimitry Andric llvm_unreachable("All enum cases should be handled"); 64*9dba64beSDimitry Andric } 65*9dba64beSDimitry Andric 66*9dba64beSDimitry Andric void GDBRemotePacket::Dump(Stream &strm) const { 67*9dba64beSDimitry Andric strm.Printf("tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", tid, 68*9dba64beSDimitry Andric bytes_transmitted, GetTypeStr().data(), packet.data.c_str()); 69*9dba64beSDimitry Andric } 70*9dba64beSDimitry Andric 71*9dba64beSDimitry Andric void yaml::ScalarEnumerationTraits<GDBRemotePacket::Type>::enumeration( 72*9dba64beSDimitry Andric IO &io, GDBRemotePacket::Type &value) { 73*9dba64beSDimitry Andric io.enumCase(value, "Invalid", GDBRemotePacket::ePacketTypeInvalid); 74*9dba64beSDimitry Andric io.enumCase(value, "Send", GDBRemotePacket::ePacketTypeSend); 75*9dba64beSDimitry Andric io.enumCase(value, "Recv", GDBRemotePacket::ePacketTypeRecv); 76*9dba64beSDimitry Andric } 77*9dba64beSDimitry Andric 78*9dba64beSDimitry Andric void yaml::ScalarTraits<GDBRemotePacket::BinaryData>::output( 79*9dba64beSDimitry Andric const GDBRemotePacket::BinaryData &Val, void *, raw_ostream &Out) { 80*9dba64beSDimitry Andric Out << toHex(Val.data); 81*9dba64beSDimitry Andric } 82*9dba64beSDimitry Andric 83*9dba64beSDimitry Andric StringRef yaml::ScalarTraits<GDBRemotePacket::BinaryData>::input( 84*9dba64beSDimitry Andric StringRef Scalar, void *, GDBRemotePacket::BinaryData &Val) { 85*9dba64beSDimitry Andric Val.data = fromHex(Scalar); 86*9dba64beSDimitry Andric return {}; 87*9dba64beSDimitry Andric } 88*9dba64beSDimitry Andric 89*9dba64beSDimitry Andric void yaml::MappingTraits<GDBRemotePacket>::mapping(IO &io, 90*9dba64beSDimitry Andric GDBRemotePacket &Packet) { 91*9dba64beSDimitry Andric io.mapRequired("packet", Packet.packet); 92*9dba64beSDimitry Andric io.mapRequired("type", Packet.type); 93*9dba64beSDimitry Andric io.mapRequired("bytes", Packet.bytes_transmitted); 94*9dba64beSDimitry Andric io.mapRequired("index", Packet.packet_idx); 95*9dba64beSDimitry Andric io.mapRequired("tid", Packet.tid); 96*9dba64beSDimitry Andric } 97*9dba64beSDimitry Andric 98*9dba64beSDimitry Andric StringRef 99*9dba64beSDimitry Andric yaml::MappingTraits<GDBRemotePacket>::validate(IO &io, 100*9dba64beSDimitry Andric GDBRemotePacket &Packet) { 101*9dba64beSDimitry Andric if (Packet.bytes_transmitted != Packet.packet.data.size()) 102*9dba64beSDimitry Andric return "BinaryData size doesn't match bytes transmitted"; 103*9dba64beSDimitry Andric 104*9dba64beSDimitry Andric return {}; 105*9dba64beSDimitry Andric } 106