3361dd9
2005-01-20  Jeff Johnston  <jjohnstn@redhat.com>
3361dd9
3361dd9
	* symtab.h (find_line_pc): Change prototype to new api
3361dd9
	which returns a list of pc values and the number of list elements.
3361dd9
	* symtab.c (find_line_pc): Change function to new api which
3361dd9
	returns a list of pc values.  Support recognizing a base ctor
3361dd9
	or dtor and finding an additional pc value for the in-charge
3361dd9
	ctor or dtor accordingly.
3361dd9
	(find_line_common): Change api to accept a start_index argument
3361dd9
	which determines where to start searching from in the line table.
3361dd9
	(find_line_by_pc): New function.
3361dd9
	* breakpoint.c (resolve_sal_pc_list): New function.
3361dd9
	(breakpoint_sals_to_pc): Support multiple pc values for a
3361dd9
	line in a ctor/dtor.
3361dd9
	(gdb_breakpoint): Change call to find_line_pc to use new api.
3361dd9
	(break_command_1): Move resolve_sals_to_pc earlier due to the
3361dd9
	fact it now can extend the sal list.
3361dd9
	* mi/mi-cmd-disas.c (mi_cmd_disassemble): Change call to
3361dd9
	find_line_pc to new api.
3361dd9
	* tui/tui-layout.c (extract_display_start_addr): Ditto.
3361dd9
	* tui/tui-win.c (make_visible_with_new_height): Ditto.
3361dd9
	* tui/tui-winsource.c (tui_update_source_windows_with_addr): Ditto.
3361dd9
9231e41
Index: gdb-6.5/gdb/mi/mi-cmd-disas.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/mi/mi-cmd-disas.c	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/mi/mi-cmd-disas.c	2006-07-11 02:16:07.000000000 -0300
3361dd9
@@ -1,5 +1,5 @@
3361dd9
 /* MI Command Set - disassemble commands.
9231e41
-   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
9231e41
+   Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
3361dd9
    Contributed by Cygnus Solutions (a Red Hat company).
3361dd9
 
3361dd9
    This file is part of GDB.
9231e41
@@ -145,11 +145,18 @@ mi_cmd_disassemble (char *command, char 
3361dd9
 
3361dd9
   if (line_seen && file_seen)
3361dd9
     {
3361dd9
+      CORE_ADDR *pc_list;
3361dd9
+      int num_pc_values;
9231e41
+
3361dd9
       s = lookup_symtab (file_string);
3361dd9
       if (s == NULL)
9231e41
 	error (_("mi_cmd_disassemble: Invalid filename."));
3361dd9
-      if (!find_line_pc (s, line_num, &start))
3361dd9
+      if (!find_line_pc (s, line_num, &pc_list, &num_pc_values))
9231e41
 	error (_("mi_cmd_disassemble: Invalid line number"));
3361dd9
+      /* FIXME: What do we do with multiple pc values for ctors/dtors
3361dd9
+                under mi?  */
3361dd9
+      start = pc_list[0];
3361dd9
+      xfree (pc_list);
3361dd9
       if (find_pc_partial_function (start, NULL, &low, &high) == 0)
9231e41
 	error (_("mi_cmd_disassemble: No function contains specified address"));
3361dd9
     }
9231e41
Index: gdb-6.5/gdb/tui/tui-layout.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/tui/tui-layout.c	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/tui/tui-layout.c	2006-07-11 02:16:07.000000000 -0300
3361dd9
@@ -1,6 +1,6 @@
3361dd9
 /* TUI layout window management.
3361dd9
 
9231e41
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
9231e41
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
3361dd9
    Foundation, Inc.
3361dd9
 
3361dd9
    Contributed by Hewlett-Packard Company.
3361dd9
@@ -511,7 +511,8 @@ extract_display_start_addr (void)
3361dd9
 {
3361dd9
   enum tui_layout_type cur_layout = tui_current_layout ();
3361dd9
   CORE_ADDR addr;
3361dd9
-  CORE_ADDR pc;
3361dd9
+  CORE_ADDR *pc_list;
3361dd9
+  int num_pc_values;
3361dd9
   struct symtab_and_line cursal = get_current_source_symtab_and_line ();
3361dd9
 
3361dd9
   switch (cur_layout)
3361dd9
@@ -520,8 +521,11 @@ extract_display_start_addr (void)
3361dd9
     case SRC_DATA_COMMAND:
3361dd9
       find_line_pc (cursal.symtab,
9231e41
 		    TUI_SRC_WIN->detail.source_info.start_line_or_addr.u.line_no,
3361dd9
-		    &pc);
3361dd9
-      addr = pc;
3361dd9
+		    &pc_list, &num_pc_values);
3361dd9
+      /* FIXME: What do we do with multiple pc values for ctors/dtors or
3361dd9
+                inlined functions?  */
3361dd9
+      addr = pc_list[0];
3361dd9
+      xfree (pc_list);
3361dd9
       break;
