This is the mail archive of the gdb-patches@sources.redhat.com 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]

[PATCH]: memory region attributes


Since these changes have been on the table for a few months with no
objections, I'm going to use my newfound status to commit them.

This shouldn't cause any problems or undue overhead when no memory
regions are defined.  In the past, I've run this through the test-
suite with no regressions.

Within a week or so, I'll be proposing a remote protocol/remote.c
change to support the memory access width attribute.

        --jtc

2001-01-23  J.T. Conklin  <jtc@redback.com>

	* exec.c (xfer_memory): Add attrib argument.
	* infptrace.c (child_xfer_memory): Likewise.
	* monitor.c (monitor_xfer_memory): Likewise.
	* remote-adapt.c (adapt_xfer_inferior_memory): Likewise.
	* remote-array.c (array_xfer_memory): Likewise.
	* remote-bug.c (bug_xfer_memory): Likewise.
	* remote-e7000.c (e7000_xfer_inferior_memory): Likewise.
	* remote-eb.c (eb_xfer_inferior_memory): Likewise.
	* remote-es.c (es1800_xfer_inferior_memory): Likewise.
	* remote-mips.c (mips_xfer_memory): Likewise.
	* remote-mm.c (mm_xfer_inferior_memory): Likewise.
	* remote-nindy.c (nindy_xfer_inferior_memory): Likewise.
	* remote-os9k.c (rombug_xfer_inferior_memory): Likewise.
	* remote-rdi.c (arm_rdi_xfer_memory): Likewise.
	* remote-rdp.c (remote_rdp_xfer_inferior_memory): Likewise.
	* remote-sds.c (sds_xfer_memory): Likewise.
	* remote-sim.c (gdbsim_xfer_inferior_memory): Likewise.
	* remote-st.c (st2000_xfer_inferior_memory): Likewise.
	* remote-udi.c (udi_xfer_inferior_memory): Likewise.
	* remote-vx.c (vx_xfer_memory): Likewise.
	* remote.c (remote_xfer_memory): Likewise.
	* target.c (debug_to_xfer_memory, do_xfer_memory): Likewise.
	* target.h (child_xfer_memory, do_xfer_memory, xfer_memory): Likewise.

	* target.h (#include "memattr.h"): Added.
	(target_ops.to_xfer_memory): Add attrib argument.

	* wince.c (_initialize_inftarg): Removed call to set_dcache_state.
	* dcache.h (set_dcache_state): Removed declaration.
	* dcache.c (set_dcache_state): Removed definition
	
	* dcache.c: Update module comment, as dcache is now enabled and
 	disabled with memory region attributes instead of by the global
 	variable "remotecache".  Add comment describing the interaction
	between dcache and memory region attributes.
	(dcache_xfer_memory): Add comment describing benefits of moving
	cache writeback to a higher level.
	(dcache_struct): Removed cache_has_stuff field.  This was used to
 	record whether the cache had been accessed in order to invalidate
 	it when it was disabled.  However, this is not needed because the
 	cache is write through and the code that enables, disables, and
 	deletes memory regions invalidate the cache.  Add comment which
 	suggests that we could be more selective and only invalidate those
	cache lines containing data from those memory regions.
	(dcache_invalidate): Updated.
	(dcache_xfer_memory): Updated.
	
	(dcache_alloc): Don't abort() if dcache_enabled_p is clear.
	(dcache_xfer_memory): Removed code that called do_xfer_memory() to
 	perform a uncached transfer if dcache_enabled_p was clear.  This
 	function is now only called if caching is enabled for the memory
	region.
	(dcache_info): Always print cache info.

	* target.c (do_xfer_memory): Add attrib argument.
	(target_xfer_memory, target_xfer_memory_partial): Break transfer
 	into chunks defined by memory regions, pass region attributes to
 	do_xfer_memory().
	* dcache.c (dcache_read_line, dcache_write_line): Likewise.

	* Makefile.in (SFILES): Add memattr.c.
	(COMMON_OBS): Add memattr.o.
	(dcache.o): Add target.h to dependencies.
	* memattr.c: New file.
	* memattr.h: Likewise.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.57
diff -c -r1.57 Makefile.in
*** Makefile.in	2001/01/08 12:47:49	1.57
--- Makefile.in	2001/01/23 19:54:01
***************
*** 1,5 ****
  # Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
! # 1998, 1999, 2000 Free Software Foundation, Inc.
  
  # This file is part of GDB.
  
--- 1,5 ----
  # Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
! # 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  
  # This file is part of GDB.
  
***************
*** 521,527 ****
  	varobj.c wrapper.c \
  	jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
  	m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
! 	mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
  	p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c \
  	printcmd.c remote.c remote-nrom.c scm-exp.c scm-lang.c \
  	scm-valprint.c source.c stabsread.c stack.c symfile.c \
--- 521,527 ----
  	varobj.c wrapper.c \
  	jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
  	m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
! 	memattr.c mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
  	p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c \
  	printcmd.c remote.c remote-nrom.c scm-exp.c scm-lang.c \
  	scm-valprint.c source.c stabsread.c stack.c symfile.c \
***************
*** 664,670 ****
  	expprint.o environ.o stack.o thread.o \
  	event-loop.o event-top.o inf-loop.o completer.o \
  	gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
! 	mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
  	kod.o kod-cisco.o \
  	gdb-events.o \
  	exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
--- 664,670 ----
  	expprint.o environ.o stack.o thread.o \
  	event-loop.o event-top.o inf-loop.o completer.o \
  	gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
! 	memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
  	kod.o kod-cisco.o \
  	gdb-events.o \
  	exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
***************
*** 1288,1294 ****
  cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
  	$(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h
  
! dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h $(gdbcore_h)
  
  dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
  	complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
--- 1288,1295 ----
  cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
  	$(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h
  
! dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h \
! 	$(gdbcore_h) target.h
  
  dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
  	complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.11
diff -c -r1.11 dcache.c
*** dcache.c	2000/12/15 01:01:46	1.11
--- dcache.c	2001/01/23 19:54:12
***************
*** 1,5 ****
  /* Caching code.
!    Copyright 1992-1993, 1995, 1998-1999, 2000 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* Caching code.
!    Copyright 1992-1993, 1995, 1998-1999, 2000, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 25,39 ****
  #include "gdbcore.h"
  #include "target.h"
  
! /* 
!    The data cache could lead to incorrect results because it doesn't know
!    about volatile variables, thus making it impossible to debug
!    functions which use memory mapped I/O devices.
  
-    set remotecache 0
- 
-    In those cases.
- 
     In general the dcache speeds up performance, some speed improvement
     comes from the actual caching mechanism, but the major gain is in
     the reduction of the remote protocol overhead; instead of reading
--- 25,35 ----
  #include "gdbcore.h"
  #include "target.h"
  
! /* The data cache could lead to incorrect results because it doesn't
!    know about volatile variables, thus making it impossible to debug
!    functions which use memory mapped I/O devices.  Set the nocache
!    memory region attribute in those cases.
  
     In general the dcache speeds up performance, some speed improvement
     comes from the actual caching mechanism, but the major gain is in
     the reduction of the remote protocol overhead; instead of reading
***************
*** 61,70 ****
  
     ENTRY_DIRTY means that the byte has some data in it which should be
     written out to the remote target one day, but contains correct
!    data.  ENTRY_OK means that the data is the same in the cache as it
!    is in remote memory.
  
  
     The ENTRY_DIRTY state is necessary because GDB likes to write large
     lumps of memory in small bits.  If the caching mechanism didn't
     maintain the DIRTY information, then something like a two byte
--- 57,68 ----
  
     ENTRY_DIRTY means that the byte has some data in it which should be
     written out to the remote target one day, but contains correct
!    data.
  
+    ENTRY_OK means that the data is the same in the cache as it is in
+    remote memory.
  
+ 
     The ENTRY_DIRTY state is necessary because GDB likes to write large
     lumps of memory in small bits.  If the caching mechanism didn't
     maintain the DIRTY information, then something like a two byte
***************
*** 76,85 ****
     protocol overhead.  This way, all those little writes are bundled
     up into an entire cache line write in one go, without having to
     read the cache line in the first place.
- 
- 
   */
  
  
  /* This value regulates the number of cache blocks stored.
     Smaller values reduce the time spent searching for a cache
--- 74,95 ----
     protocol overhead.  This way, all those little writes are bundled
     up into an entire cache line write in one go, without having to
     read the cache line in the first place.
   */
  
+ /* NOTE: Interaction of dcache and memory region attributes
+ 
+    As there is no requirement that memory region attributes be aligned
+    to or be a multiple of the dcache page size, dcache_read_line() and
+    dcache_write_line() must break up the page by memory region.  If a
+    chunk does not have the cache attribute set, an invalid memory type
+    is set, etc., then the chunk is skipped.  Those chunks are handled
+    in target_xfer_memory() (or target_xfer_memory_partial()).
+ 
+    This doesn't occur very often.  The most common occurance is when
+    the last bit of the .text segment and the first bit of the .data
+    segment fall within the same dcache page with a ro/cacheable memory
+    region defined for the .text segment and a rw/non-cacheable memory
+    region defined for the .data segment. */
  
  /* This value regulates the number of cache blocks stored.
     Smaller values reduce the time spent searching for a cache
***************
*** 123,128 ****
--- 133,151 ----
    };
  
  
+ /* FIXME: dcache_struct used to have a cache_has_stuff field that was
+    used to record whether the cache had been accessed.  This was used
+    to invalidate the cache whenever caching was (re-)enabled (if the
+    cache was disabled and later re-enabled, it could contain stale
+    data).  This was not needed because the cache is write through and
+    the code that enables, disables, and deletes memory region all
+    invalidate the cache.
+ 
+    This is overkill, since it also invalidates cache lines from
+    unrelated regions.  One way this could be addressed by adding a
+    new function that takes an address and a length and invalidates
+    only those cache lines that match. */
+ 
  struct dcache_struct
    {
      /* free list */
***************
*** 135,145 ****
  
      /* The cache itself. */
      struct dcache_block *the_cache;
- 
-     /* potentially, if the cache was enabled, and then turned off, and
-        then turned on again, the stuff in it could be stale, so this is
-        used to mark it */
-     int cache_has_stuff;
    };
  
  static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
--- 158,163 ----
***************
*** 189,196 ****
        db->p = 0;
      }
  
-   dcache->cache_has_stuff = 0;
- 
    return;
  }
  
--- 207,212 ----
***************
*** 224,262 ****
  static int
  dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
  {
!   int s;
!   int e;
  
!   if (db->anydirty)
      {
!       for (s = 0; s < LINE_SIZE; s++)
  	{
! 	  if (db->state[s] == ENTRY_DIRTY)
  	    {
! 	      int len = 0;
! 	      for (e = s; e < LINE_SIZE; e++, len++)
! 		if (db->state[e] != ENTRY_DIRTY)
! 		  break;
! 	      {
! 		/* all bytes from s..s+len-1 need to
! 		   be written out */
! 		int done = 0;
! 		while (done < len)
! 		  {
! 		    int t = do_xfer_memory (db->addr + s + done,
! 					    db->data + s + done,
! 					    len - done, 1);
! 		    if (t <= 0)
! 		      return 0;
! 		    done += t;
! 		  }
! 		memset (db->state + s, ENTRY_OK, len);
! 		s = e;
! 	      }
  	    }
  	}
-       db->anydirty = 0;
      }
    return 1;
  }
  
--- 240,314 ----
  static int
  dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
  {
!   CORE_ADDR memaddr;
!   char *myaddr;
!   int len;
!   int res;
!   int reg_len;
!   struct mem_region *region;
  
!   if (!db->anydirty)
!     return 1;
! 
!   len = LINE_SIZE;
!   memaddr = db->addr;
!   myaddr  = db->data;
! 
!   while (len > 0)
      {
!       int s;
!       int e;
!       int dirty_len;
!       
!       region = lookup_mem_region(memaddr);
!       if (memaddr + len < region->hi)
! 	reg_len = len;
!       else
! 	reg_len = region->hi - memaddr;
! 
!       if (!region->attrib.cache || region->attrib.mode == MEM_RO)
  	{
! 	  memaddr += reg_len;
! 	  myaddr  += reg_len;
! 	  len     -= reg_len;
! 	  continue;
! 	}
! 
!       while (reg_len > 0)
! 	{
! 	  s = XFORM(memaddr);
! 	  do {
! 	    if (db->state[s] == ENTRY_DIRTY)
! 	      break;
! 	    s++;
! 	    reg_len--;
! 	  } while (reg_len > 0);
! 
! 	  e = s;
! 	  do {
! 	    if (db->state[e] != ENTRY_DIRTY)
! 	      break;
! 	    e++;
! 	    reg_len--;
! 	  } while (reg_len > 0);
! 
! 	  dirty_len = e - s;
! 	  while (dirty_len > 0)
  	    {
! 	      res = do_xfer_memory(memaddr, myaddr, dirty_len, 1,
! 				   &region->attrib);
! 	      if (res <= 0)
! 		return 0;
! 
! 	      memset (db->state[XFORM(memaddr)], ENTRY_OK, res);
! 	      memaddr   += res;
! 	      myaddr    += res;
! 	      dirty_len -= res;
  	    }
  	}
      }
+ 
+   db->anydirty = 0;
    return 1;
  }
  
***************
*** 268,273 ****
--- 320,327 ----
    char *myaddr;
    int len;
    int res;
+   int reg_len;
+   struct mem_region *region;
  
    /* If there are any dirty bytes in the line, it must be written
       before a new line can be read */
***************
*** 283,295 ****
  
    while (len > 0)
      {
!       res = do_xfer_memory (memaddr, myaddr, len, 0);
!       if (res <= 0)
! 	return 0;
  
!       memaddr += res;
!       myaddr  += res;
!       len     -= res;
      }
  
    memset (db->state, ENTRY_OK, sizeof (db->data));
--- 337,368 ----
  
    while (len > 0)
      {
!       region = lookup_mem_region(memaddr);
!       if (memaddr + len < region->hi)
! 	reg_len = len;
!       else
! 	reg_len = region->hi - memaddr;
! 
!       if (!region->attrib.cache || region->attrib.mode == MEM_WO)
! 	{
! 	  memaddr += reg_len;
! 	  myaddr  += reg_len;
! 	  len     -= reg_len;
! 	  continue;
! 	}
!       
!       while (reg_len > 0)
! 	{
! 	  res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
! 				&region->attrib);
! 	  if (res <= 0)
! 	    return 0;
  
! 	  memaddr += res;
! 	  myaddr  += res;
! 	  len     -= res;
! 	  reg_len -= res;
! 	}
      }
  
    memset (db->state, ENTRY_OK, sizeof (db->data));
