From 93a789d286c79acfc3737d5bf216e019ff3794e7 Mon Sep 17 00:00:00 2001 From: cczetier Date: Mon, 6 Jan 2025 13:59:46 -0500 Subject: [PATCH] split qTBuffer/QTBuffer, fix trace explanations --- src/protocol/commands.rs | 3 ++- src/protocol/commands/_QTBuffer.rs | 40 +++++++++--------------------- src/protocol/commands/_qTBuffer.rs | 30 ++++++++++++++++++++++ src/stub/core_impl/tracepoints.rs | 37 +++++++++++---------------- 4 files changed, 59 insertions(+), 51 deletions(-) create mode 100644 src/protocol/commands/_qTBuffer.rs diff --git a/src/protocol/commands.rs b/src/protocol/commands.rs index 4a0f7ac..4431f84 100644 --- a/src/protocol/commands.rs +++ b/src/protocol/commands.rs @@ -343,11 +343,12 @@ commands! { tracepoints use 'a { "QTDP" => _QTDP::QTDP<'a>, "QTinit" => _QTinit::QTinit, - "QTBuffer" => _QTBuffer::QTBuffer<'a>, + "QTBuffer" => _QTBuffer::QTBuffer, "QTStart" => _QTStart::QTStart, "QTStop" => _QTStop::QTStop, "QTFrame" => _QTFrame::QTFrame<'a>, + "qTBuffer" => _qTBuffer::qTBuffer<'a>, "qTStatus" => _qTStatus::qTStatus, "qTP" => _qTP::qTP<'a>, "qTfP" => _qTfP::qTfP, diff --git a/src/protocol/commands/_QTBuffer.rs b/src/protocol/commands/_QTBuffer.rs index ee8f76f..50d0226 100644 --- a/src/protocol/commands/_QTBuffer.rs +++ b/src/protocol/commands/_QTBuffer.rs @@ -2,49 +2,33 @@ use super::prelude::*; use crate::target::ext::tracepoints::{BufferShape, TraceBuffer}; #[derive(Debug)] -pub enum QTBuffer<'a> -{ - Request { offset: u64, length: usize, data: &'a mut [u8] }, - Configure { buffer: TraceBuffer }, -} +pub struct QTBuffer(pub TraceBuffer); -impl<'a> ParseCommand<'a> for QTBuffer<'a> { +impl ParseCommand<'_> for QTBuffer { #[inline(always)] - fn from_packet(buf: PacketBuf<'a>) -> Option { - let (buf, body_range) = buf.into_raw_buf(); - let body = &buf[body_range]; - match body { + fn from_packet(buf: PacketBuf<'_>) -> Option { + match buf.into_body() { [b':', body @ ..] => { - let mut s = body.split(|b| *b == b':'); + let mut s = body.splitn_mut(2, |b| *b == b':'); let opt = s.next()?; - Some(match opt.as_ref() { + match opt.as_ref() { b"circular" => { let shape = s.next()?; - QTBuffer::Configure { buffer: TraceBuffer::Shape(match shape { + Some(QTBuffer(TraceBuffer::Shape(match shape { [b'1'] => Some(BufferShape::Circular), [b'0'] => Some(BufferShape::Linear), _ => None, - }?)} + }?))) }, b"size" => { let size = s.next()?; - QTBuffer::Configure { buffer: TraceBuffer::Size(match size { + Some(QTBuffer(TraceBuffer::Size(match size { [b'-', b'1'] => None, i => Some(decode_hex(i).ok()?) - })} - }, - req => { - let mut req_opts = req.split(|b| *b == b','); - let (offset, length) = (req_opts.next()?, req_opts.next()?); - let offset = decode_hex(offset).ok()?; - let length = decode_hex(length).ok()?; - // Our response has to be a hex encoded buffer that fits within - // our packet size, which means we actually have half as much space - // as our slice would indicate. - let (front, _back) = buf.split_at_mut(buf.len() / 2); - QTBuffer::Request { offset, length, data: front } + }))) }, - }) + _ => None, + } }, _ => None, diff --git a/src/protocol/commands/_qTBuffer.rs b/src/protocol/commands/_qTBuffer.rs new file mode 100644 index 0000000..531a4cb --- /dev/null +++ b/src/protocol/commands/_qTBuffer.rs @@ -0,0 +1,30 @@ +use super::prelude::*; + +#[derive(Debug)] +pub struct qTBuffer<'a> { + pub offset: u64, + pub length: usize, + pub data: &'a mut [u8] +} + +impl<'a> ParseCommand<'a> for qTBuffer<'a> { + #[inline(always)] + fn from_packet(buf: PacketBuf<'a>) -> Option { + let (buf, body_range) = buf.into_raw_buf(); + let body = &buf[body_range]; + match body { + [b':', body @ ..] => { + let mut req_opts = body.split(|b| *b == b','); + let (offset, length) = (req_opts.next()?, req_opts.next()?); + let offset = decode_hex(offset).ok()?; + let length = decode_hex(length).ok()?; + // Our response has to be a hex encoded buffer that fits within + // our packet size, which means we actually have half as much space + // as our slice would indicate. + let (front, _back) = buf.split_at_mut(buf.len() / 2); + Some(qTBuffer { offset, length, data: front }) + }, + _ => None + } + } +} diff --git a/src/stub/core_impl/tracepoints.rs b/src/stub/core_impl/tracepoints.rs index 4c668a4..821f336 100644 --- a/src/stub/core_impl/tracepoints.rs +++ b/src/stub/core_impl/tracepoints.rs @@ -1,7 +1,7 @@ use super::prelude::*; use crate::arch::Arch; use crate::internal::BeBytes; -use crate::protocol::commands::_QTBuffer::QTBuffer; +use crate::protocol::commands::_qTBuffer::qTBuffer; use crate::protocol::commands::ext::Tracepoints; use crate::protocol::commands::prelude::decode_hex; use crate::protocol::commands::prelude::decode_hex_buf; @@ -162,7 +162,7 @@ impl GdbStubImpl { status.write(res)?; let mut err = None; ops.trace_experiment_info(&mut |explanation: ExperimentExplanation<'_>| { - if let Err(e) = explanation.write(res) { + if let Err(e) = res.write_str(";").and_then(|()| explanation.write(res)) { err = Some(e) } }) @@ -205,27 +205,20 @@ impl GdbStubImpl { // TODO: support qRelocInsn? return Ok(HandlerStatus::NeedsOk); } - Tracepoints::QTBuffer(buf) => { - match buf { - QTBuffer::Request { - offset, - length, - data, - } => { - let read = ops - .trace_buffer_request(offset, length, data) - .handle_error()?; - if let Some(read) = read { - let read = read.min(data.len()); - res.write_hex_buf(&data[..read])?; - } else { - res.write_str("l")?; - } - } - QTBuffer::Configure { buffer } => { - ops.trace_buffer_configure(buffer).handle_error()?; - } + Tracepoints::qTBuffer(buf) => { + let qTBuffer { offset, length, data } = buf; + let read = ops + .trace_buffer_request(offset, length, data) + .handle_error()?; + if let Some(read) = read { + let read = read.min(data.len()); + res.write_hex_buf(&data[..read])?; + } else { + res.write_str("l")?; } + } + Tracepoints::QTBuffer(conf) => { + ops.trace_buffer_configure(conf.0).handle_error()?; // Documentation doesn't mention this, but it needs OK return Ok(HandlerStatus::NeedsOk); }