*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 2554337b0fdc06f62f644f270e9764710a7de261..783b797494b6a0403c665e8cd13266ad84a306d7 100644 (file)
@@ -67,6 +67,7 @@
 #include "continuations.h"
 #include "stack.h"
 #include "skip.h"
+#include "record.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -377,8 +378,9 @@ show_always_inserted_mode (struct ui_file *file, int from_tty,
 int
 breakpoints_always_inserted_mode (void)
 {
-  return (always_inserted_mode == always_inserted_on
-         || (always_inserted_mode == always_inserted_auto && non_stop));
+  return ((always_inserted_mode == always_inserted_on
+          || (always_inserted_mode == always_inserted_auto && non_stop))
+         && !RECORD_IS_USED);
 }
 
 void _initialize_breakpoint (void);
@@ -1047,7 +1049,9 @@ bp_location_has_shadow (struct bp_location *bl)
      bl->address + bp_location_shadow_len_after_address_max <= memaddr  */
 
 void
-breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len)
+breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
+                       const gdb_byte *writebuf_org,
+                       ULONGEST memaddr, LONGEST len)
 {
   /* Left boundary, right boundary and median element of our binary
      search.  */
@@ -1159,8 +1163,32 @@ breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len)
        bp_size -= (bp_addr + bp_size) - (memaddr + len);
       }
 
-    memcpy (buf + bp_addr - memaddr,
-           bl->target_info.shadow_contents + bptoffset, bp_size);
+    if (readbuf != NULL)
+      {
+       /* Update the read buffer with this inserted breakpoint's
+          shadow.  */
+       memcpy (readbuf + bp_addr - memaddr,
+               bl->target_info.shadow_contents + bptoffset, bp_size);
+      }
+    else
+      {
+       struct gdbarch *gdbarch = bl->gdbarch;
+       const unsigned char *bp;
+       CORE_ADDR placed_address = bl->target_info.placed_address;
+       unsigned placed_size = bl->target_info.placed_size;
+
+       /* Update the shadow with what we want to write to memory.  */
+       memcpy (bl->target_info.shadow_contents + bptoffset,
+               writebuf_org + bp_addr - memaddr, bp_size);
+
+       /* Determine appropriate breakpoint contents and size for this
+          address.  */
+       bp = gdbarch_breakpoint_from_pc (gdbarch, &placed_address, &placed_size);
+
+       /* Update the final write buffer with this inserted
+          breakpoint's INSN.  */
+       memcpy (writebuf + bp_addr - memaddr, bp + bptoffset, bp_size);
+      }
   }
 }
 \f
@@ -1574,6 +1602,9 @@ should_be_inserted (struct bp_location *bl)
   if (!bl->enabled || bl->shlib_disabled || bl->duplicate)
     return 0;
 
+  if (user_breakpoint_p (bl->owner) && bl->pspace->executing_startup)
+    return 0;
+
   /* This is set for example, when we're attached to the parent of a
      vfork, and have detached from the child.  The child is running
      free, and we expect it to do an exec or exit, at which point the
@@ -1943,7 +1974,7 @@ insert_breakpoint_locations (void)
 {
   struct breakpoint *bpt;
   struct bp_location *bl, **blp_tmp;
-  int error = 0;
+  int error_flag = 0;
   int val = 0;
   int disabled_breaks = 0;
   int hw_breakpoint_error = 0;
@@ -1982,7 +2013,7 @@ insert_breakpoint_locations (void)
       val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
                                    &hw_breakpoint_error);
       if (val)
-       error = val;
+       error_flag = val;
     }
 
   /* If we failed to insert all locations of a watchpoint, remove
@@ -2017,11 +2048,11 @@ insert_breakpoint_locations (void)
          fprintf_unfiltered (tmp_error_stream,
                              "Could not insert hardware watchpoint %d.\n", 
                              bpt->number);
-         error = -1;
+         error_flag = -1;
        }
     }
 
-  if (error)
+  if (error_flag)
     {
       /* If a hardware breakpoint or watchpoint was inserted, add a
          message about possibly exhausted resources.  */
@@ -3446,7 +3477,8 @@ print_bp_stop_message (bpstat bs)
 
 /* Print a message indicating what happened.  This is called from
    normal_stop().  The input to this routine is the head of the bpstat
-   list - a list of the eventpoints that caused this stop.  This
+   list - a list of the eventpoints that caused this stop.  KIND is
+   the target_waitkind for the stopping event.  This
    routine calls the generic print routine for printing a message
    about reasons for stopping.  This will print (for example) the
    "Breakpoint n," part of the output.  The return value of this
@@ -3465,7 +3497,7 @@ print_bp_stop_message (bpstat bs)
    further info to be printed.  */
 
 enum print_stop_action
-bpstat_print (bpstat bs)
+bpstat_print (bpstat bs, int kind)
 {
   int val;
 
@@ -3482,6 +3514,18 @@ bpstat_print (bpstat bs)
        return val;
     }
 