***************
*** 306,314 ****
  {
    register struct dcache_block *db;
  
-   if (dcache_enabled_p == 0)
-     abort ();
- 
    /* Take something from the free list */
    db = dcache->free_head;
    if (db)
--- 379,384 ----
***************
*** 342,348 ****
    return db;
  }
  
! /* Writeback any dirty lines to the remote. */
  static int
  dcache_writeback (DCACHE *dcache)
  {
--- 412,418 ----
    return db;
  }
  
! /* Writeback any dirty lines. */
  static int
  dcache_writeback (DCACHE *dcache)
  {
***************
*** 452,481 ****
  		    int should_write)
  {
    int i;
  
!   if (dcache_enabled_p)
      {
!       int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
!       xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
! 
!       for (i = 0; i < len; i++)
! 	{
! 	  if (!xfunc (dcache, memaddr + i, myaddr + i))
! 	    return 0;
! 	}
! 
!       if (should_write)
! 	dcache_writeback (dcache);
! 
!       dcache->cache_has_stuff = 1;
      }
-   else
-     {
-       if (dcache->cache_has_stuff)
- 	dcache_invalidate (dcache);
  
!       len = do_xfer_memory(memaddr, myaddr, len, should_write);
!     }
    return len;
  }
  
--- 522,548 ----
  		    int should_write)
  {
    int i;
+   int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+   xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
  
!   for (i = 0; i < len; i++)
      {
!       if (!xfunc (dcache, memaddr + i, myaddr + i))
! 	return 0;
      }
  
!   /* FIXME: There may be some benefit from moving the cache writeback
!      to a higher layer, as it could occur after a sequence of smaller
!      writes have been completed (as when a stack frame is constructed
!      for an inferior function call).  Note that only moving it up one
!      level to target_xfer_memory() (also target_xfer_memory_partial())
!      is not sufficent, since we want to coalesce memory transfers that
!      are "logically" connected but not actually a single call to one
!      of the memory transfer functions. */
! 
!   if (should_write)
!     dcache_writeback (dcache);
!     
    return len;
  }
  
***************
*** 484,495 ****
  {
    struct dcache_block *p;
  
!   if (!dcache_enabled_p)
!     {
!       printf_filtered ("Dcache not enabled\n");
!       return;
!     }
!   printf_filtered ("Dcache enabled, line width %d, depth %d\n",
  		   LINE_SIZE, DCACHE_SIZE);
  
    if (last_cache)
--- 551,557 ----
  {
    struct dcache_block *p;
  
!   printf_filtered ("Dcache line width %d, depth %d\n",
  		   LINE_SIZE, DCACHE_SIZE);
  
    if (last_cache)
***************
*** 511,523 ****
  	  printf_filtered ("\n");
  	}
      }
- }
- 
- /* Turn dcache on or off. */
- void
- set_dcache_state (int what)
- {
-   dcache_enabled_p = !!what;
  }
  
  void
--- 573,578 ----
Index: dcache.h
===================================================================
RCS file: /cvs/src/src/gdb/dcache.h,v
retrieving revision 1.6
diff -c -r1.6 dcache.h
*** dcache.h	2000/11/03 22:00:56	1.6
--- dcache.h	2001/01/23 19:54:14
***************
*** 1,7 ****
  /* Declarations for caching.  Typically used by remote back ends for
     caching remote memory.
  
!    Copyright 1992, 1993 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,7 ----
  /* Declarations for caching.  Typically used by remote back ends for
     caching remote memory.
  
!    Copyright 1992, 1993, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 38,45 ****
  
  int dcache_xfer_memory (DCACHE *cache, CORE_ADDR mem, char *my, int len,
  			int should_write);
- 
- /* Turn dcache state on or off */
- void set_dcache_state (int);
  
  #endif /* DCACHE_H */
