From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29497 invoked by alias); 15 Nov 2006 12:24:55 -0000 Received: (qmail 29472 invoked by uid 22791); 15 Nov 2006 12:24:51 -0000 X-Spam-Check-By: sourceware.org Received: from main.gmane.org (HELO ciao.gmane.org) (80.91.229.2) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 15 Nov 2006 12:24:37 +0000 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1GkJoY-0007rE-PX for gdb-patches@sources.redhat.com; Wed, 15 Nov 2006 13:24:26 +0100 Received: from 73-198.umostel.ru ([82.179.73.198]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 15 Nov 2006 13:24:26 +0100 Received: from ghost by 73-198.umostel.ru with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 15 Nov 2006 13:24:26 +0100 To: gdb-patches@sources.redhat.com From: Vladimir Prus Subject: Re: Check memory accesses Date: Wed, 15 Nov 2006 12:24:00 -0000 Message-ID: References: <200611092336.22512.vladimir@codesourcery.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart40129636.9daQOX99Do" Content-Transfer-Encoding: 7Bit User-Agent: KNode/0.10.2 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-11/txt/msg00122.txt.bz2 --nextPart40129636.9daQOX99Do Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8Bit Content-length: 1496 Eli Zaretskii wrote: >> From: Vladimir Prus >> Date: Thu, 9 Nov 2006 23:36:22 +0300 >> >> This patch makes gdb, when target memory map is available, optionally >> reject all memory accesses outside of regions in memory map. The >> rationale is that: >> >> 1. It's sometimes better to get error that have the write silently do >> nothing or read returning garbase. >> >> 2. For some targets, accesses to non-existent memory "wedge" them. >> >> Since memory maps are still rare, this behaviour is enabled only by a new >> command. >> >> OK? > > This patch introduces a new user command, but doesn't include a patch > for the user manual. Please provide one. Sorry. This version of the patch includes documentation. - Volodya gdb/ * memattr.h (enum mem_access_mode): New value MEM_NONE. * memattr.c (unknown_mem_attrib): New. (inaccessible_by_default): New. (show_inaccessible_by_default): New. (lookup_mem_region): Check inaccessible_by_default. (dummy_cmd): New. (mem_set_cmdlist, mem_show_cmdlist): New. (_initialize_mem): Register new "set" and "show" commands. * target.c (memory_xfer_partial): If memory type is MEM_NONE, return an error. Clip to region size when calling to_xfer_partial. If upper limit of memory range is 0, don't clip anything. gdb/doc/ * gdb.texinfo (Memory Access Checking): New. --nextPart40129636.9daQOX99Do Content-Type: text/x-diff; name="memcheck__gdb_mainline.diff" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="memcheck__gdb_mainline.diff" Content-length: 7141 === gdb/doc/gdb.texinfo ================================================================== --- gdb/doc/gdb.texinfo (/mirrors/gdb_mainline) (revision 2094) +++ gdb/doc/gdb.texinfo (/patches/gdb/memcheck/gdb_mainline) (revision 2094) @@ -6894,6 +6894,26 @@ Disable @value{GDBN} from caching target memory. This is the default. @end table +@subsection Memory Access Checking +@value{GDBN} can be instructed to refuse accesses to memory that is +not explicitly described. This can be useful if accessing such +regions has undesired effects for a specific target, or to provide +better error checking. The following commands control this behaviour. + +@table @code +@kindex set mem inaccessible-by-default +@item set mem inaccessible-by-default [on|off] +If @code{on} is specified, make @value{GDBN} treat memory not +explicitly described by the memory ranges as non-existent and refuse accesses +to such memory. The checks are only performed if there's at least one +memory range defined. If @code{off} is specified, make @value{GDBN} +treat the memory not explicitly described by the memory ranges as RAM. +@kindex show mem inaccessible-by-default +@item show mem inaccessible-by-default +Show the current handling of accesses to unknown 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. === gdb/target.c ================================================================== --- gdb/target.c (/mirrors/gdb_mainline) (revision 2094) +++ gdb/target.c (/patches/gdb/memcheck/gdb_mainline) (revision 2094) @@ -1015,7 +1015,8 @@ /* Try GDB's internal data cache. */ region = lookup_mem_region (memaddr); - if (memaddr + len < region->hi) + /* region->hi means there's no upper bound. */ + if (memaddr + len < region->hi || region->hi == 0) reg_len = len; else reg_len = region->hi - memaddr; @@ -1037,6 +1038,9 @@ if (writebuf != NULL) error (_("Writing to flash memory forbidden in this context")); break; + + case MEM_NONE: + return -1; } if (region->attrib.cache) @@ -1072,7 +1076,7 @@ do { res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL, - readbuf, writebuf, memaddr, len); + readbuf, writebuf, memaddr, reg_len); if (res > 0) return res; === gdb/memattr.c ================================================================== --- gdb/memattr.c (/mirrors/gdb_mainline) (revision 2094) +++ gdb/memattr.c (/patches/gdb/memcheck/gdb_mainline) (revision 2094) @@ -29,6 +29,7 @@ #include "language.h" #include "vec.h" #include "gdb_string.h" +#include "gdb_locale.h" const struct mem_attrib default_mem_attrib = { @@ -40,6 +41,17 @@ -1 /* Flash blocksize not specified. */ }; +const struct mem_attrib unknown_mem_attrib = +{ + MEM_NONE, /* mode */ + MEM_WIDTH_UNSPECIFIED, + 0, /* hwbreak */ + 0, /* cache */ + 0, /* verify */ + -1 /* Flash blocksize not specified. */ +}; + + VEC(mem_region_s) *mem_region_list, *target_mem_region_list; static int mem_number = 0; @@ -53,6 +65,25 @@ empty, then the target can't supply memory regions. */ static int target_mem_regions_valid; +/* If this flag is set, gdb will assume that memory ranges not + specified by the memory map have type MEM_NONE, and will + emit errors on all accesses to that memory. */ +static int inaccessible_by_default = 0; + +static void +show_inaccessible_by_default (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + if (inaccessible_by_default) + fprintf_filtered (file, _("\ +Unknown memory addresses will be treated as inaccessible.\n")); + else + fprintf_filtered (file, _("\ +Unknown memory addresses will be treated as RAM.\n")); +} + + /* Predicate function which returns true if LHS should sort before RHS in a list of memory regions, useful for VEC_lower_bound. */ @@ -215,13 +246,17 @@ lo = 0; hi = 0; - /* If we ever want to support a huge list of memory regions, this + /* Either find memory range containing ADDRESS, or set LO and HI + to the nearest boundaries of an existing memory range. + + If we ever want to support a huge list of memory regions, this check should be replaced with a binary search (probably using VEC_lower_bound). */ for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) { if (m->enabled_p == 1) { + /* If address is in memory return, return that memory range. */ if (addr >= m->lo && (addr < m->hi || m->hi == 0)) return m; @@ -243,7 +278,15 @@ was learned above. */ region.lo = lo; region.hi = hi; - region.attrib = default_mem_attrib; + + /* When no memory map is defined at all, we always set 'default_mem_attrib', + so that we do not make the all memory inaccessible for targets that don't + provide a memory map. */ + if (inaccessible_by_default && !VEC_empty (mem_region_s, mem_region_list)) + region.attrib = unknown_mem_attrib; + else + region.attrib = default_mem_attrib; + return ®ion; } @@ -674,9 +717,17 @@ dont_repeat (); } + +static void +dummy_cmd (char *args, int from_tty) +{ +} extern initialize_file_ftype _initialize_mem; /* -Wmissing-prototype */ +static struct cmd_list_element *mem_set_cmdlist; +static struct cmd_list_element *mem_show_cmdlist; + void _initialize_mem (void) { @@ -709,4 +760,25 @@ add_info ("mem", mem_info_command, _("Memory region attributes")); + + add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\ +Memory regions settings"), + &mem_set_cmdlist, "set mem ", + 0/* allow-unknown */, &setlist); + add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\ +Memory regions settings"), + &mem_show_cmdlist, "show mem ", + 0/* allow-unknown */, &showlist); + + add_setshow_boolean_cmd ("inaccessible-by-default", no_class, + &inaccessible_by_default, _("\ +Set handling of unknown memory regions."), _("\ +Show handling of unknown memory regions."), _("\ +If on, and some memory map is defined, debugger will emit errors on\n\ +accesses to memory not defined in the memory map. If off, accesses to all\n\ +memory addresses will be allowed."), + NULL, + show_inaccessible_by_default, + &mem_set_cmdlist, + &mem_show_cmdlist); } === gdb/memattr.h ================================================================== --- gdb/memattr.h (/mirrors/gdb_mainline) (revision 2094) +++ gdb/memattr.h (/patches/gdb/memcheck/gdb_mainline) (revision 2094) @@ -26,6 +26,7 @@ enum mem_access_mode { + MEM_NONE, /* Memory that is not physically present. */ MEM_RW, /* read/write */ MEM_RO, /* read only */ MEM_WO, /* write only */ @@ -76,7 +77,10 @@ struct mem_region { + /* Lowest address in the region. */ CORE_ADDR lo; + /* Address past the highest address of the region. + If 0, upper bound is "infinity". */ CORE_ADDR hi; /* Item number of this memory region. */ --nextPart40129636.9daQOX99Do--