3361dd9
     case DISASSEM_COMMAND:
3361dd9
     case SRC_DISASSEM_COMMAND:
9231e41
Index: gdb-6.5/gdb/tui/tui-win.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/tui/tui-win.c	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/tui/tui-win.c	2006-07-11 02:16:12.000000000 -0300
3361dd9
@@ -1,6 +1,6 @@
3361dd9
 /* TUI window generic functions.
3361dd9
 
9231e41
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
9231e41
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
9231e41
    Free Software Foundation, Inc.
3361dd9
 
3361dd9
    Contributed by Hewlett-Packard Company.
9231e41
@@ -1342,8 +1342,16 @@ make_visible_with_new_height (struct tui
9231e41
 	    }
3361dd9
 	  else
3361dd9
 	    {
3361dd9
+              CORE_ADDR *pc_list;
3361dd9
+              int num_pc_values;
9231e41
 	      line.loa = LOA_ADDRESS;
9231e41
-	      find_line_pc (s, cursal.line, &line.u.addr);
3361dd9
+	      if (find_line_pc (s, cursal.line, &pc_list, &num_pc_values))
3361dd9
+                {
3361dd9
+                  /* FIXME: What do we do with multiple pc values for
3361dd9
+                            ctors/dtors and inlined functions?  */
9231e41
+                  line.u.addr = pc_list[0];
3361dd9
+                  xfree (pc_list);
3361dd9
+                }
3361dd9
 	    }
3361dd9
 	  tui_update_source_window (win_info, s, line, TRUE);
3361dd9
 	}
9231e41
Index: gdb-6.5/gdb/tui/tui-winsource.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/tui/tui-winsource.c	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/tui/tui-winsource.c	2006-07-11 01:39:20.000000000 -0300
3361dd9
@@ -1,6 +1,6 @@
3361dd9
 /* TUI display source/assembly window.
3361dd9
 
9231e41
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
9231e41
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
9231e41
    Free Software Foundation, Inc.
3361dd9
 
3361dd9
    Contributed by Hewlett-Packard Company.
9231e41
@@ -173,14 +173,21 @@ tui_update_source_windows_with_addr (COR
3361dd9
 void
3361dd9
 tui_update_source_windows_with_line (struct symtab *s, int line)
3361dd9
 {
3361dd9
-  CORE_ADDR pc;
3361dd9
+  CORE_ADDR pc = 0;
3361dd9
+  CORE_ADDR *pc_list;
3361dd9
+  int num_pc_values;
9231e41
   struct tui_line_or_address l;
3361dd9
   
3361dd9
   switch (tui_current_layout ())
3361dd9
     {
3361dd9
     case DISASSEM_COMMAND:
3361dd9
     case DISASSEM_DATA_COMMAND:
3361dd9
-      find_line_pc (s, line, &pc);
3361dd9
+      /* FIXME: What do we do with multiple pc values for ctors/dtors?  */
3361dd9
+      if (find_line_pc (s, line, &pc_list, &num_pc_values))
3361dd9
+        {
3361dd9
+          pc = pc_list[0];
3361dd9
+          xfree (pc_list);
3361dd9
+        }
3361dd9
       tui_update_source_windows_with_addr (pc);
3361dd9
       break;
3361dd9
     default:
9231e41
@@ -189,7 +196,12 @@ tui_update_source_windows_with_line (str
3361dd9
       tui_show_symtab_source (s, l, FALSE);
3361dd9
       if (tui_current_layout () == SRC_DISASSEM_COMMAND)
3361dd9
 	{
3361dd9
-	  find_line_pc (s, line, &pc);
3361dd9
+          /* FIXME: What do we do with multiple pc values for ctors/dtors?  */
3361dd9
+          if (find_line_pc (s, line, &pc_list, &num_pc_values))
3361dd9
+            {
3361dd9
+              pc = pc_list[0];
3361dd9
+              xfree (pc_list);
3361dd9
+            }
3361dd9
 	  tui_show_disassem (pc);
3361dd9
 	}
3361dd9
       break;
9231e41
Index: gdb-6.5/gdb/symtab.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/symtab.c	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/symtab.c	2006-07-11 02:16:05.000000000 -0300
3361dd9
@@ -1,7 +1,7 @@
3361dd9
 /* Symbol table lookup for the GNU debugger, GDB.
3361dd9
 
9231e41
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
3361dd9
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3361dd9
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3361dd9
    Free Software Foundation, Inc.
3361dd9
 
3361dd9
    This file is part of GDB.
9231e41
@@ -73,7 +73,9 @@ static void sources_info (char *, int);
3361dd9
 
3361dd9
 static void output_source_filename (const char *, int *);
3361dd9
 
3361dd9
-static int find_line_common (struct linetable *, int, int *);
3361dd9
+static int find_line_common (struct linetable *, int, int, int *);
3361dd9
+
3361dd9
+static int find_line_by_pc (struct linetable *, CORE_ADDR, int *);
3361dd9
 
3361dd9
 /* This one is used by linespec.c */
3361dd9
 
9231e41
@@ -2233,6 +2235,9 @@ find_pc_line (CORE_ADDR pc, int notcurre
3361dd9
 /* Find line number LINE in any symtab whose name is the same as
3361dd9
    SYMTAB.
3361dd9
 
3361dd9
+   If INDEX is non-NULL, use the value as the starting index in the
3361dd9
+   linetable to start at.
3361dd9
+
3361dd9
    If found, return the symtab that contains the linetable in which it was
3361dd9
    found, set *INDEX to the index in the linetable of the best entry
3361dd9
    found, and set *EXACT_MATCH nonzero if the value returned is an
9231e41
@@ -2249,13 +2254,19 @@ find_line_symtab (struct symtab *symtab,
3361dd9
      so far seen.  */
3361dd9
 
3361dd9
   int best_index;
3361dd9
+  int start_index;
3361dd9
   struct linetable *best_linetable;
3361dd9
   struct symtab *best_symtab;
3361dd9
 
3361dd9
+  if (index)
3361dd9
+    start_index = *index;
3361dd9
+  else
3361dd9
+    start_index = 0;
3361dd9
+
3361dd9
   /* First try looking it up in the given symtab.  */
3361dd9
   best_linetable = LINETABLE (symtab);
3361dd9
   best_symtab = symtab;
3361dd9
-  best_index = find_line_common (best_linetable, line, &exact);
3361dd9
+  best_index = find_line_common (best_linetable, line, start_index, &exact);
3361dd9
   if (best_index < 0 || !exact)
3361dd9
     {
3361dd9
       /* Didn't find an exact match.  So we better keep looking for
9231e41
@@ -2286,7 +2297,7 @@ find_line_symtab (struct symtab *symtab,
3361dd9
 	if (strcmp (symtab->filename, s->filename) != 0)
3361dd9
 	  continue;
3361dd9
 	l = LINETABLE (s);
3361dd9
-	ind = find_line_common (l, line, &exact);
3361dd9
+	ind = find_line_common (l, line, start_index, &exact);
3361dd9
 	if (ind >= 0)
3361dd9
 	  {
3361dd9
 	    if (exact)
9231e41
@@ -2322,13 +2333,23 @@ done:
3361dd9
    Returns zero for invalid line number (and sets the PC to 0).
3361dd9
    The source file is specified with a struct symtab.  */
3361dd9
 
3361dd9
+static CORE_ADDR empty_pc_list = (CORE_ADDR)0;
3361dd9
+
3361dd9
 int
3361dd9
-find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
3361dd9
+find_line_pc (struct symtab *symtab, int line, CORE_ADDR **pc_array,
3361dd9
+              int *num_elements)
3361dd9
 {
3361dd9
   struct linetable *l;
3361dd9
-  int ind;
3361dd9
+  int ind = 0;
3361dd9
+  char *name;
3361dd9
+  CORE_ADDR main_pc;
3361dd9
+  struct minimal_symbol *minsym;
3361dd9
+  struct minimal_symbol *minsym2;
3361dd9
+
3361dd9
+
3361dd9
+  *pc_array = &empty_pc_list;
3361dd9
+  *num_elements = 0;
3361dd9
 
3361dd9
-  *pc = 0;
3361dd9
   if (symtab == 0)
3361dd9
     return 0;
3361dd9
 
9231e41
@@ -2336,7 +2357,50 @@ find_line_pc (struct symtab *symtab, int
3361dd9
   if (symtab != NULL)
3361dd9
     {
3361dd9
       l = LINETABLE (symtab);
3361dd9
-      *pc = l->item[ind].pc;
3361dd9
+      main_pc = l->item[ind].pc;
3361dd9
+      minsym = lookup_minimal_symbol_by_pc (main_pc);
3361dd9
+      if (minsym != NULL && minsym->ginfo.language == language_cplus)
3361dd9
+        {
3361dd9
+	  char *base_name = 
3361dd9
+            minsym->ginfo.language_specific.cplus_specific.demangled_name;
3361dd9
+          char *tmp_ptr = strstr (base_name, "$base(");
3361dd9
+          if (tmp_ptr != NULL)
3361dd9
+            {
3361dd9
+              char *regular_name = (char *)xmalloc (strlen (base_name));
3361dd9
+              memcpy (regular_name, base_name, tmp_ptr - base_name);
3361dd9
+              strcpy (regular_name + (tmp_ptr - base_name), 
3361dd9
+                      tmp_ptr + sizeof ("$base") - 1);
3361dd9
+              minsym2 = lookup_minimal_symbol (regular_name, NULL, NULL);
3361dd9
+              xfree (regular_name);
3361dd9
+              if (minsym2 != NULL)
3361dd9
+                {
3361dd9
+		  /* We have recognized we have a ctor or dtor and have
3361dd9
+		     located our line in the not-in-charge version.  We
3361dd9
+		     also have located the in-charge version's minsym.
3361dd9
+		     From this, we can find the index for the first line
3361dd9
+		     line in the in-charge ctor/dtor and then search forward
3361dd9
+		     for the specified line, thereby finding the 2nd match.  */
3361dd9
+		  int exact;
3361dd9
+		  int ind = find_line_by_pc (l, minsym2->ginfo.value.address,
3361dd9
+				             &exact);
3361dd9
+		  if (ind >= 0)
3361dd9
+		    {
3361dd9
+		      ind = find_line_common (l, line, ind, &exact);
3361dd9
+		      if (ind >= 0)
3361dd9
+		        {
3361dd9
+                          *pc_array = xmalloc (2 * sizeof (CORE_ADDR));
3361dd9
+                          (*pc_array)[0] = main_pc;
3361dd9
+                          (*pc_array)[1] = l->item[ind].pc;
3361dd9
+                          *num_elements = 2;
3361dd9
+                          return 1;
3361dd9
+			}
3361dd9
+		    }
3361dd9
+                }
3361dd9
+            }
3361dd9
+        }
3361dd9
+      *pc_array = xmalloc (sizeof (CORE_ADDR));
3361dd9
+      (*pc_array)[0] = main_pc;
3361dd9
+      *num_elements = 1;
3361dd9
       return 1;
3361dd9
     }
3361dd9
   else
9231e41
@@ -2354,12 +2418,22 @@ find_line_pc_range (struct symtab_and_li
3361dd9
 		    CORE_ADDR *endptr)
3361dd9
 {
3361dd9
   CORE_ADDR startaddr;
3361dd9
+  CORE_ADDR *pc_list;
3361dd9
+  int num_pc_values;
3361dd9
   struct symtab_and_line found_sal;
3361dd9
 
3361dd9
   startaddr = sal.pc;
3361dd9
-  if (startaddr == 0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
3361dd9
+  if (startaddr == 0 
3361dd9
+      && !find_line_pc (sal.symtab, sal.line, &pc_list, &num_pc_values))
3361dd9
     return 0;
3361dd9
 
3361dd9
+  /* FIXME: have to handle ctors/dtors where line equates to multiple
3361dd9
+            pc ranges.  */
3361dd9
+  if (startaddr == 0)
3361dd9
+    startaddr = pc_list[0];
3361dd9
+
3361dd9
+  xfree (pc_list);
3361dd9
+
3361dd9
   /* This whole function is based on address.  For example, if line 10 has
3361dd9
      two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then
3361dd9
      "info line *0x123" should say the line goes from 0x100 to 0x200
9231e41
@@ -2389,7 +2463,7 @@ find_line_pc_range (struct symtab_and_li
3361dd9
    Set *EXACT_MATCH nonzero if the value returned is an exact match.  */
3361dd9
 
3361dd9
 static int
3361dd9
-find_line_common (struct linetable *l, int lineno,
3361dd9
+find_line_common (struct linetable *l, int lineno, int start_index,
3361dd9
 		  int *exact_match)
3361dd9
 {
3361dd9
   int i;
9231e41
@@ -2408,7 +2482,7 @@ find_line_common (struct linetable *l, i
3361dd9
     return -1;
3361dd9
 
3361dd9
   len = l->nitems;
3361dd9
-  for (i = 0; i < len; i++)
3361dd9
+  for (i = start_index; i < len; i++)
3361dd9
     {
3361dd9
       struct linetable_entry *item = &(l->item[i]);
3361dd9
 
9231e41
@@ -2432,6 +2506,52 @@ find_line_common (struct linetable *l, i
3361dd9
   return best_index;
3361dd9
 }
3361dd9
 
3361dd9
+/* Given a line table and a pc value, return the index into the line
3361dd9
+   table for the line with pc >= specified pc value.
3361dd9
+   Return -1 if none is found.  The value is >= 0 if it is an index.
3361dd9
+
3361dd9
+   Set *EXACT_MATCH nonzero if the value returned is an exact match.  */
3361dd9
+
3361dd9
+static int
3361dd9
+find_line_by_pc (struct linetable *l, CORE_ADDR pc,
3361dd9
+	         int *exact_match)
3361dd9
+{
3361dd9
+  int i;
3361dd9
+  int len;
3361dd9
+
3361dd9
+  /* BEST is the smallest linenumber > LINENO so far seen,
3361dd9
+     or 0 if none has been seen so far.
3361dd9
+     BEST_INDEX identifies the item for it.  */
3361dd9
+
3361dd9
+  if (l == 0)
3361dd9
+    return -1;
3361dd9
+
3361dd9
+  len = l->nitems;
3361dd9
+  for (i = 0; i < len; i++)
3361dd9
+    {
3361dd9
+      struct linetable_entry *item = &(l->item[i]);
3361dd9
+
3361dd9
+      /* Return the first (lowest address) entry which matches or
3361dd9
+         exceeds the given pc value.  */
3361dd9
+      if (item->pc == pc)
3361dd9
+	{
3361dd9
+	  *exact_match = 1;
3361dd9
+	  return i;
3361dd9
+	}
3361dd9
+
3361dd9
+      if (item->pc > pc)
3361dd9
+	{
3361dd9
+	  *exact_match = 0;
3361dd9
+	  return i;
3361dd9
+	}
3361dd9
+    }
3361dd9
+
3361dd9
+  /* If we got here, we didn't get a match.  */
3361dd9
+
3361dd9
+  *exact_match = 0;
3361dd9
+  return -1;
3361dd9
+}
3361dd9
+
3361dd9
 int
3361dd9
 find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
3361dd9
 {
9231e41
Index: gdb-6.5/gdb/symtab.h
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/symtab.h	2006-07-11 01:30:43.000000000 -0300
9231e41
+++ gdb-6.5/gdb/symtab.h	2006-07-11 01:39:20.000000000 -0300
3361dd9
@@ -1,7 +1,7 @@
3361dd9
 /* Symbol table definitions for GDB.
3361dd9
 
9231e41
    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
3361dd9
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
3361dd9
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
3361dd9
    Foundation, Inc.
3361dd9
 
3361dd9
    This file is part of GDB.
3361dd9
@@ -1256,13 +1256,16 @@ extern struct symtab_and_line find_pc_se
3361dd9
 
3361dd9
 /* Given a symtab and line number, return the pc there.  */
3361dd9
 
3361dd9
-extern int find_line_pc (struct symtab *, int, CORE_ADDR *);
3361dd9
+extern int find_line_pc (struct symtab *, int, CORE_ADDR **, int *);
3361dd9
 
3361dd9
 extern int find_line_pc_range (struct symtab_and_line, CORE_ADDR *,
3361dd9
 			       CORE_ADDR *);
3361dd9
 
3361dd9
 extern void resolve_sal_pc (struct symtab_and_line *);
3361dd9
 
3361dd9
+extern void resolve_sal_pc_list (struct symtab_and_line *, CORE_ADDR **,
3361dd9
+				 int *);
3361dd9
+
3361dd9
 /* Given a string, return the line specified by it.  For commands like "list"
3361dd9
    and "breakpoint".  */
3361dd9
 
9231e41
Index: gdb-6.5/gdb/breakpoint.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/breakpoint.c	2006-07-11 01:30:53.000000000 -0300
9231e41
+++ gdb-6.5/gdb/breakpoint.c	2006-07-11 01:39:20.000000000 -0300
9231e41
@@ -5268,10 +5268,40 @@ static void
3361dd9
 breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
3361dd9
 		       char *address)
3361dd9
 {    
3361dd9
-  int i;
3361dd9
-  for (i = 0; i < sals->nelts; i++)
3361dd9
-    {
3361dd9
-      resolve_sal_pc (&sals->sals[i]);
3361dd9
+  int i, j, incr;
3361dd9
+  int num_pc_values = 1;
3361dd9
+
3361dd9
+  /* If a line has multiple pc values, we want to create an sal for
3361dd9
+     each pc value so we will end up creating n breakpoints.  */
3361dd9
+  for (i = 0; i < sals->nelts; i+=incr)
3361dd9
+    {
3361dd9
+      CORE_ADDR *pc_list;
3361dd9
+      incr = 1;
3361dd9
+
3361dd9
+      resolve_sal_pc_list (&sals->sals[i], &pc_list, &num_pc_values);
3361dd9
+      if (num_pc_values != 0)
3361dd9
+        sals->sals[i].pc = pc_list[0];
3361dd9
+      if (num_pc_values > 1)
3361dd9
+        {
3361dd9
+          struct symtab_and_line *new_sals = 
3361dd9
+            xmalloc ((sals->nelts + num_pc_values - 1) 
3361dd9
+                     * sizeof (struct symtab_and_line));
3361dd9
+          memcpy (new_sals, sals->sals, (i + 1) 
3361dd9
+                  * sizeof (struct symtab_and_line));
3361dd9
+          memcpy (&(new_sals[i + 1]), &sals->sals[i], 
3361dd9
+                  sizeof (struct symtab_and_line));
3361dd9
+          xfree (sals->sals);
3361dd9
+          sals->sals = new_sals;
3361dd9
+          sals->nelts += num_pc_values - 1;
3361dd9
+          for (j = 1; j < num_pc_values; ++j)
3361dd9
+            {
3361dd9
+              sals->sals[i + j].pc = pc_list[j];
3361dd9
+            }
3361dd9
+          incr = num_pc_values;
3361dd9
+        }
3361dd9
+
3361dd9
+      if (num_pc_values != 0)
3361dd9
+        xfree (pc_list);
3361dd9
 
3361dd9
       /* It's possible for the PC to be nonzero, but still an illegal
3361dd9
          value on some targets.
9231e41
@@ -5406,6 +5436,10 @@ break_command_1 (char *arg, int flag, in
3361dd9
 
3361dd9
   if (!pending)
3361dd9
     {
3361dd9
+      /* Resolve all line numbers to PC's and verify that the addresses
3361dd9
+         are ok for the target.  */
3361dd9
+      breakpoint_sals_to_pc (&sals, addr_start);
3361dd9
+
3361dd9
       /* Make sure that all storage allocated to SALS gets freed.  */
3361dd9
       make_cleanup (xfree, sals.sals);
3361dd9
       
9231e41
@@ -5436,11 +5470,6 @@ break_command_1 (char *arg, int flag, in
3361dd9
 	make_cleanup (xfree, addr_string[i]);
3361dd9
     }
3361dd9
 
3361dd9
-  /* Resolve all line numbers to PC's and verify that the addresses
3361dd9
-     are ok for the target.  */
3361dd9
-  if (!pending)
3361dd9
-    breakpoint_sals_to_pc (&sals, addr_start);
3361dd9
-
3361dd9
   /* Verify that condition can be parsed, before setting any
3361dd9
      breakpoints.  Allocate a separate condition expression for each
3361dd9
      breakpoint. */
9231e41
@@ -5670,14 +5699,16 @@ gdb_breakpoint (char *address, char *con
3361dd9
 void
3361dd9
 resolve_sal_pc (struct symtab_and_line *sal)
3361dd9
 {
3361dd9
-  CORE_ADDR pc;
3361dd9
+  CORE_ADDR *pc_list;
3361dd9
+  int num_pc_values;
3361dd9
 
3361dd9
   if (sal->pc == 0 && sal->symtab != NULL)
3361dd9
     {
3361dd9
-      if (!find_line_pc (sal->symtab, sal->line, &pc))
3361dd9
+      if (!find_line_pc (sal->symtab, sal->line, &pc_list, &num_pc_values))
9231e41
 	error (_("No line %d in file \"%s\"."),
3361dd9
 	       sal->line, sal->symtab->filename);
3361dd9
-      sal->pc = pc;
3361dd9
+      sal->pc = pc_list[0];
3361dd9
+      xfree (pc_list);
3361dd9
     }
3361dd9
 
3361dd9
   if (sal->section == 0 && sal->symtab != NULL)
9231e41
@@ -5714,6 +5745,54 @@ resolve_sal_pc (struct symtab_and_line *
3361dd9
     }
3361dd9
 }
3361dd9
 
3361dd9
+/* Helper function for break_command_1 and disassemble_command.  */
3361dd9
+
3361dd9
+void
3361dd9
+resolve_sal_pc_list (struct symtab_and_line *sal, CORE_ADDR **pc_list,
3361dd9
+                     int *num_pc_values)
3361dd9
+{
3361dd9
+  *num_pc_values = 0;
3361dd9
+  if (sal->pc == 0 && sal->symtab != NULL)
3361dd9
+    {
3361dd9
+      if (!find_line_pc (sal->symtab, sal->line, pc_list, num_pc_values))
3361dd9
+	error ("No line %d in file \"%s\".",
3361dd9
+	       sal->line, sal->symtab->filename);
3361dd9
+      sal->pc = (*pc_list)[0];
3361dd9
+    }
3361dd9
+
3361dd9
+  if (sal->section == 0 && sal->symtab != NULL)
3361dd9
+    {
3361dd9
+      struct blockvector *bv;
3361dd9
+      struct block *b;
3361dd9
+      struct symbol *sym;
3361dd9
+      int index;
3361dd9
+
3361dd9
+      bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
3361dd9
+      if (bv != NULL)
3361dd9
+	{
3361dd9
+	  b = BLOCKVECTOR_BLOCK (bv, index);
3361dd9
+	  sym = block_function (b);
3361dd9
+	  if (sym != NULL)
3361dd9
+	    {
3361dd9
+	      fixup_symbol_section (sym, sal->symtab->objfile);
3361dd9
+	      sal->section = SYMBOL_BFD_SECTION (sym);
3361dd9
+	    }
3361dd9
+	  else
3361dd9
+	    {
3361dd9
+	      /* It really is worthwhile to have the section, so we'll just
3361dd9
+	         have to look harder. This case can be executed if we have 
3361dd9
+	         line numbers but no functions (as can happen in assembly 
3361dd9
+	         source).  */
3361dd9
+
3361dd9
+	      struct minimal_symbol *msym;
3361dd9
+
3361dd9
+	      msym = lookup_minimal_symbol_by_pc (sal->pc);
3361dd9
+	      if (msym)
3361dd9
+		sal->section = SYMBOL_BFD_SECTION (msym);
3361dd9
+	    }
3361dd9
+	}
3361dd9
+    }
3361dd9
+}
3361dd9
 void
3361dd9
 break_command (char *arg, int from_tty)
3361dd9
 {