* dummy-frame.c (deprecated_pc_in_call_dummy): Add GDBARCH parameter,
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 1cbd6e0dd1f6e236b20229e895c229d691a9a626..ee138ff0ae3936026aab10f774d0ae032011da18 100644 (file)
@@ -1,7 +1,7 @@
 /* Symbol table lookup for the GNU debugger, GDB.
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -55,6 +55,7 @@
 #include "gdb_stat.h"
 #include <ctype.h>
 #include "cp-abi.h"
+#include "cp-support.h"
 #include "observer.h"
 #include "gdb_assert.h"
 #include "solist.h"
@@ -149,7 +150,7 @@ multiple_symbols_select_mode (void)
 struct type *builtin_type_error;
 
 /* Block in which the most recently searched-for symbol was found.
-   Might be better to make this a parameter to lookup_symbol and 
+   Might be better to make this a parameter to lookup_symbol and
    value_of_this. */
 
 const struct block *block_found;
@@ -187,10 +188,10 @@ got_symtab:
       {
        return s;
       }
-      
+
     /* If the user gave us an absolute path, try to find the file in
        this symtab and use its absolute path.  */
-    
+
     if (full_path != NULL)
       {
         const char *fp = symtab_to_fullname (s);
@@ -437,7 +438,7 @@ static void
 create_demangled_names_hash (struct objfile *objfile)
 {
   /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
-     The hash table code will round this up to the next prime number. 
+     The hash table code will round this up to the next prime number.
      Choosing a much larger table size wastes memory, and saves only about
      1% in symbol reading.  */
 
@@ -630,7 +631,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
 char *
 symbol_natural_name (const struct general_symbol_info *gsymbol)
 {
-  switch (gsymbol->language) 
+  switch (gsymbol->language)
     {
     case language_cplus:
     case language_java:
@@ -655,7 +656,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol)
 char *
 symbol_demangled_name (const struct general_symbol_info *gsymbol)
 {
-  switch (gsymbol->language) 
+  switch (gsymbol->language)
     {
     case language_cplus:
     case language_java:
@@ -677,7 +678,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol)
 
 /* Return the search name of a symbol---generally the demangled or
    linkage name of the symbol, depending on how it will be searched for.
-   If there is no distinct demangled name, then returns the same value 
+   If there is no distinct demangled name, then returns the same value
    (same pointer) as SYMBOL_LINKAGE_NAME. */
 char *
 symbol_search_name (const struct general_symbol_info *gsymbol)
@@ -770,7 +771,7 @@ matching_obj_sections (struct obj_section *obj_first,
 /* Find which partial symtab contains PC and SECTION starting at psymtab PST.
    We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
 
-struct partial_symtab *
+static struct partial_symtab *
 find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section,
                             struct partial_symtab *pst,
                             struct minimal_symbol *msymbol)
@@ -878,7 +879,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
        if (pst != NULL)
          {
            /* FIXME: addrmaps currently do not handle overlayed sections,
-              so fall back to the non-addrmap case if we're debugging 
+              so fall back to the non-addrmap case if we're debugging
               overlays and the addrmap returned the wrong section.  */
            if (overlay_debugging && msymbol && section)
              {
@@ -932,7 +933,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
   return NULL;
 }
 
-/* Find which partial symtab contains PC.  Return 0 if none. 
+/* Find which partial symtab contains PC.  Return 0 if none.
    Backward compatibility, no section */
 
 struct partial_symtab *
@@ -941,7 +942,7 @@ find_pc_psymtab (CORE_ADDR pc)
   return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
 }
 
-/* Find which partial symbol within a psymtab matches PC and SECTION.  
+/* Find which partial symbol within a psymtab matches PC and SECTION.
    Return 0 if none.  Check all psymtabs if PSYMTAB is 0.  */
 
 struct partial_symbol *
@@ -1013,7 +1014,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
   return best;
 }
 
-/* Find which partial symbol within a psymtab matches PC.  Return 0 if none.  
+/* Find which partial symbol within a psymtab matches PC.  Return 0 if none.
    Check all psymtabs if PSYMTAB is 0.  Backwards compatibility, no section. */
 
 struct partial_symbol *
@@ -1053,7 +1054,7 @@ fixup_section (struct general_symbol_info *ginfo,
         point in attempting to extend the lookup-by-name mechanism to
         handle this case due to the fact that there can be multiple
         names.
-        
+
         So, instead, search the section table when lookup by name has
         failed.  The ``addr'' and ``endaddr'' fields may have already
         been relocated.  If so, the relocation offset (i.e. the
@@ -1061,7 +1062,7 @@ fixup_section (struct general_symbol_info *ginfo,
         performing the comparison.  We unconditionally subtract it,
         because, when no relocation has been performed, the ANOFFSET
         value will simply be zero.
-        
+
         The address of the symbol whose section we're fixing up HAS
         NOT BEEN adjusted (relocated) yet.  It can't have been since
         the section isn't yet known and knowing the section is
@@ -1073,13 +1074,13 @@ fixup_section (struct general_symbol_info *ginfo,
         (subtracting the relocation value if necessary) to find the
         matching minimal symbol, but this is overkill and much less
         efficient.  It is not necessary to find the matching minimal
-        symbol, only its section.  
-        
+        symbol, only its section.
+
         Note that this technique (of doing a section table search)
         can fail when unrelocated section addresses overlap.  For
         this reason, we still attempt a lookup by name prior to doing
         a search of the section table.  */
-        
+
       struct obj_section *s;
       ALL_OBJFILE_OSECTIONS (objfile, s)
        {
@@ -1175,7 +1176,7 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
    Returns the struct symbol pointer, or zero if no symbol is found.
    C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
    NAME is a field of the current implied argument `this'.  If so set
-   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero. 
+   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
    BLOCK_FOUND is set to the block in which NAME is found (in the case of
    a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
 
@@ -1197,8 +1198,8 @@ lookup_symbol_in_language (const char *name, const struct block *block,
   char *demangled_name = NULL;
   const char *modified_name = NULL;
   const char *mangled_name = NULL;
-  int needtofreename = 0;
   struct symbol *returnval;
+  struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
 
   modified_name = name;
 
@@ -1211,18 +1212,29 @@ lookup_symbol_in_language (const char *name, const struct block *block,
        {
          mangled_name = name;
          modified_name = demangled_name;
-         needtofreename = 1;
+         make_cleanup (xfree, demangled_name);
+       }
+      else
+       {
+         /* If we were given a non-mangled name, canonicalize it
+            according to the language (so far only for C++).  */
+         demangled_name = cp_canonicalize_string (name);
+         if (demangled_name)
+           {
+             modified_name = demangled_name;
+             make_cleanup (xfree, demangled_name);
+           }
        }
     }
   else if (lang == language_java)
     {
-      demangled_name = cplus_demangle (name, 
+      demangled_name = cplus_demangle (name,
                                       DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
       if (demangled_name)
        {
          mangled_name = name;
          modified_name = demangled_name;
-         needtofreename = 1;
+         make_cleanup (xfree, demangled_name);
        }
     }
 
@@ -1241,10 +1253,9 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 
   returnval = lookup_symbol_aux (modified_name, mangled_name, block,
                                 domain, lang, is_a_field_of_this);
-  if (needtofreename)
-    xfree (demangled_name);
+  do_cleanups (cleanup);
 
-  return returnval;     
+  return returnval;
 }
 
 /* Behave like lookup_symbol_in_language, but performed with the
@@ -1298,7 +1309,7 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
       struct symbol *sym = NULL;
       /* 'this' is only defined in the function's block, so find the
         enclosing function block.  */
-      for (; block && !BLOCK_FUNCTION (block); 
+      for (; block && !BLOCK_FUNCTION (block);
           block = BLOCK_SUPERBLOCK (block));
 
       if (block && !dict_empty (BLOCK_DICT (block)))
@@ -1307,19 +1318,19 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
       if (sym)
        {
          struct type *t = sym->type;
-         
+
          /* I'm not really sure that type of this can ever
             be typedefed; just be safe.  */
          CHECK_TYPEDEF (t);
          if (TYPE_CODE (t) == TYPE_CODE_PTR
              || TYPE_CODE (t) == TYPE_CODE_REF)
            t = TYPE_TARGET_TYPE (t);
-         
+
          if (TYPE_CODE (t) != TYPE_CODE_STRUCT
              && TYPE_CODE (t) != TYPE_CODE_UNION)
-           error (_("Internal error: `%s' is not an aggregate"), 
+           error (_("Internal error: `%s' is not an aggregate"),
                   langdef->la_name_of_this);
-         
+
          if (check_field (t, name))
            {
              *is_a_field_of_this = 1;
@@ -1344,7 +1355,7 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
   if (sym != NULL)
     return sym;
-  
+
   sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
   if (sym != NULL)
     return sym;
@@ -1650,11 +1661,11 @@ lookup_symbol_global (const char *name,
 }
 
 int
-symbol_matches_domain (enum language symbol_language, 
+symbol_matches_domain (enum language symbol_language,
                       domain_enum symbol_domain,
                       domain_enum domain)
 {
-  /* For C++ "struct foo { ... }" also defines a typedef for "foo".  
+  /* For C++ "struct foo { ... }" also defines a typedef for "foo".
      A Java class declaration also defines a typedef for the class.
      Similarly, any Ada type declaration implicitly defines a typedef.  */
   if (symbol_language == language_cplus
@@ -1684,7 +1695,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
   struct partial_symbol **top, **real_top, **bottom, **center;
   int length = (global ? pst->n_global_syms : pst->n_static_syms);
   int do_linear_search = 1;
-  
+
   if (length == 0)
     {
       return (NULL);
@@ -1692,7 +1703,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
   start = (global ?
           pst->objfile->global_psymbols.list + pst->globals_offset :
           pst->objfile->static_psymbols.list + pst->statics_offset);
-  
+
   if (global)                  /* This means we can use a binary search. */
     {
       do_linear_search = 0;
@@ -1744,10 +1755,10 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
      we should also do a linear search. */
 
   if (do_linear_search)
-    {                  
+    {
       for (psym = start; psym < start + length; psym++)
        {
-         if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym), 
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
                                     SYMBOL_DOMAIN (*psym), domain))
            {
              if (linkage_name != NULL
@@ -1912,7 +1923,7 @@ find_main_psymtab (void)
    a match we'll never find, since it will go pretty quick.  Once the
    binary search terminates, we drop through and do a straight linear
    search on the symbols.  Each symbol which is marked as being a ObjC/C++
-   symbol (language_cplus or language_objc set) has both the encoded and 
+   symbol (language_cplus or language_objc set) has both the encoded and
    non-encoded names tested for a match.
 
    If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
@@ -2154,8 +2165,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
   /* elz: added this because this function returned the wrong
      information if the pc belongs to a stub (import/export)
      to call a shlib function. This stub would be anywhere between
-     two functions in the target, and the line info was erroneously 
-     taken to be the one of the line before the pc. 
+     two functions in the target, and the line info was erroneously
+     taken to be the one of the line before the pc.
    */
   /* RT: Further explanation:
 
@@ -2168,7 +2179,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
    * sorted by start address. The stubs are marked as "trampoline",
    * the others appear as text. E.g.:
    *
-   *  Minimal symbol table for main image 
+   *  Minimal symbol table for main image
    *     main:  code for main (text symbol)
    *     shr1: stub  (trampoline symbol)
    *     foo:   code for foo (text symbol)
@@ -2186,7 +2197,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
    * Assumptions being made about the minimal symbol table:
    *   1. lookup_minimal_symbol_by_pc() will return a trampoline only
    *      if we're really in the trampoline. If we're beyond it (say
-   *      we're in "foo" in the above example), it'll have a closer 
+   *      we're in "foo" in the above example), it'll have a closer
    *      symbol (the "foo" text symbol for example) and will not
    *      return the trampoline.
    *   2. lookup_minimal_symbol_text() will find a real text symbol
@@ -2207,7 +2218,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
           * gdb shmain // test program with shared libraries
           * (gdb) break shr1  // function in shared lib
           * Warning: In stub for ...
-          * In the above situation, the shared lib is not loaded yet, 
+          * In the above situation, the shared lib is not loaded yet,
           * so of course we can't find the real func/line info,
           * but the "break" still works, and the warning is annoying.
           * So I commented out the warning. RT */
@@ -2361,7 +2372,7 @@ find_pc_line (CORE_ADDR pc, int notcurrent)
 struct symtab *
 find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
 {
-  int exact;
+  int exact = 0;  /* Initialized here to avoid a compiler warning.  */
 
   /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
      so far seen.  */
@@ -2588,6 +2599,47 @@ find_function_start_pc (struct gdbarch *gdbarch,
   return pc;
 }
 
+/* Given a function start address FUNC_ADDR and SYMTAB, find the first
+   address for that function that has an entry in SYMTAB's line info
+   table.  If such an entry cannot be found, return FUNC_ADDR
+   unaltered.  */
+CORE_ADDR
+skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
+{
+  CORE_ADDR func_start, func_end;
+  struct linetable *l;
+  int ind, i, len;
+  int best_lineno = 0;
+  CORE_ADDR best_pc = func_addr;
+
+  /* Give up if this symbol has no lineinfo table.  */
+  l = LINETABLE (symtab);
+  if (l == NULL)
+    return func_addr;
+
+  /* Get the range for the function's PC values, or give up if we
+     cannot, for some reason.  */
+  if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
+    return func_addr;
+
+  /* Linetable entries are ordered by PC values, see the commentary in
+     symtab.h where `struct linetable' is defined.  Thus, the first
+     entry whose PC is in the range [FUNC_START..FUNC_END[ is the
+     address we are looking for.  */
+  for (i = 0; i < l->nitems; i++)
+    {
+      struct linetable_entry *item = &(l->item[i]);
+
+      /* Don't use line numbers of zero, they mark special entries in
+        the table.  See the commentary on symtab.h before the
+        definition of struct linetable.  */
+      if (item->line > 0 && func_start <= item->pc && item->pc < func_end)
+       return item->pc;
+    }
+
+  return func_addr;
+}
+
 /* Given a function symbol SYM, find the symtab and line for the start
    of the function.
    If the argument FUNFIRSTLINE is nonzero, we want the first line
@@ -2629,15 +2681,30 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
      to `__main' in `main' between the prologue and before user
      code.  */
   if (funfirstline
-      && gdbarch_skip_main_prologue_p (current_gdbarch)
+      && gdbarch_skip_main_prologue_p (gdbarch)
       && SYMBOL_LINKAGE_NAME (sym)
       && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
     {
-      pc = gdbarch_skip_main_prologue (current_gdbarch, pc);
+      pc = gdbarch_skip_main_prologue (gdbarch, pc);
       /* Recalculate the line number (might not be N+1).  */
       sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
     }
 
+  /* If we still don't have a valid source line, try to find the first
+     PC in the lineinfo table that belongs to the same function.  This
+     happens with COFF debug info, which does not seem to have an
+     entry in lineinfo table for the code after the prologue which has
+     no direct relation to source.  For example, this was found to be
+     the case with the DJGPP target using "gcc -gcoff" when the
+     compiler inserted code after the prologue to make sure the stack
+     is aligned.  */
+  if (funfirstline && sal.symtab == NULL)
+    {
+      pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
+      /* Recalculate the line number.  */
+      sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
+    }
+
   sal.pc = pc;
 
   return sal;
@@ -2699,7 +2766,7 @@ operator_chars (char *p, char **end)
            else
              error (_("nothing is allowed between '[' and ']'"));
          }
-       else 
+       else
          {
            /* Gratuitous qoute: skip it and move on. */
            p++;
@@ -2989,7 +3056,6 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound)
    Only symbols of KIND are searched:
    FUNCTIONS_DOMAIN - search all functions
    TYPES_DOMAIN     - search all type names
-   METHODS_DOMAIN   - search all methods NOT IMPLEMENTED
    VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
    and constants (enums)
 
@@ -3130,8 +3196,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                    && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
                         && SYMBOL_CLASS (*psym) != LOC_BLOCK)
                        || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK)
-                       || (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
-                       || (kind == METHODS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+                       || (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))))
              {
                PSYMTAB_TO_SYMTAB (ps);
                keep_going = 0;
@@ -3206,8 +3271,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                           && SYMBOL_CLASS (sym) != LOC_BLOCK
                           && SYMBOL_CLASS (sym) != LOC_CONST)
                          || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
-                         || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
-                         || (kind == METHODS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+                         || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
                {
                  /* match */
                  psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
@@ -3335,9 +3399,10 @@ print_symbol_info (domain_enum kind, struct symtab *s, struct symbol *sym,
 static void
 print_msymbol_info (struct minimal_symbol *msymbol)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (msymbol_objfile (msymbol));
   char *tmp;
 
-  if (gdbarch_addr_bit (current_gdbarch) <= 32)
+  if (gdbarch_addr_bit (gdbarch) <= 32)
     tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
                             & (CORE_ADDR) 0xffffffff,
                             8);
@@ -3546,10 +3611,10 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
 {
   static char *tmp = NULL;
   static unsigned int tmplen = 0;
-    
+
   char *method, *category, *selector;
   char *tmp2 = NULL;
-    
+
   method = SYMBOL_NATURAL_NAME (msymbol);
 
   /* Is it a method?  */
@@ -3559,7 +3624,7 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
   if (sym_text[0] == '[')
     /* Complete on shortened method method.  */
     completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
-    
+
   while ((strlen (method) + 1) >= tmplen)
     {
       if (tmplen == 0)
@@ -3571,9 +3636,9 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
   selector = strchr (method, ' ');
   if (selector != NULL)
     selector++;
-    
+
   category = strchr (method, '(');
-    
+
   if ((category != NULL) && (selector != NULL))
     {
       memcpy (tmp, method, (category - method));
@@ -3583,7 +3648,7 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
       if (sym_text[0] == '[')
        completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
     }
-    
+
   if (selector != NULL)
     {
       /* Complete on selector only.  */
@@ -3591,7 +3656,7 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
       tmp2 = strchr (tmp, ']');
       if (tmp2 != NULL)
        *tmp2 = '\0';
-       
+
       completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
     }
 }
@@ -3784,7 +3849,7 @@ default_make_symbol_completion_list (char *text, char *word)
   {
     QUIT;
     COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
-    
+
     completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
   }
 
@@ -3893,6 +3958,16 @@ make_symbol_completion_list (char *text, char *word)
   return current_language->la_make_symbol_completion_list (text, word);
 }
 
+/* Like make_symbol_completion_list, but suitable for use as a
+   completion function.  */
+
+char **
+make_symbol_completion_list_fn (struct cmd_list_element *ignore,
+                               char *text, char *word)
+{
+  return make_symbol_completion_list (text, word);
+}
+
 /* Like make_symbol_completion_list, but returns a list of symbols
    defined in a source file FILE.  */
 
@@ -4163,7 +4238,7 @@ make_source_files_completion_list (char *text, char *word)
  */
 
 int
-in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
+in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
 {
   struct symtab_and_line sal;
   CORE_ADDR func_addr, func_end;
@@ -4195,7 +4270,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
       if (! func_start)
        return 1;               /* We *might* be in a prologue.  */
 
-      prologue_end = gdbarch_skip_prologue (current_gdbarch, func_start);
+      prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
 
       return func_start <= pc && pc < prologue_end;
     }
@@ -4219,8 +4294,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
       /* We don't have any good line number info, so use the minsym
         information, together with the architecture-specific prologue
         scanning code.  */
-      CORE_ADDR prologue_end = gdbarch_skip_prologue
-                                (current_gdbarch, func_addr);
+      CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
 
       return func_addr <= pc && pc < prologue_end;
     }
@@ -4247,7 +4321,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
    found in both ia64 and ppc).  */
 
 CORE_ADDR
-skip_prologue_using_sal (CORE_ADDR func_addr)
+skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
 {
   struct symtab_and_line prologue_sal;
   CORE_ADDR start_pc;
@@ -4256,7 +4330,7 @@ skip_prologue_using_sal (CORE_ADDR func_addr)
 
   /* Get an initial range for the function.  */
   find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
-  start_pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
+  start_pc += gdbarch_deprecated_function_start_offset (gdbarch);
 
   prologue_sal = find_pc_line (start_pc, 0);
   if (prologue_sal.line != 0)
@@ -4326,14 +4400,14 @@ decode_line_spec (char *string, int funfirstline)
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line cursal;
-  
+
   if (string == 0)
     error (_("Empty line specification."));
-    
+
   /* We use whatever is set as the current source line. We do not try
-     and get a default  or it will recursively call us! */  
+     and get a default  or it will recursively call us! */
   cursal = get_current_source_symtab_and_line ();
-  
+
   sals = decode_line_1 (&string, funfirstline,
                        cursal.symtab, cursal.line,
                        (char ***) NULL, NULL);
@@ -4386,14 +4460,14 @@ find_main_name (void)
      a more complicated approach.  */
   new_main_name = ada_main_name ();
   if (new_main_name != NULL)
-    { 
+    {
       set_main_name (new_main_name);
       return;
     }
 
   new_main_name = pascal_main_name ();
   if (new_main_name != NULL)
-    { 
+    {
       set_main_name (new_main_name);
       return;
     }
@@ -4428,18 +4502,67 @@ append_expanded_sal (struct symtabs_and_lines *sal,
                     struct symtab *symtab,
                     int lineno, CORE_ADDR pc)
 {
-  CORE_ADDR func_addr, func_end;
-  
-  sal->sals = xrealloc (sal->sals, 
-                       sizeof (sal->sals[0]) 
+  sal->sals = xrealloc (sal->sals,
+                       sizeof (sal->sals[0])
                        * (sal->nelts + 1));
   init_sal (sal->sals + sal->nelts);
   sal->sals[sal->nelts].symtab = symtab;
   sal->sals[sal->nelts].section = NULL;
   sal->sals[sal->nelts].end = 0;
-  sal->sals[sal->nelts].line = lineno;  
+  sal->sals[sal->nelts].line = lineno;
   sal->sals[sal->nelts].pc = pc;
-  ++sal->nelts;      
+  ++sal->nelts;
+}
+
+/* Helper to expand_line_sal below.  Search in the symtabs for any
+   linetable entry that exactly matches FILENAME and LINENO and append
+   them to RET. If there is at least one match, return 1; otherwise,
+   return 0, and return the best choice in BEST_ITEM and BEST_SYMTAB.  */
+
+static int
+append_exact_match_to_sals (char *filename, int lineno,
+                           struct symtabs_and_lines *ret,
+                           struct linetable_entry **best_item,
+                           struct symtab **best_symtab)
+{
+  struct objfile *objfile;
+  struct symtab *symtab;
+  int exact = 0;
+  int j;
+  *best_item = 0;
+  *best_symtab = 0;
+  
+  ALL_SYMTABS (objfile, symtab)
+    {
+      if (strcmp (filename, symtab->filename) == 0)
+       {
+         struct linetable *l;
+         int len;
+         l = LINETABLE (symtab);
+         if (!l)
+           continue;
+         len = l->nitems;
+
+         for (j = 0; j < len; j++)
+           {
+             struct linetable_entry *item = &(l->item[j]);
+
+             if (item->line == lineno)
+               {
+                 exact = 1;
+                 append_expanded_sal (ret, symtab, lineno, item->pc);
+               }
+             else if (!exact && item->line > lineno
+                      && (*best_item == NULL
+                          || item->line < (*best_item)->line))
+               {
+                 *best_item = item;
+                 *best_symtab = symtab;
+               }
+           }
+       }
+    }
+  return exact;
 }
 
 /* Compute a set of all sals in
@@ -4447,7 +4570,7 @@ append_expanded_sal (struct symtabs_and_lines *sal,
    and line as SAL and return those.  If there
    are several sals that belong to the same block,
    only one sal for the block is included in results.  */
-   
+
 struct symtabs_and_lines
 expand_line_sal (struct symtab_and_line sal)
 {
@@ -4479,13 +4602,13 @@ expand_line_sal (struct symtab_and_line sal)
 
       lineno = sal.line;
 
-      /* We meed to find all symtabs for a file which name
-        is described by sal. We cannot just directly 
+      /* We need to find all symtabs for a file which name
+        is described by sal.  We cannot just directly
         iterate over symtabs, since a symtab might not be
-        yet created. We also cannot iterate over psymtabs,
+        yet created.  We also cannot iterate over psymtabs,
         calling PSYMTAB_TO_SYMTAB and working on that symtab,
         since PSYMTAB_TO_SYMTAB will return NULL for psymtab
-        corresponding to an included file. Therefore, we do
+        corresponding to an included file.  Therefore, we do
         first pass over psymtabs, reading in those with
         the right name.  Then, we iterate over symtabs, knowing
         that all symtabs we're interested in are loaded.  */
@@ -4497,44 +4620,14 @@ expand_line_sal (struct symtab_and_line sal)
            PSYMTAB_TO_SYMTAB (psymtab);
        }
 
-        
-      /* For each symtab, we add all pcs to ret.sals. I'm actually
-        not sure what to do if we have exact match in one symtab,
-        and non-exact match on another symtab.
-      */
-      ALL_SYMTABS (objfile, symtab)
-       {
-         if (strcmp (sal.symtab->filename,
-                     symtab->filename) == 0)
-           {
-             struct linetable *l;
-             int len;
-             l = LINETABLE (symtab);
-             if (!l)
-               continue;
-             len = l->nitems;
-
-             for (j = 0; j < len; j++)
-               {
-                 struct linetable_entry *item = &(l->item[j]);
-
-                 if (item->line == lineno)
-                   {
-                     exact = 1;
-                     append_expanded_sal (&ret, symtab, lineno, item->pc);
-                   }      
-                 else if (!exact && item->line > lineno
-                          && (best_item == NULL || item->line < best_item->line))
-                 
-                   {
-                     best_item = item;
-                     best_symtab = symtab;
-                   }
-               }
-           }
-       }
+      /* Now search the symtab for exact matches and append them.  If
+        none is found, append the best_item and all its exact
+        matches.  */
+      exact = append_exact_match_to_sals (sal.symtab->filename, lineno,
+                                         &ret, &best_item, &best_symtab);
       if (!exact && best_item)
-       append_expanded_sal (&ret, best_symtab, lineno, best_item->pc);
+       append_exact_match_to_sals (best_symtab->filename, best_item->line,
+                                   &ret, &best_item, &best_symtab);
     }
 
   /* For optimized code, compiler can scatter one source line accross
@@ -4544,7 +4637,7 @@ expand_line_sal (struct symtab_and_line sal)
      in two PC ranges.  In this case, we don't want to set breakpoint
      on first PC of each range.  To filter such cases, we use containing
      blocks -- for each PC found above we see if there are other PCs
-     that are in the same block.  If yes, the other PCs are filtered out.  */  
+     that are in the same block.  If yes, the other PCs are filtered out.  */
 
   filter = alloca (ret.nelts * sizeof (int));
   blocks = alloca (ret.nelts * sizeof (struct block *));
@@ -4563,15 +4656,15 @@ expand_line_sal (struct symtab_and_line sal)
            ++deleted;
            break;
          }
-  
+
   {
-    struct symtab_and_line *final = 
+    struct symtab_and_line *final =
       xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
-    
+
     for (i = 0, j = 0; i < ret.nelts; ++i)
       if (filter[i])
        final[j++] = ret.sals[i];
-    
+
     ret.nelts -= deleted;
     xfree (ret.sals);
     ret.sals = final;
@@ -4593,7 +4686,6 @@ All global and static variable names, or those matching REGEXP."));
   add_info ("functions", functions_info,
            _("All function names, or those matching REGEXP."));
 
-  
   /* FIXME:  This command has at least the following problems:
      1.  It prints builtin types (in a very strange and confusing fashion).
      2.  It doesn't print right, e.g. with
This page took 0.035532 seconds and 4 git commands to generate.