PR symtab/17559
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 4e6c627d913abcb4e7108f71b8787b3c81832df2..3ebe9c978ad4bc02eb19c2215d53a3ec08c1134f 100644 (file)
@@ -36,7 +36,6 @@
 #include "gdbthread.h"
 #include "target.h"
 #include "language.h"
-#include <string.h>
 #include "gdb-demangle.h"
 #include "filenames.h"
 #include "annotate.h"
 #include "gdb.h"
 #include "ui-out.h"
 #include "cli/cli-script.h"
-#include "gdb_assert.h"
 #include "block.h"
 #include "solib.h"
 #include "solist.h"
 #include "observer.h"
-#include "exceptions.h"
 #include "memattr.h"
 #include "ada-lang.h"
 #include "top.h"
@@ -154,7 +151,8 @@ struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
 static struct breakpoint *
   momentary_breakpoint_from_master (struct breakpoint *orig,
                                    enum bptype type,
-                                   const struct breakpoint_ops *ops);
+                                   const struct breakpoint_ops *ops,
+                                   int loc_enabled);
 
 static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
 
@@ -227,17 +225,50 @@ static void stopat_command (char *arg, int from_tty);
 
 static void tcatch_command (char *arg, int from_tty);
 
-static void detach_single_step_breakpoints (void);
-
 static void free_bp_location (struct bp_location *loc);
 static void incref_bp_location (struct bp_location *loc);
 static void decref_bp_location (struct bp_location **loc);
 
 static struct bp_location *allocate_bp_location (struct breakpoint *bpt);
 
-static void update_global_location_list (int);
+/* update_global_location_list's modes of operation wrt to whether to
+   insert locations now.  */
+enum ugll_insert_mode
+{
+  /* Don't insert any breakpoint locations into the inferior, only
+     remove already-inserted locations that no longer should be
+     inserted.  Functions that delete a breakpoint or breakpoints
+     should specify this mode, so that deleting a breakpoint doesn't
+     have the side effect of inserting the locations of other
+     breakpoints that are marked not-inserted, but should_be_inserted
+     returns true on them.
+
+     This behavior is useful is situations close to tear-down -- e.g.,
+     after an exec, while the target still has execution, but
+     breakpoint shadows of the previous executable image should *NOT*
+     be restored to the new image; or before detaching, where the
+     target still has execution and wants to delete breakpoints from
+     GDB's lists, and all breakpoints had already been removed from
+     the inferior.  */
+  UGLL_DONT_INSERT,
+
+  /* May insert breakpoints iff breakpoints_should_be_inserted_now
+     claims breakpoints should be inserted now.  */
+  UGLL_MAY_INSERT,
+
+  /* Insert locations now, irrespective of
+     breakpoints_should_be_inserted_now.  E.g., say all threads are
+     stopped right now, and the user did "continue".  We need to
+     insert breakpoints _before_ resuming the target, but
+     UGLL_MAY_INSERT wouldn't insert them, because
+     breakpoints_should_be_inserted_now returns false at that point,
+     as no thread is running yet.  */
+  UGLL_INSERT
+};
+
+static void update_global_location_list (enum ugll_insert_mode);
 
-static void update_global_location_list_nothrow (int);
+static void update_global_location_list_nothrow (enum ugll_insert_mode);
 
 static int is_hardware_watchpoint (const struct breakpoint *bpt);
 
@@ -294,12 +325,6 @@ static struct breakpoint_ops bkpt_probe_breakpoint_ops;
 /* Dynamic printf class type.  */
 struct breakpoint_ops dprintf_breakpoint_ops;
 
-/* One (or perhaps two) breakpoints used for software single
-   stepping.  */
-
-static void *single_step_breakpoints[2];
-static struct gdbarch *single_step_gdbarch[2];
-
 /* The style in which to perform a dynamic printf.  This is a user
    option because different output options have different tradeoffs;
    if GDB does the printing, there is better error handling if there
@@ -419,34 +444,48 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* If on, gdb will keep breakpoints inserted even as inferior is
-   stopped, and immediately insert any new breakpoints.  If off, gdb
-   will insert breakpoints into inferior only when resuming it, and
-   will remove breakpoints upon stop.  If auto, GDB will behave as ON
-   if in non-stop mode, and as OFF if all-stop mode.*/
-
-static enum auto_boolean always_inserted_mode = AUTO_BOOLEAN_AUTO;
+/* If on, GDB keeps breakpoints inserted even if the inferior is
+   stopped, and immediately inserts any new breakpoints as soon as
+   they're created.  If off (default), GDB keeps breakpoints off of
+   the target as long as possible.  That is, it delays inserting
+   breakpoints until the next resume, and removes them again when the
+   target fully stops.  This is a bit safer in case GDB crashes while
+   processing user input.  */
+static int always_inserted_mode = 0;
 
 static void
 show_always_inserted_mode (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  if (always_inserted_mode == AUTO_BOOLEAN_AUTO)
-    fprintf_filtered (file,
-                     _("Always inserted breakpoint "
-                       "mode is %s (currently %s).\n"),
-                     value,
-                     breakpoints_always_inserted_mode () ? "on" : "off");
-  else
-    fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
-                     value);
+  fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
+                   value);
 }
 
+/* See breakpoint.h.  */
+
 int
-breakpoints_always_inserted_mode (void)
+breakpoints_should_be_inserted_now (void)
 {
-  return (always_inserted_mode == AUTO_BOOLEAN_TRUE
-         || (always_inserted_mode == AUTO_BOOLEAN_AUTO && non_stop));
+  if (gdbarch_has_global_breakpoints (target_gdbarch ()))
+    {
+      /* If breakpoints are global, they should be inserted even if no
+        thread under gdb's control is running, or even if there are
+        no threads under GDB's control yet.  */
+      return 1;
+    }
+  else if (target_has_execution)
+    {
+      if (always_inserted_mode)
+       {
+         /* The user wants breakpoints inserted even if all threads
+            are stopped.  */
+         return 1;
+       }
+
+      if (threads_are_executing ())
+       return 1;
+    }
+  return 0;
 }
 
 static const char condition_evaluation_both[] = "host or target";
@@ -833,7 +872,7 @@ set_condition_evaluation_mode (char *args, int from_tty,
        }
 
       /* Do the update.  */
-      update_global_location_list (1);
+      update_global_location_list (UGLL_MAY_INSERT);
     }
 
   return;
@@ -1061,7 +1100,7 @@ condition_command (char *arg, int from_tty)
        set_breakpoint_condition (b, p, from_tty);
 
        if (is_breakpoint (b))
-         update_global_location_list (1);
+         update_global_location_list (UGLL_MAY_INSERT);
 
        return;
       }
@@ -1493,8 +1532,8 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
   else
     {
       const unsigned char *bp;
-      CORE_ADDR placed_address = target_info->placed_address;
-      int placed_size = target_info->placed_size;
+      CORE_ADDR addr = target_info->reqstd_address;
+      int placed_size;
 
       /* Update the shadow with what we want to write to memory.  */
       memcpy (target_info->shadow_contents + bptoffset,
@@ -1502,7 +1541,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 
       /* Determine appropriate breakpoint contents and size for this
         address.  */
-      bp = gdbarch_breakpoint_from_pc (gdbarch, &placed_address, &placed_size);
+      bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &placed_size);
 
       /* Update the final write buffer with this inserted
         breakpoint's INSN.  */
@@ -1614,21 +1653,6 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
     one_breakpoint_xfer_memory (readbuf, writebuf, writebuf_org,
                                memaddr, len, &bl->target_info, bl->gdbarch);
   }
