)]}'
{
  "commit": "366e3746c572c2c78454761e62fa9181cba413ca",
  "tree": "732c601e940cd5b648b4e1ccf2f0b38443ee0c1d",
  "parents": [
    "330d63093c562a4b221835832c5e4f767dc623c3"
  ],
  "author": {
    "name": "Pedro Alves",
    "email": "pedro@palves.net",
    "time": "Thu Mar 31 22:04:42 2022 +0100"
  },
  "committer": {
    "name": "Pedro Alves",
    "email": "pedro@palves.net",
    "time": "Thu Apr 14 20:22:42 2022 +0100"
  },
  "message": "gdbserver: special case target_write_memory len\u003d\u003d0\n\nThe next patch in this series adds a common helper routine for both\nmemory reads and writes, like this:\n\n static int\n proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,\n\t\t  const gdb_byte *writebuf, int len)\n {\n   gdb_assert ((readbuf \u003d\u003d nullptr) !\u003d (writebuf \u003d\u003d nullptr));\n   ...\n }\n\n int\n linux_process_target::read_memory (CORE_ADDR memaddr,\n                                    unsigned char *myaddr, int len)\n {\n   return proc_xfer_memory (memaddr, myaddr, nullptr, len);\n }\n\n linux_process_target::write_memory (CORE_ADDR memaddr,\n                                    const unsigned char *myaddr, int len)\n {\n   return proc_xfer_memory (memaddr, nullptr, myaddr, len);\n }\n\nSurprisingly, the assertion fails.  That happens because it can happen\nthat target_write_memory is called with LEN\u003d\u003d0, due to this in\ngdb/remote.c:\n\n /* Determine whether the remote target supports binary downloading.\n    This is accomplished by sending a no-op memory write of zero length\n    to the target at the specified address. (...) */\n\n void\n remote_target::check_binary_download (CORE_ADDR addr)\n {\n ...\n       p \u003d rs-\u003ebuf.data ();\n       *p++ \u003d \u0027X\u0027;\n       p +\u003d hexnumstr (p, (ULONGEST) addr);\n       *p++ \u003d \u0027,\u0027;\n       p +\u003d hexnumstr (p, (ULONGEST) 0);\n       *p++ \u003d \u0027:\u0027;\n       *p \u003d \u0027\\0\u0027;\n\nIn this scenario, in gdbserver\u0027s target_write_memory, the \"myaddr\"\nargument of the_target-\u003ewrite_memory is passed the data() of a local\ngdb::byte_vector (which is a specialized std::vector).  It\u0027s valid for\nstd::vector::data() to return NULL when the vector is empty.\n\nThis commit adds an early return to target_write_memory to avoid\ntarget backends having to care about this.  For good measure, do the\nsame on the read side, in read_inferior_memory.\n\nChange-Id: Iac8f04fcf99014c624ef4036bd318ca1771ad491\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "5009146d66373665ea74c92ffc42a5cd0a377e9e",
      "old_mode": 33188,
      "old_path": "gdbserver/target.cc",
      "new_id": "e9d1e1aa38c2e8c12d1efdf0773ef214399b7d85",
      "new_mode": 33188,
      "new_path": "gdbserver/target.cc"
    }
  ]
}
