diff options
author | Tom Tromey <tromey@adacore.com> | 2024-12-09 10:40:48 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2024-12-11 10:00:47 -0700 |
commit | a32d76186d24be8f23bd4c2fd20d9cf762dc3673 (patch) | |
tree | 2fbbb6270c1d3e20316d54c0358ab196f4f27086 | |
parent | a5939d229614a4913daf3c687ec54fdf3020d496 (diff) | |
download | binutils-a32d76186d24be8f23bd4c2fd20d9cf762dc3673.zip binutils-a32d76186d24be8f23bd4c2fd20d9cf762dc3673.tar.gz binutils-a32d76186d24be8f23bd4c2fd20d9cf762dc3673.tar.bz2 |
Fix gdbreplay checksum calculation
I needed to use gdbreplay today. It didn't work quite right, and
using "set debug remote 1" showed that gdb was rejecting some
responses like:
[remote] Sending packet: $vCont?#49
[remote] Junk: #vCont?
[remote] Junk: 8vCont?
[remote] Junk: 3vCont?
[remote] Received Ack
The checksum recalculation seems to have gone wrong. Looking at the
code, it seems like 'where_csum' is calculated inconsistently: in the
main loop it is after the '#' but in the "== 0" case it is before the
'#'.
This patch fixes the problem and also avoids a string copy.
CC: Alexandra Hájková <ahajkova@redhat.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
-rw-r--r-- | gdbserver/gdbreplay.cc | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/gdbserver/gdbreplay.cc b/gdbserver/gdbreplay.cc index a9a5592..951f50e 100644 --- a/gdbserver/gdbreplay.cc +++ b/gdbserver/gdbreplay.cc @@ -405,11 +405,12 @@ expect (FILE *fp) /* Calculate checksum for the packet stored in buffer buf. Store the checksum in a hexadecimal format in a checksum_hex variable. */ static void -recalculate_csum (const std::string &buf, int cnt, unsigned char *checksum_hex) +recalculate_csum (const std::string &buf, int off, unsigned char *checksum_hex) { unsigned char csum = 0; - for (int i = 0; i < cnt; i++) + int len = buf.length (); + for (int i = off; i < len; ++i) csum += buf[i]; checksum_hex[0] = tohex ((csum >> 4) & 0xf); @@ -435,9 +436,9 @@ play (FILE *fp) } while ((fromlog = logchar (fp, false)) != EOL) { - line.push_back (fromlog); - if (line[line.length ()] == '#') + if (fromlog == '#') where_csum = line.length (); + line.push_back (fromlog); } /* Packet starts with '+$' or '$', we don't want to calculate those @@ -446,23 +447,13 @@ play (FILE *fp) if (line[0] == '+') offset = 2; - /* If '#' is missing at the end of the line, add it and adjust the line - length. */ - if (where_csum == 0) - { - where_csum = line.length (); - line.push_back ('#'); - } - recalculate_csum (line.substr (offset), where_csum - offset, checksum); - - /* Check if the checksum is missing and adjust the line length to be able - to fit the checksum. */ - if (where_csum + 1 >= line.length ()) - line.resize (where_csum + 3); + if (where_csum > 0) + line.resize (where_csum); + recalculate_csum (line, offset, checksum); - /* Replace what is at the end of the packet with the checksum. */ - line[where_csum + 1] = checksum[0]; - line[where_csum + 2] = checksum[1]; + line.push_back ('#'); + line.push_back (checksum[0]); + line.push_back (checksum[1]); if (write (remote_desc_out, line.data (), line.size ()) != line.size ()) remote_error ("Error during write to gdb"); |