[patch] Unaligned reads/writes to/from GDB: Refinement

Dave Brolley <[email protected]>
Newsgroups gmane.comp.emulators.sid.devel
Message-ID <[email protected]>
I've committed this patch which is a correction for my previous work on 
non-aligned memory reads/writes from GDB. It's too late to handle 
bus::unaligned by retrying one byte at a time in process_set_mem because 
by then the input data is no longer in the input stream. I've moved the 
retry to write_bus_word. For consistency, I've also moved the retry for 
reading from process_get_mem to read_bus_word.

Dave
sid-gdb-align2.ChangeLog (text/plain, 240 B)
2004-08-11  Dave Brolley  <[email protected]>

	* gdb.cxx (read_bus_word): Handle bus::misaligned. Return type now
	'void' again.
	(write_bus_word): Ditto.
	(process_get_mem): Don't handle bus::misaligned here.
	(process_set_mem): Ditto.
sid-gdb-align2.patch.txt (text/plain, 7.1 KB)
Index: sid/component/gdb/gdb.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/gdb/gdb.cxx,v
retrieving revision 1.13
diff -c -p -r1.13 gdb.cxx
*** sid/component/gdb/gdb.cxx	1 Jul 2004 16:54:47 -0000	1.13
--- sid/component/gdb/gdb.cxx	11 Aug 2004 20:53:30 -0000
*************** gdb::process_get_exp_regs ()
*** 532,538 ****
  // Helper functions
  
  template <class Type>
! bus::status
  read_bus_word(gdbserv* gdbserv, 
  	      sid::bus* bus,
  	      host_int_4 address,
--- 532,538 ----
  // Helper functions
  
  template <class Type>
! void
  read_bus_word(gdbserv* gdbserv, 
  	      sid::bus* bus,
  	      host_int_4 address,
*************** read_bus_word(gdbserv* gdbserv, 
*** 545,559 ****
        for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
  	gdbserv_output_byte (gdbserv, value.read_byte(i));
      }
!   // misaligned will be handled by the caller
!   else if (s != bus::misaligned)
      gdbserv_output_string (gdbserv, "E05");
-   return s;
  }
  
  
  template <class Type>
! bus::status
  write_bus_word(gdbserv* gdbserv, 
  	       int binary,
  	       sid::bus* bus,
--- 545,570 ----
        for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
  	gdbserv_output_byte (gdbserv, value.read_byte(i));
      }
!   else if (s == bus::misaligned)
!     {
!       // Try it one byte at a time
!       for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
! 	{
! 	  big_int_1 b; // endianness of a single byte is irrelevent
! 	  s = bus->read (address + i, b);
! 	  if (s == bus::ok) 
! 	    gdbserv_output_byte (gdbserv, b);
! 	  else
! 	    gdbserv_output_string (gdbserv, "E05");
! 	}
!     }
!   else
      gdbserv_output_string (gdbserv, "E05");
  }
  
  
  template <class Type>
! void
  write_bus_word(gdbserv* gdbserv, 
  	       int binary,
  	       sid::bus* bus,
*************** write_bus_word(gdbserv* gdbserv, 
*** 574,584 ****
      }
  
    bus::status s = bus->write (address, value);
!   if (s == bus::ok || s == bus::misaligned)
!     ; // No response means "OK" -- misaligned will be handled by the caller
!   else
      gdbserv_output_string (gdbserv, "E05");
-   return s;
  }
  
  
--- 585,604 ----
      }
  
    bus::status s = bus->write (address, value);
!   if (s == bus::misaligned)
!     {
!       // Try it a byte at a time
!       for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
! 	{
! 	  // endianness of a single byte is irrelevent
! 	  big_int_1 b = value.read_byte (i);
! 	  s = bus->write (address + i, b);
! 	  if (s != bus::ok)
! 	    gdbserv_output_string (gdbserv, "E05");
! 	}
!     }
!   else if (s != bus::ok)
      gdbserv_output_string (gdbserv, "E05");
  }
  
  
*************** gdb::process_get_mem (struct gdbserv_reg
*** 623,651 ****
      }
    host_int_4 addr = addr8; // truncate
  
-   bus::status b = bus::misaligned;
    if (len==1 && e==endian_big) 
!     b = read_bus_word (gdbserv, memory, addr, big_int_1());
    else if (len==1 && e==endian_little)
!     b = read_bus_word (gdbserv, memory, addr, little_int_1());
    else if (len==2 && e==endian_big) 
!     b = read_bus_word (gdbserv, memory, addr, big_int_2());
    else if (len==2 && e==endian_little)
!     b = read_bus_word (gdbserv, memory, addr, little_int_2());
    else if (len==4 && e==endian_big) 