-
-  /* Now process single-step breakpoints.  These are not found in the
-     bp_location array.  */
-  for (i = 0; i < 2; i++)
-    {
-      struct bp_target_info *bp_tgt = single_step_breakpoints[i];
-
-      if (bp_tgt != NULL)
-       {
-         struct gdbarch *gdbarch = single_step_gdbarch[i];
-
-         one_breakpoint_xfer_memory (readbuf, writebuf, writebuf_org,
-                                     memaddr, len, bp_tgt, gdbarch);
-       }
-    }
 }
 
 \f
@@ -1701,6 +1725,29 @@ watchpoint_del_at_next_stop (struct watchpoint *w)
   b->disposition = disp_del_at_next_stop;
 }
 
+/* Extract a bitfield value from value VAL using the bit parameters contained in
+   watchpoint W.  */
+
+static struct value *
+extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val)
+{
+  struct value *bit_val;
+
+  if (val == NULL)
+    return NULL;
+
+  bit_val = allocate_value (value_type (val));
+
+  unpack_value_bitfield (bit_val,
+                        w->val_bitpos,
+                        w->val_bitsize,
+                        value_contents_for_printing (val),
+                        value_offset (val),
+                        val);
+
+  return bit_val;
+}
+
 /* Assuming that B is a watchpoint:
    - Reparse watchpoint expression, if REPARSE is non-zero
    - Evaluate expression and store the result in B->val
@@ -1875,6 +1922,12 @@ update_watchpoint (struct watchpoint *b, int reparse)
         watchpoints.  */
       if (!b->val_valid && !is_masked_watchpoint (&b->base))
        {
+         if (b->val_bitsize != 0)
+           {
+             v = extract_bitfield_from_watchpoint_value (b, v);
+             if (v != NULL)
+               release_value (v);
+           }
          b->val = v;
          b->val_valid = 1;
        }
@@ -1904,8 +1957,31 @@ update_watchpoint (struct watchpoint *b, int reparse)
                  CORE_ADDR addr;
                  int type;
                  struct bp_location *loc, **tmp;
+                 int bitpos = 0, bitsize = 0;
+
+                 if (value_bitsize (v) != 0)
+                   {
+                     /* Extract the bit parameters out from the bitfield
+                        sub-expression.  */
+                     bitpos = value_bitpos (v);
+                     bitsize = value_bitsize (v);
+                   }
+                 else if (v == result && b->val_bitsize != 0)
+                   {
+                    /* If VAL_BITSIZE != 0 then RESULT is actually a bitfield
+                       lvalue whose bit parameters are saved in the fields
+                       VAL_BITPOS and VAL_BITSIZE.  */
+                     bitpos = b->val_bitpos;
+                     bitsize = b->val_bitsize;
+                   }
 
                  addr = value_address (v);
+                 if (bitsize != 0)
+                   {
+                     /* Skip the bytes that don't contain the bitfield.  */
+                     addr += bitpos / 8;
+                   }
+
                  type = hw_write;
                  if (b->base.type == bp_read_watchpoint)
                    type = hw_read;
@@ -1920,7 +1996,15 @@ update_watchpoint (struct watchpoint *b, int reparse)
 
                  loc->pspace = frame_pspace;
                  loc->address = addr;
-                 loc->length = TYPE_LENGTH (value_type (v));
+
+                 if (bitsize != 0)
+                   {
+                     /* Just cover the bytes that make up the bitfield.  */
+                     loc->length = ((bitpos % 8) + bitsize + 7) / 8;
+                   }
+                 else
+                   loc->length = TYPE_LENGTH (value_type (v));
+
                  loc->watchpoint_type = type;
                }
            }
@@ -2087,7 +2171,32 @@ should_be_inserted (struct bp_location *bl)
        || bl->loc_type == bp_loc_hardware_breakpoint)
       && stepping_past_instruction_at (bl->pspace->aspace,
                                       bl->address))
-    return 0;
+    {
+      if (debug_infrun)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: skipping breakpoint: "
+                             "stepping past insn at: %s\n",
+                             paddress (bl->gdbarch, bl->address));
+       }
+      return 0;
+    }
+
+  /* Don't insert watchpoints if we're trying to step past the
+     instruction that triggered one.  */
+  if ((bl->loc_type == bp_loc_hardware_watchpoint)
+      && stepping_past_nonsteppable_watchpoint ())
+    {
+      if (debug_infrun)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: stepping past non-steppable watchpoint. "
+                             "skipping watchpoint at %s:%d\n",
+                             paddress (bl->gdbarch, bl->address),
+                             bl->length);
+       }
+      return 0;
+    }
 
   return 1;
 }
@@ -2481,7 +2590,7 @@ insert_bp_location (struct bp_location *bl,
      we have a breakpoint inserted at that address and thus
      read the breakpoint instead of returning the data saved in
      the breakpoint location's shadow contents.  */
-  bl->target_info.placed_address = bl->address;
+  bl->target_info.reqstd_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
   bl->target_info.length = bl->length;
 
@@ -2522,7 +2631,7 @@ insert_bp_location (struct bp_location *bl,
             program, but it's not going to work anyway with current
             gdb.  */
          struct mem_region *mr 
-           = lookup_mem_region (bl->target_info.placed_address);
+           = lookup_mem_region (bl->target_info.reqstd_address);
          
          if (mr)
            {
@@ -2551,10 +2660,16 @@ insert_bp_location (struct bp_location *bl,
                    }
                }
              else if (bl->loc_type == bp_loc_software_breakpoint
-                      && mr->attrib.mode != MEM_RW)        
-               warning (_("cannot set software breakpoint "
-                          "at readonly address %s"),
-                        paddress (bl->gdbarch, bl->address));
+                      && mr->attrib.mode != MEM_RW)
+               {
+                 fprintf_unfiltered (tmp_error_stream,
+                                     _("Cannot insert breakpoint %d.\n"
+                                       "Cannot set software breakpoint "
+                                       "at read-only address %s\n"),
+                                     bl->owner->number,
+                                     paddress (bl->gdbarch, bl->address));
+                 return 1;
+               }
            }
        }
         
@@ -2596,7 +2711,7 @@ insert_bp_location (struct bp_location *bl,
                                                             bl->section);
                  /* Set a software (trap) breakpoint at the LMA.  */
                  bl->overlay_target_info = bl->target_info;
-                 bl->overlay_target_info.placed_address = addr;
+                 bl->overlay_target_info.reqstd_address = addr;
 
                  /* No overlay handling: just set the breakpoint.  */
                  TRY_CATCH (e, RETURN_MASK_ALL)
@@ -2662,8 +2777,8 @@ insert_bp_location (struct bp_location *bl,
          if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
              && bl->loc_type == bp_loc_software_breakpoint
              && (solib_name_from_address (bl->pspace, bl->address)
-                 || userloaded_objfile_contains_address_p (bl->pspace,
-                                                           bl->address)))
+                 || shared_objfile_contains_address_p (bl->pspace,
+                                                       bl->address)))
            {
              /* See also: disable_breakpoints_in_shlibs.  */
              bl->shlib_disabled = 1;
@@ -2846,7 +2961,7 @@ breakpoint_program_space_exit (struct program_space *pspace)
 
   /* Now update the global location list to permanently delete the
      removed locations above.  */
-  update_global_location_list (0);
+  update_global_location_list (UGLL_DONT_INSERT);
 }
 
 /* Make sure all breakpoints are inserted in inferior.
@@ -2866,13 +2981,10 @@ insert_breakpoints (void)
        update_watchpoint (w, 0 /* don't reparse.  */);
       }
 
