+/* If this flag is set, the memory region list should be automatically
+ updated from the target. If it is clear, the list is user-controlled
+ and should be left alone. */
+static int mem_use_target = 1;
+
+/* If this flag is set, we have tried to fetch the target memory regions
+ since the last time it was invalidated. If that list is still
+ 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 = 1;
+
+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. */
+
+static int
+mem_region_lessthan (const struct mem_region *lhs,
+ const struct mem_region *rhs)
+{
+ return lhs->lo < rhs->lo;
+}
+
+/* A helper function suitable for qsort, used to sort a
+ VEC(mem_region_s) by starting address. */
+
+int
+mem_region_cmp (const void *untyped_lhs, const void *untyped_rhs)
+{
+ const struct mem_region *lhs = untyped_lhs;
+ const struct mem_region *rhs = untyped_rhs;
+
+ if (lhs->lo < rhs->lo)
+ return -1;
+ else if (lhs->lo == rhs->lo)
+ return 0;
+ else
+ return 1;
+}
+
+/* Allocate a new memory region, with default settings. */
+
+void
+mem_region_init (struct mem_region *new)
+{
+ memset (new, 0, sizeof (struct mem_region));
+ new->enabled_p = 1;
+ new->attrib = default_mem_attrib;
+}
+
+/* This function should be called before any command which would
+ modify the memory region list. It will handle switching from
+ a target-provided list to a local list, if necessary. */
+
+static void
+require_user_regions (int from_tty)
+{
+ struct mem_region *m;
+ int ix, length;
+
+ /* If we're already using a user-provided list, nothing to do. */
+ if (!mem_use_target)
+ return;
+
+ /* Switch to a user-provided list (possibly a copy of the current
+ one). */
+ mem_use_target = 0;
+
+ /* If we don't have a target-provided region list yet, then
+ no need to warn. */
+ if (mem_region_list == NULL)
+ return;
+
+ /* Otherwise, let the user know how to get back. */
+ if (from_tty)
+ warning (_("Switching to manual control of memory regions; use "
+ "\"mem auto\" to fetch regions from the target again."));
+
+ /* And create a new list for the user to modify. */
+ length = VEC_length (mem_region_s, target_mem_region_list);
+ mem_region_list = VEC_alloc (mem_region_s, length);
+ for (ix = 0; VEC_iterate (mem_region_s, target_mem_region_list, ix, m); ix++)
+ VEC_quick_push (mem_region_s, mem_region_list, m);
+}
+
+/* This function should be called before any command which would
+ read the memory region list, other than those which call
+ require_user_regions. It will handle fetching the
+ target-provided list, if necessary. */
+
+static void
+require_target_regions (void)
+{
+ if (mem_use_target && !target_mem_regions_valid)
+ {
+ target_mem_regions_valid = 1;
+ target_mem_region_list = target_memory_map ();
+ mem_region_list = target_mem_region_list;
+ }
+}
+
+static void