!     b = read_bus_word (gdbserv, memory, addr, big_int_4());
    else if (len==4 && e==endian_little)
!     b = read_bus_word (gdbserv, memory, addr, little_int_4());
    else if (len==8 && e==endian_big) 
!     b = read_bus_word (gdbserv, memory, addr, big_int_8());
    else if (len==8 && e==endian_little)
!     b = read_bus_word (gdbserv, memory, addr, little_int_8());
! 
!   if (b != bus::misaligned)
!     return;
!   
!   // Unaligned access or unsupported size.
!   if (e==endian_little)
      {
        for (unsigned long i=0; i<len; i++)
  	read_bus_word (gdbserv, memory, addr + i, little_int_1());
--- 643,665 ----
      }
    host_int_4 addr = addr8; // truncate
  
    if (len==1 && e==endian_big) 
!     read_bus_word (gdbserv, memory, addr, big_int_1());
    else if (len==1 && e==endian_little)
!     read_bus_word (gdbserv, memory, addr, little_int_1());
    else if (len==2 && e==endian_big) 
!     read_bus_word (gdbserv, memory, addr, big_int_2());
    else if (len==2 && e==endian_little)
!     read_bus_word (gdbserv, memory, addr, little_int_2());
    else if (len==4 && e==endian_big) 
!     read_bus_word (gdbserv, memory, addr, big_int_4());
    else if (len==4 && e==endian_little)
!     read_bus_word (gdbserv, memory, addr, little_int_4());
    else if (len==8 && e==endian_big) 
!     read_bus_word (gdbserv, memory, addr, big_int_8());
    else if (len==8 && e==endian_little)
!     read_bus_word (gdbserv, memory, addr, little_int_8());
!   else if (e==endian_little)
      {
        for (unsigned long i=0; i<len; i++)
  	read_bus_word (gdbserv, memory, addr + i, little_int_1());
*************** gdb::process_set_mem (struct gdbserv_reg
*** 709,737 ****
      }
    host_int_4 addr = addr8; // truncate
  
-   bus::status b = bus::misaligned;
    if (len==1 && e==endian_big) 
!     b = write_bus_word (gdbserv, binary, memory, addr, big_int_1());
!   if (len==1 && e==endian_little)
!     b = write_bus_word (gdbserv, binary, memory, addr, little_int_1());
!   if (len==2 && e==endian_big) 
!     b = write_bus_word (gdbserv, binary, memory, addr, big_int_2());
!   if (len==2 && e==endian_little)
!     b = write_bus_word (gdbserv, binary, memory, addr, little_int_2());
!   if (len==4 && e==endian_big) 
!     b = write_bus_word (gdbserv, binary, memory, addr, big_int_4());
!   if (len==4 && e==endian_little)
!     b = write_bus_word (gdbserv, binary, memory, addr, little_int_4());
!   if (len==8 && e==endian_big) 
!     b = write_bus_word (gdbserv, binary, memory, addr, big_int_8());
!   if (len==8 && e==endian_little)
!     b = write_bus_word (gdbserv, binary, memory, addr, little_int_8());
! 
!   if (b != bus::misaligned)
!     return;
! 
!   // Unaligned access or unsupported size.
!   if (e==endian_little)
      {
        for (unsigned long i=0; i<len; i++)
  	write_bus_word (gdbserv, binary, memory, addr + i, little_int_1());
--- 723,745 ----
      }
    host_int_4 addr = addr8; // truncate
  
    if (len==1 && e==endian_big) 
!     write_bus_word (gdbserv, binary, memory, addr, big_int_1());
!   else if (len==1 && e==endian_little)
!     write_bus_word (gdbserv, binary, memory, addr, little_int_1());
!   else if (len==2 && e==endian_big) 
!     write_bus_word (gdbserv, binary, memory, addr, big_int_2());
!   else if (len==2 && e==endian_little)
!     write_bus_word (gdbserv, binary, memory, addr, little_int_2());
!   else if (len==4 && e==endian_big) 
!     write_bus_word (gdbserv, binary, memory, addr, big_int_4());
!   else if (len==4 && e==endian_little)
!     write_bus_word (gdbserv, binary, memory, addr, little_int_4());
!   else if (len==8 && e==endian_big) 
!     write_bus_word (gdbserv, binary, memory, addr, big_int_8());
!   else if (len==8 && e==endian_little)
!     write_bus_word (gdbserv, binary, memory, addr, little_int_8());
!   else if (e==endian_little)
      {
        for (unsigned long i=0; i<len; i++)
  	write_bus_word (gdbserv, binary, memory, addr + i, little_int_1());
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.