-  update_global_location_list (1);
-
-  /* update_global_location_list does not insert breakpoints when
-     always_inserted_mode is not enabled.  Explicitly insert them
-     now.  */
-  if (!breakpoints_always_inserted_mode ())
-    insert_breakpoint_locations ();
+  /* Updating watchpoints creates new locations, so update the global
+     location list.  Explicitly tell ugll to insert locations and
+     ignore breakpoints_always_inserted_mode.  */
+  update_global_location_list (UGLL_INSERT);
 }
 
 /* Invoke CALLBACK for each of bp_location.  */
@@ -3329,7 +3441,7 @@ create_overlay_event_breakpoint (void)
          overlay_events_enabled = 0;
        }
     }
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 }
 
 static void
@@ -3439,7 +3551,7 @@ create_longjmp_master_breakpoint (void)
        }
     }
   }
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 
   do_cleanups (old_chain);
 }
@@ -3495,7 +3607,7 @@ create_std_terminate_master_breakpoint (void)
     }
   }
 
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 
   do_cleanups (old_chain);
 }
@@ -3597,7 +3709,7 @@ create_exception_master_breakpoint (void)
       b->enable_state = bp_disabled;
     }
 
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 }
 
 void
@@ -3654,6 +3766,13 @@ update_breakpoints_after_exec (void)
        continue;
       }
 
+    /* Just like single-step breakpoints.  */
+    if (b->type == bp_single_step)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
     /* Longjmp and longjmp-resume breakpoints are also meaningless
        after an exec.  */
     if (b->type == bp_longjmp || b->type == bp_longjmp_resume
@@ -3713,11 +3832,6 @@ update_breakpoints_after_exec (void)
        continue;
       }
   }
-  /* FIXME what about longjmp breakpoints?  Re-create them here?  */
-  create_overlay_event_breakpoint ();
-  create_longjmp_master_breakpoint ();
-  create_std_terminate_master_breakpoint ();
-  create_exception_master_breakpoint ();
 }
 
 int
@@ -3751,9 +3865,6 @@ detach_breakpoints (ptid_t ptid)
       val |= remove_breakpoint_1 (bl, mark_inserted);
   }
 
-  /* Detach single-step breakpoints as well.  */
-  detach_single_step_breakpoints ();
-
   do_cleanups (old_chain);
   return val;
 }
@@ -3772,7 +3883,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
   /* BL is never in moribund_locations by our callers.  */
   gdb_assert (bl->owner != NULL);
 
-  if (bl->owner->enable_state == bp_permanent)
+  if (bl->permanent)
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
@@ -3802,7 +3913,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
             whether another dynamic object might have loaded over the
             breakpoint's address -- the user might well let us know
             about it next with add-symbol-file (the whole point of
-            OBJF_USERLOADED is letting the user manually maintain a
+            add-symbol-file is letting the user manually maintain a
             list of dynamically loaded objects).  If we have the
             breakpoint's shadow memory, that is, this is a software
             breakpoint managed by GDB, check whether the breakpoint
@@ -3875,8 +3986,8 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
          && (bl->loc_type == bp_loc_software_breakpoint
              && (bl->shlib_disabled
                  || solib_name_from_address (bl->pspace, bl->address)
-                 || userloaded_objfile_contains_address_p (bl->pspace,
-                                                           bl->address))))
+                 || shared_objfile_contains_address_p (bl->pspace,
+                                                       bl->address))))
        val = 0;
 
       if (val)
@@ -3922,7 +4033,7 @@ remove_breakpoint (struct bp_location *bl, insertion_state_t is)
   /* BL is never in moribund_locations by our callers.  */
   gdb_assert (bl->owner != NULL);
 
-  if (bl->owner->enable_state == bp_permanent)
+  if (bl->permanent)
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
@@ -3948,7 +4059,8 @@ mark_breakpoints_out (void)
   struct bp_location *bl, **blp_tmp;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
-    if (bl->pspace == current_program_space)
+    if (bl->pspace == current_program_space
+       && !bl->permanent)
       bl->inserted = 0;
 }
 
@@ -3977,13 +4089,7 @@ breakpoint_init_inferior (enum inf_context context)
   if (gdbarch_has_global_breakpoints (target_gdbarch ()))
     return;
 
-  ALL_BP_LOCATIONS (bl, blp_tmp)
-  {
-    /* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL.  */
-    if (bl->pspace == pspace
-       && bl->owner->enable_state != bp_permanent)
-      bl->inserted = 0;
-  }
+  mark_breakpoints_out ();
 
   ALL_BREAKPOINTS_SAFE (b, b_tmp)
   {
@@ -4023,6 +4129,10 @@ breakpoint_init_inferior (enum inf_context context)
 
        /* Also remove step-resume breakpoints.  */
 
+      case bp_single_step:
+
+       /* Also remove single-step breakpoints.  */
+
        delete_breakpoint (b);
        break;
 
@@ -4087,14 +4197,14 @@ breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
 
       /* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL.  */
       if ((breakpoint_enabled (bl->owner)
-          || bl->owner->enable_state == bp_permanent)
+          || bl->permanent)
          && breakpoint_location_address_match (bl, aspace, pc))
        {
          if (overlay_debugging 
              && section_is_overlay (bl->section)
              && !section_is_mapped (bl->section))
            continue;           /* unmapped overlay -- can't be a match */
-         else if (bl->owner->enable_state == bp_permanent)
+         else if (bl->permanent)
            return permanent_breakpoint_here;
          else
            any_breakpoint_here = 1;
@@ -4119,14 +4229,10 @@ moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
   return 0;
 }
 
-/* Returns non-zero if there's a breakpoint inserted at PC, which is
-   inserted using regular breakpoint_chain / bp_location array
-   mechanism.  This does not check for single-step breakpoints, which
-   are inserted and removed using direct target manipulation.  */
+/* Returns non-zero iff there's a breakpoint inserted at PC.  */
 
 int
-regular_breakpoint_inserted_here_p (struct address_space *aspace, 
-                                   CORE_ADDR pc)
+breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
 {
   struct bp_location *bl, **blp_tmp;
 
@@ -4150,21 +4256,6 @@ regular_breakpoint_inserted_here_p (struct address_space *aspace,
   return 0;
 }
 
-/* Returns non-zero iff there's either regular breakpoint
-   or a single step breakpoint inserted at PC.  */
-
-int
-breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
-{
-  if (regular_breakpoint_inserted_here_p (aspace, pc))
-    return 1;
-
-  if (single_step_breakpoint_inserted_here_p (aspace, pc))
-    return 1;
-
-  return 0;
-}
-
 /* This function returns non-zero iff there is a software breakpoint
    inserted at PC.  */
 
@@ -4192,10 +4283,6 @@ software_breakpoint_inserted_here_p (struct address_space *aspace,
        }
     }
 
-  /* Also check for software single-step breakpoints.  */
-  if (single_step_breakpoint_inserted_here_p (aspace, pc))
-    return 1;
-
   return 0;
 }
 
@@ -4230,65 +4317,6 @@ hardware_watchpoint_inserted_in_range (struct address_space *aspace,
     }
   return 0;
 }
