+static bool bp_loc_is_permanent (struct bp_location *loc);
+
+/* Handle "set breakpoint auto-hw on".
+
+ If the explicitly specified breakpoint type is not hardware
+ breakpoint, check the memory map to see whether the breakpoint
+ address is in read-only memory.
+
+ - location type is not hardware breakpoint, memory is read-only.
+ We change the type of the location to hardware breakpoint.
+
+ - location type is hardware breakpoint, memory is read-write. This
+ means we've previously made the location hardware one, but then the
+ memory map changed, so we undo.
+*/
+
+static void
+handle_automatic_hardware_breakpoints (bp_location *bl)
+{
+ if (automatic_hardware_breakpoints
+ && bl->owner->type != bp_hardware_breakpoint
+ && (bl->loc_type == bp_loc_software_breakpoint
+ || bl->loc_type == bp_loc_hardware_breakpoint))
+ {
+ /* When breakpoints are removed, remove_breakpoints will use
+ location types we've just set here, the only possible problem
+ is that memory map has changed during running program, but
+ it's not going to work anyway with current gdb. */
+ mem_region *mr = lookup_mem_region (bl->address);
+
+ if (mr != nullptr)
+ {
+ enum bp_loc_type new_type;
+
+ if (mr->attrib.mode != MEM_RW)
+ new_type = bp_loc_hardware_breakpoint;
+ else
+ new_type = bp_loc_software_breakpoint;
+
+ if (new_type != bl->loc_type)
+ {
+ static bool said = false;
+
+ bl->loc_type = new_type;
+ if (!said)
+ {
+ fprintf_filtered (gdb_stdout,
+ _("Note: automatically using "
+ "hardware breakpoints for "
+ "read-only addresses.\n"));
+ said = true;
+ }
+ }
+ }
+ }
+}