This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Use the address mask with addresses for SREC, etc.


Hello,

 Some binary formats, such as SREC, only support 32-bit addresses and do 
not sign-extend them properly for targets that require it.  This causes a 
problem with the MIPS target when KSEG addresses are used as they have bit 
31 set which should be propagated through the high 32 bits to suit 64-bit 
BFD.  It is seen with the gdb.base/dump.exp set of tests.

 Here is a change that fixes the problem.  It has been successfully tested 
for mipsisa32-sde-elf, with the mips-sim-sde32/-EB, 
mips-sim-sde32/-mips16/-EB, mips-sim-sde32/-EL and 
mips-sim-sde32/-mips16/-EL target boards, removing all the 15 failures 
like below seen there:

(gdb) file intarr1.srec
Load new symbol table from ".../gdb/testsuite.mips-sim-sde32.-EL/intarr1.srec"? (y or n) y
Reading symbols from .../gdb/testsuite.mips-sim-sde32.-EL/intarr1.srec...done.
(gdb) print intarray
Cannot access memory at address 0x800220a8
(gdb) PASS: gdb.base/dump.exp: reload array as value, srec; capture intarray
FAIL: gdb.base/dump.exp: reload array as value, srec; value restored ok

2007-07-24  Nigel Stephens  <nigel@mips.com>
            Chris Dearman  <chris@mips.com>
            Maciej W. Rozycki  <macro@mips.com>

	* cli/cli-dump.c (restore_section_callback): Use the address mask
	when comparing addresses.
	* exec.c (xfer_memory): Likewise.

 OK to apply?

  Maciej

12100-3.diff
Index: binutils-quilt/src/gdb/exec.c
===================================================================
--- binutils-quilt.orig/src/gdb/exec.c	2007-07-23 18:59:51.000000000 +0100
+++ binutils-quilt/src/gdb/exec.c	2007-07-23 19:00:23.000000000 +0100
@@ -463,6 +463,8 @@
   struct section_table *p;
   CORE_ADDR nextsectaddr, memend;
   asection *section = NULL;
+  int addr_bit = gdbarch_addr_bit (current_gdbarch);
+  CORE_ADDR addr_mask;
 
   if (len <= 0)
     internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
@@ -474,30 +476,46 @@
 	memaddr = overlay_mapped_address (memaddr, section);
     }
 
+  /* Only match address bits which are significant
+     for the current architecture.  */
+  if (addr_bit < sizeof (CORE_ADDR) * HOST_CHAR_BIT)
+    {
+      addr_mask = ((CORE_ADDR)1 << addr_bit) - 1;
+      memaddr &= addr_mask;
+    }
+  else
+    addr_mask = ~(CORE_ADDR)0;
+
   memend = memaddr + len;
   nextsectaddr = memend;
 
   for (p = target->to_sections; p < target->to_sections_end; p++)
     {
+      CORE_ADDR p_addr;
+
       if (overlay_debugging && section && p->the_bfd_section &&
 	  strcmp (section->name, p->the_bfd_section->name) != 0)
 	continue;		/* not the section we need */
-      if (memaddr >= p->addr)
+
+      p_addr = p->addr & addr_mask;
+      if (memaddr >= p_addr)
         {
-	  if (memend <= p->endaddr)
+	  CORE_ADDR p_endaddr = p->endaddr & addr_mask;
+
+	  if (memend <= p_endaddr)
 	    {
 	      /* Entire transfer is within this section.  */
 	      if (write)
 		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						myaddr, memaddr - p_addr,
 						len);
 	      else
 		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						myaddr, memaddr - p_addr,
 						len);
 	      return (res != 0) ? len : 0;
 	    }
-	  else if (memaddr >= p->endaddr)
+	  else if (memaddr >= p_endaddr)
 	    {
 	      /* This section ends before the transfer starts.  */
 	      continue;
@@ -505,20 +523,20 @@
 	  else
 	    {
 	      /* This section overlaps the transfer.  Just do half.  */
-	      len = p->endaddr - memaddr;
+	      len = p_endaddr - memaddr;
 	      if (write)
 		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						myaddr, memaddr - p_addr,
 						len);
 	      else
 		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						myaddr, memaddr - p_addr,
 						len);
 	      return (res != 0) ? len : 0;
 	    }
         }
       else
-	nextsectaddr = min (nextsectaddr, p->addr);
+	nextsectaddr = min (nextsectaddr, p_addr);
     }
 
   if (nextsectaddr >= memend)
Index: binutils-quilt/src/gdb/cli/cli-dump.c
===================================================================
--- binutils-quilt.orig/src/gdb/cli/cli-dump.c	2007-07-23 18:59:51.000000000 +0100
+++ binutils-quilt/src/gdb/cli/cli-dump.c	2007-07-23 19:00:34.000000000 +0100
@@ -462,6 +462,8 @@
   bfd_vma sec_end    = sec_start + size;
   bfd_size_type sec_offset = 0;
   bfd_size_type sec_load_count = size;
+  int addr_bit = gdbarch_addr_bit (current_gdbarch);
+  CORE_ADDR addr_mask;
   struct cleanup *old_chain;
   gdb_byte *buf;
   int ret;
@@ -470,9 +472,17 @@
   if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD))
     return;
 
-  /* Does the section overlap with the desired restore range? */
-  if (sec_end <= data->load_start 
-      || (data->load_end > 0 && sec_start >= data->load_end))
+  /* Only match address bits which are significant
+     for the current architecture.  */
+  if (addr_bit < sizeof (CORE_ADDR) * HOST_CHAR_BIT)
+    addr_mask = ((CORE_ADDR) 1 << addr_bit) - 1;
+  else
+    addr_mask = ~(CORE_ADDR) 0;
+
+  /* Does the section overlap with the desired restore range?  */
+  if (sec_end <= (data->load_start & addr_mask)
+      || ((data->load_end & addr_mask) > 0
+	  && sec_start >= (data->load_end & addr_mask)))
     {
       /* No, no useable data in this section. */
       printf_filtered (_("skipping section %s...\n"), 
@@ -483,11 +493,11 @@
   /* Compare section address range with user-requested
      address range (if any).  Compute where the actual
      transfer should start and end.  */
-  if (sec_start < data->load_start)
+  if (sec_start < (data->load_start & addr_mask))
     sec_offset = data->load_start - sec_start;
   /* Size of a partial transfer: */
   sec_load_count -= sec_offset;
-  if (data->load_end > 0 && sec_end > data->load_end)
+  if (data->load_end > 0 && sec_end > (data->load_end & addr_mask))
     sec_load_count -= sec_end - data->load_end;
 
   /* Get the data.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]