-
-/* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
-   PC is valid for process/thread PTID.  */
-
-int
-breakpoint_thread_match (struct address_space *aspace, CORE_ADDR pc,
-                        ptid_t ptid)
-{
-  struct bp_location *bl, **blp_tmp;
-  /* The thread and task IDs associated to PTID, computed lazily.  */
-  int thread = -1;
-  int task = 0;
-  
-  ALL_BP_LOCATIONS (bl, blp_tmp)
-    {
-      if (bl->loc_type != bp_loc_software_breakpoint
-         && bl->loc_type != bp_loc_hardware_breakpoint)
-       continue;
-
-      /* ALL_BP_LOCATIONS bp_location has bl->OWNER always non-NULL.  */
-      if (!breakpoint_enabled (bl->owner)
-         && bl->owner->enable_state != bp_permanent)
-       continue;
-
-      if (!breakpoint_location_address_match (bl, aspace, pc))
-       continue;
-
-      if (bl->owner->thread != -1)
-       {
-         /* This is a thread-specific breakpoint.  Check that ptid
-            matches that thread.  If thread hasn't been computed yet,
-            it is now time to do so.  */
-         if (thread == -1)
-           thread = pid_to_thread_id (ptid);
-         if (bl->owner->thread != thread)
-           continue;
-       }
-
-      if (bl->owner->task != 0)
-        {
-         /* This is a task-specific breakpoint.  Check that ptid
-            matches that task.  If task hasn't been computed yet,
-            it is now time to do so.  */
-         if (task == 0)
-           task = ada_get_task_number (ptid);
-         if (bl->owner->task != task)
-           continue;
-        }
-
-      if (overlay_debugging 
-         && section_is_overlay (bl->section)
-         && !section_is_mapped (bl->section))
-       continue;           /* unmapped overlay -- can't be a match */
-
-      return 1;
-    }
-
-  return 0;
-}
 \f
 
 /* bpstat stuff.  External routines' interfaces are documented
@@ -5024,6 +5052,9 @@ watchpoint_check (void *p)
       mark = value_mark ();
       fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL, 0);
 
+      if (b->val_bitsize != 0)
+       new_val = extract_bitfield_from_watchpoint_value (b, new_val);
+
       /* We use value_equal_contents instead of value_equal because
         the latter coerces an array to a pointer, thus comparing just
         the address of the array instead of its contents.  This is
@@ -5439,7 +5470,7 @@ bpstat_stop_status (struct address_space *aspace,
 
   ALL_BREAKPOINTS (b)
     {
-      if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
+      if (!breakpoint_enabled (b))
        continue;
 
       for (bl = b->loc; bl != NULL; bl = bl->next)
@@ -5483,6 +5514,7 @@ bpstat_stop_status (struct address_space *aspace,
        }
     }
 
+  /* Check if a moribund breakpoint explains the stop.  */
   for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
     {
       if (breakpoint_location_address_match (loc, aspace, bp_addr))
@@ -5534,8 +5566,7 @@ bpstat_stop_status (struct address_space *aspace,
              if (b->disposition == disp_disable)
                {
                  --(b->enable_count);
-                 if (b->enable_count <= 0
-                     && b->enable_state != bp_permanent)
+                 if (b->enable_count <= 0)
                    b->enable_state = bp_disabled;
                  removed_any = 1;
                }
@@ -5576,9 +5607,9 @@ bpstat_stop_status (struct address_space *aspace,
        }
 
   if (need_remove_insert)
-    update_global_location_list (1);
+    update_global_location_list (UGLL_MAY_INSERT);
   else if (removed_any)
-    update_global_location_list (0);
+    update_global_location_list (UGLL_DONT_INSERT);
 
   return bs_head;
 }
@@ -5638,6 +5669,7 @@ bpstat_what (bpstat bs_head)
          break;
        case bp_breakpoint:
        case bp_hardware_breakpoint:
+       case bp_single_step:
        case bp_until:
        case bp_finish:
        case bp_shlib_event:
@@ -5996,6 +6028,7 @@ bptype_string (enum bptype type)
     {bp_none, "?deleted?"},
     {bp_breakpoint, "breakpoint"},
     {bp_hardware_breakpoint, "hw breakpoint"},
+    {bp_single_step, "sw single-step"},
     {bp_until, "until"},
     {bp_finish, "finish"},
     {bp_watchpoint, "watchpoint"},
@@ -6187,6 +6220,7 @@ print_one_breakpoint_location (struct breakpoint *b,
 
       case bp_breakpoint:
       case bp_hardware_breakpoint:
+      case bp_single_step:
       case bp_until:
       case bp_finish:
       case bp_longjmp:
@@ -6816,8 +6850,6 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
                             ((b->enable_state == bp_disabled
                               || b->enable_state == bp_call_disabled)
                              ? " (disabled)"
-                             : b->enable_state == bp_permanent 
-                             ? " (permanent)"
                              : ""),
                             (others > 1) ? "," 
                             : ((others == 1) ? " and" : ""));
@@ -7029,6 +7061,16 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
          have their addresses modified.  */
       return bpaddr;
     }
+  else if (bptype == bp_single_step)
+    {
+      /* Single-step breakpoints should not have their addresses
+        modified.  If there's any architectural constrain that
+        applies to this address, then it should have already been
+        taken into account when the breakpoint was created in the
+        first place.  If we didn't do this, stepping through e.g.,
+        Thumb-2 IT blocks would break.  */
+      return bpaddr;
+    }
   else
     {
       CORE_ADDR adjusted_bpaddr;
@@ -7065,6 +7107,7 @@ init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
   switch (owner->type)
     {
     case bp_breakpoint:
+    case bp_single_step:
     case bp_until:
     case bp_finish:
     case bp_longjmp:
@@ -7338,15 +7381,16 @@ make_breakpoint_permanent (struct breakpoint *b)
 {
   struct bp_location *bl;
 
-  b->enable_state = bp_permanent;
-
   /* By definition, permanent breakpoints are already present in the
      code.  Mark all locations as inserted.  For now,
      make_breakpoint_permanent is called in just one place, so it's
      hard to say if it's reasonable to have permanent breakpoint with
      multiple locations or not, but it's easy to implement.  */
   for (bl = b->loc; bl; bl = bl->next)
-    bl->inserted = 1;
+    {
+      bl->permanent = 1;
+      bl->inserted = 1;
+    }
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -7374,7 +7418,7 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
        /* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
           after their removal.  */
        clone = momentary_breakpoint_from_master (b, type,
-                                                 &longjmp_breakpoint_ops);
+                                                 &longjmp_breakpoint_ops, 1);
        clone->thread = thread;
       }
 
@@ -7424,7 +7468,8 @@ set_longjmp_breakpoint_for_call_dummy (void)
        struct breakpoint *new_b;
 
        new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
-                                                 &momentary_breakpoint_ops);
+                                                 &momentary_breakpoint_ops,
+                                                 1);
        new_b->thread = pid_to_thread_id (inferior_ptid);
 
        /* Link NEW_B into the chain of RETVAL breakpoints.  */
@@ -7442,7 +7487,7 @@ set_longjmp_breakpoint_for_call_dummy (void)
 }
 
 /* Verify all existing dummy frames and their associated breakpoints for
-   THREAD.  Remove those which can no longer be found in the current frame
+   TP.  Remove those which can no longer be found in the current frame
    stack.
 
    You should call this function only at places where it is safe to currently
@@ -7450,12 +7495,12 @@ set_longjmp_breakpoint_for_call_dummy (void)
    frames.  */
 
 void
-check_longjmp_breakpoint_for_call_dummy (int thread)
+check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
 {
   struct breakpoint *b, *b_tmp;
 
   ALL_BREAKPOINTS_SAFE (b, b_tmp)
-    if (b->type == bp_longjmp_call_dummy && b->thread == thread)
+    if (b->type == bp_longjmp_call_dummy && b->thread == tp->num)
       {
        struct breakpoint *dummy_b = b->related_breakpoint;
 
@@ -7465,7 +7510,7 @@ check_longjmp_breakpoint_for_call_dummy (int thread)
            || frame_find_by_id (dummy_b->frame_id) != NULL)
          continue;
        
-       dummy_frame_discard (dummy_b->frame_id);
+       dummy_frame_discard (dummy_b->frame_id, tp->ptid);
 
        while (b->related_breakpoint != b)
          {
@@ -7486,7 +7531,7 @@ enable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_enabled;
-      update_global_location_list (1);
+      update_global_location_list (UGLL_MAY_INSERT);
       overlay_events_enabled = 1;
     }
 }
