Don't die when gdb thinks XLEN is 64 but it's 32.
authorTim Newsome <tim@sifive.com>
Fri, 7 Oct 2016 15:56:05 +0000 (08:56 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Fri, 7 Oct 2016 18:40:18 +0000 (11:40 -0700)
Instead, just give gdb what it asks for.
Also when gdb does a register write, let the user know that it's likely
misconfigured and tell them how to fix it.

This is probably as well as issue #72 can be fixed in spike.

riscv/gdbserver.cc
riscv/gdbserver.h

index c4a2625486de686c809f0058c4e425f29b7f00d8..ca567dbe4e64a1d1291c34b58a1e66c3e6eb6dfa 100644 (file)
@@ -593,8 +593,12 @@ class register_read_op_t : public operation_t
       switch (step) {
         case 0:
           if (reg >= REG_XPR0 && reg <= REG_XPR31) {
-            die("handle_register_read");
-            // send(p->state.XPR[reg - REG_XPR0]);
+            if (gs.xlen == 32) {
+              gs.dr_write32(0, sw(reg - REG_XPR0, 0, (uint16_t) DEBUG_RAM_START + 16));
+            } else {
+              gs.dr_write32(0, sd(reg - REG_XPR0, 0, (uint16_t) DEBUG_RAM_START + 16));
+            }
+            gs.dr_write_jump(1);
           } else if (reg == REG_PC) {
             gs.start_packet();
             if (gs.xlen == 32) {
@@ -882,8 +886,8 @@ class memory_write_op_t : public operation_t
       }
 
       if (gs.dr_read32(DEBUG_RAM_SIZE / 4 - 1)) {
-        fprintf(stderr, "Exception happened while writing to 0x%016" PRIx64
-                " -> 0x%016" PRIx64 "\n", vaddr, paddr);
+        gs.send_packet("E98");
+        return true;
       }
 
       offset += access_size;
@@ -1670,7 +1674,8 @@ uint64_t consume_hex_number(std::vector<uint8_t>::const_iterator &iter,
 
 // First byte is the least-significant one.
 // Eg. "08675309" becomes 0x09536708
-uint64_t consume_hex_number_le(std::vector<uint8_t>::const_iterator &iter,
+uint64_t gdbserver_t::consume_hex_number_le(
+    std::vector<uint8_t>::const_iterator &iter,
     std::vector<uint8_t>::const_iterator end)
 {
   uint64_t value = 0;
@@ -1688,6 +1693,12 @@ uint64_t consume_hex_number_le(std::vector<uint8_t>::const_iterator &iter,
     else
       shift -= 4;
   }
+  if (shift >= xlen) {
+    fprintf(stderr,
+        "gdb sent too many data bytes. That means it thinks XLEN is greater than %d.\n"
+        "To fix that, tell gdb: set arch riscv:rv%d\n",
+        xlen, xlen);
+  }
   return value;
 }
 
index c2689da186d7a0839ed547ef9646d3ff39432369..0ed8881304680598f76432ed01d2779948ca330d 100644 (file)
@@ -202,6 +202,9 @@ public:
   uint64_t dr_read64(unsigned int index);
   uint64_t dr_read(enum slot slot);
 
+  uint64_t consume_hex_number_le(std::vector<uint8_t>::const_iterator &iter,
+      std::vector<uint8_t>::const_iterator end);
+
   // Return access size to use when writing length bytes to address, so that
   // every write will be aligned.
   unsigned int find_access_size(reg_t address, int length);