--- 38,42 ----
Index: exec.c
===================================================================
RCS file: /cvs/src/src/gdb/exec.c,v
retrieving revision 1.8
diff -c -r1.8 exec.c
*** exec.c	2000/12/15 01:01:46	1.8
--- exec.c	2001/01/23 19:54:19
***************
*** 1,5 ****
  /* Work with executable files, for GDB. 
!    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998
     Free Software Foundation, Inc.
  
     This file is part of GDB.
--- 1,5 ----
  /* Work with executable files, for GDB. 
!    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998, 2001
     Free Software Foundation, Inc.
  
     This file is part of GDB.
***************
*** 449,454 ****
--- 449,455 ----
  
  int
  xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ 	     struct mem_attrib *attrib,
  	     struct target_ops *target)
  {
    boolean res;
Index: infptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/infptrace.c,v
retrieving revision 1.6
diff -c -r1.6 infptrace.c
*** infptrace.c	2000/09/09 01:38:49	1.6
--- infptrace.c	2001/01/23 19:54:20
***************
*** 1,5 ****
  /* Low level Unix child interface to ptrace, for GDB when running under Unix.
!    Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998 
     Free Software Foundation, Inc.
  
     This file is part of GDB.
--- 1,5 ----
  /* Low level Unix child interface to ptrace, for GDB when running under Unix.
!    Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998, 2001 
     Free Software Foundation, Inc.
  
     This file is part of GDB.
***************
*** 511,516 ****
--- 511,517 ----
  
  int
  child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ 		   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
  		   struct target_ops *target)
  {
    register int i;
Index: memattr.c
===================================================================
RCS file: memattr.c
diff -N memattr.c
*** /dev/null	Tue May  5 13:32:27 1998
--- memattr.c	Tue Jan 23 11:54:21 2001
***************
*** 0 ****
--- 1,497 ----
+ /* memattr.c */
+ #include "defs.h"
+ #include "command.h"
+ #include "gdbcmd.h"
+ #include "memattr.h"
+ #include "target.h"
+ #include "value.h"
+ #include "language.h"
+ #include "gdb_string.h"
+ 
+ /* FIXME: While this conflicts with the enum defined in breakpoint.h,
+    I used them to be consistant with how breakpoints, tracepoints, and
+    displays are implemented.  It doesn't lose now because breakpoint.h
+    is not included.  */
+ enum enable
+ {
+   disabled,
+   enabled
+ };
+ 
+ const struct mem_attrib default_mem_attrib =
+ {
+   MEM_RW,			/* mode */
+   MEM_WIDTH_UNSPECIFIED,
+   false,			/* hwbreak */
+   false,			/* cache */
+   false				/* verify */
+ };
+ 
+ static struct mem_region *mem_region_chain = NULL;
+ static mem_number = 0;
+ 
+ static struct mem_region *
+ create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
+ 		   const struct mem_attrib *attrib)
+ {
+   struct mem_region *n, *p, *new;
+ 
+   if (lo > hi)
+     {
+       printf_unfiltered ("invalid memory region\n");
+       return NULL;
+     }
+ 
+   n = mem_region_chain;
+   while (n)
+     {
+       /* overlapping node */
+       if ((lo >= n->lo && lo <= n->hi) ||
+ 	  (hi >= n->lo && hi <= n->hi))
+ 	{
+ 	  printf_unfiltered ("overlapping memory region\n");
+ 	  return NULL;
+ 	}
+     }
+ 
+   new = xmalloc (sizeof (struct mem_region));
+   new->lo = lo;
+   new->hi = hi;
+   new->number = ++mem_number;
+   new->status = enabled;
+   new->attrib = *attrib;
+ 
+   /* link in new node */
+   new->next = mem_region_chain;
+   mem_region_chain = new;
+ 
+   return new;
+ }
+ 
+ static void
+ delete_mem_region (struct mem_region *m)
+ {
+   free (m);
+ }
+ 
+ /*
+  * Look up the memory region cooresponding to ADDR.
+  */
+ struct mem_region *
+ lookup_mem_region (CORE_ADDR addr)
+ {
+   static struct mem_region region;
+   struct mem_region *m;
+   CORE_ADDR lo;
+   CORE_ADDR hi;
+ 
+   /* First we initialize LO and HI so that they describe the entire
+      memory space.  As we process the memory region chain, they are
+      redefined to describe the minimal region containing ADDR.  LO
+      and HI are used in the case where no memory region is defined
+      that contains ADDR.  If a memory region is disabled, it is
+      treated as if it does not exist.  */
+ 
+   lo = (CORE_ADDR) 0;
+   hi = (CORE_ADDR) ~ 0;
+ 
+   for (m = mem_region_chain; m; m = m->next)
+     {
+       if (m->status == enabled)
+ 	{
+ 	  if (addr >= m->lo && addr < m->hi)
+ 	    return m;
+ 
+ 	  if (addr >= m->hi && lo < m->hi)
+ 	    lo = m->hi;
+ 
+ 	  if (addr <= m->lo && hi > m->lo)
+ 	    hi = m->lo;
+ 	}
+     }
+ 
+   /* Because no region was found, we must cons up one based on what
+      was learned above.  */
+   region.lo = lo;
+   region.hi = hi;
+   region.attrib = default_mem_attrib;
+   return &region;
+ }
+ 
+ 
+ static void
+ mem_command (char *args, int from_tty)
+ {
+   CORE_ADDR lo, hi;
+   char *tok;
+   struct mem_attrib attrib;
+ 
+   if (!args)
+     error_no_arg ("No mem");
+ 
+   tok = strtok (args, " \t");
+   if (!tok)
+     error ("no lo address");
+   lo = parse_and_eval_address (tok);
+ 
+   tok = strtok (NULL, " \t");
+   if (!tok)
+     error ("no hi address");
+   hi = parse_and_eval_address (tok);
+ 
+   attrib = default_mem_attrib;
+   while ((tok = strtok (NULL, " \t")) != NULL)
+     {
+       if (strcmp (tok, "rw") == 0)
+ 	attrib.mode = MEM_RW;
+       else if (strcmp (tok, "ro") == 0)
+ 	attrib.mode = MEM_RO;
+       else if (strcmp (tok, "wo") == 0)
+ 	attrib.mode = MEM_WO;
+ 
+       else if (strcmp (tok, "8") == 0)
+ 	attrib.width = MEM_WIDTH_8;
+       else if (strcmp (tok, "16") == 0)
+ 	{
+ 	  if ((lo % 2 != 0) || (hi % 2 != 0))
+ 	    error ("region bounds not 16 bit aligned");
+ 	  attrib.width = MEM_WIDTH_16;
+ 	}
+       else if (strcmp (tok, "32") == 0)
+ 	{
+ 	  if ((lo % 4 != 0) || (hi % 4 != 0))
+ 	    error ("region bounds not 32 bit aligned");
+ 	  attrib.width = MEM_WIDTH_32;
+ 	}
+       else if (strcmp (tok, "64") == 0)
+ 	{
+ 	  if ((lo % 8 != 0) || (hi % 8 != 0))
+ 	    error ("region bounds not 64 bit aligned");
+ 	  attrib.width = MEM_WIDTH_64;
+ 	}
+ 
+ #if 0
+       else if (strcmp (tok, "hwbreak") == 0)
+ 	attrib.hwbreak = true;
+       else if (strcmp (tok, "swbreak") == 0)
+ 	attrib.hwbreak = false;
+ #endif
+ 
+       else if (strcmp (tok, "cache") == 0)
+ 	attrib.cache = true;
+       else if (strcmp (tok, "nocache") == 0)
+ 	attrib.cache = false;
+ 
+ #if 0
+       else if (strcmp (tok, "verify") == 0)
+ 	attrib.verify = true;
+       else if (strcmp (tok, "noverify") == 0)
+ 	attrib.verify = false;
+ #endif
+ 
+       else
+ 	error ("unknown attribute: %s", tok);
+     }
+ 
+   create_mem_region (lo, hi, &attrib);
+ }
+ 
+ 
+ static void
+ mem_info_command (char *args, int from_tty)
+ {
+   struct mem_region *m;
+   struct mem_attrib *attrib;
+ 
+   if (!mem_region_chain)
+     {
+       printf_unfiltered ("There are no memory regions defined.\n");
+       return;
+     }
+ 
+   printf_filtered ("Memory regions now in effect:\n");
+   for (m = mem_region_chain; m; m = m->next)
+     {
+       printf_filtered ("%d: %c\t",
+ 		       m->number,
+ 		       m->status ? 'y' : 'n');
+       printf_filtered ("%s - ",
+ 		    local_hex_string_custom ((unsigned long) m->lo, "08l"));
+       printf_filtered ("%s\t",
+ 		    local_hex_string_custom ((unsigned long) m->hi, "08l"));
+ 
+       /* Print a token for each attribute.
+ 
+        * FIXME: Should we output a comma after each token?  It may
+        * make it easier for users to read, but we'd lose the ability
+        * to cut-and-paste the list of attributes when defining a new
+        * region.  Perhaps that is not important.
+        *
+        * FIXME: If more attributes are added to GDB, the output may
+        * become cluttered and difficult for users to read.  At that
+        * time, we may want to consider printing tokens only if they
+        * are different from the default attribute.  */
+ 
+       attrib = &m->attrib;
+       switch (attrib->mode)
+ 	{
+ 	case MEM_RW:
+ 	  printf_filtered ("rw ");
+ 	  break;
+ 	case MEM_RO:
+ 	  printf_filtered ("ro ");
+ 	  break;
+ 	case MEM_WO:
+ 	  printf_filtered ("wo ");
+ 	  break;
+ 	}
+ 
+       switch (attrib->width)
+ 	{
+ 	case MEM_WIDTH_8:
+ 	  printf_filtered ("8 ");
+ 	  break;
+ 	case MEM_WIDTH_16:
+ 	  printf_filtered ("16 ");
+ 	  break;
+ 	case MEM_WIDTH_32:
+ 	  printf_filtered ("32 ");
+ 	  break;
+ 	case MEM_WIDTH_64:
+ 	  printf_filtered ("64 ");
+ 	  break;
+ 	case MEM_WIDTH_UNSPECIFIED:
+ 	  break;
+ 	}
+ 
+ #if 0
+       if (attrib->hwbreak)
+ 	printf_filtered ("hwbreak");
+       else
+ 	printf_filtered ("swbreak");
+ #endif
+ 
+       if (attrib->cache)
+ 	printf_filtered ("cache ");
+       else
+ 	printf_filtered ("nocache ");
+ 
+ #if 0
+       if (attrib->verify)
+ 	printf_filtered ("verify ");
+       else
+ 	printf_filtered ("noverify ");
+ #endif
+ 
+       printf_filtered ("\n");
+ 
+       gdb_flush (gdb_stdout);
+     }
+ }
+ 
+ 
+ /* Enable the memory region number NUM. */
+ 
+ static void
+ mem_enable (int num)
+ {
+   struct mem_region *m;
+ 
+   for (m = mem_region_chain; m; m = m->next)
+     if (m->number == num)
+       {
+ 	m->status = enabled;
+ 	return;
+       }
+   printf_unfiltered ("No memory region number %d.\n", num);
+ }
+ 
+ static void
+ mem_enable_command (char *args, int from_tty)
+ {
+   char *p = args;
+   char *p1;
+   int num;
+   struct mem_region *m;
+ 
+   dcache_invalidate (target_dcache);
+ 
+   if (p == 0)
+     {
+       for (m = mem_region_chain; m; m = m->next)
+ 	m->status = enabled;
+     }
+   else
+     while (*p)
+       {
+ 	p1 = p;
+ 	while (*p1 >= '0' && *p1 <= '9')
+ 	  p1++;
+ 	if (*p1 && *p1 != ' ' && *p1 != '\t')
+ 	  error ("Arguments must be memory region numbers.");
+ 
+ 	num = atoi (p);
+ 	mem_enable (num);
+ 
+ 	p = p1;
+ 	while (*p == ' ' || *p == '\t')
+ 	  p++;
+       }
+ }
+ 
+ 
+ /* Disable the memory region number NUM. */
+ 
+ static void
+ mem_disable (int num)
+ {
+   struct mem_region *m;
+ 
+   for (m = mem_region_chain; m; m = m->next)
+     if (m->number == num)
+       {
+ 	m->status = disabled;
+ 	return;
+       }
+   printf_unfiltered ("No memory region number %d.\n", num);
+ }
+ 
+ static void
+ mem_disable_command (char *args, int from_tty)
+ {
+   char *p = args;
+   char *p1;
+   int num;
+   struct mem_region *m;
+ 
+   dcache_invalidate (target_dcache);
+ 
+   if (p == 0)
+     {
+       for (m = mem_region_chain; m; m = m->next)
+ 	m->status = disabled;
+     }
+   else
+     while (*p)
+       {
+ 	p1 = p;
+ 	while (*p1 >= '0' && *p1 <= '9')
+ 	  p1++;
+ 	if (*p1 && *p1 != ' ' && *p1 != '\t')
+ 	  error ("Arguments must be memory region numbers.");
+ 
+ 	num = atoi (p);
+ 	mem_disable (num);
+ 
+ 	p = p1;
+ 	while (*p == ' ' || *p == '\t')
+ 	  p++;
+       }
+ }
+ 
+ /* Clear memory region list */
+ 
+ static void
+ mem_clear (void)
+ {
+   struct mem_region *m;
+ 
+   while ((m = mem_region_chain) != 0)
+     {
+       mem_region_chain = m->next;
+       delete_mem_region (m);
+     }
+ }
+ 
+ /* Delete the memory region number NUM. */
+ 
+ static void
+ mem_delete (int num)
+ {
+   struct mem_region *m1, *m;
+ 
+   if (!mem_region_chain)
+     {
+       printf_unfiltered ("No memory region number %d.\n", num);
+       return;
+     }
+ 
+   if (mem_region_chain->number == num)
+     {
+       m1 = mem_region_chain;
+       mem_region_chain = m1->next;
+       delete_mem_region (m1);
+     }
+   else
+     for (m = mem_region_chain; m->next; m = m->next)
+       {
+ 	if (m->next->number == num)
+ 	  {
+ 	    m1 = m->next;
+ 	    m->next = m1->next;
+ 	    delete_mem_region (m1);
+ 	    break;
+ 	  }
+       }
+ }
+ 
+ static void
+ mem_delete_command (char *args, int from_tty)
+ {
+   char *p = args;
+   char *p1;
+   int num;
+ 
+   dcache_invalidate (target_dcache);
+ 
+   if (p == 0)
+     {
+       if (query ("Delete all memory regions? "))
+ 	mem_clear ();
+       dont_repeat ();
+       return;
+     }
+ 
+   while (*p)
+     {
+       p1 = p;
+       while (*p1 >= '0' && *p1 <= '9')
+ 	p1++;
+       if (*p1 && *p1 != ' ' && *p1 != '\t')
+ 	error ("Arguments must be memory region numbers.");
+ 
+       num = atoi (p);
+       mem_delete (num);
+ 
+       p = p1;
+       while (*p == ' ' || *p == '\t')
+ 	p++;
+     }
+ 
+   dont_repeat ();
+ }
+ 
+ void
+ _initialize_mem ()
+ {
+   add_com ("mem", class_vars, mem_command,
+ 	   "Define attributes for memory region.");
+ 
+   add_cmd ("mem", class_vars, mem_enable_command,
+ 	   "Enable memory region.\n\
+ Arguments are the code numbers of the memory regions to enable.\n\
+ Do \"info mem\" to see current list of code numbers.", &enablelist);
+ 
+   add_cmd ("mem", class_vars, mem_disable_command,
+ 	   "Disable memory region.\n\
+ Arguments are the code numbers of the memory regions to disable.\n\
+ Do \"info mem\" to see current list of code numbers.", &disablelist);
+ 
+   add_cmd ("mem", class_vars, mem_delete_command,
+ 	   "Delete memory region.\n\
+ Arguments are the code numbers of the memory regions to delete.\n\
+ Do \"info mem\" to see current list of code numbers.", &deletelist);
+ 
+   add_info ("mem", mem_info_command,
+ 	    "Memory region attributes");
+ }
Index: memattr.h
===================================================================
RCS file: memattr.h
diff -N memattr.h
*** /dev/null	Tue May  5 13:32:27 1998
--- memattr.h	Tue Jan 23 11:54:21 2001
***************
*** 0 ****
--- 1,72 ----
+ /* memattr.h */
+ #ifndef MEMATTR_H
+ #define MEMATTR_H
+ 
+ enum mem_access_mode
+ {
+   MEM_RW,			/* read/write */
+   MEM_RO,			/* read only */
+   MEM_WO,			/* write only */
+ };
+ 
+ enum mem_access_width
+ {
+   MEM_WIDTH_UNSPECIFIED,
+   MEM_WIDTH_8,			/*  8 bit accesses */
+   MEM_WIDTH_16,			/* 16  "      "    */
+   MEM_WIDTH_32,			/* 32  "      "    */
+   MEM_WIDTH_64			/* 64  "      "    */
+ };
+ 
+ /* The set of all attributes that can be set for a memory region.
+   
+    This structure was created so that memory attributes can be passed
+    to target_ functions without exposing the details of memory region
+    list, which would be necessary if these fields were simply added to
+    the mem_region structure.
+ 
+    FIXME: It would be useful if there was a mechanism for targets to
+    add their own attributes.  For example, the number of wait states. */
+  
+ struct mem_attrib 
+ {
+   /* read/write, read-only, or write-only */
+   enum mem_access_mode mode;
+ 
+   enum mem_access_width width;
+ 
+   /* enables hardware breakpoints */
+   int hwbreak;
+   
+   /* enables host-side caching of memory region data */
+   int cache;
+   
+   /* enables memory verification.  after a write, memory is re-read
+      to verify that the write was successful. */
+   int verify; 
+ };
+ 
+ struct mem_region 
+ {
+   /* FIXME: memory regions are stored in an unsorted singly-linked
+      list.  This probably won't scale to handle hundreds of memory
+      regions --- that many could be needed to describe the allowed
+      access modes for memory mapped i/o device registers. */
+   struct mem_region *next;
+   
+   CORE_ADDR lo;
+   CORE_ADDR hi;
+ 
+   /* Item number of this memory region. */
+   int number;
+ 
+   /* Status of this memory region (enabled or disabled) */
+   int status;
+ 
+   /* Attributes for this region */
+   struct mem_attrib attrib;
+ };
+ 
+ extern struct mem_region *lookup_mem_region(CORE_ADDR);
+ 
+ #endif	/* MEMATTR_H */
Index: monitor.c
===================================================================
RCS file: /cvs/src/src/gdb/monitor.c,v
retrieving revision 1.15
diff -c -r1.15 monitor.c
*** monitor.c	2000/12/15 01:01:48	1.15
--- monitor.c	2001/01/23 19:54:23
***************
*** 1,5 ****
  /* Remote debugging interface for boot monitors, for GDB.
!    Copyright 1990-1993, 1995-1997, 1999-2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Rob Savoye for Cygnus.
     Resurrected from the ashes by Stu Grossman.
  
--- 1,5 ----
  /* Remote debugging interface for boot monitors, for GDB.
!    Copyright 1990-1993, 1995-1997, 1999-2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Rob Savoye for Cygnus.
     Resurrected from the ashes by Stu Grossman.
  
***************
*** 77,83 ****
  static void monitor_store_registers (int regno);
  static void monitor_prepare_to_store (void);
  static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				int write, struct target_ops *target);
  static void monitor_files_info (struct target_ops *ops);
  static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow);
  static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow);
--- 77,85 ----
  static void monitor_store_registers (int regno);
  static void monitor_prepare_to_store (void);
  static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				int write, 
! 				struct mem_attrib *attrib,
! 				struct target_ops *target);
  static void monitor_files_info (struct target_ops *ops);
  static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow);
  static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow);
***************
*** 1988,1994 ****
  
  static int
  monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		     struct target_ops *target)
  {
    int res;
  
--- 1990,1997 ----
  
  static int
  monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-adapt.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-adapt.c,v
retrieving revision 1.6
diff -c -r1.6 remote-adapt.c
*** remote-adapt.c	2000/12/15 01:01:48	1.6
--- remote-adapt.c	2001/01/23 19:54:24
***************
*** 1,5 ****
  /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. 
!    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
     Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
     Adapted from work done at Cygnus Support in remote-eb.c.
  
--- 1,5 ----
  /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. 
!    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
     Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
     Adapted from work done at Cygnus Support in remote-eb.c.
  
***************
*** 1167,1173 ****
  
  /* FIXME!  Merge these two.  */
  int
! adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
  
    memaddr = translate_addr (memaddr);
--- 1167,1175 ----
  
  /* FIXME!  Merge these two.  */
  int
! adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			    struct target_ops *target ATTRIBUTE_UNUSED)
  {
  
    memaddr = translate_addr (memaddr);
Index: remote-array.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-array.c,v
retrieving revision 1.7
diff -c -r1.7 remote-array.c
*** remote-array.c	2000/10/02 00:49:55	1.7
--- remote-array.c	2001/01/23 19:54:33
***************
*** 1,5 ****
  /* Remote debugging interface for Array Tech RAID controller..
!    Copyright 90, 91, 92, 93, 94, 1995, 1998  Free Software Foundation, Inc.
     Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
  
     This module talks to a debug monitor called 'MONITOR', which
--- 1,5 ----
  /* Remote debugging interface for Array Tech RAID controller..
!    Copyright 90, 91, 92, 93, 94, 1995, 1998, 2001  Free Software Foundation, Inc.
     Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
  
     This module talks to a debug monitor called 'MONITOR', which
***************
*** 1026,1032 ****
  
  static int
  array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		   struct target_ops *target)
  {
    if (write)
      return array_write_inferior_memory (memaddr, myaddr, len);
--- 1026,1033 ----
  
  static int
  array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		   struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return array_write_inferior_memory (memaddr, myaddr, len);
Index: remote-bug.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-bug.c,v
retrieving revision 1.9
diff -c -r1.9 remote-bug.c
*** remote-bug.c	2000/12/15 01:01:48	1.9
--- remote-bug.c	2001/01/23 19:54:36
***************
*** 1,7 ****
  /* Remote debugging interface for Motorola's MVME187BUG monitor, an embedded
     monitor for the m88k.
  
!    Copyright 1992, 1993 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by K. Richard Pixley.
  
     This file is part of GDB.
--- 1,7 ----
  /* Remote debugging interface for Motorola's MVME187BUG monitor, an embedded
     monitor for the m88k.
  
!    Copyright 1992, 1993, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by K. Richard Pixley.
  
     This file is part of GDB.
***************
*** 555,561 ****
  
  int
  bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		 struct target_ops *target)
  {
    int res;
  
--- 555,562 ----
  
  int
  bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-e7000.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-e7000.c,v
retrieving revision 1.11
diff -c -r1.11 remote-e7000.c
*** remote-e7000.c	2000/12/02 11:37:15	1.11
--- remote-e7000.c	2001/01/23 19:54:39
***************
*** 1,5 ****
  /* Remote debugging interface for Hitachi E7000 ICE, for GDB
!    Copyright 1993, 1994, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support. 
  
     Written by Steve Chamberlain for Cygnus Support.
--- 1,5 ----
  /* Remote debugging interface for Hitachi E7000 ICE, for GDB
!    Copyright 1993, 1994, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support. 
  
     Written by Steve Chamberlain for Cygnus Support.
***************
*** 1474,1480 ****
  
  static int
  e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
! 			    int len, int write, struct target_ops *target)
  {
    if (write)
      return e7000_write_inferior_memory (memaddr, myaddr, len);
--- 1474,1482 ----
  
  static int
  e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
! 			    int len, int write, 
! 			    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			    struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return e7000_write_inferior_memory (memaddr, myaddr, len);
Index: remote-eb.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-eb.c,v
retrieving revision 1.6
diff -c -r1.6 remote-eb.c
*** remote-eb.c	2000/12/15 01:01:48	1.6
--- remote-eb.c	2001/01/23 19:54:40
***************
*** 1,5 ****
  /* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB.
!    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
  
     This file is part of GDB.
--- 1,5 ----
  /* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB.
!    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
  
     This file is part of GDB.
***************
*** 879,885 ****
  
  int
  eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			 struct target_ops *target)
  {
    if (write)
      return eb_write_inferior_memory (memaddr, myaddr, len);
--- 879,886 ----
  
  int
  eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return eb_write_inferior_memory (memaddr, myaddr, len);
Index: remote-es.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-es.c,v
retrieving revision 1.8
diff -c -r1.8 remote-es.c
*** remote-es.c	2001/01/19 08:01:46	1.8
--- remote-es.c	2001/01/23 19:54:42
***************
*** 1,5 ****
  /* Memory-access and commands for remote es1800 processes, for GDB.
!    Copyright (C) 1988, 1992 Free Software Foundation, Inc.
  
     This file is added to GDB to make it possible to do debugging via an
     ES-1800 emulator. The code was originally written by Johan Holmberg
--- 1,5 ----
  /* Memory-access and commands for remote es1800 processes, for GDB.
!    Copyright (C) 1988, 1992, 2001 Free Software Foundation, Inc.
  
     This file is added to GDB to make it possible to do debugging via an
     ES-1800 emulator. The code was originally written by Johan Holmberg
***************
*** 134,140 ****
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
! 			     struct target_ops *);
  
  static void es1800_prepare_to_store (void);
  
--- 134,140 ----
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
! 			     struct mem_attrib *, struct target_ops *);
  
  static void es1800_prepare_to_store (void);
  
***************
*** 959,965 ****
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *tops)
  {
    int origlen = len;
    int xfersize;
--- 959,967 ----
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int origlen = len;
    int xfersize;
Index: remote-mips.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-mips.c,v
retrieving revision 1.11
diff -c -r1.11 remote-mips.c
*** remote-mips.c	2000/12/15 01:01:48	1.11
--- remote-mips.c	2001/01/23 19:54:44
***************
*** 1,5 ****
  /* Remote debugging interface for MIPS remote debugging protocol.
!    Copyright 1993, 1994, 1995, 2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Ian Lance Taylor
     <ian@cygnus.com>.
  
--- 1,5 ----
  /* Remote debugging interface for MIPS remote debugging protocol.
!    Copyright 1993, 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Ian Lance Taylor
     <ian@cygnus.com>.
  
***************
*** 112,118 ****
  			    char *old_contents);
  
  static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *ignore);
  
  static void mips_files_info (struct target_ops *ignore);
  
--- 112,120 ----
  			    char *old_contents);
  
  static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib,
! 			     struct target_ops *target);
  
  static void mips_files_info (struct target_ops *ignore);
  
***************
*** 2069,2075 ****
  
  static int
  mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		  struct target_ops *ignore)
  {
    int i;
    CORE_ADDR addr;
--- 2071,2078 ----
  
  static int
  mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		  struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		  struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int i;
    CORE_ADDR addr;
Index: remote-mm.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-mm.c,v
retrieving revision 1.5
diff -c -r1.5 remote-mm.c
*** remote-mm.c	2000/12/15 01:01:48	1.5
--- remote-mm.c	2001/01/23 19:54:46
***************
*** 1,5 ****
  /* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
!    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
     Originally written by Daniel Mann at AMD.
  
     This file is part of GDB.
--- 1,5 ----
  /* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
!    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
     Originally written by Daniel Mann at AMD.
  
     This file is part of GDB.
***************
*** 1173,1179 ****
  
  /* FIXME!  Merge these two.  */
  static int
! mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
  
    memaddr = translate_addr (memaddr);
--- 1173,1181 ----
  
  /* FIXME!  Merge these two.  */
  static int
! mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			 struct target_ops *target ATTRIBUTE_UNUSED)
  {
  
    memaddr = translate_addr (memaddr);
Index: remote-nindy.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-nindy.c,v
retrieving revision 1.10
diff -c -r1.10 remote-nindy.c
*** remote-nindy.c	2000/12/15 01:01:49	1.10
--- remote-nindy.c	2001/01/23 19:54:46
***************
*** 1,5 ****
  /* Memory-access and commands for remote NINDY process, for GDB.
!    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
     Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
  
     GDB is distributed in the hope that it will be useful, but WITHOUT ANY
--- 1,5 ----
  /* Memory-access and commands for remote NINDY process, for GDB.
!    Copyright 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
     Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
  
     GDB is distributed in the hope that it will be useful, but WITHOUT ANY
***************
*** 476,482 ****
  
  int
  nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			    int should_write, struct target_ops *target)
  {
    int res;
  
--- 476,484 ----
  
  int
  nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			    int should_write, 
! 			    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			    struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-os9k.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-os9k.c,v
retrieving revision 1.7
diff -c -r1.7 remote-os9k.c
*** remote-os9k.c	2000/10/10 05:17:25	1.7
--- remote-os9k.c	2001/01/23 19:54:47
***************
*** 1,5 ****
  /* Remote debugging interface for boot monitors, for GDB.
!    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* Remote debugging interface for boot monitors, for GDB.
!    Copyright 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 826,832 ****
  
  static int
  rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (write)
      return rombug_write_inferior_memory (memaddr, myaddr, len);
--- 826,834 ----
  
  static int
  rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return rombug_write_inferior_memory (memaddr, myaddr, len);
Index: remote-rdi.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-rdi.c,v
retrieving revision 1.10
diff -c -r1.10 remote-rdi.c
*** remote-rdi.c	2000/12/15 01:01:49	1.10
--- remote-rdi.c	2001/01/23 19:54:48
***************
*** 1,5 ****
  /* GDB interface to ARM RDI library.
!    Copyright 1997, 1998 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* GDB interface to ARM RDI library.
!    Copyright 1997, 1998, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 52,57 ****
--- 52,58 ----
  
  static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
  				int len, int should_write,
+ 				struct mem_attrib *attrib,
  				struct target_ops *target);
  
  static void arm_rdi_prepare_to_store (void);
***************
*** 626,633 ****
  
  /* ARGSUSED */
  static int
! arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 		     int should_write, struct target_ops *target)
  {
    int rslt, i;
  
--- 627,635 ----
  
  /* ARGSUSED */
  static int
! arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
! 		     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int rslt, i;
  
Index: remote-rdp.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-rdp.c,v
retrieving revision 1.8
diff -c -r1.8 remote-rdp.c
*** remote-rdp.c	2000/12/15 01:01:49	1.8
--- remote-rdp.c	2001/01/23 19:54:48
***************
*** 1,5 ****
  /* Remote debugging for the ARM RDP interface.
!    Copyright 1994, 1995 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* Remote debugging for the ARM RDP interface.
!    Copyright 1994, 1995, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 167,176 ****
  static char *commandline = NULL;
  
  static int
! remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr,
! 				 char *myaddr,
! 				 int len,
! 				 int write, struct target_ops *target);
  
  
  /* Stuff for talking to the serial layer. */
--- 167,176 ----
  static char *commandline = NULL;
  
  static int
! remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				 int write, 
! 				 struct mem_attrib *attrib,
! 				 struct target_ops *target);
  
  
  /* Stuff for talking to the serial layer. */