@@ -7500,7 +7545,7 @@ disable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_disabled;
-      update_global_location_list (0);
+      update_global_location_list (UGLL_DONT_INSERT);
       overlay_events_enabled = 0;
     }
 }
@@ -7517,7 +7562,7 @@ set_std_terminate_breakpoint (void)
        && b->type == bp_std_terminate_master)
       {
        momentary_breakpoint_from_master (b, bp_std_terminate,
-                                         &momentary_breakpoint_ops);
+                                         &momentary_breakpoint_ops, 1);
       }
 }
 
@@ -7545,7 +7590,7 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
   b->addr_string
     = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
 
-  update_global_location_list_nothrow (1);
+  update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
   return b;
 }
@@ -7576,7 +7621,7 @@ create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
 
   b = create_internal_breakpoint (gdbarch, address, bp_jit_event,
                                  &internal_breakpoint_ops);
-  update_global_location_list_nothrow (1);
+  update_global_location_list_nothrow (UGLL_MAY_INSERT);
   return b;
 }
 
@@ -7604,14 +7649,56 @@ remove_solib_event_breakpoints (void)
       delete_breakpoint (b);
 }
 
-struct breakpoint *
-create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+/* See breakpoint.h.  */
+
+void
+remove_solib_event_breakpoints_at_next_stop (void)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    if (b->type == bp_shlib_event
+       && b->loc->pspace == current_program_space)
+      b->disposition = disp_del_at_next_stop;
+}
+
+/* Helper for create_solib_event_breakpoint /
+   create_and_insert_solib_event_breakpoint.  Allows specifying which
+   INSERT_MODE to pass through to update_global_location_list.  */
+
+static struct breakpoint *
+create_solib_event_breakpoint_1 (struct gdbarch *gdbarch, CORE_ADDR address,
+                                enum ugll_insert_mode insert_mode)
 {
   struct breakpoint *b;
 
   b = create_internal_breakpoint (gdbarch, address, bp_shlib_event,
                                  &internal_breakpoint_ops);
-  update_global_location_list_nothrow (1);
+  update_global_location_list_nothrow (insert_mode);
+  return b;
+}
+
+struct breakpoint *
+create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+  return create_solib_event_breakpoint_1 (gdbarch, address, UGLL_MAY_INSERT);
+}
+
+/* See breakpoint.h.  */
+
+struct breakpoint *
+create_and_insert_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+  struct breakpoint *b;
+
+  /* Explicitly tell update_global_location_list to insert
+     locations.  */
+  b = create_solib_event_breakpoint_1 (gdbarch, address, UGLL_INSERT);
+  if (!b->loc->inserted)
+    {
+      delete_breakpoint (b);
+      return NULL;
+    }
   return b;
 }
 
@@ -7713,18 +7800,19 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
   if (objfile == NULL)
     return;
 
-  /* OBJF_USERLOADED are dynamic modules manually managed by the user
-     with add-symbol-file/remove-symbol-file.  Similarly to how
-     breakpoints in shared libraries are handled in response to
-     "nosharedlibrary", mark breakpoints in OBJF_USERLOADED modules
+  /* OBJF_SHARED|OBJF_USERLOADED objfiles are dynamic modules manually
+     managed by the user with add-symbol-file/remove-symbol-file.
+     Similarly to how breakpoints in shared libraries are handled in
+     response to "nosharedlibrary", mark breakpoints in such modules
      shlib_disabled so they end up uninserted on the next global
      location list update.  Shared libraries not loaded by the user
      aren't handled here -- they're already handled in
      disable_breakpoints_in_unloaded_shlib, called by solib.c's
      solib_unloaded observer.  We skip objfiles that are not
-     OBJF_USERLOADED (nor OBJF_SHARED) as those aren't considered
-     dynamic objects (e.g. the main objfile).  */
-  if ((objfile->flags & OBJF_USERLOADED) == 0)
+     OBJF_SHARED as those aren't considered dynamic objects (e.g. the
+     main objfile).  */
+  if ((objfile->flags & OBJF_SHARED) == 0
+      || (objfile->flags & OBJF_USERLOADED) == 0)
     return;
 
   ALL_BREAKPOINTS (b)
@@ -8727,7 +8815,7 @@ install_breakpoint (int internal, struct breakpoint *b, int update_gll)
   observer_notify_breakpoint_created (b);
 
   if (update_gll)
-    update_global_location_list (1);
+    update_global_location_list (UGLL_MAY_INSERT);
 }
 
 static void
@@ -8969,7 +9057,7 @@ disable_watchpoints_before_interactive_call_start (void)
     if (is_watchpoint (b) && breakpoint_enabled (b))
       {
        b->enable_state = bp_call_disabled;
-       update_global_location_list (0);
+       update_global_location_list (UGLL_DONT_INSERT);
       }
   }
 }
@@ -8984,7 +9072,7 @@ enable_watchpoints_after_interactive_call_stop (void)
     if (is_watchpoint (b) && b->enable_state == bp_call_disabled)
       {
        b->enable_state = bp_enabled;
-       update_global_location_list (1);
+       update_global_location_list (UGLL_MAY_INSERT);
       }
   }
 }
@@ -8993,7 +9081,7 @@ void
 disable_breakpoints_before_startup (void)
 {
   current_program_space->executing_startup = 1;
-  update_global_location_list (0);
+  update_global_location_list (UGLL_DONT_INSERT);
 }
 
 void
@@ -9003,10 +9091,31 @@ enable_breakpoints_after_startup (void)
   breakpoint_re_set ();
 }
 
+/* Create a new single-step breakpoint for thread THREAD, with no
+   locations.  */
+
+static struct breakpoint *
+new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
+{
+  struct breakpoint *b = XNEW (struct breakpoint);
+
+  init_raw_breakpoint_without_location (b, gdbarch, bp_single_step,
+                                       &momentary_breakpoint_ops);
+
+  b->disposition = disp_donttouch;
+  b->frame_id = null_frame_id;
+
+  b->thread = thread;
+  gdb_assert (b->thread != 0);
+
+  add_to_breakpoint_chain (b);
 
-/* Set a breakpoint that will evaporate an end of command
-   at address specified by SAL.
-   Restrict it to frame FRAME if FRAME is nonzero.  */
+  return b;
+}
+
+/* Set a momentary breakpoint of type TYPE at address specified by
+   SAL.  If FRAME_ID is valid, the breakpoint is restricted to that
+   frame.  */
 
 struct breakpoint *
 set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
@@ -9029,19 +9138,20 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
   if (in_thread_list (inferior_ptid))
     b->thread = pid_to_thread_id (inferior_ptid);
 
-  update_global_location_list_nothrow (1);
+  update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
   return b;
 }
 
 /* Make a momentary breakpoint based on the master breakpoint ORIG.
-   The new breakpoint will have type TYPE, and use OPS as it
-   breakpoint_ops.  */
+   The new breakpoint will have type TYPE, use OPS as its
+   breakpoint_ops, and will set enabled to LOC_ENABLED.  */
 
 static struct breakpoint *
 momentary_breakpoint_from_master (struct breakpoint *orig,
                                  enum bptype type,
-                                 const struct breakpoint_ops *ops)
+                                 const struct breakpoint_ops *ops,
+                                 int loc_enabled)
 {
   struct breakpoint *copy;
 
@@ -9057,6 +9167,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->probe = orig->loc->probe;
   copy->loc->line_number = orig->loc->line_number;
   copy->loc->symtab = orig->loc->symtab;
+  copy->loc->enabled = loc_enabled;
   copy->frame_id = orig->frame_id;
   copy->thread = orig->thread;
   copy->pspace = orig->pspace;
@@ -9065,7 +9176,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->disposition = disp_donttouch;
   copy->number = internal_breakpoint_number--;
 
-  update_global_location_list_nothrow (0);
+  update_global_location_list_nothrow (UGLL_DONT_INSERT);
   return copy;
 }
 