+  /* If we had hit a shared library event breakpoint,
+     print_bp_stop_message would print out this message.  If we hit an
+     OS-level shared library event, do the same thing.  */
+  if (kind == TARGET_WAITKIND_LOADED)
+    {
+      ui_out_text (current_uiout, _("Stopped due to shared library event\n"));
+      if (ui_out_is_mi_like_p (current_uiout))
+       ui_out_field_string (current_uiout, "reason",
+                            async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+      return PRINT_NOTHING;
+    }
+
   /* We reached the end of the chain, or we got a null BS to start
      with and nothing was printed.  */
   return PRINT_UNKNOWN;
@@ -4547,7 +4591,7 @@ print_breakpoint_location (struct breakpoint *b,
 
   if (b->display_canonical)
     ui_out_field_string (uiout, "what", b->addr_string);
-  else if (b->source_file && loc)
+  else if (loc && loc->source_file)
     {
       struct symbol *sym 
        = find_pc_sect_function (loc->address, loc->section);
@@ -4560,7 +4604,7 @@ print_breakpoint_location (struct breakpoint *b,
          ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
          ui_out_text (uiout, "at ");
        }
-      ui_out_field_string (uiout, "file", b->source_file);
+      ui_out_field_string (uiout, "file", loc->source_file);
       ui_out_text (uiout, ":");
       
       if (ui_out_is_mi_like_p (uiout))
@@ -4572,7 +4616,7 @@ print_breakpoint_location (struct breakpoint *b,
            ui_out_field_string (uiout, "fullname", fullname);
        }
       
-      ui_out_field_int (uiout, "line", b->line_number);
+      ui_out_field_int (uiout, "line", loc->line_number);
     }
   else if (loc)
     {
@@ -4879,6 +4923,8 @@ print_one_breakpoint_location (struct breakpoint *b,
       /* FIXME should make an annotation for this.  */
       if (ep_is_catchpoint (b))
        ui_out_text (uiout, "\tcatchpoint");
+      else if (is_tracepoint (b))
+       ui_out_text (uiout, "\ttracepoint");
       else
        ui_out_text (uiout, "\tbreakpoint");
       ui_out_text (uiout, " already hit ");
@@ -4903,6 +4949,18 @@ print_one_breakpoint_location (struct breakpoint *b,
       ui_out_text (uiout, " hits\n");
     }
 
+  if (!part_of_multiple && is_tracepoint (b))
+    {
+      struct tracepoint *tp = (struct tracepoint *) b;
+
+      if (tp->traceframe_usage)
+       {
+         ui_out_text (uiout, "\ttrace buffer usage ");
+         ui_out_field_int (uiout, "traceframe-usage", tp->traceframe_usage);
+         ui_out_text (uiout, " bytes\n");
+       }
+    }
+  
   l = b->commands ? b->commands->commands : NULL;
   if (!part_of_multiple && l)
     {
@@ -5314,8 +5372,7 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
              printf_filtered (" (thread %d)", b->thread);
            printf_filtered ("%s%s ",
                             ((b->enable_state == bp_disabled
-                              || b->enable_state == bp_call_disabled
-                              || b->enable_state == bp_startup_disabled)
+                              || b->enable_state == bp_call_disabled)
                              ? " (disabled)"
                              : b->enable_state == bp_permanent 
                              ? " (permanent)"
@@ -5790,15 +5847,11 @@ init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
   if (bptype != bp_catchpoint)
     gdb_assert (sal.pspace != NULL);
 
-  /* Store the program space that was used to set the breakpoint, for
-     breakpoint resetting.  */
-  b->pspace = sal.pspace;
-
-  if (sal.symtab == NULL)
-    b->source_file = NULL;
-  else
-    b->source_file = xstrdup (sal.symtab->filename);
-  b->line_number = sal.line;
+  /* Store the program space that was used to set the breakpoint,
+     except for ordinary breakpoints, which are independent of the
+     program space.  */
+  if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
+    b->pspace = sal.pspace;
 
   breakpoints_changed ();
 }
@@ -6176,12 +6229,25 @@ breakpoint_hit_catch_fork (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_fork (bpstat bs)
 {
+  struct ui_out *uiout = current_uiout;
   struct breakpoint *b = bs->breakpoint_at;
   struct fork_catchpoint *c = (struct fork_catchpoint *) bs->breakpoint_at;
 
   annotate_catchpoint (b->number);
-  printf_filtered (_("\nCatchpoint %d (forked process %d), "),
-                  b->number, ptid_get_pid (c->forked_inferior_pid));
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary catchpoint ");
+  else
+    ui_out_text (uiout, "\nCatchpoint ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (EXEC_ASYNC_FORK));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, " (forked process ");
+  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
+  ui_out_text (uiout, "), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6272,12 +6338,25 @@ breakpoint_hit_catch_vfork (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_vfork (bpstat bs)
 {
+  struct ui_out *uiout = current_uiout;
   struct breakpoint *b = bs->breakpoint_at;
   struct fork_catchpoint *c = (struct fork_catchpoint *) b;
 
   annotate_catchpoint (b->number);
-  printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
-                  b->number, ptid_get_pid (c->forked_inferior_pid));
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary catchpoint ");
+  else
+    ui_out_text (uiout, "\nCatchpoint ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (EXEC_ASYNC_VFORK));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, " (vforked process ");
+  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
+  ui_out_text (uiout, "), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6486,6 +6565,7 @@ breakpoint_hit_catch_syscall (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_syscall (bpstat bs)
 {
+  struct ui_out *uiout = current_uiout;
   struct breakpoint *b = bs->breakpoint_at;
   /* These are needed because we want to know in which state a
      syscall is.  It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
@@ -6494,7 +6574,6 @@ print_it_catch_syscall (bpstat bs)
   ptid_t ptid;
   struct target_waitstatus last;
   struct syscall s;
-  struct cleanup *old_chain;
   char *syscall_id;
 
   get_last_target_status (&ptid, &last);
@@ -6503,21 +6582,31 @@ print_it_catch_syscall (bpstat bs)
 
   annotate_catchpoint (b->number);
 
-  if (s.name == NULL)
-    syscall_id = xstrprintf ("%d", last.value.syscall_number);
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary catchpoint ");
   else
-    syscall_id = xstrprintf ("'%s'", s.name);
-
-  old_chain = make_cleanup (xfree, syscall_id);
+    ui_out_text (uiout, "\nCatchpoint ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
+                                               ? EXEC_ASYNC_SYSCALL_ENTRY
+                                               : EXEC_ASYNC_SYSCALL_RETURN));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+  ui_out_field_int (uiout, "bkptno", b->number);
 
   if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
-    printf_filtered (_("\nCatchpoint %d (call to syscall %s), "),
-                     b->number, syscall_id);
-  else if (last.kind == TARGET_WAITKIND_SYSCALL_RETURN)
-    printf_filtered (_("\nCatchpoint %d (returned from syscall %s), "),
-                     b->number, syscall_id);
+    ui_out_text (uiout, " (call to syscall ");
+  else
+    ui_out_text (uiout, " (returned from syscall ");
 
-  do_cleanups (old_chain);
+  if (s.name == NULL || ui_out_is_mi_like_p (uiout))
+    ui_out_field_int (uiout, "syscall-number", last.value.syscall_number);
+  if (s.name != NULL)
+    ui_out_field_string (uiout, "syscall-name", s.name);
+
+  ui_out_text (uiout, "), ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -6762,12 +6851,26 @@ breakpoint_hit_catch_exec (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_exec (bpstat bs)
 {
+  struct ui_out *uiout = current_uiout;
   struct breakpoint *b = bs->breakpoint_at;
   struct exec_catchpoint *c = (struct exec_catchpoint *) b;
 
   annotate_catchpoint (b->number);
-  printf_filtered (_("\nCatchpoint %d (exec'd %s), "), b->number,
-                  c->exec_pathname);
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary catchpoint ");
+  else
+    ui_out_text (uiout, "\nCatchpoint ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (EXEC_ASYNC_EXEC));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, " (exec'd ");
+  ui_out_field_string (uiout, "new-exec", c->exec_pathname);
+  ui_out_text (uiout, "), ");
+
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6932,53 +7035,15 @@ enable_watchpoints_after_interactive_call_stop (void)
 void
 disable_breakpoints_before_startup (void)
 {
-  struct breakpoint *b;
-  int found = 0;
-
-  ALL_BREAKPOINTS (b)
-    {
-      if (b->pspace != current_program_space)
-       continue;
-
-      if ((b->type == bp_breakpoint
-          || b->type == bp_hardware_breakpoint)
-         && breakpoint_enabled (b))
-       {
-         b->enable_state = bp_startup_disabled;
-         found = 1;
-       }
-    }
-
-  if (found)
-    update_global_location_list (0);
-
   current_program_space->executing_startup = 1;
+  update_global_location_list (0);
 }
 
 void
 enable_breakpoints_after_startup (void)
 {
-  struct breakpoint *b;
-  int found = 0;
-
   current_program_space->executing_startup = 0;
-
-  ALL_BREAKPOINTS (b)
-    {
-      if (b->pspace != current_program_space)
-       continue;
-
-      if ((b->type == bp_breakpoint
-          || b->type == bp_hardware_breakpoint)
-         && b->enable_state == bp_startup_disabled)
-       {
-         b->enable_state = bp_enabled;
-         found = 1;
-       }
-    }
-
-  if (found)
-    breakpoint_re_set ();
+  breakpoint_re_set ();
 }
 
 
@@ -7033,12 +7098,10 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->section = orig->loc->section;
   copy->loc->pspace = orig->loc->pspace;
 
-  if (orig->source_file == NULL)
-    copy->source_file = NULL;
-  else
-    copy->source_file = xstrdup (orig->source_file);
+  if (orig->loc->source_file != NULL)
+    copy->loc->source_file = xstrdup (orig->loc->source_file);
 
-  copy->line_number = orig->line_number;
+  copy->loc->line_number = orig->loc->line_number;
   copy->frame_id = orig->frame_id;
   copy->thread = orig->thread;
   copy->pspace = orig->pspace;
@@ -7122,6 +7185,11 @@ add_location_to_breakpoint (struct breakpoint *b,
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
+
+  if (sal->symtab != NULL)
+    loc->source_file = xstrdup (sal->symtab->filename);
+  loc->line_number = sal->line;
+
   set_breakpoint_location_function (loc,
                                    sal->explicit_pc || sal->explicit_line);
   return loc;
@@ -7136,7 +7204,7 @@ bp_loc_is_permanent (struct bp_location *loc)
 {
   int len;
   CORE_ADDR addr;
-  const gdb_byte *brk;
+  const gdb_byte *bpoint;
   gdb_byte *target_mem;
   struct cleanup *cleanup;
   int retval = 0;
@@ -7144,10 +7212,10 @@ bp_loc_is_permanent (struct bp_location *loc)
   gdb_assert (loc != NULL);
 
   addr = loc->address;
-  brk = gdbarch_breakpoint_from_pc (loc->gdbarch, &addr, &len);
+  bpoint = gdbarch_breakpoint_from_pc (loc->gdbarch, &addr, &len);
 
   /* Software breakpoints unsupported?  */
-  if (brk == NULL)
+  if (bpoint == NULL)
     return 0;
 
   target_mem = alloca (len);
@@ -7161,7 +7229,7 @@ bp_loc_is_permanent (struct bp_location *loc)
   make_show_memory_breakpoints_cleanup (0);
 
   if (target_read_memory (loc->address, target_mem, len) == 0
-      && memcmp (target_mem, brk, len) == 0)
+      && memcmp (target_mem, bpoint, len) == 0)
     retval = 1;
 
   do_cleanups (cleanup);
@@ -7178,7 +7246,7 @@ bp_loc_is_permanent (struct bp_location *loc)
 static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                     struct symtabs_and_lines sals, char *addr_string,
-                    char *cond_string,
+                    char *filter, char *cond_string,
                     enum bptype type, enum bpdisp disposition,
                     int thread, int task, int ignore_count,
                     const struct breakpoint_ops *ops, int from_tty,
@@ -7188,9 +7256,11 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
 
   if (type == bp_hardware_breakpoint)
     {
-      int i = hw_breakpoint_used_count ();
-      int target_resources_ok = 
-       target_can_use_hardware_watchpoint (bp_hardware_breakpoint, 
+      int target_resources_ok;
+
+      i = hw_breakpoint_used_count ();
+      target_resources_ok =
+       target_can_use_hardware_watchpoint (bp_hardware_breakpoint,
                                            i + 1, 0);
       if (target_resources_ok == 0)
        error (_("No hardware breakpoint support in the target."));
@@ -7225,7 +7295,6 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          b->ignore_count = ignore_count;
          b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
-         b->pspace = sals.sals[0].pspace;
 
          if (type == bp_static_tracepoint)
            {
@@ -7239,7 +7308,6 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                  char *p = &addr_string[3];
                  char *endp;
                  char *marker_str;
-                 int i;
 
                  p = skip_spaces (p);
 
@@ -7266,11 +7334,6 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                           "tracepoint marker to probe"));
            }
 
-         if (enabled && b->pspace->executing_startup
-             && (b->type == bp_breakpoint
-                 || b->type == bp_hardware_breakpoint))
-           b->enable_state = bp_startup_disabled;
-
          loc = b->loc;
        }
       else
@@ -7298,12 +7361,13 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
        me.  */
     b->addr_string
       = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
+  b->filter = filter;
 }
 
 static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
                       struct symtabs_and_lines sals, char *addr_string,
-                      char *cond_string,
+                      char *filter, char *cond_string,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       const struct breakpoint_ops *ops, int from_tty,
@@ -7326,7 +7390,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 
   init_breakpoint_sal (b, gdbarch,
                       sals, addr_string,
-                      cond_string,
+                      filter, cond_string,
                       type, disposition,
                       thread, task, ignore_count,
                       ops, from_tty,
@@ -7336,138 +7400,6 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
   install_breakpoint (internal, b, 0);
 }
 
-/* Remove element at INDEX_TO_REMOVE from SAL, shifting other
-   elements to fill the void space.  */
-static void
-remove_sal (struct symtabs_and_lines *sal, int index_to_remove)
-{
-  int i = index_to_remove+1;
-  int last_index = sal->nelts-1;
-
-  for (;i <= last_index; ++i)
-    sal->sals[i-1] = sal->sals[i];
-
-  --(sal->nelts);
-}
-
-/* If appropriate, obtains all sals that correspond to the same file
-   and line as SAL, in all program spaces.  Users debugging with IDEs,
-   will want to set a breakpoint at foo.c:line, and not really care
-   about program spaces.  This is done only if SAL does not have
-   explicit PC and has line and file information.  If we got just a
-   single expanded sal, return the original.
-
-   Otherwise, if SAL.explicit_line is not set, filter out all sals for
-   which the name of enclosing function is different from SAL.  This
-   makes sure that if we have breakpoint originally set in template
-   instantiation, say foo<int>(), we won't expand SAL to locations at
-   the same line in all existing instantiations of 'foo'.  */
-
-static struct symtabs_and_lines
-expand_line_sal_maybe (struct symtab_and_line sal)
-{
-  struct symtabs_and_lines expanded;
-  CORE_ADDR original_pc = sal.pc;
-  char *original_function = NULL;
-  int found;
-  int i;
-  struct cleanup *old_chain;
-
-  /* If we have explicit pc, don't expand.
-     If we have no line number, we can't expand.  */
-  if (sal.explicit_pc || sal.line == 0 || sal.symtab == NULL)
-    {
-      expanded.nelts = 1;
-      expanded.sals = xmalloc (sizeof (struct symtab_and_line));
-      expanded.sals[0] = sal;
-      return expanded;
-    }
-
-  sal.pc = 0;
-
-  old_chain = save_current_space_and_thread ();
-
-  switch_to_program_space_and_thread (sal.pspace);
-
-  find_pc_partial_function (original_pc, &original_function, NULL, NULL);
-
-  /* Note that expand_line_sal visits *all* program spaces.  */
-  expanded = expand_line_sal (sal);
-
-  if (expanded.nelts == 1)
-    {
-      /* We had one sal, we got one sal.  Return that sal, adjusting it
-         past the function prologue if necessary.  */
-      xfree (expanded.sals);
-      expanded.nelts = 1;
-      expanded.sals = xmalloc (sizeof (struct symtab_and_line));
-      sal.pc = original_pc;
-      expanded.sals[0] = sal;
-      skip_prologue_sal (&expanded.sals[0]);
-      do_cleanups (old_chain);
-      return expanded;      
-    }
-
-  if (!sal.explicit_line)
-    {
-      CORE_ADDR func_addr, func_end;
-      for (i = 0; i < expanded.nelts; ++i)
-       {
-         CORE_ADDR pc = expanded.sals[i].pc;
-         char *this_function;
-
-         /* We need to switch threads as well since we're about to
-            read memory.  */
-         switch_to_program_space_and_thread (expanded.sals[i].pspace);
-
-         if (find_pc_partial_function (pc, &this_function, 
-                                       &func_addr, &func_end))
-           {
-             if (this_function
-                 && strcmp (this_function, original_function) != 0)
-               {
-                 remove_sal (&expanded, i);
-                 --i;
-               }
-           }
-       }
-    }
-
-  /* Skip the function prologue if necessary.  */
-  for (i = 0; i < expanded.nelts; ++i)
-    skip_prologue_sal (&expanded.sals[i]);
-
-  do_cleanups (old_chain);
-
-  if (expanded.nelts <= 1)
-    {
-      /* This is an ugly workaround.  If we get zero expanded sals
-         then something is really wrong.  Fix that by returning the
-         original sal.  */
-
-      xfree (expanded.sals);
-      expanded.nelts = 1;
-      expanded.sals = xmalloc (sizeof (struct symtab_and_line));
-      sal.pc = original_pc;
-      expanded.sals[0] = sal;
-      return expanded;      
-    }
-
-  if (original_pc)
-    {
-      found = 0;
-      for (i = 0; i < expanded.nelts; ++i)
-       if (expanded.sals[i].pc == original_pc)
-         {
-           found = 1;
-           break;
-         }
-      gdb_assert (found);
-    }
-
-  return expanded;
-}
-
 /* Add SALS.nelts breakpoints to the breakpoint table.  For each
    SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i]
    value.  COND_STRING, if not NULL, specified the condition to be
@@ -7485,7 +7417,6 @@ expand_line_sal_maybe (struct symtab_and_line sal)
 
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
-                       struct symtabs_and_lines sals,
                        struct linespec_result *canonical,
                        char *cond_string,
                        enum bptype type, enum bpdisp disposition,
@@ -7494,17 +7425,30 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
                        int enabled, int internal)
 {
   int i;
+  struct linespec_sals *lsal;
 
-  for (i = 0; i < sals.nelts; ++i)
+  if (canonical->pre_expanded)
+    gdb_assert (VEC_length (linespec_sals, canonical->sals) == 1);
+
+  for (i = 0; VEC_iterate (linespec_sals, canonical->sals, i, lsal); ++i)
     {
-      struct symtabs_and_lines expanded = 
-       expand_line_sal_maybe (sals.sals[i]);
+      /* Note that 'addr_string' can be NULL in the case of a plain
+        'break', without arguments.  */
+      char *addr_string = (canonical->addr_string
+                          ? xstrdup (canonical->addr_string)
+                          : NULL);
+      char *filter_string = lsal->canonical ? xstrdup (lsal->canonical) : NULL;
+      struct cleanup *inner = make_cleanup (xfree, addr_string);
 
-      create_breakpoint_sal (gdbarch, expanded, canonical->canonical[i],
+      make_cleanup (xfree, filter_string);
+      create_breakpoint_sal (gdbarch, lsal->sals,
+                            addr_string,
+                            filter_string,
                             cond_string, type, disposition,
                             thread, task, ignore_count, ops,
                             from_tty, enabled, internal,
                             canonical->special_display);
+      discard_cleanups (inner);
     }
 }
 
@@ -7518,7 +7462,6 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
 
 static void
 parse_breakpoint_sals (char **address,
-                      struct symtabs_and_lines *sals,
                       struct linespec_result *canonical)
 {
   char *addr_start = *address;
@@ -7532,10 +7475,11 @@ parse_breakpoint_sals (char **address,
          address.  */
       if (last_displayed_sal_is_valid ())
        {
+         struct linespec_sals lsal;
          struct symtab_and_line sal;
 
          init_sal (&sal);              /* Initialize to zeroes.  */
-         sals->sals = (struct symtab_and_line *)
+         lsal.sals.sals = (struct symtab_and_line *)
            xmalloc (sizeof (struct symtab_and_line));
 
          /* Set sal's pspace, pc, symtab, and line to the values
@@ -7550,8 +7494,11 @@ parse_breakpoint_sals (char **address,
             instances with the same symtab and line.  */
          sal.explicit_pc = 1;
 
-         sals->sals[0] = sal;
-         sals->nelts = 1;
+         lsal.sals.sals[0] = sal;
+         lsal.sals.nelts = 1;
+         lsal.canonical = NULL;
+
+         VEC_safe_push (linespec_sals, canonical->sals, &lsal);
        }
       else
        error (_("No default breakpoint address now."));
@@ -7561,40 +7508,16 @@ parse_breakpoint_sals (char **address,
       /* Force almost all breakpoints to be in terms of the
          current_source_symtab (which is decode_line_1's default).
          This should produce the results we want almost all of the
-        time while leaving the last displayed codepoint pointers
-        alone.
-
-         ObjC: However, don't match an Objective-C method name which
-         may have a '+' or '-' succeeded by a '[' */
-        
-      struct symtab_and_line cursal = get_current_source_symtab_and_line ();
-                       
-      if (last_displayed_sal_is_valid ()
-         && (!cursal.symtab
-             || ((strchr ("+-", (*address)[0]) != NULL)
-                 && ((*address)[1] != '['))))
-       *sals = decode_line_1 (address, 1,
-                              get_last_displayed_symtab (),
-                              get_last_displayed_line (),
-                              canonical);
+         time while leaving default_breakpoint_* alone.  */
+      if (last_displayed_sal_is_valid ())
+       decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
+                         get_last_displayed_symtab (),
+                         get_last_displayed_line (),
+                         canonical, NULL, NULL);
       else
-       *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0,
-                              canonical);
-    }
-  /* For any SAL that didn't have a canonical string, fill one in.  */
-  if (sals->nelts > 0 && canonical->canonical == NULL)
-    canonical->canonical = xcalloc (sals->nelts, sizeof (char *));
-  if (addr_start != (*address))
-    {
-      int i;
-
-      for (i = 0; i < sals->nelts; i++)
-       {
-         /* Add the string if not present.  */
-         if (canonical->canonical[i] == NULL)
-           canonical->canonical[i] = savestring (addr_start, 
-                                                 (*address) - addr_start);
-       }
+       decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
+                         (struct symtab *) NULL, 0,
+                         canonical, NULL, NULL);
     }
 }
 
@@ -7629,15 +7552,22 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
 
   for (i = 0; i < sals->nelts; i++)
     {
+      struct gdbarch *sarch;
+
       sal = &sals->sals[i];
 
-      rslt = gdbarch_fast_tracepoint_valid_at (gdbarch, sal->pc,
+      sarch = get_sal_arch (*sal);
+      /* We fall back to GDBARCH if there is no architecture
+        associated with SAL.  */
+      if (sarch == NULL)
+       sarch = gdbarch;
+      rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal->pc,
                                               NULL, &msg);
       old_chain = make_cleanup (xfree, msg);
 
       if (!rslt)
        error (_("May not have a fast tracepoint at 0x%s%s"),
-              paddress (gdbarch, sal->pc), (msg ? msg : ""));
+              paddress (sarch, sal->pc), (msg ? msg : ""));
 
       do_cleanups (old_chain);
     }
@@ -7779,9 +7709,7 @@ create_breakpoint (struct gdbarch *gdbarch,
                   int from_tty, int enabled, int internal)
 {
   volatile struct gdb_exception e;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line pending_sal;
-  char *copy_arg;
+  char *copy_arg = NULL;
   char *addr_start = arg;
   struct linespec_result canonical;
   struct cleanup *old_chain;
@@ -7793,26 +7721,27 @@ create_breakpoint (struct gdbarch *gdbarch,
 
   gdb_assert (ops != NULL);
 
-  sals.sals = NULL;
-  sals.nelts = 0;
   init_linespec_result (&canonical);
 
   if (type_wanted == bp_static_tracepoint && is_marker_spec (arg))
     {
       int i;
+      struct linespec_sals lsal;
 
-      sals = decode_static_tracepoint_spec (&arg);
+      lsal.sals = decode_static_tracepoint_spec (&arg);
 
       copy_arg = savestring (addr_start, arg - addr_start);
-      canonical.canonical = xcalloc (sals.nelts, sizeof (char *));
-      for (i = 0; i < sals.nelts; i++)
-       canonical.canonical[i] = xstrdup (copy_arg);
+
+      canonical.addr_string = xstrdup (copy_arg);
+      lsal.canonical = xstrdup (copy_arg);
+      VEC_safe_push (linespec_sals, canonical.sals, &lsal);
+
       goto done;
     }
 
   TRY_CATCH (e, RETURN_MASK_ALL)
     {
-      parse_breakpoint_sals (&arg, &sals, &canonical);
+      parse_breakpoint_sals (&arg, &canonical);
     }
 
   /* If caller is interested in rc value from parse, set value.  */
@@ -7836,43 +7765,39 @@ create_breakpoint (struct gdbarch *gdbarch,
           /* If pending breakpoint support is auto query and the user
             selects no, then simply return the error code.  */
          if (pending_break_support == AUTO_BOOLEAN_AUTO
-             && !nquery (_("Make breakpoint pending on "
-                           "future shared library load? ")))
+             && !nquery (_("Make %s pending on future shared library load? "),
+                         bptype_string (type_wanted)))
            return 0;
 
          /* At this point, either the user was queried about setting
             a pending breakpoint and selected yes, or pending
             breakpoint behavior is on and thus a pending breakpoint
             is defaulted on behalf of the user.  */
-         copy_arg = xstrdup (addr_start);
-         canonical.canonical = &copy_arg;
-         sals.nelts = 1;
-         sals.sals = &pending_sal;
-         pending_sal.pc = 0;
-         pending = 1;
+         {
+           struct linespec_sals lsal;
+
+           copy_arg = xstrdup (addr_start);
+           lsal.canonical = xstrdup (copy_arg);
+           lsal.sals.nelts = 1;
+           lsal.sals.sals = XNEW (struct symtab_and_line);
+           init_sal (&lsal.sals.sals[0]);
+           pending = 1;
+           VEC_safe_push (linespec_sals, canonical.sals, &lsal);
+         }
          break;
        default:
          throw_exception (e);
        }
       break;
     default:
-      if (!sals.nelts)
+      if (VEC_empty (linespec_sals, canonical.sals))
        return 0;
     }
 
   done:
 
   /* Create a chain of things that always need to be cleaned up.  */
-  old_chain = make_cleanup (null_cleanup, 0);
-
-  if (!pending)
-    {
-      /* Make sure that all storage allocated to SALS gets freed.  */
-      make_cleanup (xfree, sals.sals);
-      
-      /* Cleanup the canonical array but not its contents.  */
-      make_cleanup (xfree, canonical.canonical);
-    }
+  old_chain = make_cleanup_destroy_linespec_result (&canonical);
 
   /* ----------------------------- SNIP -----------------------------
      Anything added to the cleanup chain beyond this point is assumed
@@ -7880,28 +7805,36 @@ create_breakpoint (struct gdbarch *gdbarch,
      then the memory is not reclaimed.  */
   bkpt_chain = make_cleanup (null_cleanup, 0);
 
-  /* Mark the contents of the canonical for cleanup.  These go on
-     the bkpt_chain and only occur if the breakpoint create fails.  */
-  for (i = 0; i < sals.nelts; i++)
-    {
-      if (canonical.canonical[i] != NULL)
-       make_cleanup (xfree, canonical.canonical[i]);
-    }
-
   /* Resolve all line numbers to PC's and verify that the addresses
      are ok for the target.  */
   if (!pending)
-    breakpoint_sals_to_pc (&sals);
+    {
+      int ix;
+      struct linespec_sals *iter;
+
+      for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
+       breakpoint_sals_to_pc (&iter->sals);
+    }
 
   /* Fast tracepoints may have additional restrictions on location.  */
-  if (type_wanted == bp_fast_tracepoint)
-    check_fast_tracepoint_sals (gdbarch, &sals);
+  if (!pending && type_wanted == bp_fast_tracepoint)
+    {
+      int ix;
+      struct linespec_sals *iter;
+
+      for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
+       check_fast_tracepoint_sals (gdbarch, &iter->sals);
+    }
 
   /* Verify that condition can be parsed, before setting any
      breakpoints.  Allocate a separate condition expression for each
      breakpoint.  */
   if (!pending)
     {
+      struct linespec_sals *lsal;
+
+      lsal = VEC_index (linespec_sals, canonical.sals, 0);
+
       if (parse_condition_and_thread)
         {
             /* Here we only parse 'arg' to separate condition
@@ -7910,7 +7843,7 @@ create_breakpoint (struct gdbarch *gdbarch,
                re-parse it in context of each sal.  */
             cond_string = NULL;
             thread = -1;
-            find_condition_and_thread (arg, sals.sals[0].pc, &cond_string,
+            find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
                                        &thread, &task);
             if (cond_string)
                 make_cleanup (xfree, cond_string);
@@ -7932,24 +7865,26 @@ create_breakpoint (struct gdbarch *gdbarch,
         expand multiple locations for each sal, given than SALS
         already should contain all sals for MARKER_ID.  */
       if (type_wanted == bp_static_tracepoint
-         && is_marker_spec (canonical.canonical[0]))
+         && is_marker_spec (copy_arg))
        {
          int i;
 
-         for (i = 0; i < sals.nelts; ++i)
+         for (i = 0; i < lsal->sals.nelts; ++i)
            {
              struct symtabs_and_lines expanded;
              struct tracepoint *tp;
              struct cleanup *old_chain;
+             char *addr_string;
 
              expanded.nelts = 1;
-             expanded.sals = xmalloc (sizeof (struct symtab_and_line));
-             expanded.sals[0] = sals.sals[i];
-             old_chain = make_cleanup (xfree, expanded.sals);
+             expanded.sals = &lsal->sals.sals[i];
+
+             addr_string = xstrdup (canonical.addr_string);
+             old_chain = make_cleanup (xfree, addr_string);
 
              tp = XCNEW (struct tracepoint);
              init_breakpoint_sal (&tp->base, gdbarch, expanded,
-                                  canonical.canonical[i],
+                                  addr_string, NULL,
                                   cond_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
@@ -7965,11 +7900,11 @@ create_breakpoint (struct gdbarch *gdbarch,
 
              install_breakpoint (internal, &tp->base, 0);
 
-             do_cleanups (old_chain);
+             discard_cleanups (old_chain);
            }
        }
       else
-       create_breakpoints_sal (gdbarch, sals, &canonical, cond_string,
+       create_breakpoints_sal (gdbarch, &canonical, cond_string,
                                type_wanted,
                                tempflag ? disp_del : disp_donttouch,
                                thread, task, ignore_count, ops, from_tty,
@@ -7981,31 +7916,31 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       make_cleanup (xfree, copy_arg);
 
-      b = set_raw_breakpoint_without_location (gdbarch, type_wanted, ops);
-      set_breakpoint_number (internal, b);
-      b->thread = -1;
-      b->addr_string = canonical.canonical[0];
+      if (is_tracepoint_type (type_wanted))
+       {
+         struct tracepoint *t;
+
+         t = XCNEW (struct tracepoint);
+         b = &t->base;
+       }
+      else
+       b = XNEW (struct breakpoint);
+
+      init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
+
+      b->addr_string = copy_arg;
       b->cond_string = NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
       b->enable_state = enabled ? bp_enabled : bp_disabled;
-      b->pspace = current_program_space;
-      b->py_bp_object = NULL;
-
-      if (enabled && b->pspace->executing_startup
-         && (b->type == bp_breakpoint
-             || b->type == bp_hardware_breakpoint))
-       b->enable_state = bp_startup_disabled;
+      if (type_wanted != bp_breakpoint && type_wanted != bp_hardware_breakpoint)
+       b->pspace = current_program_space;
 
-      if (!internal)
-        /* Do not mention breakpoints with a negative number, 
-          but do notify observers.  */
-       mention (b);
-      observer_notify_breakpoint_created (b);
+      install_breakpoint (internal, b, 0);
     }
   
-  if (sals.nelts > 1)
+  if (VEC_length (linespec_sals, canonical.sals) > 1)
     {
       warning (_("Multiple breakpoints were set.\nUse the "
                 "\"delete\" command to delete unwanted breakpoints."));
@@ -8386,8 +8321,8 @@ break_range_command (char *arg, int from_tty)
   CORE_ADDR end;
   struct breakpoint *b;
   struct symtab_and_line sal_start, sal_end;
-  struct symtabs_and_lines sals_start, sals_end;
   struct cleanup *cleanup_bkpt;
+  struct linespec_sals *lsal_start, *lsal_end;
 
   /* We don't support software ranged breakpoints.  */
   if (target_ranged_break_num_registers () < 0)
@@ -8400,71 +8335,62 @@ break_range_command (char *arg, int from_tty)
   if (can_use_bp < 0)
     error (_("Hardware breakpoints used exceeds limit."));
 
+  arg = skip_spaces (arg);
   if (arg == NULL || arg[0] == '\0')
     error(_("No address range specified."));
 
-  sals_start.sals = NULL;
-  sals_start.nelts = 0;
   init_linespec_result (&canonical_start);
 
-  while (*arg == ' ' || *arg == '\t')
-    arg++;
-
-  parse_breakpoint_sals (&arg, &sals_start, &canonical_start);
+  arg_start = arg;
+  parse_breakpoint_sals (&arg, &canonical_start);
 
-  sal_start = sals_start.sals[0];
-  addr_string_start = canonical_start.canonical[0];
-  cleanup_bkpt = make_cleanup (xfree, addr_string_start);
-  xfree (sals_start.sals);
-  xfree (canonical_start.canonical);
+  cleanup_bkpt = make_cleanup_destroy_linespec_result (&canonical_start);
 
   if (arg[0] != ',')
     error (_("Too few arguments."));
-  else if (sals_start.nelts == 0)
+  else if (VEC_empty (linespec_sals, canonical_start.sals))
     error (_("Could not find location of the beginning of the range."));
-  else if (sals_start.nelts != 1)
+
+  lsal_start = VEC_index (linespec_sals, canonical_start.sals, 0);
+
+  if (VEC_length (linespec_sals, canonical_start.sals) > 1
+      || lsal_start->sals.nelts != 1)
     error (_("Cannot create a ranged breakpoint with multiple locations."));
 
-  resolve_sal_pc (&sal_start);
+  sal_start = lsal_start->sals.sals[0];
+  addr_string_start = savestring (arg_start, arg - arg_start);
+  make_cleanup (xfree, addr_string_start);
 
   arg++;       /* Skip the comma.  */
-  while (*arg == ' ' || *arg == '\t')
-    arg++;
+  arg = skip_spaces (arg);
 
   /* Parse the end location.  */
 
-  sals_end.sals = NULL;
-  sals_end.nelts = 0;
   init_linespec_result (&canonical_end);
   arg_start = arg;
 
-  /* We call decode_line_1 directly here instead of using
+  /* We call decode_line_full directly here instead of using
      parse_breakpoint_sals because we need to specify the start location's
      symtab and line as the default symtab and line for the end of the
      range.  This makes it possible to have ranges like "foo.c:27, +14",
      where +14 means 14 lines from the start location.  */
-  sals_end = decode_line_1 (&arg, 1, sal_start.symtab, sal_start.line,
-                           &canonical_end);
-
-  /* canonical_end can be NULL if it was of the form "*0xdeadbeef".  */
-  if (canonical_end.canonical == NULL)
-    canonical_end.canonical = xcalloc (1, sizeof (char *));
-  /* Add the string if not present.  */
-  if (arg_start != arg && canonical_end.canonical[0] == NULL)
-    canonical_end.canonical[0] = savestring (arg_start, arg - arg_start);
-
-  sal_end = sals_end.sals[0];
-  addr_string_end = canonical_end.canonical[0];
-  make_cleanup (xfree, addr_string_end);
-  xfree (sals_end.sals);
-  xfree (canonical_end.canonical);
+  decode_line_full (&arg, DECODE_LINE_FUNFIRSTLINE,
+                   sal_start.symtab, sal_start.line,
+                   &canonical_end, NULL, NULL);
+
+  make_cleanup_destroy_linespec_result (&canonical_end);
 
-  if (sals_end.nelts == 0)
+  if (VEC_empty (linespec_sals, canonical_end.sals))
     error (_("Could not find location of the end of the range."));
-  else if (sals_end.nelts != 1)
+
+  lsal_end = VEC_index (linespec_sals, canonical_end.sals, 0);
+  if (VEC_length (linespec_sals, canonical_end.sals) > 1
+      || lsal_end->sals.nelts != 1)
     error (_("Cannot create a ranged breakpoint with multiple locations."));
 
-  resolve_sal_pc (&sal_end);
+  sal_end = lsal_end->sals.sals[0];
+  addr_string_end = savestring (arg_start, arg - arg_start);
+  make_cleanup (xfree, addr_string_end);
 
   end = find_breakpoint_range_end (sal_end);
   if (sal_start.pc > end)
@@ -8491,11 +8417,11 @@ break_range_command (char *arg, int from_tty)
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
   b->disposition = disp_donttouch;
-  b->addr_string = addr_string_start;
-  b->addr_string_range_end = addr_string_end;
+  b->addr_string = xstrdup (addr_string_start);
+  b->addr_string_range_end = xstrdup (addr_string_end);
   b->loc->length = length;
 
-  discard_cleanups (cleanup_bkpt);
+  do_cleanups (cleanup_bkpt);
 
   mention (b);
   observer_notify_breakpoint_created (b);
@@ -9602,12 +9528,12 @@ until_break_command (char *arg, int from_tty, int anywhere)
      this function.  */
 
   if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (&arg, 1,
+    sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE,
                          get_last_displayed_symtab (),
-                         get_last_displayed_line (),
-                         NULL);
+                         get_last_displayed_line ());
   else
-    sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, NULL);
+    sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE,
+                         (struct symtab *) NULL, 0);
 
   if (sals.nelts != 1)
     error (_("Couldn't get information on specified line."));
@@ -10103,22 +10029,46 @@ tcatch_command (char *arg, int from_tty)
   error (_("Catch requires an event name."));
 }
 
+/* A qsort comparison function that sorts breakpoints in order.  */
+
+static int
+compare_breakpoints (const void *a, const void *b)
+{
+  const breakpoint_p *ba = a;
+  uintptr_t ua = (uintptr_t) *ba;
+  const breakpoint_p *bb = b;
+  uintptr_t ub = (uintptr_t) *bb;
+
+  if ((*ba)->number < (*bb)->number)
+    return -1;
+  else if ((*ba)->number > (*bb)->number)
+    return 1;
+
+  /* Now sort by address, in case we see, e..g, two breakpoints with
+     the number 0.  */
+  if (ua < ub)
+    return -1;
+  return ub > ub ? 1 : 0;
+}
+
 /* Delete breakpoints by address or line.  */
 
 static void
 clear_command (char *arg, int from_tty)
 {
-  struct breakpoint *b;
+  struct breakpoint *b, *prev;
   VEC(breakpoint_p) *found = 0;
   int ix;
   int default_match;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   int i;
+  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
 
   if (arg)
     {
-      sals = decode_line_spec (arg, 1);
+      sals = decode_line_spec (arg, (DECODE_LINE_FUNFIRSTLINE
+                                    | DECODE_LINE_LIST_MODE));
       default_match = 0;
     }
   else
@@ -10164,6 +10114,7 @@ clear_command (char *arg, int from_tty)
      breakpoint.  */
 
   found = NULL;
+  make_cleanup (VEC_cleanup (breakpoint_p), &found);
   for (i = 0; i < sals.nelts; i++)
     {
       /* If exact pc given, clear bpts at that pc.
@@ -10190,18 +10141,21 @@ clear_command (char *arg, int from_tty)
              struct bp_location *loc = b->loc;
              for (; loc; loc = loc->next)
                {
-                 int pc_match = sal.pc
-                   && (loc->pspace == sal.pspace)
-                   && (loc->address == sal.pc)
-                   && (!section_is_overlay (loc->section)
-                       || loc->section == sal.section);
-                 int line_match = ((default_match || (0 == sal.pc))
-                                   && b->source_file != NULL
+                 /* If the user specified file:line, don't allow a PC
+                    match.  This matches historical gdb behavior.  */
+                 int pc_match = (!sal.explicit_line
+                                 && sal.pc
+                                 && (loc->pspace == sal.pspace)
+                                 && (loc->address == sal.pc)
+                                 && (!section_is_overlay (loc->section)
+                                     || loc->section == sal.section));
+                 int line_match = ((default_match || sal.explicit_line)
+                                   && loc->source_file != NULL
                                    && sal.symtab != NULL
                                    && sal.pspace == loc->pspace
-                                   && filename_cmp (b->source_file,
+                                   && filename_cmp (loc->source_file,
                                                     sal.symtab->filename) == 0
-                                   && b->line_number == sal.line);
+                                   && loc->line_number == sal.line);
                  if (pc_match || line_match)
                    {
                      match = 1;
@@ -10214,6 +10168,7 @@ clear_command (char *arg, int from_tty)
            VEC_safe_push(breakpoint_p, found, b);
        }
     }
+
   /* Now go thru the 'found' chain and delete them.  */
   if (VEC_empty(breakpoint_p, found))
     {
@@ -10223,6 +10178,21 @@ clear_command (char *arg, int from_tty)
        error (_("No breakpoint at this line."));
     }
 
+  /* Remove duplicates from the vec.  */
+  qsort (VEC_address (breakpoint_p, found),
+        VEC_length (breakpoint_p, found),
+        sizeof (breakpoint_p),
+        compare_breakpoints);
+  prev = VEC_index (breakpoint_p, found, 0);
+  for (ix = 1; VEC_iterate (breakpoint_p, found, ix, b); ++ix)
+    {
+      if (b == prev)
+       {
+         VEC_ordered_remove (breakpoint_p, found, ix);
+         --ix;
+       }
+    }
+
   if (VEC_length(breakpoint_p, found) > 1)
     from_tty = 1;      /* Always report if deleted more than one.  */
   if (from_tty)
@@ -10242,6 +10212,8 @@ clear_command (char *arg, int from_tty)
     }
   if (from_tty)
     putchar_unfiltered ('\n');
+
+  do_cleanups (cleanups);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints and
@@ -10663,14 +10635,10 @@ update_global_location_list (int should_insert)
     {
       /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always
         non-NULL.  */
-      struct breakpoint *b = loc->owner;
       struct bp_location **loc_first_p;
+      b = loc->owner;
 
-      if (b->enable_state == bp_disabled
-         || b->enable_state == bp_call_disabled
-         || b->enable_state == bp_startup_disabled
-         || !loc->enabled
-         || loc->shlib_disabled
+      if (!should_be_inserted (loc)
          || !breakpoint_address_is_meaningful (b)
          /* Don't detect duplicate for tracepoint locations because they are
           never duplicated.  See the comments in field `duplicate' of
@@ -10797,15 +10765,25 @@ say_where (struct breakpoint *b)
     }
   else
     {
-      if (opts.addressprint || b->source_file == NULL)
+      if (opts.addressprint || b->loc->source_file == NULL)
        {
          printf_filtered (" at ");
          fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
                          gdb_stdout);
        }
-      if (b->source_file)
-       printf_filtered (": file %s, line %d.",
-                        b->source_file, b->line_number);
+      if (b->loc->source_file)
+       {
+         /* If there is a single location, we can print the location
+            more nicely.  */
+         if (b->loc->next == NULL)
+           printf_filtered (": file %s, line %d.",
+                            b->loc->source_file, b->loc->line_number);
+         else
+           /* This is not ideal, but each location may have a
+              different file name, and this at least reflects the
+              real situation somewhat.  */
+           printf_filtered (": %s.", b->addr_string);
+       }
 
       if (b->loc->next)
        {
@@ -10825,6 +10803,7 @@ bp_location_dtor (struct bp_location *self)
 {
   xfree (self->cond);
   xfree (self->function_name);
+  xfree (self->source_file);
 }
 
 static const struct bp_location_ops bp_location_ops =
@@ -10841,8 +10820,8 @@ base_breakpoint_dtor (struct breakpoint *self)
   decref_counted_command_line (&self->commands);
   xfree (self->cond_string);
   xfree (self->addr_string);
+  xfree (self->filter);
   xfree (self->addr_string_range_end);
-  xfree (self->source_file);
 }
 
 static struct bp_location *
@@ -10956,10 +10935,6 @@ static struct breakpoint_ops base_breakpoint_ops =
 static void
 bkpt_re_set (struct breakpoint *b)
 {
-  /* Do not attempt to re-set breakpoints disabled during startup.  */
-  if (b->enable_state == bp_startup_disabled)
-    return;
-
   /* FIXME: is this still reachable?  */
   if (b->addr_string == NULL)
     {
@@ -11135,6 +11110,7 @@ internal_bkpt_check_status (bpstat bs)
 static enum print_stop_action
 internal_bkpt_print_it (bpstat bs)
 {
+  struct ui_out *uiout = current_uiout;
   struct breakpoint *b;
 
   b = bs->breakpoint_at;
@@ -11145,7 +11121,10 @@ internal_bkpt_print_it (bpstat bs)
       /* Did we stop because the user set the stop_on_solib_events
         variable?  (If so, we report this as a generic, "Stopped due
         to shlib event" message.) */
-      printf_filtered (_("Stopped due to shared library event\n"));
+      ui_out_text (uiout, _("Stopped due to shared library event\n"));
+      if (ui_out_is_mi_like_p (uiout))
+       ui_out_field_string (uiout, "reason",
+                            async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
       break;
 
     case bp_thread_event:
@@ -11636,26 +11615,26 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
       if (!VEC_empty(static_tracepoint_marker_p, markers))
        {
-         struct symtab_and_line sal;
+         struct symtab_and_line sal2;
          struct symbol *sym;
-         struct static_tracepoint_marker *marker;
+         struct static_tracepoint_marker *tpmarker;
          struct ui_out *uiout = current_uiout;
 
-         marker = VEC_index (static_tracepoint_marker_p, markers, 0);
+         tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0);
 
          xfree (tp->static_trace_marker_id);
-         tp->static_trace_marker_id = xstrdup (marker->str_id);
+         tp->static_trace_marker_id = xstrdup (tpmarker->str_id);
 
          warning (_("marker for static tracepoint %d (%s) not "
                     "found at previous line number"),
                   b->number, tp->static_trace_marker_id);
 
-         init_sal (&sal);
+         init_sal (&sal2);
 
-         sal.pc = marker->address;
+         sal2.pc = tpmarker->address;
 
-         sal = find_pc_line (marker->address, 0);
-         sym = find_pc_sect_function (marker->address, NULL);
+         sal2 = find_pc_line (tpmarker->address, 0);
+         sym = find_pc_sect_function (tpmarker->address, NULL);
          ui_out_text (uiout, "Now in ");
          if (sym)
            {
@@ -11663,36 +11642,37 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
                                   SYMBOL_PRINT_NAME (sym));
              ui_out_text (uiout, " at ");
            }
-         ui_out_field_string (uiout, "file", sal.symtab->filename);
+         ui_out_field_string (uiout, "file", sal2.symtab->filename);
          ui_out_text (uiout, ":");
 
          if (ui_out_is_mi_like_p (uiout))
            {
-             char *fullname = symtab_to_fullname (sal.symtab);
+             char *fullname = symtab_to_fullname (sal2.symtab);
 
              if (fullname)
                ui_out_field_string (uiout, "fullname", fullname);
            }
 
-         ui_out_field_int (uiout, "line", sal.line);
+         ui_out_field_int (uiout, "line", sal2.line);
          ui_out_text (uiout, "\n");
 
-         b->line_number = sal.line;
+         b->loc->line_number = sal2.line;
 
-         xfree (b->source_file);
+         xfree (b->loc->source_file);
          if (sym)
-           b->source_file = xstrdup (sal.symtab->filename);
+           b->loc->source_file = xstrdup (sal2.symtab->filename);
          else
-           b->source_file = NULL;
+           b->loc->source_file = NULL;
 
          xfree (b->addr_string);
          b->addr_string = xstrprintf ("%s:%d",
-                                      sal.symtab->filename, b->line_number);
+                                      sal2.symtab->filename,
+                                      b->loc->line_number);
 
          /* Might be nice to check if function changed, and warn if
             so.  */
 
-         release_static_tracepoint_marker (marker);
+         release_static_tracepoint_marker (tpmarker);
        }
     }
   return sal;
@@ -11737,8 +11717,17 @@ update_breakpoint_locations (struct breakpoint *b,
   int i;
   struct bp_location *existing_locations = b->loc;
 
-  /* Ranged breakpoints have only one start location and one end location.  */
-  gdb_assert (sals_end.nelts == 0 || (sals.nelts == 1 && sals_end.nelts == 1));
+  if (sals_end.nelts != 0 && (sals.nelts != 1 || sals_end.nelts != 1))
+    {
+      /* Ranged breakpoints have only one start location and one end
+        location.  */
+      b->enable_state = bp_disabled;
+      update_global_location_list (1);
+      printf_unfiltered (_("Could not reset ranged breakpoint %d: "
+                          "multiple locations found\n"),
+                        b->number);
+      return;
+    }
 
   /* If there's no new locations, and all existing locations are
      pending, don't do anything.  This optimizes the common case where
@@ -11753,8 +11742,11 @@ update_breakpoint_locations (struct breakpoint *b,
 
   for (i = 0; i < sals.nelts; ++i)
     {
-      struct bp_location *new_loc = 
-       add_location_to_breakpoint (b, &(sals.sals[i]));
+      struct bp_location *new_loc;
+
+      switch_to_program_space_and_thread (sals.sals[i].pspace);
+
+      new_loc = add_location_to_breakpoint (b, &(sals.sals[i]));
 
       /* Reparse conditions, they might contain references to the
         old symtab.  */
@@ -11778,16 +11770,6 @@ update_breakpoint_locations (struct breakpoint *b,
            }
        }
 
-      if (b->source_file != NULL)
-       xfree (b->source_file);
-      if (sals.sals[i].symtab == NULL)
-       b->source_file = NULL;
-      else
-       b->source_file = xstrdup (sals.sals[i].symtab->filename);
-
-      if (b->line_number == 0)
-       b->line_number = sals.sals[i].line;
-
       if (sals_end.nelts)
        {
          CORE_ADDR end = find_breakpoint_range_end (sals_end.sals[0]);
@@ -11854,7 +11836,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
   char *s;
   int marker_spec;
   struct symtabs_and_lines sals = {0};
-  struct gdb_exception e;
+  volatile struct gdb_exception e;
 
   s = addr_string;
   marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
@@ -11875,7 +11857,31 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
            error (_("marker %s not found"), tp->static_trace_marker_id);
        }
       else
-       sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, NULL);
+       {
+         struct linespec_result canonical;
+
+         init_linespec_result (&canonical);
+         decode_line_full (&s, DECODE_LINE_FUNFIRSTLINE,
+                           (struct symtab *) NULL, 0,
+                           &canonical, multiple_symbols_all,
+                           b->filter);
+
+         /* We should get 0 or 1 resulting SALs.  */
+         gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
+
+         if (VEC_length (linespec_sals, canonical.sals) > 0)
+           {
+             struct linespec_sals *lsal;
+
+             lsal = VEC_index (linespec_sals, canonical.sals, 0);
+             sals = lsal->sals;
+             /* Arrange it so the destructor does not free the
+                contents.  */
+             lsal->sals.sals = NULL;
+           }
+
+         destroy_linespec_result (&canonical);
+       }
     }
   if (e.reason < 0)
     {
@@ -11890,6 +11896,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
       if (e.error == NOT_FOUND_ERROR
          && (b->condition_not_parsed 
              || (b->loc && b->loc->shlib_disabled)
+             || (b->loc && b->loc->pspace->executing_startup)
              || b->enable_state == bp_disabled))
        not_found_and_ok = 1;
 
@@ -11908,9 +11915,10 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
 
   if (e.reason == 0 || e.error != NOT_FOUND_ERROR)
     {
-      gdb_assert (sals.nelts == 1);
+      int i;
 
-      resolve_sal_pc (&sals.sals[0]);
+      for (i = 0; i < sals.nelts; ++i)
+       resolve_sal_pc (&sals.sals[i]);
       if (b->condition_not_parsed && s && s[0])
        {
          char *cond_string = 0;
@@ -11953,7 +11961,7 @@ breakpoint_re_set_default (struct breakpoint *b)
   if (found)
     {
       make_cleanup (xfree, sals.sals);
-      expanded = expand_line_sal_maybe (sals.sals[0]);
+      expanded = sals;
     }
 
   if (b->addr_string_range_end)
@@ -11962,7 +11970,7 @@ breakpoint_re_set_default (struct breakpoint *b)
       if (found)
        {
          make_cleanup (xfree, sals_end.sals);
-         expanded_end = expand_line_sal_maybe (sals_end.sals[0]);
+         expanded_end = sals_end;
        }
     }
 
@@ -11978,7 +11986,8 @@ prepare_re_set_context (struct breakpoint *b)
 
   input_radix = b->input_radix;
   cleanups = save_current_space_and_thread ();
-  switch_to_program_space_and_thread (b->pspace);
+  if (b->pspace != NULL)
+    switch_to_program_space_and_thread (b->pspace);
   set_language (b->language);
 
   return cleanups;
@@ -12490,20 +12499,18 @@ invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len,
    if they aren't valid.  */
 
 struct symtabs_and_lines
-decode_line_spec_1 (char *string, int funfirstline)
+decode_line_spec_1 (char *string, int flags)
 {
   struct symtabs_and_lines sals;
 
   if (string == 0)
     error (_("Empty line specification."));
   if (last_displayed_sal_is_valid ())
-    sals = decode_line_1 (&string, funfirstline,
+    sals = decode_line_1 (&string, flags,
                          get_last_displayed_symtab (),
-                         get_last_displayed_line (),
-                         NULL);
+                         get_last_displayed_line ());
   else
-    sals = decode_line_1 (&string, funfirstline,
-                         (struct symtab *) NULL, 0, NULL);
+    sals = decode_line_1 (&string, flags, (struct symtab *) NULL, 0);
   if (*string)
     error (_("Junk at end of line specification: %s"), string);
   return sals;
@@ -12900,6 +12907,10 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
               "have no source form, ignoring them"),
             utp->number);
 
+  /* Copy any status information that might be available.  */
+  tp->base.hit_count = utp->hit_count;
+  tp->traceframe_usage = utp->traceframe_usage;
+
   return tp;
 }
   
This page took 0.04689 seconds and 4 git commands to generate.