***************
*** 873,879 ****
  	char *copy = alloca (args[2].n);
  	int done = callback->read (callback, args[0].n, copy, args[2].n);
  	if (done > 0)
! 	  remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0);
  	args->n = args[2].n - done;
  	return 1;
        }
--- 873,879 ----
  	char *copy = alloca (args[2].n);
  	int done = callback->read (callback, args[0].n, copy, args[2].n);
  	if (done > 0)
! 	  remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
  	args->n = args[2].n - done;
  	return 1;
        }
***************
*** 905,914 ****
  	      commandline[255] = '\0';
  	    }
  	  remote_rdp_xfer_inferior_memory (args[0].n,
! 					   commandline, len + 1, 1, 0);
  	}
        else
! 	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0);
        return 1;
  
      default:
--- 905,914 ----
  	      commandline[255] = '\0';
  	    }
  	  remote_rdp_xfer_inferior_memory (args[0].n,
! 					   commandline, len + 1, 1, 0, 0);
  	}
        else
! 	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
        return 1;
  
      default:
***************
*** 955,960 ****
--- 955,961 ----
  					       buf,
  					       len,
  					       0,
+ 					       0,
  					       0);
  	    }
  	  else
***************
*** 1249,1255 ****
  
  static int
  remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				 int write, struct target_ops *target)
  {
    /* I infer from D Taylor's code that there's a limit on the amount
       we can transfer in one chunk.. */
--- 1250,1258 ----
  
  static int
  remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				 int write, 
! 				 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 				 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    /* I infer from D Taylor's code that there's a limit on the amount
       we can transfer in one chunk.. */
Index: remote-sds.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sds.c,v
retrieving revision 1.9
diff -c -r1.9 remote-sds.c
*** remote-sds.c	2000/11/03 22:00:56	1.9
--- remote-sds.c	2001/01/23 19:54:49
***************
*** 1,5 ****
  /* Remote target communications for serial-line targets using SDS' protocol.
!    Copyright 1997 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* Remote target communications for serial-line targets using SDS' protocol.
!    Copyright 1997, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 55,61 ****
  
  static void sds_files_info (struct target_ops *ignore);
  
! static int sds_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  static void sds_prepare_to_store (void);
  
--- 55,62 ----
  
  static void sds_files_info (struct target_ops *ignore);
  
! static int sds_xfer_memory (CORE_ADDR, char *, int, int, 
! 			    struct mem_attrib *, struct target_ops *);
  
  static void sds_prepare_to_store (void);
  
***************
*** 657,663 ****
  /* ARGSUSED */
  static int
  sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
! 		 struct target_ops *target)
  {
    int res;
  
--- 658,665 ----
  /* ARGSUSED */
  static int
  sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
! 		 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sim.c,v
retrieving revision 1.8
diff -c -r1.8 remote-sim.c
*** remote-sim.c	2000/10/12 21:39:21	1.8
--- remote-sim.c	2001/01/23 19:54:49
***************
*** 1,5 ****
  /* Generic remote debugging interface for simulators.
!    Copyright 1993, 1994, 1996, 1997, 2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support.
     Steve Chamberlain (sac@cygnus.com).
  
--- 1,5 ----
  /* Generic remote debugging interface for simulators.
!    Copyright 1993, 1994, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.
     Steve Chamberlain (sac@cygnus.com).
  
***************
*** 91,99 ****
  
  static void gdbsim_prepare_to_store (void);
  
! static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr,
! 					char *myaddr, int len,
! 					int write, struct target_ops *target);
  
  static void gdbsim_files_info (struct target_ops *target);
  
--- 91,100 ----
  
  static void gdbsim_prepare_to_store (void);
  
! static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, 
! 					int len, int write,
! 					struct mem_attrib *attrib,
! 					struct target_ops *target);
  
  static void gdbsim_files_info (struct target_ops *target);
  
***************
*** 714,720 ****
  
  static int
  gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (!program_loaded)
      error ("No program loaded.");
--- 715,723 ----
  
  static int
  gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (!program_loaded)
      error ("No program loaded.");
Index: remote-st.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-st.c,v
retrieving revision 1.5
diff -c -r1.5 remote-st.c
*** remote-st.c	2000/10/16 06:42:28	1.5
--- remote-st.c	2001/01/23 19:54:49
***************
*** 1,5 ****
  /* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
!    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
  
     This file is part of GDB.
--- 1,5 ----
  /* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
!    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
  
     This file is part of GDB.
***************
*** 556,562 ****
  
  static int
  st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (write)
      return st2000_write_inferior_memory (memaddr, myaddr, len);
--- 556,564 ----
  
  static int
  st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return st2000_write_inferior_memory (memaddr, myaddr, len);
Index: remote-udi.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-udi.c,v
retrieving revision 1.8
diff -c -r1.8 remote-udi.c
*** remote-udi.c	2000/12/15 01:01:49	1.8
--- remote-udi.c	2001/01/23 19:54:50
***************
*** 1,5 ****
  /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
!    Copyright 1990, 1992, 1995, 2000 Free Software Foundation, Inc.
     Written by Daniel Mann.  Contributed by AMD.
  
     This file is part of GDB.
--- 1,5 ----
  /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
!    Copyright 1990, 1992, 1995, 2000, 2001 Free Software Foundation, Inc.
     Written by Daniel Mann.  Contributed by AMD.
  
     This file is part of GDB.
***************
*** 923,929 ****
  /* FIXME!  Merge these two.  */
  static int
  udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			  struct target_ops * target)
  {
  
    memaddr = translate_addr (memaddr);
--- 923,930 ----
  /* FIXME!  Merge these two.  */
  static int
  udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			  struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			  struct target_ops *target ATTRIBUTE_UNUSED)
  {
  
    memaddr = translate_addr (memaddr);
Index: remote-vx.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-vx.c,v
retrieving revision 1.10
diff -c -r1.10 remote-vx.c
*** remote-vx.c	2000/12/15 01:01:49	1.10
--- remote-vx.c	2001/01/23 19:54:51
***************
*** 1,5 ****
  /* Memory-access and commands for remote VxWorks processes, for GDB.
!    Copyright (C) 1990-95, 1997-98, 1999 Free Software Foundation, Inc.
     Contributed by Wind River Systems and Cygnus Support.
  
     This file is part of GDB.
--- 1,5 ----
  /* Memory-access and commands for remote VxWorks processes, for GDB.
!    Copyright (C) 1990-95, 1997-98, 1999, 2001 Free Software Foundation, Inc.
     Contributed by Wind River Systems and Cygnus Support.
  
     This file is part of GDB.
***************
*** 476,482 ****
  
  static int
  vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct target_ops *target)
  {
    int status;
    Rptrace ptrace_in;
--- 476,483 ----
  
  static int
  vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int status;
    Rptrace ptrace_in;
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.34
diff -c -r1.34 remote.c
*** remote.c	2001/01/18 15:29:11	1.34
--- remote.c	2001/01/23 19:54:55
***************
*** 1,5 ****
  /* Remote target communications for serial-line targets in custom GDB protocol
!    Copyright 1988, 1991-2000 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
--- 1,5 ----
  /* Remote target communications for serial-line targets in custom GDB protocol
!    Copyright 1988, 1991-2000, 2001 Free Software Foundation, Inc.
  
     This file is part of GDB.
  
***************
*** 70,75 ****
--- 70,76 ----
  
  static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
  			       int len, int should_write,
+ 			       struct mem_attrib *attrib,
  			       struct target_ops *target);
  
  static void remote_prepare_to_store (void);
***************
*** 3543,3549 ****
  /* ARGSUSED */
  static int
  remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
! 		    int should_write, struct target_ops *target)
  {
    CORE_ADDR targ_addr;
    int targ_len;
--- 3544,3552 ----
  /* ARGSUSED */
  static int
  remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
! 		    int should_write,
! 		    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		    struct target_ops *target)
  {
    CORE_ADDR targ_addr;
    int targ_len;
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.17
diff -c -r1.17 target.c
*** target.c	2000/12/15 01:01:50	1.17
--- target.c	2001/01/23 19:54:57
***************
*** 1,5 ****
  /* Select target systems and architectures at runtime for GDB.
!    Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support.
  
     This file is part of GDB.
--- 1,5 ----
  /* Select target systems and architectures at runtime for GDB.
!    Copyright 1990, 1992-1995, 1998-2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.
  
     This file is part of GDB.
***************
*** 102,108 ****
  static void debug_to_prepare_to_store (void);
  
  static int
! debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  static void debug_to_files_info (struct target_ops *);
  
--- 102,109 ----
  static void debug_to_prepare_to_store (void);
  
  static int
! debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, 
! 		      struct target_ops *);
  
  static void debug_to_files_info (struct target_ops *);
  
***************
*** 379,385 ****
  	    (void (*) (void)) 
  	    noprocess);
    de_fault (to_xfer_memory, 
! 	    (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
  	    nomemory);
    de_fault (to_files_info, 
  	    (void (*) (struct target_ops *)) 
--- 380,386 ----
  	    (void (*) (void)) 
  	    noprocess);
    de_fault (to_xfer_memory, 
! 	    (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
  	    nomemory);
    de_fault (to_files_info, 
  	    (void (*) (struct target_ops *)) 
***************
*** 843,849 ****
     Result is -1 on error, or the number of bytes transfered.  */
  
  int
! do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
    int res;
    int done = 0;
--- 844,851 ----
     Result is -1 on error, or the number of bytes transfered.  */
  
  int
! do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct mem_attrib *attrib)
  {
    int res;
    int done = 0;
***************
*** 860,866 ****
  
    /* The quick case is that the top target can handle the transfer.  */
    res = current_target.to_xfer_memory
!     (memaddr, myaddr, len, write, &current_target);
  
    /* If res <= 0 then we call it again in the loop.  Ah well. */
    if (res <= 0)
--- 862,868 ----
  
    /* The quick case is that the top target can handle the transfer.  */
    res = current_target.to_xfer_memory
!     (memaddr, myaddr, len, write, attrib, &current_target);
  
    /* If res <= 0 then we call it again in the loop.  Ah well. */
    if (res <= 0)
***************
*** 871,877 ****
  	  if (!t->to_has_memory)
  	    continue;
  
! 	  res = t->to_xfer_memory (memaddr, myaddr, len, write, t);
  	  if (res > 0)
  	    break;		/* Handled all or part of xfer */
  	  if (t->to_has_all_memory)
--- 873,879 ----
  	  if (!t->to_has_memory)
  	    continue;
  
! 	  res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
  	  if (res > 0)
  	    break;		/* Handled all or part of xfer */
  	  if (t->to_has_all_memory)
***************
*** 895,900 ****
--- 897,904 ----
  target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
    int res;
+   int reg_len;
+   struct mem_region *region;
  
    /* Zero length requests are ok and require no work.  */
    if (len == 0)
***************
*** 904,925 ****
  
    while (len > 0)
      {
!       res = dcache_xfer_memory(target_dcache, memaddr, myaddr, len, write);
!       if (res <= 0)
  	{
! 	  /* If this address is for nonexistent memory,
! 	     read zeros if reading, or do nothing if writing.  Return error. */
  	  if (!write)
- 	    memset (myaddr, 0, len);
- 	  if (errno == 0)
  	    return EIO;
! 	  else
! 	    return errno;
  	}
  
!       memaddr += res;
!       myaddr  += res;
!       len     -= res;
      }
    
    return 0;			/* We managed to cover it all somehow. */
--- 908,959 ----
  
    while (len > 0)
      {
!       region = lookup_mem_region(memaddr);
!       if (memaddr + len < region->hi)
! 	reg_len = len;
!       else
! 	reg_len = region->hi - memaddr;
! 
!       switch (region->attrib.mode)
  	{
! 	case MEM_RO:
! 	  if (write)
! 	    return EIO;
! 	  break;
! 	  
! 	case MEM_WO:
  	  if (!write)
  	    return EIO;
! 	  break;
  	}
+ 
+       while (reg_len > 0)
+ 	{
+ 	  if (region->attrib.cache)
+ 	    res = dcache_xfer_memory(target_dcache, memaddr, myaddr,
+ 				     reg_len, write);
+ 	  else
+ 	    res = do_xfer_memory(memaddr, myaddr, reg_len, write,
+ 				 &region->attrib);
+ 	      
+ 	  if (res <= 0)
+ 	    {
+ 	      /* If this address is for nonexistent memory, read zeros
+ 		 if reading, or do nothing if writing.  Return
+ 		 error. */
+ 	      if (!write)
+ 		memset (myaddr, 0, len);
+ 	      if (errno == 0)
+ 		return EIO;
+ 	      else
+ 		return errno;
+ 	    }
  
! 	  memaddr += res;
! 	  myaddr  += res;
! 	  len     -= res;
! 	  reg_len -= res;
! 	}
      }
    
    return 0;			/* We managed to cover it all somehow. */
***************
*** 935,940 ****
--- 969,976 ----
  			    int write_p, int *err)
  {
    int res;
+   int reg_len;
+   struct mem_region *region;
  
    /* Zero length requests are ok and require no work.  */
    if (len == 0)
***************
*** 942,949 ****
        *err = 0;
        return 0;
      }
  