@@ -9079,7 +9190,7 @@ clone_momentary_breakpoint (struct breakpoint *orig)
   if (orig == NULL)
     return NULL;
 
-  return momentary_breakpoint_from_master (orig, orig->type, orig->ops);
+  return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
 }
 
 struct breakpoint *
@@ -9109,6 +9220,8 @@ mention (struct breakpoint *b)
 }
 \f
 
+static int bp_loc_is_permanent (struct bp_location *loc);
+
 static struct bp_location *
 add_location_to_breakpoint (struct breakpoint *b,
                            const struct symtab_and_line *sal)
@@ -9150,6 +9263,13 @@ add_location_to_breakpoint (struct breakpoint *b,
 
   set_breakpoint_location_function (loc,
                                    sal->explicit_pc || sal->explicit_line);
+
+  if (bp_loc_is_permanent (loc))
+    {
+      loc->inserted = 1;
+      loc->permanent = 1;
+    }
+
   return loc;
 }
 \f
@@ -9392,9 +9512,6 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
            loc->inserted = 1;
        }
 
-      if (bp_loc_is_permanent (loc))
-       make_breakpoint_permanent (b);
-
       if (b->cond_string)
        {
          const char *arg = b->cond_string;
@@ -10020,7 +10137,7 @@ create_breakpoint (struct gdbarch *gdbarch,
   do_cleanups (old_chain);
 
   /* error call may happen here - have BKPT_CHAIN already discarded.  */
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 
   return 1;
 }
@@ -10083,8 +10200,8 @@ resolve_sal_pc (struct symtab_and_line *sal)
 
   if (sal->section == 0 && sal->symtab != NULL)
     {
-      struct blockvector *bv;
-      struct block *b;
+      const struct blockvector *bv;
+      const struct block *b;
       struct symbol *sym;
 
       bv = blockvector_for_pc_sect (sal->pc, 0, &b, sal->symtab);
@@ -10532,7 +10649,7 @@ break_range_command (char *arg, int from_tty)
 
   mention (b);
   observer_notify_breakpoint_created (b);
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 }
 
 /*  Return non-zero if EXP is verified as constant.  Returned zero
@@ -10581,8 +10698,6 @@ watchpoint_exp_is_const (const struct expression *exp)
        case BINOP_MAX:
        case BINOP_INTDIV:
        case BINOP_CONCAT:
-       case BINOP_IN:
-       case BINOP_RANGE:
        case TERNOP_COND:
        case TERNOP_SLICE:
 
@@ -11155,6 +11270,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   struct expression *exp;
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
   struct value *val, *mark, *result;
+  int saved_bitpos = 0, saved_bitsize = 0;
   struct frame_info *frame;
   const char *exp_start = NULL;
   const char *exp_end = NULL;
@@ -11288,6 +11404,12 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   mark = value_mark ();
   fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location);
 
+  if (val != NULL && just_location)
+    {
+      saved_bitpos = value_bitpos (val);
+      saved_bitsize = value_bitsize (val);
+    }
+
   if (just_location)
     {
       int ret;
@@ -11423,6 +11545,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   else
     {
       w->val = val;
+      w->val_bitpos = saved_bitpos;
+      w->val_bitsize = saved_bitsize;
       w->val_valid = 1;
     }
 
@@ -11649,7 +11773,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
   int thread;
   struct thread_info *tp;
 
-  clear_proceed_status ();
+  clear_proceed_status (0);
 
   /* Set a breakpoint where the user wants it and at return from
      this function.  */
@@ -12227,7 +12351,7 @@ breakpoint_auto_delete (bpstat bs)
 /* A comparison function for bp_location AP and BP being interfaced to
    qsort.  Sort elements primarily by their ADDRESS (no matter what
    does breakpoint_address_is_meaningful say for its OWNER),
-   secondarily by ordering first bp_permanent OWNERed elements and
+   secondarily by ordering first permanent elements and
    terciarily just ensuring the array is sorted stable way despite
    qsort being an unstable algorithm.  */
 
@@ -12236,9 +12360,6 @@ bp_location_compare (const void *ap, const void *bp)
 {
   struct bp_location *a = *(void **) ap;
   struct bp_location *b = *(void **) bp;
-  /* A and B come from existing breakpoints having non-NULL OWNER.  */
-  int a_perm = a->owner->enable_state == bp_permanent;
-  int b_perm = b->owner->enable_state == bp_permanent;
 
   if (a->address != b->address)
     return (a->address > b->address) - (a->address < b->address);
@@ -12252,8 +12373,8 @@ bp_location_compare (const void *ap, const void *bp)
            - (a->pspace->num < b->pspace->num));
 
   /* Sort permanent breakpoints first.  */
-  if (a_perm != b_perm)
-    return (a_perm < b_perm) - (a_perm > b_perm);
+  if (a->permanent != b->permanent)
+    return (a->permanent < b->permanent) - (a->permanent > b->permanent);
 
   /* Make the internal GDB representation stable across GDB runs
      where A and B memory inside GDB can differ.  Breakpoint locations of
@@ -12428,24 +12549,16 @@ force_breakpoint_reinsertion (struct bp_location *bl)
        }
     }
 }
+/* Called whether new breakpoints are created, or existing breakpoints
+   deleted, to update the global location list and recompute which
+   locations are duplicate of which.
 
-/* If SHOULD_INSERT is false, do not insert any breakpoint locations
-   into the inferior, only remove already-inserted locations that no
-   longer should be inserted.  Functions that delete a breakpoint or
-   breakpoints should pass false, so that deleting a breakpoint
-   doesn't have the side effect of inserting the locations of other
-   breakpoints that are marked not-inserted, but should_be_inserted
-   returns true on them.
-
-   This behaviour is useful is situations close to tear-down -- e.g.,
-   after an exec, while the target still has execution, but breakpoint
-   shadows of the previous executable image should *NOT* be restored
-   to the new image; or before detaching, where the target still has
-   execution and wants to delete breakpoints from GDB's lists, and all
-   breakpoints had already been removed from the inferior.  */
+   The INSERT_MODE flag determines whether locations may not, may, or
+   shall be inserted now.  See 'enum ugll_insert_mode' for more
+   info.  */
 
 static void
-update_global_location_list (int should_insert)
+update_global_location_list (enum ugll_insert_mode insert_mode)
 {
   struct breakpoint *b;
   struct bp_location **locp, *loc;
@@ -12732,7 +12845,7 @@ update_global_location_list (int should_insert)
        }
 
       /* Permanent breakpoint should always be inserted.  */
-      if (b->enable_state == bp_permanent && ! loc->inserted)
+      if (loc->permanent && ! loc->inserted)
        internal_error (__FILE__, __LINE__,
                        _("allegedly permanent breakpoint is not "
                        "actually inserted"));
@@ -12773,30 +12886,30 @@ update_global_location_list (int should_insert)
       /* Clear the condition modification flag.  */
       loc->condition_changed = condition_unchanged;
 
-      if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
-         && b->enable_state != bp_permanent)
+      if (loc->inserted && !loc->permanent
+         && (*loc_first_p)->permanent)
        internal_error (__FILE__, __LINE__,
                        _("another breakpoint was inserted on top of "
                        "a permanent breakpoint"));
     }
 
