xref: /freebsd-src/contrib/llvm-project/lldb/source/Utility/GDBRemote.cpp (revision 9dba64be9536c28e4800e06512b7f29b43ade345)
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