!   res = dcache_xfer_memory (target_dcache, memaddr, myaddr, len, write_p);
    if (res <= 0)
      {
        if (errno != 0)
--- 978,1016 ----
        *err = 0;
        return 0;
      }
+ 
+   region = lookup_mem_region(memaddr);
+   if (memaddr + len < region->hi)
+     reg_len = len;
+   else
+     reg_len = region->hi - memaddr;
+ 
+   switch (region->attrib.mode)
+     {
+     case MEM_RO:
+       if (write_p)
+ 	{
+ 	  *err = EIO;
+ 	  return 0;
+ 	}
+       break;
+ 
+     case MEM_WO:
+       if (write_p)
+ 	{
+ 	  *err = EIO;
+ 	  return 0;
+ 	}
+       break;
+     }
  
!   if (region->attrib.cache)
!     res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
! 			      reg_len, write_p);
!   else
!     res = do_xfer_memory (memaddr, myaddr, reg_len, write_p,
! 			  &region->attrib);
!       
    if (res <= 0)
      {
        if (errno != 0)
***************
*** 2313,2323 ****
  
  static int
  debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
  		      struct target_ops *target)
  {
    int retval;
  
!   retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
  
    fprintf_unfiltered (gdb_stdlog,
  		      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
--- 2380,2392 ----
  
  static int
  debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ 		      struct mem_attrib *attrib,
  		      struct target_ops *target)
  {
    int retval;
  
!   retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
! 					attrib, target);
  
    fprintf_unfiltered (gdb_stdlog,
  		      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.10
diff -c -r1.10 target.h
*** target.h	2001/01/18 15:42:24	1.10
--- target.h	2001/01/23 19:54:58
***************
*** 1,5 ****
  /* Interface between GDB and target environments, including files and processes
!    Copyright 1990-1994, 1999, 2000 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by John Gilmore.
  
     This file is part of GDB.
--- 1,5 ----
  /* Interface between GDB and target environments, including files and processes
!    Copyright 1990-1994, 1999, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Support.  Written by John Gilmore.
  
     This file is part of GDB.
***************
*** 44,49 ****
--- 44,50 ----
  #include "bfd.h"
  #include "symtab.h"
  #include "dcache.h"
+ #include "memattr.h"
  
  enum strata
    {
***************
*** 363,369 ****
         something at MEMADDR + N.  */
  
      int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
! 			   int len, int write, struct target_ops * target);
  
  #if 0
      /* Enable this after 4.12.  */
--- 364,372 ----
         something at MEMADDR + N.  */
  
      int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
! 			   int len, int write, 
! 			   struct mem_attrib *attrib,
! 			   struct target_ops *target);
  
  #if 0
      /* Enable this after 4.12.  */