-  if (breakpoints_always_inserted_mode ()
-      && (have_live_inferiors ()
-         || (gdbarch_has_global_breakpoints (target_gdbarch ()))))
+  if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ())
     {
-      if (should_insert)
+      if (insert_mode != UGLL_DONT_INSERT)
        insert_breakpoint_locations ();
       else
        {
-         /* Though should_insert is false, we may need to update conditions
-            on the target's side if it is evaluating such conditions.  We
+         /* Even though the caller told us to not insert new
+            locations, we may still need to update conditions on the
+            target's side of breakpoints that were already inserted
+            if the target is evaluating breakpoint conditions.  We
             only update conditions for locations that are marked
             "needs_update".  */
          update_inserted_breakpoint_locations ();
        }
     }
 
-  if (should_insert)
+  if (insert_mode != UGLL_DONT_INSERT)
     download_tracepoint_locations ();
 
   do_cleanups (cleanups);
@@ -12818,12 +12931,12 @@ breakpoint_retire_moribund (void)
 }
 
 static void
-update_global_location_list_nothrow (int inserting)
+update_global_location_list_nothrow (enum ugll_insert_mode insert_mode)
 {
   volatile struct gdb_exception e;
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
-    update_global_location_list (inserting);
+    update_global_location_list (insert_mode);
 }
 
 /* Clear BKP from a BPS.  */
@@ -13116,11 +13229,9 @@ static int
 bkpt_insert_location (struct bp_location *bl)
 {
   if (bl->loc_type == bp_loc_hardware_breakpoint)
-    return target_insert_hw_breakpoint (bl->gdbarch,
-                                       &bl->target_info);
+    return target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info);
   else
-    return target_insert_breakpoint (bl->gdbarch,
-                                    &bl->target_info);
+    return target_insert_breakpoint (bl->gdbarch, &bl->target_info);
 }
 
 static int
@@ -13475,9 +13586,10 @@ bkpt_probe_insert_location (struct bp_location *bl)
     {
       /* The insertion was successful, now let's set the probe's semaphore
         if needed.  */
-      bl->probe.probe->pops->set_semaphore (bl->probe.probe,
-                                           bl->probe.objfile,
-                                           bl->gdbarch);
+      if (bl->probe.probe->pops->set_semaphore != NULL)
+       bl->probe.probe->pops->set_semaphore (bl->probe.probe,
+                                             bl->probe.objfile,
+                                             bl->gdbarch);
     }
 
   return v;
@@ -13487,9 +13599,10 @@ static int
 bkpt_probe_remove_location (struct bp_location *bl)
 {
   /* Let's clear the semaphore before removing the location.  */
-  bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
-                                         bl->probe.objfile,
-                                         bl->gdbarch);
+  if (bl->probe.probe->pops->clear_semaphore != NULL)
+    bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
+                                           bl->probe.objfile,
+                                           bl->gdbarch);
 
   return bkpt_remove_location (bl);
 }
@@ -13934,7 +14047,7 @@ delete_breakpoint (struct breakpoint *bpt)
      itself, since remove_breakpoint looks at location's owner.  It
      might be better design to have location completely
      self-contained, but it's not the case now.  */
-  update_global_location_list (0);
+  update_global_location_list (UGLL_DONT_INSERT);
 
   bpt->ops->dtor (bpt);
   /* On the chance that someone will soon try again to delete this
@@ -14263,7 +14376,7 @@ update_breakpoint_locations (struct breakpoint *b,
       /* Ranged breakpoints have only one start location and one end
         location.  */
       b->enable_state = bp_disabled;
-      update_global_location_list (1);
+      update_global_location_list (UGLL_MAY_INSERT);
       printf_unfiltered (_("Could not reset ranged breakpoint %d: "
                           "multiple locations found\n"),
                         b->number);
@@ -14320,10 +14433,6 @@ update_breakpoint_locations (struct breakpoint *b,
        }
     }
 
-  /* Update locations of permanent breakpoints.  */
-  if (b->enable_state == bp_permanent)
-    make_breakpoint_permanent (b);
-
   /* If possible, carry over 'disable' status from existing
      breakpoints.  */
   {
@@ -14366,7 +14475,7 @@ update_breakpoint_locations (struct breakpoint *b,
   if (!locations_are_equal (existing_locations, b->loc))
     observer_notify_breakpoint_modified (b);
 
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 }
 
 /* Find the SaL locations corresponding to the given ADDR_STRING.
@@ -14727,7 +14836,7 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
 
   while (!state.finished)
     {
-      char *p = state.string;
+      const char *p = state.string;
 
       match = 0;
 
@@ -14806,10 +14915,6 @@ disable_breakpoint (struct breakpoint *bpt)
   if (bpt->type == bp_watchpoint_scope)
     return;
 
-  /* You can't disable permanent breakpoints.  */
-  if (bpt->enable_state == bp_permanent)
-    return;
-
   bpt->enable_state = bp_disabled;
 
   /* Mark breakpoint locations modified.  */
@@ -14824,7 +14929,7 @@ disable_breakpoint (struct breakpoint *bpt)
        target_disable_tracepoint (location);
     }
 
-  update_global_location_list (0);
+  update_global_location_list (UGLL_DONT_INSERT);
 
   observer_notify_breakpoint_modified (bpt);
 }
@@ -14879,7 +14984,7 @@ disable_command (char *args, int from_tty)
                      && is_tracepoint (loc->owner))
                    target_disable_tracepoint (loc);
                }
-             update_global_location_list (0);
+             update_global_location_list (UGLL_DONT_INSERT);
            }
          else
            map_breakpoint_numbers (num, do_map_disable_breakpoint, NULL);
@@ -14930,9 +15035,6 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
        }
     }
 
-  if (bpt->enable_state != bp_permanent)
-    bpt->enable_state = bp_enabled;
-
   bpt->enable_state = bp_enabled;
 
   /* Mark breakpoint locations modified.  */
@@ -14949,7 +15051,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
 
   bpt->disposition = disposition;
   bpt->enable_count = count;
-  update_global_location_list (1);
+  update_global_location_list (UGLL_MAY_INSERT);
 
   observer_notify_breakpoint_modified (bpt);
 }
@@ -15013,7 +15115,7 @@ enable_command (char *args, int from_tty)
                      && is_tracepoint (loc->owner))
                    target_enable_tracepoint (loc);
                }
-             update_global_location_list (1);
+             update_global_location_list (UGLL_MAY_INSERT);
            }
          else
            map_breakpoint_numbers (num, do_map_enable_breakpoint, NULL);
@@ -15127,48 +15229,6 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior,
       }
 }
 
-/* Create and insert a raw software breakpoint at PC.  Return an
-   identifier, which should be used to remove the breakpoint later.
-   In general, places which call this should be using something on the
-   breakpoint chain instead; this function should be eliminated
-   someday.  */
-
-void *
-deprecated_insert_raw_breakpoint (struct gdbarch *gdbarch,
-                                 struct address_space *aspace, CORE_ADDR pc)
-{
-  struct bp_target_info *bp_tgt;
-
-  bp_tgt = XCNEW (struct bp_target_info);
-
-  bp_tgt->placed_address_space = aspace;
-  bp_tgt->placed_address = pc;
-
-  if (target_insert_breakpoint (gdbarch, bp_tgt) != 0)
-    {
-      /* Could not insert the breakpoint.  */
-      xfree (bp_tgt);
-      return NULL;
-    }
-
-  return bp_tgt;
-}
-
-/* Remove a breakpoint BP inserted by
-   deprecated_insert_raw_breakpoint.  */
-
-int
-deprecated_remove_raw_breakpoint (struct gdbarch *gdbarch, void *bp)
-{
-  struct bp_target_info *bp_tgt = bp;
-  int ret;
-
-  ret = target_remove_breakpoint (gdbarch, bp_tgt);
-  xfree (bp_tgt);
-
-  return ret;
-}
-
 /* Create and insert a breakpoint for software single step.  */
 
 void
