mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 00:49:43 +00:00
Add a simple qSupported packet, fix a bug in decode_binary_data(),
add a new 'x' packet for reading data in binary format. Document the 'x' packet. <rdar://problem/16032150> llvm-svn: 208051
This commit is contained in:
parent
7eba3f90ae
commit
018ff31462
@ -836,6 +836,40 @@ For instance, with a Mac OS X process which has nothing mapped in the first
|
||||
The lack of 'permissions:' indicates that none of read/write/execute are valid
|
||||
for this region.
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 'x' - Binary memory read
|
||||
//
|
||||
// Like the 'm' (read) and 'M' (write) packets, this is a partner to the
|
||||
// 'X' (write binary data) packet, 'x'.
|
||||
//
|
||||
// It is called like
|
||||
//
|
||||
// xADDRESS,LENGTH
|
||||
//
|
||||
// where both ADDRESS and LENGTH are big-endian base 16 values.
|
||||
//
|
||||
// To test if this packet is available, send a addr/len of 0:
|
||||
//
|
||||
// x0,0
|
||||
//
|
||||
// and you will get an "OK" response.
|
||||
//
|
||||
// The reply will be the data requested in 8-bit binary data format.
|
||||
// The standard quoting is applied to the payload -- characters
|
||||
// } # $ *
|
||||
// will all be escaped with '}' (0x7d) character and then XOR'ed with 0x20.
|
||||
//
|
||||
// A typical use to read 512 bytes at 0x1000 would look like
|
||||
//
|
||||
// x0x1000,0x200
|
||||
//
|
||||
// The "0x" prefixes are optional - like most of the gdb-remote packets,
|
||||
// omitting them will work fine; these numbers are always base 16.
|
||||
//
|
||||
// The length of the payload is not provided. A reliable, 8-bit clean,
|
||||
// transport layer is assumed.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Detach and stay stopped:
|
||||
//
|
||||
|
@ -136,14 +136,15 @@ RNBRemote::CreatePacketTable ()
|
||||
// t.push_back (Packet (restart, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
|
||||
// t.push_back (Packet (search_mem_backwards, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards"));
|
||||
t.push_back (Packet (thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T", "Is thread alive"));
|
||||
t.push_back (Packet (query_supported_features, &RNBRemote::HandlePacket_qSupported, NULL, "qSupported", "Query about supported features"));
|
||||
t.push_back (Packet (vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach", "Attach to a new process"));
|
||||
t.push_back (Packet (vattachwait, &RNBRemote::HandlePacket_v, NULL, "vAttachWait", "Wait for a process to start up then attach to it"));
|
||||
t.push_back (Packet (vattachorwait, &RNBRemote::HandlePacket_v, NULL, "vAttachOrWait", "Attach to the process or if it doesn't exist, wait for the process to start up then attach to it"));
|
||||
t.push_back (Packet (vattachname, &RNBRemote::HandlePacket_v, NULL, "vAttachName", "Attach to an existing process by name"));
|
||||
t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont;", "Verbose resume with thread actions"));
|
||||
t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont?", "List valid continue-with-thread-actions actions"));
|
||||
// The X packet doesn't currently work. If/when it does, remove the line above and uncomment out the line below
|
||||
// t.push_back (Packet (write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, "X", "Write data to memory"));
|
||||
t.push_back (Packet (read_data_from_memory, &RNBRemote::HandlePacket_x, NULL, "x", "Read data from memory"));
|
||||
t.push_back (Packet (write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, "X", "Write data to memory"));
|
||||
// t.push_back (Packet (insert_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint"));
|
||||
// t.push_back (Packet (remove_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint"));
|
||||
t.push_back (Packet (insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z2", "Insert write watchpoint"));
|
||||
@ -817,10 +818,10 @@ best_guess_cpu_type ()
|
||||
|
||||
/* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
|
||||
(8-bit bytes).
|
||||
This encoding uses 0x7d ('}') as an escape character for 0x7d ('}'),
|
||||
0x23 ('#'), and 0x24 ('$').
|
||||
This encoding uses 0x7d ('}') as an escape character for
|
||||
0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*').
|
||||
LEN is the number of bytes to be processed. If a character is escaped,
|
||||
it is 2 characters for LEN. A LEN of -1 means encode-until-nul-byte
|
||||
it is 2 characters for LEN. A LEN of -1 means decode-until-nul-byte
|
||||
(end of string). */
|
||||
|
||||
std::vector<uint8_t>
|
||||
@ -841,7 +842,7 @@ decode_binary_data (const char *str, size_t len)
|
||||
{
|
||||
len--;
|
||||
str++;
|
||||
c ^= 0x20;
|
||||
c = *str ^ 0x20;
|
||||
}
|
||||
bytes.push_back (c);
|
||||
}
|
||||
@ -2537,6 +2538,89 @@ RNBRemote::HandlePacket_m (const char *p)
|
||||
return SendPacket (ostrm.str ());
|
||||
}
|
||||
|
||||
// Read memory, sent it up as binary data.
|
||||
// Usage: xADDR,LEN
|
||||
// ADDR and LEN are both base 16.
|
||||
|
||||
// Responds with 'OK' for zero-length request
|
||||
// or
|
||||
//
|
||||
// DATA
|
||||
//
|
||||
// where DATA is the binary data payload.
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_x (const char *p)
|
||||
{
|
||||
if (p == NULL || p[0] == '\0' || strlen (p) < 3)
|
||||
{
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
|
||||
}
|
||||
|
||||
char *c;
|
||||
p++;
|
||||
errno = 0;
|
||||
nub_addr_t addr = strtoull (p, &c, 16);
|
||||
if (errno != 0)
|
||||
{
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
|
||||
}
|
||||
if (*c != ',')
|
||||
{
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
|
||||
}
|
||||
|
||||
/* Advance 'p' to the number of bytes to be read. */
|
||||
p += (c - p) + 1;
|
||||
|
||||
errno = 0;
|
||||
int length = strtoul (p, NULL, 16);
|
||||
if (errno != 0)
|
||||
{
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet");
|
||||
}
|
||||
|
||||
// zero length read means this is a test of whether that packet is implemented or not.
|
||||
if (length == 0)
|
||||
{
|
||||
return SendPacket ("OK");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buf (length);
|
||||
|
||||
if (buf.capacity() != length)
|
||||
{
|
||||
return SendPacket ("E79");
|
||||
}
|
||||
int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
|
||||
if (bytes_read == 0)
|
||||
{
|
||||
return SendPacket ("E80");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buf_quoted;
|
||||
buf_quoted.reserve (bytes_read + 30);
|
||||
for (int i = 0; i < bytes_read; i++)
|
||||
{
|
||||
if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*')
|
||||
{
|
||||
buf_quoted.push_back(0x7d);
|
||||
buf_quoted.push_back(buf[i] ^ 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_quoted.push_back(buf[i]);
|
||||
}
|
||||
}
|
||||
length = buf_quoted.size();
|
||||
|
||||
std::ostringstream ostrm;
|
||||
for (int i = 0; i < length; i++)
|
||||
ostrm << buf_quoted[i];
|
||||
|
||||
return SendPacket (ostrm.str ());
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_X (const char *p)
|
||||
{
|
||||
@ -2558,14 +2642,16 @@ RNBRemote::HandlePacket_X (const char *p)
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
|
||||
}
|
||||
|
||||
/* Advance 'p' to the length part of the packet. */
|
||||
/* Advance 'p' to the length part of the packet. NB this is the length of the packet
|
||||
including any escaped chars. The data payload may be a little bit smaller after
|
||||
decoding. */
|
||||
p += (c - p) + 1;
|
||||
|
||||
errno = 0;
|
||||
int length = strtoul (p, NULL, 16);
|
||||
if (errno != 0 && length == 0)
|
||||
{
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
|
||||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet");
|
||||
}
|
||||
|
||||
// I think gdb sends a zero length write request to test whether this
|
||||
@ -2882,6 +2968,15 @@ GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
|
||||
return return_val;
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_qSupported (const char *p)
|
||||
{
|
||||
uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less
|
||||
char buf[64];
|
||||
snprintf (buf, sizeof(buf), "PacketSize=%x", max_packet_size);
|
||||
return SendPacket (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
vAttach;pid
|
||||
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded process name ASCII bytes
|
||||
vcont, // 'vCont'
|
||||
vcont_list_actions, // 'vCont?'
|
||||
read_data_from_memory, // 'x'
|
||||
write_data_to_memory, // 'X'
|
||||
insert_mem_bp, // 'Z0'
|
||||
remove_mem_bp, // 'z0'
|
||||
@ -92,6 +93,7 @@ public:
|
||||
query_register_info, // 'qRegisterInfo'
|
||||
query_shlib_notify_info_addr, // 'qShlibInfoAddr'
|
||||
query_step_packet_supported, // 'qStepPacketSupported'
|
||||
query_supported_features, // 'qSupported'
|
||||
query_vattachorwait_supported, // 'qVAttachOrWaitSupported'
|
||||
query_sync_thread_state_supported,// 'QSyncThreadState'
|
||||
query_host_info, // 'qHostInfo'
|
||||
@ -202,6 +204,7 @@ public:
|
||||
rnb_err_t HandlePacket_last_signal (const char *p);
|
||||
rnb_err_t HandlePacket_m (const char *p);
|
||||
rnb_err_t HandlePacket_M (const char *p);
|
||||
rnb_err_t HandlePacket_x (const char *p);
|
||||
rnb_err_t HandlePacket_X (const char *p);
|
||||
rnb_err_t HandlePacket_g (const char *p);
|
||||
rnb_err_t HandlePacket_G (const char *p);
|
||||
@ -215,6 +218,7 @@ public:
|
||||
rnb_err_t HandlePacket_k (const char *p);
|
||||
rnb_err_t HandlePacket_s (const char *p);
|
||||
rnb_err_t HandlePacket_S (const char *p);
|
||||
rnb_err_t HandlePacket_qSupported (const char *p);
|
||||
rnb_err_t HandlePacket_v (const char *p);
|
||||
rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
|
||||
rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
|
||||
|
Loading…
x
Reference in New Issue
Block a user