***************
*** 619,625 ****
  
  extern DCACHE *target_dcache;
  
! extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
  
  extern int target_read_string (CORE_ADDR, char **, int, int *);
  
--- 622,629 ----
  
  extern DCACHE *target_dcache;
  
! extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			   struct mem_attrib *attrib);
  
  extern int target_read_string (CORE_ADDR, char **, int, int *);
  
***************
*** 627,636 ****
  
  extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
  
! extern int xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
! extern int
! child_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  /* Make a single attempt at transfering LEN bytes.  On a successful
     transfer, the number of bytes actually transfered is returned and
--- 631,641 ----
  
  extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
  
! extern int xfer_memory (CORE_ADDR, char *, int, int, 
! 			struct mem_attrib *, struct target_ops *);
  
! extern int child_xfer_memory (CORE_ADDR, char *, int, int, 
! 			      struct mem_attrib *, struct target_ops *);
  
  /* Make a single attempt at transfering LEN bytes.  On a successful
     transfer, the number of bytes actually transfered is returned and
Index: wince.c
===================================================================
RCS file: /cvs/src/src/gdb/wince.c,v
retrieving revision 1.11
diff -c -r1.11 wince.c
*** wince.c	2000/12/15 01:01:51	1.11
--- wince.c	2001/01/23 19:55:01
***************
*** 1,5 ****
  /* Target-vector operations for controlling Windows CE child processes, for GDB.
!    Copyright 1999, 2000 Free Software Foundation, Inc.
     Contributed by Cygnus Solutions, A Red Hat Company.
  
     This file is part of GDB.
--- 1,5 ----
  /* Target-vector operations for controlling Windows CE child processes, for GDB.
!    Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
     Contributed by Cygnus Solutions, A Red Hat Company.
  
     This file is part of GDB.
***************
*** 1975,1981 ****
    add_show_from_set (set, &showlist);
    set->function.cfunc = set_upload_type;
    set_upload_type (NULL, 0);
-   set_dcache_state (1);
  
    add_show_from_set
      (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
--- 1975,1980 ----
Index: doc/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/doc/ChangeLog,v
retrieving revision 1.57
diff -c -r1.57 ChangeLog
*** ChangeLog	2001/01/04 15:39:28	1.57
--- ChangeLog	2001/01/23 19:55:04
***************
*** 1,3 ****
--- 1,7 ----
+ 2001-01-23  J.T. Conklin  <jtc@redback.com>
+ 
+ 	* gdb.texinfo (Memory region attributes): New manual section.
+ 
  2001-01-04  Nicholas Duffek  <nsd@redhat.com>
  
  	* gdbint.texinfo (POP_FRAME): Document use by return_command.
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.30
diff -c -r1.30 gdb.texinfo
*** gdb.texinfo	2000/11/19 06:31:39	1.30
--- gdb.texinfo	2001/01/23 19:56:21
***************
*** 1,5 ****
  \input texinfo      @c -*-texinfo-*-
! @c Copyright 1988-2000
  @c Free Software Foundation, Inc.
  @c
  @c %**start of header
--- 1,5 ----
  \input texinfo      @c -*-texinfo-*-
! @c Copyright 1988-2001
  @c Free Software Foundation, Inc.
  @c
  @c %**start of header
***************
*** 4347,4352 ****
--- 4347,4353 ----
  * Convenience Vars::            Convenience variables
  * Registers::                   Registers
  * Floating Point Hardware::     Floating point hardware
+ * Memory Region Attributes::    Memory region attributes
  @end menu
  
  @node Expressions
***************
*** 5503,5508 ****
--- 5504,5640 ----
  floating point chip.  Currently, @samp{info float} is supported on
  the ARM and x86 machines.
  @end table
+ 
+ @node Memory Region Attributes
+ @section Memory Region Attributes 
+ @cindex memory region attributes
+ 
+ @dfn{Memory region attributes} allow you to describe special handling 
+ required by regions of your target's memory.  @value{GDBN} uses attributes 
+ to determine whether to allow certain types of memory accesses; whether to
+ use specific width accesses; and whether to cache target memory.
+ 
+ Defined memory regions can be individually enabled and disabled.  When a
+ memory region is disabled, @value{GDBN} uses the default attributes when
+ accessing memory in that region.  Similarly, if no memory regions have
+ been defined, @value{GDBN} uses the default attributes when accessing
+ all memory.
+ 
+ When a memory region is defined, it is given a number to identify it; 
+ to enable, disable, or remove a memory region, you specify that number.
+ 
+ @table @code
+ @kindex mem
+ @item mem @var{address1} @var{address1} @var{attributes}@dots{}
+ Define memory region bounded by @var{address1} and @var{address2}
+ with attributes @var{attributes}@dots{}.
+ 
+ @kindex delete mem
+ @item delete mem @var{nums}@dots{}
+ Remove memory region numbers @var{nums}.
+ 
+ @kindex disable mem
+ @item disable mem @var{nums}@dots{}
+ Disable memory region numbers @var{nums}.
+ A disabled memory region is not forgotten.  
+ It may be enabled again later.
+ 
+ @kindex enable mem
+ @item enable mem @var{nums}@dots{}
+ Enable memory region numbers @var{nums}.
+ 
+ @kindex info mem
+ @item info mem
+ Print a table of all defined memory regions, with the following columns
+ for each region.
+ 
+ @table @emph
+ @item Memory Region Number
+ @item Enabled or Disabled.
+ Enabled memory regions are marked with @samp{y}.  
+ Disabled memory regions are marked with @samp{n}.
+ 
+ @item Lo Address
+ The address defining the inclusive lower bound of the memory region.
+ 
+ @item Hi Address
+ The address defining the exclusive upper bound of the memory region.
+ 
+ @item Attributes
+ The list of attributes set for this memory region.
+ @end table
+ @end table
+ 
+ 
+ @subsection Attributes
+ 
+ @subsubsection Memory Access Mode 
+ The access mode attributes set whether @value{GDBN} may make read or
+ write accesses to a memory region.
+ 
+ While these attributes prevent @value{GDBN} from performing invalid
+ memory accesses, they do nothing to prevent the target system, I/O DMA,
+ etc. from accessing memory.
+ 
+ @table @code
+ @item ro
+ Memory is read only.
+ @item wo
+ Memory is write only.
+ @item rw
+ Memory is read/write (default).
+ @end table
+ 
+ @subsubsection Memory Access Size
+ The acccess size attributes tells @value{GDBN} to use specific sized
+ accesses in the memory region.  Often memory mapped device registers
+ require specific sized accesses.  If no access size attribute is
+ specified, @value{GDBN} may use accesses of any size.
+ 
+ @table @code
+ @item 8
+ Use 8 bit memory accesses.
+ @item 16
+ Use 16 bit memory accesses.
+ @item 32
+ Use 32 bit memory accesses.
+ @item 64
+ Use 64 bit memory accesses.
+ @end table
+ 
+ @c @subsubsection Hardware/Software Breakpoints
+ @c The hardware/software breakpoint attributes set whether @value{GDBN}
+ @c will use hardware or software breakpoints for the internal breakpoints
+ @c used by the step, next, finish, until, etc. commands.
+ @c
+ @c @table @code
+ @c @item hwbreak
+ @c Always use hardware breakpoints 
+ @c @item swbreak (default)
+ @c @end table
+ 
+ @subsubsection Data Cache
+ The data cache attributes set whether @value{GDBN} will cache target
+ memory.  While this generally improves performance by reducing debug
+ protocol overhead, it can lead to incorrect results because @value{GDBN}
+ does not know about volatile variables or memory mapped device
+ registers.
+ 
+ @table @code
+ @item cache
+ Enable @value{GDBN} to cache target memory. 
+ @item nocache (default)
+ Disable @value{GDBN} from caching target memory.
+ @end table
+ 
+ @c @subsubsection Memory Write Verification
+ @c The memory write verification attributes set whether @value{GDBN} 
+ @c will re-reads data after each write to verify the write was successful.
+ @c
+ @c @table @code
+ @c @item verify
+ @c @item noverify (default)
+ @c @end table
  
  @node Languages
  @chapter Using @value{GDBN} with Different Languages


-- 
J.T. Conklin
RedBack Networks

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