@@ -15176,118 +15236,57 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
                               struct address_space *aspace, 
                               CORE_ADDR next_pc)
 {
-  void **bpt_p;
+  struct thread_info *tp = inferior_thread ();
+  struct symtab_and_line sal;
+  CORE_ADDR pc = next_pc;
 
-  if (single_step_breakpoints[0] == NULL)
-    {
-      bpt_p = &single_step_breakpoints[0];
-      single_step_gdbarch[0] = gdbarch;
-    }
-  else
+  if (tp->control.single_step_breakpoints == NULL)
     {
-      gdb_assert (single_step_breakpoints[1] == NULL);
-      bpt_p = &single_step_breakpoints[1];
-      single_step_gdbarch[1] = gdbarch;
+      tp->control.single_step_breakpoints
+       = new_single_step_breakpoint (tp->num, gdbarch);
     }
 
-  /* NOTE drow/2006-04-11: A future improvement to this function would
-     be to only create the breakpoints once, and actually put them on
-     the breakpoint chain.  That would let us use set_raw_breakpoint.
-     We could adjust the addresses each time they were needed.  Doing
-     this requires corresponding changes elsewhere where single step
-     breakpoints are handled, however.  So, for now, we use this.  */
+  sal = find_pc_line (pc, 0);
+  sal.pc = pc;
+  sal.section = find_pc_overlay (pc);
+  sal.explicit_pc = 1;
+  add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
 
-  *bpt_p = deprecated_insert_raw_breakpoint (gdbarch, aspace, next_pc);
-  if (*bpt_p == NULL)
-    error (_("Could not insert single-step breakpoint at %s"),
-            paddress (gdbarch, next_pc));
+  update_global_location_list (UGLL_INSERT);
 }
 
-/* Check if the breakpoints used for software single stepping
-   were inserted or not.  */
+/* See breakpoint.h.  */
 
 int
-single_step_breakpoints_inserted (void)
-{
-  return (single_step_breakpoints[0] != NULL
-          || single_step_breakpoints[1] != NULL);
-}
-
-/* Remove and delete any breakpoints used for software single step.  */
-
-void
-remove_single_step_breakpoints (void)
-{
-  gdb_assert (single_step_breakpoints[0] != NULL);
-
-  /* See insert_single_step_breakpoint for more about this deprecated
-     call.  */
-  deprecated_remove_raw_breakpoint (single_step_gdbarch[0],
-                                   single_step_breakpoints[0]);
-  single_step_gdbarch[0] = NULL;
-  single_step_breakpoints[0] = NULL;
-
-  if (single_step_breakpoints[1] != NULL)
-    {
-      deprecated_remove_raw_breakpoint (single_step_gdbarch[1],
-                                       single_step_breakpoints[1]);
-      single_step_gdbarch[1] = NULL;
-      single_step_breakpoints[1] = NULL;
-    }
-}
-
-/* Delete software single step breakpoints without removing them from
-   the inferior.  This is intended to be used if the inferior's address
-   space where they were inserted is already gone, e.g. after exit or
-   exec.  */
-
-void
-cancel_single_step_breakpoints (void)
+breakpoint_has_location_inserted_here (struct breakpoint *bp,
+                                      struct address_space *aspace,
+                                      CORE_ADDR pc)
 {
-  int i;
-
-  for (i = 0; i < 2; i++)
-    if (single_step_breakpoints[i])
-      {
-       xfree (single_step_breakpoints[i]);
-       single_step_breakpoints[i] = NULL;
-       single_step_gdbarch[i] = NULL;
-      }
-}
-
-/* Detach software single-step breakpoints from INFERIOR_PTID without
-   removing them.  */
+  struct bp_location *loc;
 
-static void
-detach_single_step_breakpoints (void)
-{
-  int i;
+  for (loc = bp->loc; loc != NULL; loc = loc->next)
+    if (loc->inserted
+       && breakpoint_location_address_match (loc, aspace, pc))
+      return 1;
 
-  for (i = 0; i < 2; i++)
-    if (single_step_breakpoints[i])
-      target_remove_breakpoint (single_step_gdbarch[i],
-                               single_step_breakpoints[i]);
+  return 0;
 }
 
 /* Check whether a software single-step breakpoint is inserted at
    PC.  */
 
 int
-single_step_breakpoint_inserted_here_p (struct address_space *aspace, 
+single_step_breakpoint_inserted_here_p (struct address_space *aspace,
                                        CORE_ADDR pc)
 {
-  int i;
+  struct breakpoint *bpt;
 
-  for (i = 0; i < 2; i++)
+  ALL_BREAKPOINTS (bpt)
     {
-      struct bp_target_info *bp_tgt = single_step_breakpoints[i];
-      if (bp_tgt
-         && breakpoint_address_match (bp_tgt->placed_address_space,
-                                      bp_tgt->placed_address,
-                                      aspace, pc))
+      if (bpt->type == bp_single_step
+         && breakpoint_has_location_inserted_here (bpt, aspace, pc))
        return 1;
     }
-
   return 0;
 }
 
@@ -15860,7 +15859,7 @@ save_breakpoints (char *filename, int from_tty,
       }
 
     if (tp->enable_state == bp_disabled)
-      fprintf_unfiltered (fp, "disable\n");
+      fprintf_unfiltered (fp, "disable $bpnum\n");
 
     /* If this is a multi-location breakpoint, check if the locations
        should be individually disabled.  Watchpoint locations are
@@ -15949,8 +15948,7 @@ static struct cmd_list_element *tcatch_cmdlist;
 
 void
 add_catch_command (char *name, char *docstring,
-                  void (*sfunc) (char *args, int from_tty,
-                                 struct cmd_list_element *command),
+                  cmd_sfunc_ftype *sfunc,
                   completer_ftype *completer,
                   void *user_data_catch,
                   void *user_data_tcatch)
@@ -15986,7 +15984,7 @@ save_command (char *arg, int from_tty)
 {
   printf_unfiltered (_("\"save\" must be followed by "
                       "the name of a save subcommand.\n"));
-  help_list (save_cmdlist, "save ", -1, gdb_stdout);
+  help_list (save_cmdlist, "save ", all_commands, gdb_stdout);
 }
 
 struct breakpoint *
@@ -16777,18 +16775,15 @@ a warning will be emitted for such breakpoints."),
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
 
-  add_setshow_auto_boolean_cmd ("always-inserted", class_support,
-                               &always_inserted_mode, _("\
+  add_setshow_boolean_cmd ("always-inserted", class_support,
+                          &always_inserted_mode, _("\
 Set mode for inserting breakpoints."), _("\
 Show mode for inserting breakpoints."), _("\
-When this mode is off, breakpoints are inserted in inferior when it is\n\
-resumed, and removed when execution stops.  When this mode is on,\n\
-breakpoints are inserted immediately and removed only when the user\n\
-deletes the breakpoint.  When this mode is auto (which is the default),\n\
-the behaviour depends on the non-stop setting (see help set non-stop).\n\
-In this case, if gdb is controlling the inferior in non-stop mode, gdb\n\
-behaves as if always-inserted mode is on; if gdb is controlling the\n\
-inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
+When this mode is on, breakpoints are inserted immediately as soon as\n\
+they're created, kept inserted even when execution stops, and removed\n\
+only when the user deletes them.  When this mode is off (the default),\n\
+breakpoints are inserted only when execution continues, and removed\n\
+when execution stops."),
                                NULL,
                                &show_always_inserted_mode,
                                &breakpoint_set_cmdlist,
This page took 0.070623 seconds and 4 git commands to generate.