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]

Re: [PATCH]: memory region attributes


You forgot to look for xfer_memory in the gdbtk subdirectory...

Insight does not currently build.

Fernando


"J.T. Conklin" wrote:
> 
> 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

-- 
Fernando Nasser
Red Hat Canada Ltd.                     E-Mail:  fnasser@redhat.com
2323 Yonge Street, Suite #300
Toronto, Ontario   M4P 2C9

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