* dummy-frame.c (deprecated_pc_in_call_dummy): Add GDBARCH parameter,
[deliverable/binutils-gdb.git] / gdb / symtab.c
index fa8b3e7c287d5c87b0ba72b021066481355dacb9..ee138ff0ae3936026aab10f774d0ae032011da18 100644 (file)
@@ -1,14 +1,14 @@
 /* Symbol table lookup for the GNU debugger, GDB.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -41,6 +39,9 @@
 #include "source.h"
 #include "filenames.h"         /* for FILENAME_CMP */
 #include "objc-lang.h"
+#include "ada-lang.h"
+#include "p-lang.h"
+#include "addrmap.h"
 
 #include "hashtab.h"
 
 #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"
+#include "macrotab.h"
+#include "macroscope.h"
 
 /* Prototypes for local functions */
 
@@ -69,7 +76,7 @@ static void variables_info (char *, int);
 
 static void sources_info (char *, int);
 
-static void output_source_filename (char *, int *);
+static void output_source_filename (const char *, int *);
 
 static int find_line_common (struct linetable *, int, int *);
 
@@ -81,44 +88,26 @@ static struct symbol *lookup_symbol_aux (const char *name,
                                         const char *linkage_name,
                                         const struct block *block,
                                         const domain_enum domain,
-                                        int *is_a_field_of_this,
-                                        struct symtab **symtab);
+                                        enum language language,
+                                        int *is_a_field_of_this);
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
                                        const char *linkage_name,
                                        const struct block *block,
-                                       const domain_enum domain,
-                                       struct symtab **symtab);
+                                       const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
                                          const char *name,
                                          const char *linkage_name,
-                                         const domain_enum domain,
-                                         struct symtab **symtab);
+                                         const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_psymtabs (int block_index,
                                           const char *name,
                                           const char *linkage_name,
-                                          const domain_enum domain,
-                                          struct symtab **symtab);
-
-#if 0
-static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
-                                         const char *linkage_name,
-                                         const domain_enum domain,
-                                         int *is_a_field_of_this,
-                                         struct symtab **symtab);
-#endif
-
-/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
-/* Signals the presence of objects compiled by HP compilers */
-int hp_som_som_object_present = 0;
-
-static void fixup_section (struct general_symbol_info *, struct objfile *);
+                                          const domain_enum domain);
 
 static int file_matches (char *, char **, int);
 
@@ -133,11 +122,35 @@ void _initialize_symtab (void);
 
 /* */
 
+/* Allow the user to configure the debugger behavior with respect
+   to multiple-choice menus when more than one symbol matches during
+   a symbol lookup.  */
+
+const char multiple_symbols_ask[] = "ask";
+const char multiple_symbols_all[] = "all";
+const char multiple_symbols_cancel[] = "cancel";
+static const char *multiple_symbols_modes[] =
+{
+  multiple_symbols_ask,
+  multiple_symbols_all,
+  multiple_symbols_cancel,
+  NULL
+};
+static const char *multiple_symbols_mode = multiple_symbols_all;
+
+/* Read-only accessor to AUTO_SELECT_MODE.  */
+
+const char *
+multiple_symbols_select_mode (void)
+{
+  return multiple_symbols_mode;
+}
+
 /* The single non-language-specific builtin type */
 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;
@@ -175,27 +188,31 @@ 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_filename (s);
-       if (FILENAME_CMP (full_path, fp) == 0)
-         {
-           return s;
-         }
+        const char *fp = symtab_to_fullname (s);
+        if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+          {
+            return s;
+          }
       }
 
     if (real_path != NULL)
       {
-       char *rp = gdb_realpath (symtab_to_filename (s));
-        make_cleanup (xfree, rp);
-       if (FILENAME_CMP (real_path, rp) == 0)
-         {
-           return s;
-         }
+        char *fullname = symtab_to_fullname (s);
+        if (fullname != NULL)
+          {
+            char *rp = gdb_realpath (fullname);
+            make_cleanup (xfree, rp);
+            if (FILENAME_CMP (real_path, rp) == 0)
+              {
+                return s;
+              }
+          }
       }
   }
 
@@ -216,7 +233,7 @@ got_symtab:
     return (NULL);
 
   if (ps->readin)
-    error ("Internal: readin %s pst for `%s' found when no symtab found.",
+    error (_("Internal: readin %s pst for `%s' found when no symtab found."),
           ps->filename, name);
 
   s = PSYMTAB_TO_SYMTAB (ps);
@@ -268,8 +285,7 @@ lookup_partial_symtab (const char *name)
        this symtab and use its absolute path.  */
     if (full_path != NULL)
       {
-       if (pst->fullname == NULL)
-         source_full_path_of (pst->filename, &pst->fullname);
+       psymtab_to_fullname (pst);
        if (pst->fullname != NULL
            && FILENAME_CMP (full_path, pst->fullname) == 0)
          {
@@ -280,8 +296,7 @@ lookup_partial_symtab (const char *name)
     if (real_path != NULL)
       {
         char *rp = NULL;
-       if (pst->fullname == NULL)
-         source_full_path_of (pst->filename, &pst->fullname);
+       psymtab_to_fullname (pst);
         if (pst->fullname != NULL)
           {
             rp = gdb_realpath (pst->fullname);
@@ -423,13 +438,13 @@ 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.  */
 
-  objfile->demangled_names_hash = htab_create_alloc_ex
+  objfile->demangled_names_hash = htab_create_alloc
     (256, htab_hash_string, (int (*) (const void *, const void *)) streq,
-     NULL, objfile->md, xmcalloc, xmfree);
+     NULL, xcalloc, xfree);
 }
 
 /* Try to determine the demangled name for a symbol, based on the
@@ -485,7 +500,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
 
 /* Set both the mangled and demangled (if any) names for GSYMBOL based
    on LINKAGE_NAME and LEN.  The hash table corresponding to OBJFILE
-   is used, and the memory comes from that objfile's symbol_obstack.
+   is used, and the memory comes from that objfile's objfile_obstack.
    LINKAGE_NAME is copied, so the pointer can be discarded after
    calling this function.  */
 
@@ -524,6 +539,24 @@ symbol_set_names (struct general_symbol_info *gsymbol,
   if (objfile->demangled_names_hash == NULL)
     create_demangled_names_hash (objfile);
 
+  if (gsymbol->language == language_ada)
+    {
+      /* In Ada, we do the symbol lookups using the mangled name, so
+         we can save some space by not storing the demangled name.
+
+         As a side note, we have also observed some overlap between
+         the C++ mangling and Ada mangling, similarly to what has
+         been observed with Java.  Because we don't store the demangled
+         name with the symbol, we don't need to use the same trick
+         as Java.  */
+      gsymbol->name = obstack_alloc (&objfile->objfile_obstack, len + 1);
+      memcpy (gsymbol->name, linkage_name, len);
+      gsymbol->name[len] = '\0';
+      gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+
+      return;
+    }
+
   /* The stabs reader generally provides names that are not
      NUL-terminated; most of the other readers don't do this, so we
      can just use the given copy, unless we're in the Java case.  */
@@ -572,7 +605,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
       /* If there is a demangled name, place it right after the mangled name.
         Otherwise, just place a second zero byte after the end of the mangled
         name.  */
-      *slot = obstack_alloc (&objfile->symbol_obstack,
+      *slot = obstack_alloc (&objfile->objfile_obstack,
                             lookup_len + demangled_len + 2);
       memcpy (*slot, lookup_name, lookup_len + 1);
       if (demangled_name != NULL)
@@ -592,71 +625,68 @@ symbol_set_names (struct general_symbol_info *gsymbol,
     gsymbol->language_specific.cplus_specific.demangled_name = NULL;
 }
 
-/* Initialize the demangled name of GSYMBOL if possible.  Any required space
-   to store the name is obtained from the specified obstack.  The function
-   symbol_set_names, above, should be used instead where possible for more
-   efficient memory usage.  */
-
-void
-symbol_init_demangled_name (struct general_symbol_info *gsymbol,
-                            struct obstack *obstack)
-{
-  char *mangled = gsymbol->name;
-  char *demangled = NULL;
-
-  demangled = symbol_find_demangled_name (gsymbol, mangled);
-  if (gsymbol->language == language_cplus
-      || gsymbol->language == language_java
-      || gsymbol->language == language_objc)
-    {
-      if (demangled)
-       {
-         gsymbol->language_specific.cplus_specific.demangled_name
-           = obsavestring (demangled, strlen (demangled), obstack);
-         xfree (demangled);
-       }
-      else
-       gsymbol->language_specific.cplus_specific.demangled_name = NULL;
-    }
-  else
-    {
-      /* Unknown language; just clean up quietly.  */
-      if (demangled)
-       xfree (demangled);
-    }
-}
-
 /* Return the source code name of a symbol.  In languages where
    demangling is necessary, this is the demangled name.  */
 
 char *
 symbol_natural_name (const struct general_symbol_info *gsymbol)
 {
-  if ((gsymbol->language == language_cplus
-       || gsymbol->language == language_java
-       || gsymbol->language == language_objc)
-      && (gsymbol->language_specific.cplus_specific.demangled_name != NULL))
+  switch (gsymbol->language)
     {
-      return gsymbol->language_specific.cplus_specific.demangled_name;
-    }
-  else
-    {
-      return gsymbol->name;
+    case language_cplus:
+    case language_java:
+    case language_objc:
+      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+       return gsymbol->language_specific.cplus_specific.demangled_name;
+      break;
+    case language_ada:
+      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+       return gsymbol->language_specific.cplus_specific.demangled_name;
+      else
+       return ada_decode_symbol (gsymbol);
+      break;
+    default:
+      break;
     }
+  return gsymbol->name;
 }
 
 /* Return the demangled name for a symbol based on the language for
    that symbol.  If no demangled name exists, return NULL. */
 char *
-symbol_demangled_name (struct general_symbol_info *gsymbol)
+symbol_demangled_name (const struct general_symbol_info *gsymbol)
 {
-  if (gsymbol->language == language_cplus
-      || gsymbol->language == language_java
-      || gsymbol->language == language_objc)
-    return gsymbol->language_specific.cplus_specific.demangled_name;
+  switch (gsymbol->language)
+    {
+    case language_cplus:
+    case language_java:
+    case language_objc:
+      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+       return gsymbol->language_specific.cplus_specific.demangled_name;
+      break;
+    case language_ada:
+      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+       return gsymbol->language_specific.cplus_specific.demangled_name;
+      else
+       return ada_decode_symbol (gsymbol);
+      break;
+    default:
+      break;
+    }
+  return NULL;
+}
 
-  else 
-    return NULL;
+/* 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
+   (same pointer) as SYMBOL_LINKAGE_NAME. */
+char *
+symbol_search_name (const struct general_symbol_info *gsymbol)
+{
+  if (gsymbol->language == language_ada)
+    return gsymbol->name;
+  else
+    return symbol_natural_name (gsymbol);
 }
 
 /* Initialize the structure fields to zero values.  */
@@ -668,16 +698,160 @@ init_sal (struct symtab_and_line *sal)
   sal->line = 0;
   sal->pc = 0;
   sal->end = 0;
+  sal->explicit_pc = 0;
+  sal->explicit_line = 0;
 }
 \f
 
+/* Return 1 if the two sections are the same, or if they could
+   plausibly be copies of each other, one in an original object
+   file and another in a separated debug file.  */
+
+int
+matching_obj_sections (struct obj_section *obj_first,
+                      struct obj_section *obj_second)
+{
+  asection *first = obj_first? obj_first->the_bfd_section : NULL;
+  asection *second = obj_second? obj_second->the_bfd_section : NULL;
+  struct objfile *obj;
+
+  /* If they're the same section, then they match.  */
+  if (first == second)
+    return 1;
+
+  /* If either is NULL, give up.  */
+  if (first == NULL || second == NULL)
+    return 0;
+
+  /* This doesn't apply to absolute symbols.  */
+  if (first->owner == NULL || second->owner == NULL)
+    return 0;
+
+  /* If they're in the same object file, they must be different sections.  */
+  if (first->owner == second->owner)
+    return 0;
+
+  /* Check whether the two sections are potentially corresponding.  They must
+     have the same size, address, and name.  We can't compare section indexes,
+     which would be more reliable, because some sections may have been
+     stripped.  */
+  if (bfd_get_section_size (first) != bfd_get_section_size (second))
+    return 0;
+
+  /* In-memory addresses may start at a different offset, relativize them.  */
+  if (bfd_get_section_vma (first->owner, first)
+      - bfd_get_start_address (first->owner)
+      != bfd_get_section_vma (second->owner, second)
+        - bfd_get_start_address (second->owner))
+    return 0;
+
+  if (bfd_get_section_name (first->owner, first) == NULL
+      || bfd_get_section_name (second->owner, second) == NULL
+      || strcmp (bfd_get_section_name (first->owner, first),
+                bfd_get_section_name (second->owner, second)) != 0)
+    return 0;
+
+  /* Otherwise check that they are in corresponding objfiles.  */
+
+  ALL_OBJFILES (obj)
+    if (obj->obfd == first->owner)
+      break;
+  gdb_assert (obj != NULL);
+
+  if (obj->separate_debug_objfile != NULL
+      && obj->separate_debug_objfile->obfd == second->owner)
+    return 1;
+  if (obj->separate_debug_objfile_backlink != NULL
+      && obj->separate_debug_objfile_backlink->obfd == second->owner)
+    return 1;
+
+  return 0;
+}
+
+/* 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.  */
 
-/* Find which partial symtab on contains PC and SECTION.  Return 0 if none.  */
+static struct partial_symtab *
+find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section,
+                            struct partial_symtab *pst,
+                            struct minimal_symbol *msymbol)
+{
+  struct objfile *objfile = pst->objfile;
+  struct partial_symtab *tpst;
+  struct partial_symtab *best_pst = pst;
+  CORE_ADDR best_addr = pst->textlow;
+
+  /* An objfile that has its functions reordered might have
+     many partial symbol tables containing the PC, but
+     we want the partial symbol table that contains the
+     function containing the PC.  */
+  if (!(objfile->flags & OBJF_REORDERED) &&
+      section == 0)    /* can't validate section this way */
+    return pst;
+
+  if (msymbol == NULL)
+    return (pst);
+
+  /* The code range of partial symtabs sometimes overlap, so, in
+     the loop below, we need to check all partial symtabs and
+     find the one that fits better for the given PC address. We
+     select the partial symtab that contains a symbol whose
+     address is closest to the PC address.  By closest we mean
+     that find_pc_sect_symbol returns the symbol with address
+     that is closest and still less than the given PC.  */
+  for (tpst = pst; tpst != NULL; tpst = tpst->next)
+    {
+      if (pc >= tpst->textlow && pc < tpst->texthigh)
+       {
+         struct partial_symbol *p;
+         CORE_ADDR this_addr;
+
+         /* NOTE: This assumes that every psymbol has a
+            corresponding msymbol, which is not necessarily
+            true; the debug info might be much richer than the
+            object's symbol table.  */
+         p = find_pc_sect_psymbol (tpst, pc, section);
+         if (p != NULL
+             && SYMBOL_VALUE_ADDRESS (p)
+             == SYMBOL_VALUE_ADDRESS (msymbol))
+           return tpst;
+
+         /* Also accept the textlow value of a psymtab as a
+            "symbol", to provide some support for partial
+            symbol tables with line information but no debug
+            symbols (e.g. those produced by an assembler).  */
+         if (p != NULL)
+           this_addr = SYMBOL_VALUE_ADDRESS (p);
+         else
+           this_addr = tpst->textlow;
+
+         /* Check whether it is closer than our current
+            BEST_ADDR.  Since this symbol address is
+            necessarily lower or equal to PC, the symbol closer
+            to PC is the symbol which address is the highest.
+            This way we return the psymtab which contains such
+            best match symbol. This can help in cases where the
+            symbol information/debuginfo is not complete, like
+            for instance on IRIX6 with gcc, where no debug info
+            is emitted for statics. (See also the nodebug.exp
+            testcase.) */
+         if (this_addr > best_addr)
+           {
+             best_addr = this_addr;
+             best_pst = tpst;
+           }
+       }
+    }
+  return best_pst;
+}
 
+/* Find which partial symtab contains PC and SECTION.  Return 0 if
+   none.  We return the psymtab that contains a symbol whose address
+   exactly matches PC, or, if we cannot find an exact match, the
+   psymtab that contains a symbol whose address is closest to PC.  */
 struct partial_symtab *
-find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
+find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
 {
-  struct partial_symtab *pst;
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
 
@@ -686,50 +860,80 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
      not include the data ranges.  */
   msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
   if (msymbol
-      && (msymbol->type == mst_data
-         || msymbol->type == mst_bss
-         || msymbol->type == mst_abs
-         || msymbol->type == mst_file_data
-         || msymbol->type == mst_file_bss))
+      && (MSYMBOL_TYPE (msymbol) == mst_data
+         || MSYMBOL_TYPE (msymbol) == mst_bss
+         || MSYMBOL_TYPE (msymbol) == mst_abs
+         || MSYMBOL_TYPE (msymbol) == mst_file_data
+         || MSYMBOL_TYPE (msymbol) == mst_file_bss))
     return NULL;
 
-  ALL_PSYMTABS (objfile, pst)
-  {
-    if (pc >= pst->textlow && pc < pst->texthigh)
-      {
-       struct partial_symtab *tpst;
+  /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
+     than the later used TEXTLOW/TEXTHIGH one.  */
 
-       /* An objfile that has its functions reordered might have
-          many partial symbol tables containing the PC, but
-          we want the partial symbol table that contains the
-          function containing the PC.  */
-       if (!(objfile->flags & OBJF_REORDERED) &&
-           section == 0)       /* can't validate section this way */
-         return (pst);
-
-       if (msymbol == NULL)
-         return (pst);
+  ALL_OBJFILES (objfile)
+    if (objfile->psymtabs_addrmap != NULL)
+      {
+       struct partial_symtab *pst;
 
-       for (tpst = pst; tpst != NULL; tpst = tpst->next)
+       pst = addrmap_find (objfile->psymtabs_addrmap, pc);
+       if (pst != NULL)
          {
-           if (pc >= tpst->textlow && pc < tpst->texthigh)
+           /* FIXME: addrmaps currently do not handle overlayed sections,
+              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)
              {
                struct partial_symbol *p;
-
-               p = find_pc_sect_psymbol (tpst, pc, section);
-               if (p != NULL
-                   && SYMBOL_VALUE_ADDRESS (p)
-                   == SYMBOL_VALUE_ADDRESS (msymbol))
-                 return (tpst);
+               /* NOTE: This assumes that every psymbol has a
+                  corresponding msymbol, which is not necessarily
+                  true; the debug info might be much richer than the
+                  object's symbol table.  */
+               p = find_pc_sect_psymbol (pst, pc, section);
+               if (!p
+                   || SYMBOL_VALUE_ADDRESS (p)
+                      != SYMBOL_VALUE_ADDRESS (msymbol))
+                 continue;
              }
+
+           /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
+              PSYMTABS_ADDRMAP we used has already the best 1-byte
+              granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
+              a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
+              overlap.  */
+
+           return pst;
          }
-       return (pst);
       }
-  }
-  return (NULL);
+
+  /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
+     which still have no corresponding full SYMTABs read.  But it is not
+     present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
+     so far.  */
+
+  ALL_OBJFILES (objfile)
+    {
+      struct partial_symtab *pst;
+
+      /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
+        its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
+        debug info type in single OBJFILE.  */
+
+      ALL_OBJFILE_PSYMTABS (objfile, pst)
+       if (pc >= pst->textlow && pc < pst->texthigh)
+         {
+           struct partial_symtab *best_pst;
+
+           best_pst = find_pc_sect_psymtab_closer (pc, section, pst,
+                                                   msymbol);
+           if (best_pst != NULL)
+             return best_pst;
+         }
+    }
+
+  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 *
@@ -738,12 +942,12 @@ 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 *
 find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
-                     asection *section)
+                     struct obj_section *section)
 {
   struct partial_symbol *best = NULL, *p, **pp;
   CORE_ADDR best_pc;
@@ -775,7 +979,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
          if (section)          /* match on a specific section */
            {
              fixup_psymbol_section (p, psymtab->objfile);
-             if (SYMBOL_BFD_SECTION (p) != section)
+             if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
                continue;
            }
          best_pc = SYMBOL_VALUE_ADDRESS (p);
@@ -799,7 +1003,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
          if (section)          /* match on a specific section */
            {
              fixup_psymbol_section (p, psymtab->objfile);
-             if (SYMBOL_BFD_SECTION (p) != section)
+             if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
                continue;
            }
          best_pc = SYMBOL_VALUE_ADDRESS (p);
@@ -810,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 *
@@ -823,28 +1027,115 @@ find_pc_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc)
    out of the minimal symbols and stash that in the debug symbol.  */
 
 static void
-fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+fixup_section (struct general_symbol_info *ginfo,
+              CORE_ADDR addr, struct objfile *objfile)
 {
   struct minimal_symbol *msym;
-  msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
 
+  /* First, check whether a minimal symbol with the same name exists
+     and points to the same address.  The address check is required
+     e.g. on PowerPC64, where the minimal symbol for a function will
+     point to the function descriptor, while the debug symbol will
+     point to the actual function code.  */
+  msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
   if (msym)
     {
-      ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+      ginfo->obj_section = SYMBOL_OBJ_SECTION (msym);
       ginfo->section = SYMBOL_SECTION (msym);
     }
+  else
+    {
+      /* Static, function-local variables do appear in the linker
+        (minimal) symbols, but are frequently given names that won't
+        be found via lookup_minimal_symbol().  E.g., it has been
+        observed in frv-uclinux (ELF) executables that a static,
+        function-local variable named "foo" might appear in the
+        linker symbols as "foo.6" or "foo.3".  Thus, there is no
+        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
+        ANOFFSET value) needs to be subtracted from these values when
+        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
+        necessary in order to add the correct relocation value.  In
+        other words, we wouldn't even be in this function (attempting
+        to compute the section) if it were already known.
+
+        Note that it is possible to search the minimal symbols
+        (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.
+
+        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)
+       {
+         int idx = s->the_bfd_section->index;
+         CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+
+         if (obj_section_addr (s) - offset <= addr
+             && addr < obj_section_endaddr (s) - offset)
+           {
+             ginfo->obj_section = s;
+             ginfo->section = idx;
+             return;
+           }
+       }
+    }
 }
 
 struct symbol *
 fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 {
+  CORE_ADDR addr;
+
   if (!sym)
     return NULL;
 
-  if (SYMBOL_BFD_SECTION (sym))
+  if (SYMBOL_OBJ_SECTION (sym))
     return sym;
 
-  fixup_section (&sym->ginfo, objfile);
+  /* We either have an OBJFILE, or we can get at it from the sym's
+     symtab.  Anything else is a bug.  */
+  gdb_assert (objfile || SYMBOL_SYMTAB (sym));
+
+  if (objfile == NULL)
+    objfile = SYMBOL_SYMTAB (sym)->objfile;
+
+  /* We should have an objfile by now.  */
+  gdb_assert (objfile);
+
+  switch (SYMBOL_CLASS (sym))
+    {
+    case LOC_STATIC:
+    case LOC_LABEL:
+      addr = SYMBOL_VALUE_ADDRESS (sym);
+      break;
+    case LOC_BLOCK:
+      addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+      break;
+
+    default:
+      /* Nothing else will be listed in the minsyms -- no use looking
+        it up.  */
+      return sym;
+    }
+
+  fixup_section (&sym->ginfo, addr, objfile);
 
   return sym;
 }
@@ -852,13 +1143,30 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 struct partial_symbol *
 fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
 {
+  CORE_ADDR addr;
+
   if (!psym)
     return NULL;
 
-  if (SYMBOL_BFD_SECTION (psym))
+  if (SYMBOL_OBJ_SECTION (psym))
     return psym;
 
-  fixup_section (&psym->ginfo, objfile);
+  gdb_assert (objfile);
+
+  switch (SYMBOL_CLASS (psym))
+    {
+    case LOC_STATIC:
+    case LOC_LABEL:
+    case LOC_BLOCK:
+      addr = SYMBOL_VALUE_ADDRESS (psym);
+      break;
+    default:
+      /* Nothing else will be listed in the minsyms -- no use looking
+        it up.  */
+      return psym;
+    }
+
+  fixup_section (&psym->ginfo, addr, objfile);
 
   return psym;
 }
@@ -866,11 +1174,9 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
 /* Find the definition for a specified symbol name NAME
    in domain DOMAIN, visible from lexical block BLOCK.
    Returns the struct symbol pointer, or zero if no symbol is found.
-   If SYMTAB is non-NULL, store the symbol table in which the
-   symbol was found there, or NULL if not 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.) */
 
@@ -885,28 +1191,50 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
    code).  */
 
 struct symbol *
-lookup_symbol (const char *name, const struct block *block,
-              const domain_enum domain, int *is_a_field_of_this,
-              struct symtab **symtab)
+lookup_symbol_in_language (const char *name, const struct block *block,
+                          const domain_enum domain, enum language lang,
+                          int *is_a_field_of_this)
 {
   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;
 
-  /* If we are using C++ language, demangle the name before doing a lookup, so
+  /* If we are using C++ or Java, demangle the name before doing a lookup, so
      we can always binary search. */
-  if (current_language->la_language == language_cplus)
+  if (lang == language_cplus)
     {
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
       if (demangled_name)
        {
          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,
+                                      DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+      if (demangled_name)
+       {
+         mangled_name = name;
+         modified_name = demangled_name;
+         make_cleanup (xfree, demangled_name);
        }
     }
 
@@ -924,14 +1252,25 @@ lookup_symbol (const char *name, const struct block *block,
     }
 
   returnval = lookup_symbol_aux (modified_name, mangled_name, block,
-                                domain, is_a_field_of_this, symtab);
-  if (needtofreename)
-    xfree (demangled_name);
+                                domain, lang, is_a_field_of_this);
+  do_cleanups (cleanup);
+
+  return returnval;
+}
+
+/* Behave like lookup_symbol_in_language, but performed with the
+   current language.  */
 
-  return returnval;     
+struct symbol *
+lookup_symbol (const char *name, const struct block *block,
+              domain_enum domain, int *is_a_field_of_this)
+{
+  return lookup_symbol_in_language (name, block, domain,
+                                   current_language->la_language,
+                                   is_a_field_of_this);
 }
 
-/* Behave like lookup_symbol_aux except that NAME is the natural name
+/* Behave like lookup_symbol except that NAME is the natural name
    of the symbol that we're looking for and, if LINKAGE_NAME is
    non-NULL, ensure that the symbol's linkage name matches as
    well.  */
@@ -939,9 +1278,10 @@ lookup_symbol (const char *name, const struct block *block,
 static struct symbol *
 lookup_symbol_aux (const char *name, const char *linkage_name,
                   const struct block *block, const domain_enum domain,
-                  int *is_a_field_of_this, struct symtab **symtab)
+                  enum language language, int *is_a_field_of_this)
 {
   struct symbol *sym;
+  const struct language_defn *langdef;
 
   /* Make sure we do something sensible with is_a_field_of_this, since
      the callers that set this parameter to some non-null value will
@@ -954,34 +1294,55 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain,
-                                symtab);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
   if (sym != NULL)
     return sym;
 
-  /* If requested to do so by the caller and if appropriate for the
-     current language, check to see if NAME is a field of `this'. */
+  /* If requested to do so by the caller and if appropriate for LANGUAGE,
+     check to see if NAME is a field of `this'. */
 
-  if (current_language->la_value_of_this != NULL
-      && is_a_field_of_this != NULL)
-    {
-      struct value *v = current_language->la_value_of_this (0);
+  langdef = language_def (language);
 
-      if (v && check_field (v, name))
+  if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
+      && block != NULL)
+    {
+      struct symbol *sym = NULL;
+      /* 'this' is only defined in the function's block, so find the
+        enclosing function block.  */
+      for (; block && !BLOCK_FUNCTION (block);
+          block = BLOCK_SUPERBLOCK (block));
+
+      if (block && !dict_empty (BLOCK_DICT (block)))
+       sym = lookup_block_symbol (block, langdef->la_name_of_this,
+                                  NULL, VAR_DOMAIN);
+      if (sym)
        {
-         *is_a_field_of_this = 1;
-         if (symtab != NULL)
-           *symtab = NULL;
-         return NULL;
+         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"),
+                  langdef->la_name_of_this);
+
+         if (check_field (t, name))
+           {
+             *is_a_field_of_this = 1;
+             return NULL;
+           }
        }
     }
 
-  /* Now do whatever is appropriate for the current language to look
+  /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
 
-  sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name,
-                                                    block, domain,
-                                                    symtab);
+  sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -991,18 +1352,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
      desired name as a file-level static, then do psymtab-to-symtab
      conversion on the fly and return the found symbol. */
 
-  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name,
-                                  domain, symtab);
+  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, symtab);
+
+  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
   if (sym != NULL)
     return sym;
 
-  if (symtab != NULL)
-    *symtab = NULL;
   return NULL;
 }
 
@@ -1012,8 +1369,7 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
                         const struct block *block,
-                        const domain_enum domain,
-                        struct symtab **symtab)
+                        const domain_enum domain)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
@@ -1025,8 +1381,7 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
 
   while (block != static_block)
     {
-      sym = lookup_symbol_aux_block (name, linkage_name, block, domain,
-                                    symtab);
+      sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
       if (sym != NULL)
        return sym;
       block = BLOCK_SUPERBLOCK (block);
@@ -1037,47 +1392,96 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
   return NULL;
 }
 
-/* Look up a symbol in a block; if found, locate its symtab, fixup the
-   symbol, and set block_found appropriately.  */
+/* Look up OBJFILE to BLOCK.  */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+  struct objfile *obj;
+  struct symtab *s;
+
+  if (block == NULL)
+    return NULL;
+
+  block = block_global_block (block);
+  /* Go through SYMTABS.  */
+  ALL_SYMTABS (obj, s)
+    if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+      return obj;
+
+  return NULL;
+}
+
+/* Look up a symbol in a block; if found, fixup the symbol, and set
+   block_found appropriately.  */
 
 struct symbol *
 lookup_symbol_aux_block (const char *name, const char *linkage_name,
                         const struct block *block,
-                        const domain_enum domain,
-                        struct symtab **symtab)
+                        const domain_enum domain)
 {
   struct symbol *sym;
-  struct objfile *objfile = NULL;
-  struct blockvector *bv;
-  struct block *b;
-  struct symtab *s = NULL;
 
   sym = lookup_block_symbol (block, name, linkage_name, domain);
   if (sym)
     {
       block_found = block;
-      if (symtab != NULL)
-       {
-         /* Search the list of symtabs for one which contains the
-            address of the start of this block.  */
-         ALL_SYMTABS (objfile, s)
-           {
-             bv = BLOCKVECTOR (s);
-             b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-             if (BLOCK_START (b) <= BLOCK_START (block)
-                 && BLOCK_END (b) > BLOCK_START (block))
-               goto found;
-           }
-       found:
-         *symtab = s;
-       }
-      
-      return fixup_symbol_section (sym, objfile);
+      return fixup_symbol_section (sym, NULL);
     }
 
   return NULL;
 }
 
+/* Check all global symbols in OBJFILE in symtabs and
+   psymtabs.  */
+
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *objfile,
+                                  const char *name,
+                                  const char *linkage_name,
+                                  const domain_enum domain)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct symtab *s;
+  struct partial_symtab *ps;
+
+  /* Go through symtabs.  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+  {
+    bv = BLOCKVECTOR (s);
+    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    if (sym)
+      {
+       block_found = block;
+       return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  /* Now go through psymtabs.  */
+  ALL_OBJFILE_PSYMTABS (objfile, ps)
+  {
+    if (!ps->readin
+       && lookup_partial_symbol (ps, name, linkage_name,
+                                 1, domain))
+      {
+       s = PSYMTAB_TO_SYMTAB (ps);
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+       sym = lookup_block_symbol (block, name, linkage_name, domain);
+       return fixup_symbol_section (sym, (struct objfile *)objfile);
+      }
+  }
+
+  if (objfile->separate_debug_objfile)
+    return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile,
+                                             name, linkage_name, domain);
+
+  return NULL;
+}
+
 /* Check to see if the symbol is defined in one of the symtabs.
    BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
    depending on whether or not we want to search global symbols or
@@ -1086,8 +1490,7 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_symtabs (int block_index,
                           const char *name, const char *linkage_name,
-                          const domain_enum domain,
-                          struct symtab **symtab)
+                          const domain_enum domain)
 {
   struct symbol *sym;
   struct objfile *objfile;
@@ -1095,7 +1498,7 @@ lookup_symbol_aux_symtabs (int block_index,
   const struct block *block;
   struct symtab *s;
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, block_index);
@@ -1103,8 +1506,6 @@ lookup_symbol_aux_symtabs (int block_index,
     if (sym)
       {
        block_found = block;
-       if (symtab != NULL)
-         *symtab = s;
        return fixup_symbol_section (sym, objfile);
       }
   }
@@ -1120,8 +1521,7 @@ lookup_symbol_aux_symtabs (int block_index,
 static struct symbol *
 lookup_symbol_aux_psymtabs (int block_index, const char *name,
                            const char *linkage_name,
-                           const domain_enum domain,
-                           struct symtab **symtab)
+                           const domain_enum domain)
 {
   struct symbol *sym;
   struct objfile *objfile;
@@ -1159,12 +1559,10 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
                                       STATIC_BLOCK : GLOBAL_BLOCK);
            sym = lookup_block_symbol (block, name, linkage_name, domain);
            if (!sym)
-             error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>).",
+             error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
                     block_index == GLOBAL_BLOCK ? "global" : "static",
                     name, ps->filename, name, name);
          }
-       if (symtab != NULL)
-         *symtab = s;
        return fixup_symbol_section (sym, objfile);
       }
   }
@@ -1172,132 +1570,6 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
   return NULL;
 }
 
-#if 0
-/* Check for the possibility of the symbol being a function or a
-   mangled variable that is stored in one of the minimal symbol
-   tables.  Eventually, all global symbols might be resolved in this
-   way.  */
-
-/* NOTE: carlton/2002-12-05: At one point, this function was part of
-   lookup_symbol_aux, and what are now 'return' statements within
-   lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if
-   sym was NULL.  As far as I can tell, this was basically accidental;
-   it didn't happen every time that msymbol was non-NULL, but only if
-   some additional conditions held as well, and it caused problems
-   with HP-generated symbol tables.  */
-
-/* NOTE: carlton/2003-05-14: This function was once used as part of
-   lookup_symbol.  It is currently unnecessary for correctness
-   reasons, however, and using it doesn't seem to be any faster than
-   using lookup_symbol_aux_psymtabs, so I'm commenting it out.  */
-
-static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
-                          const char *linkage_name,
-                          const domain_enum domain,
-                          int *is_a_field_of_this,
-                          struct symtab **symtab)
-{
-  struct symbol *sym;
-  struct blockvector *bv;
-  const struct block *block;
-  struct minimal_symbol *msymbol;
-  struct symtab *s;
-
-  if (domain == VAR_DOMAIN)
-    {
-      msymbol = lookup_minimal_symbol (name, NULL, NULL);
-
-      if (msymbol != NULL)
-       {
-         /* OK, we found a minimal symbol in spite of not finding any
-            symbol. There are various possible explanations for
-            this. One possibility is the symbol exists in code not
-            compiled -g. Another possibility is that the 'psymtab'
-            isn't doing its job.  A third possibility, related to #2,
-            is that we were confused by name-mangling. For instance,
-            maybe the psymtab isn't doing its job because it only
-            know about demangled names, but we were given a mangled
-            name...  */
-
-         /* We first use the address in the msymbol to try to locate
-            the appropriate symtab. Note that find_pc_sect_symtab()
-            has a side-effect of doing psymtab-to-symtab expansion,
-            for the found symtab.  */
-         s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
-                                  SYMBOL_BFD_SECTION (msymbol));
-         if (s != NULL)
-           {
-             /* This is a function which has a symtab for its address.  */
-             bv = BLOCKVECTOR (s);
-             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-
-             /* This call used to pass `SYMBOL_LINKAGE_NAME (msymbol)' as the
-                `name' argument to lookup_block_symbol.  But the name
-                of a minimal symbol is always mangled, so that seems
-                to be clearly the wrong thing to pass as the
-                unmangled name.  */
-             sym =
-               lookup_block_symbol (block, name, linkage_name, domain);
-             /* We kept static functions in minimal symbol table as well as
-                in static scope. We want to find them in the symbol table. */
-             if (!sym)
-               {
-                 block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-                 sym = lookup_block_symbol (block, name,
-                                            linkage_name, domain);
-               }
-
-             /* NOTE: carlton/2002-12-04: The following comment was
-                taken from a time when two versions of this function
-                were part of the body of lookup_symbol_aux: this
-                comment was taken from the version of the function
-                that was #ifdef HPUXHPPA, and the comment was right
-                before the 'return NULL' part of lookup_symbol_aux.
-                (Hence the "Fall through and return 0" comment.)
-                Elena did some digging into the situation for
-                Fortran, and she reports:
-
-                "I asked around (thanks to Jeff Knaggs), and I think
-                the story for Fortran goes like this:
-
-                "Apparently, in older Fortrans, '_' was not part of
-                the user namespace.  g77 attached a final '_' to
-                procedure names as the exported symbols for linkage
-                (foo_) , but the symbols went in the debug info just
-                like 'foo'. The rationale behind this is not
-                completely clear, and maybe it was done to other
-                symbols as well, not just procedures."  */
-
-             /* If we get here with sym == 0, the symbol was 
-                found in the minimal symbol table
-                but not in the symtab.
-                Fall through and return 0 to use the msymbol 
-                definition of "foo_".
-                (Note that outer code generally follows up a call
-                to this routine with a call to lookup_minimal_symbol(),
-                so a 0 return means we'll just flow into that other routine).
-
-                This happens for Fortran  "foo_" symbols,
-                which are "foo" in the symtab.
-
-                This can also happen if "asm" is used to make a
-                regular symbol but not a debugging symbol, e.g.
-                asm(".globl _main");
-                asm("_main:");
-              */
-
-             if (symtab != NULL && sym != NULL)
-               *symtab = s;
-             return fixup_symbol_section (sym, s->objfile);
-           }
-       }
-    }
-
-  return NULL;
-}
-#endif /* 0 */
-
 /* A default version of lookup_symbol_nonlocal for use by languages
    that can't think of anything better to do.  This implements the C
    lookup rules.  */
@@ -1306,8 +1578,7 @@ struct symbol *
 basic_lookup_symbol_nonlocal (const char *name,
                              const char *linkage_name,
                              const struct block *block,
-                             const domain_enum domain,
-                             struct symtab **symtab)
+                             const domain_enum domain)
 {
   struct symbol *sym;
 
@@ -1339,11 +1610,11 @@ basic_lookup_symbol_nonlocal (const char *name,
      than that one, so I don't think we should worry about that for
      now.  */
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+  sym = lookup_symbol_static (name, linkage_name, block, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, domain, symtab);
+  return lookup_symbol_global (name, linkage_name, block, domain);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1353,14 +1624,12 @@ struct symbol *
 lookup_symbol_static (const char *name,
                      const char *linkage_name,
                      const struct block *block,
-                     const domain_enum domain,
-                     struct symtab **symtab)
+                     const domain_enum domain)
 {
   const struct block *static_block = block_static_block (block);
 
   if (static_block != NULL)
-    return lookup_symbol_aux_block (name, linkage_name, static_block,
-                                   domain, symtab);
+    return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
   else
     return NULL;
 }
@@ -1371,18 +1640,44 @@ lookup_symbol_static (const char *name,
 struct symbol *
 lookup_symbol_global (const char *name,
                      const char *linkage_name,
-                     const domain_enum domain,
-                     struct symtab **symtab)
+                     const struct block *block,
+                     const domain_enum domain)
 {
-  struct symbol *sym;
+  struct symbol *sym = NULL;
+  struct objfile *objfile = NULL;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
-                                  domain, symtab);
+  /* Call library-specific lookup procedure.  */
+  objfile = lookup_objfile_from_block (block);
+  if (objfile != NULL)
+    sym = solib_global_lookup (objfile, name, linkage_name, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
-                                    domain, symtab);
+  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  if (sym != NULL)
+    return sym;
+
+  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+}
+
+int
+symbol_matches_domain (enum language symbol_language,
+                      domain_enum symbol_domain,
+                      domain_enum domain)
+{
+  /* 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
+      || symbol_language == language_java
+      || symbol_language == language_ada)
+    {
+      if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
+         && symbol_domain == STRUCT_DOMAIN)
+       return 1;
+    }
+  /* For all other languages, strict match is required.  */
+  return (symbol_domain == domain);
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
@@ -1400,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);
@@ -1408,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;
@@ -1426,13 +1721,13 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
        {
          center = bottom + (top - bottom) / 2;
          if (!(center < top))
-           internal_error (__FILE__, __LINE__, "failed internal consistency check");
+           internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
          if (!do_linear_search
              && (SYMBOL_LANGUAGE (*center) == language_java))
            {
              do_linear_search = 1;
            }
-         if (strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*center), name) >= 0)
+         if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
            {
              top = center;
            }
@@ -1442,17 +1737,16 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
            }
        }
       if (!(top == bottom))
-       internal_error (__FILE__, __LINE__, "failed internal consistency check");
+       internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
       while (top <= real_top
             && (linkage_name != NULL
                 ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
-                : SYMBOL_MATCHES_NATURAL_NAME (*top,name)))
+                : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
        {
-         if (SYMBOL_DOMAIN (*top) == domain)
-           {
-                 return (*top);
-           }
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+                                    SYMBOL_DOMAIN (*top), domain))
+           return (*top);
          top++;
        }
     }
@@ -1461,14 +1755,15 @@ 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 (domain == SYMBOL_DOMAIN (*psym))
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+                                    SYMBOL_DOMAIN (*psym), domain))
            {
              if (linkage_name != NULL
                  ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
-                 : SYMBOL_MATCHES_NATURAL_NAME (*psym, name))
+                 : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
                {
                  return (*psym);
                }
@@ -1510,7 +1805,7 @@ basic_lookup_transparent_type (const char *name)
      of the desired name as a global, then do psymtab-to-symtab
      conversion on the fly and return the found symbol.  */
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
@@ -1540,9 +1835,9 @@ basic_lookup_transparent_type (const char *name)
            block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
            sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
            if (!sym)
-             error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+             error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
                     name, ps->filename, name, name);
          }
        if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -1558,7 +1853,7 @@ basic_lookup_transparent_type (const char *name)
      conversion on the fly and return the found symbol.
    */
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
@@ -1587,9 +1882,9 @@ basic_lookup_transparent_type (const char *name)
            block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
            sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
            if (!sym)
-             error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+             error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
                     name, ps->filename, name, name);
          }
        if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -1628,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
@@ -1649,7 +1944,8 @@ lookup_block_symbol (const struct block *block, const char *name,
           sym != NULL;
           sym = dict_iter_name_next (name, &iter))
        {
-         if (SYMBOL_DOMAIN (sym) == domain
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                    SYMBOL_DOMAIN (sym), domain)
              && (linkage_name != NULL
                  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
            return sym;
@@ -1670,18 +1966,13 @@ lookup_block_symbol (const struct block *block, const char *name,
           sym != NULL;
           sym = dict_iter_name_next (name, &iter))
        {
-         if (SYMBOL_DOMAIN (sym) == domain
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+                                    SYMBOL_DOMAIN (sym), domain)
              && (linkage_name != NULL
                  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
            {
              sym_found = sym;
-             if (SYMBOL_CLASS (sym) != LOC_ARG &&
-                 SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
-                 SYMBOL_CLASS (sym) != LOC_REF_ARG &&
-                 SYMBOL_CLASS (sym) != LOC_REGPARM &&
-                 SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
-                 SYMBOL_CLASS (sym) != LOC_BASEREG_ARG &&
-                 SYMBOL_CLASS (sym) != LOC_COMPUTED_ARG)
+             if (!SYMBOL_IS_ARGUMENT (sym))
                {
                  break;
                }
@@ -1695,7 +1986,7 @@ lookup_block_symbol (const struct block *block, const char *name,
    psymtabs and read in another symtab if necessary. */
 
 struct symtab *
-find_pc_sect_symtab (CORE_ADDR pc, asection *section)
+find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
 {
   struct block *b;
   struct blockvector *bv;
@@ -1713,11 +2004,11 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
      on the partial_symtab's texthigh and textlow.  */
   msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
   if (msymbol
-      && (msymbol->type == mst_data
-         || msymbol->type == mst_bss
-         || msymbol->type == mst_abs
-         || msymbol->type == mst_file_data
-         || msymbol->type == mst_file_bss))
+      && (MSYMBOL_TYPE (msymbol) == mst_data
+         || MSYMBOL_TYPE (msymbol) == mst_bss
+         || MSYMBOL_TYPE (msymbol) == mst_abs
+         || MSYMBOL_TYPE (msymbol) == mst_file_data
+         || MSYMBOL_TYPE (msymbol) == mst_file_bss))
     return NULL;
 
   /* Search all symtabs for the one whose file contains our address, and which
@@ -1735,7 +2026,7 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
      It also happens for objfiles that have their functions reordered.
      For these, the symtab we are looking for is not necessarily read in.  */
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     bv = BLOCKVECTOR (s);
     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
@@ -1765,7 +2056,7 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
            ALL_BLOCK_SYMBOLS (b, iter, sym)
              {
                fixup_symbol_section (sym, objfile);
-               if (section == SYMBOL_BFD_SECTION (sym))
+               if (matching_obj_sections (SYMBOL_OBJ_SECTION (sym), section))
                  break;
              }
            if (sym == NULL)
@@ -1787,8 +2078,8 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
        /* Might want to error() here (in case symtab is corrupt and
           will cause a core dump), but maybe we can successfully
           continue, so let's not.  */
-       warning ("\
-(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
+       warning (_("\
+(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n"),
                 paddr_nz (pc));
       s = PSYMTAB_TO_SYMTAB (ps);
     }
@@ -1823,7 +2114,7 @@ find_pc_symtab (CORE_ADDR pc)
 /* If it's worth the effort, we could be using a binary search.  */
 
 struct symtab_and_line
-find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent)
+find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 {
   struct symtab *s;
   struct linetable *l;
@@ -1874,8 +2165,8 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_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:
 
@@ -1888,7 +2179,7 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_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)
@@ -1906,7 +2197,7 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_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
@@ -1927,19 +2218,19 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_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 */
          /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
        /* fall through */
-       else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
+       else if (SYMBOL_VALUE_ADDRESS (mfunsym) == SYMBOL_VALUE_ADDRESS (msymbol))
          /* Avoid infinite recursion */
          /* See above comment about why warning is commented out */
          /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
        /* fall through */
        else
-         return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
+         return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
       }
 
 
@@ -2026,23 +2317,11 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent)
 
   if (!best_symtab)
     {
-      if (!alt_symtab)
-       {                       /* If we didn't find any line # info, just
-                                  return zeros.  */
-         val.pc = pc;
-       }
-      else
-       {
-         val.symtab = alt_symtab;
-         val.line = alt->line - 1;
-
-         /* Don't return line 0, that means that we didn't find the line.  */
-         if (val.line == 0)
-           ++val.line;
-
-         val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
-         val.end = alt->pc;
-       }
+      /* If we didn't find any line number info, just return zeros.
+        We used to return alt->line - 1 here, but that could be
+        anywhere; if we don't have line number info for this PC,
+        don't make some up.  */
+      val.pc = pc;
     }
   else if (best->line == 0)
     {
@@ -2072,7 +2351,7 @@ find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent)
 struct symtab_and_line
 find_pc_line (CORE_ADDR pc, int notcurrent)
 {
-  asection *section;
+  struct obj_section *section;
 
   section = find_pc_overlay (pc);
   if (pc_in_unmapped_range (pc, section))
@@ -2093,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.  */
@@ -2122,12 +2401,20 @@ find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
 
       struct objfile *objfile;
       struct symtab *s;
+      struct partial_symtab *p;
 
       if (best_index >= 0)
        best = best_linetable->item[best_index].line;
       else
        best = 0;
 
+      ALL_PSYMTABS (objfile, p)
+      {
+        if (strcmp (symtab->filename, p->filename) != 0)
+          continue;
+        PSYMTAB_TO_SYMTAB (p);
+      }
+
       ALL_SYMTABS (objfile, s)
       {
        struct linetable *l;
@@ -2252,6 +2539,8 @@ find_line_common (struct linetable *l, int lineno,
   int best_index = -1;
   int best = 0;
 
+  *exact_match = 0;
+
   if (lineno <= 0)
     return -1;
   if (l == 0)
@@ -2277,8 +2566,6 @@ find_line_common (struct linetable *l, int lineno,
     }
 
   /* If we got here, we didn't get an exact match.  */
-
-  *exact_match = 0;
   return best_index;
 }
 
@@ -2292,6 +2579,67 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
   return sal.symtab != 0;
 }
 
+/* Given a function start address PC and SECTION, find the first
+   address after the function prologue.  */
+CORE_ADDR
+find_function_start_pc (struct gdbarch *gdbarch,
+                       CORE_ADDR pc, struct obj_section *section)
+{
+  /* If the function is in an unmapped overlay, use its unmapped LMA address,
+     so that gdbarch_skip_prologue has something unique to work on.  */
+  if (section_is_overlay (section) && !section_is_mapped (section))
+    pc = overlay_unmapped_address (pc, section);
+
+  pc += gdbarch_deprecated_function_start_offset (gdbarch);
+  pc = gdbarch_skip_prologue (gdbarch, pc);
+
+  /* For overlays, map pc back into its mapped VMA range.  */
+  pc = overlay_mapped_address (pc, section);
+
+  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
@@ -2300,39 +2648,63 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
 struct symtab_and_line
 find_function_start_sal (struct symbol *sym, int funfirstline)
 {
+  struct block *block = SYMBOL_BLOCK_VALUE (sym);
+  struct objfile *objfile = lookup_objfile_from_block (block);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
   CORE_ADDR pc;
   struct symtab_and_line sal;
 
-  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-  fixup_symbol_section (sym, NULL);
+  pc = BLOCK_START (block);
+  fixup_symbol_section (sym, objfile);
   if (funfirstline)
-    {                          /* skip "first line" of function (which is actually its prologue) */
-      asection *section = SYMBOL_BFD_SECTION (sym);
-      /* If function is in an unmapped overlay, use its unmapped LMA
-         address, so that SKIP_PROLOGUE has something unique to work on */
-      if (section_is_overlay (section) &&
-         !section_is_mapped (section))
-       pc = overlay_unmapped_address (pc, section);
-
-      pc += FUNCTION_START_OFFSET;
-      pc = SKIP_PROLOGUE (pc);
-
-      /* For overlays, map pc back into its mapped VMA range */
-      pc = overlay_mapped_address (pc, section);
+    {
+      /* Skip "first line" of function (which is actually its prologue).  */
+      pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym));
     }
-  sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+  sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
 
-  /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+  /* Check if gdbarch_skip_prologue left us in mid-line, and the next
      line is still part of the same function.  */
   if (sal.pc != pc
-      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
-      && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+      && BLOCK_START (block) <= sal.end
+      && sal.end < BLOCK_END (block))
     {
       /* First pc of next line */
       pc = sal.end;
       /* Recalculate the line number (might not be N+1).  */
-      sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+      sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
     }
+
+  /* On targets with executable formats that don't have a concept of
+     constructors (ELF with .init has, PE doesn't), gcc emits a call
+     to `__main' in `main' between the prologue and before user
+     code.  */
+  if (funfirstline
+      && gdbarch_skip_main_prologue_p (gdbarch)
+      && SYMBOL_LINKAGE_NAME (sym)
+      && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
+    {
+      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;
@@ -2385,16 +2757,16 @@ operator_chars (char *p, char **end)
        else if (p[1] == '[')
          {
            if (p[2] == ']')
-             error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+             error (_("mismatched quoting on brackets, try 'operator\\[\\]'"));
            else if (p[2] == '\\' && p[3] == ']')
              {
                *end = p + 4;   /* 'operator\[\]' */
                return p;
              }
            else
-             error ("nothing is allowed between '[' and ']'");
+             error (_("nothing is allowed between '[' and ']'"));
          }
-       else 
+       else
          {
            /* Gratuitous qoute: skip it and move on. */
            p++;
@@ -2448,21 +2820,21 @@ operator_chars (char *p, char **end)
        return p;
       case '(':
        if (p[1] != ')')
-         error ("`operator ()' must be specified without whitespace in `()'");
+         error (_("`operator ()' must be specified without whitespace in `()'"));
        *end = p + 2;
        return p;
       case '?':
        if (p[1] != ':')
-         error ("`operator ?:' must be specified without whitespace in `?:'");
+         error (_("`operator ?:' must be specified without whitespace in `?:'"));
        *end = p + 2;
        return p;
       case '[':
        if (p[1] != ']')
-         error ("`operator []' must be specified without whitespace in `[]'");
+         error (_("`operator []' must be specified without whitespace in `[]'"));
        *end = p + 2;
        return p;
       default:
-       error ("`operator %s' not supported", p);
+       error (_("`operator %s' not supported"), p);
        break;
       }
 
@@ -2519,7 +2891,7 @@ filename_seen (const char *file, int add, int *first)
    NAME is the name to print and *FIRST is nonzero if this is the first
    name printed.  Set *FIRST to zero.  */
 static void
-output_source_filename (char *name, int *first)
+output_source_filename (const char *name, int *first)
 {
   /* Since a single source file can result in several partial symbol
      tables, we need to avoid printing it more than once.  Note: if
@@ -2560,7 +2932,7 @@ sources_info (char *ignore, int from_tty)
 
   if (!have_full_symbols () && !have_partial_symbols ())
     {
-      error ("No symbol table is loaded.  Use the \"file\" command.");
+      error (_("No symbol table is loaded.  Use the \"file\" command."));
     }
 
   printf_filtered ("Source files for which symbols have been read in:\n\n");
@@ -2568,7 +2940,8 @@ sources_info (char *ignore, int from_tty)
   first = 1;
   ALL_SYMTABS (objfile, s)
   {
-    output_source_filename (s->filename, &first);
+    const char *fullname = symtab_to_fullname (s);
+    output_source_filename (fullname ? fullname : s->filename, &first);
   }
   printf_filtered ("\n\n");
 
@@ -2579,7 +2952,8 @@ sources_info (char *ignore, int from_tty)
   {
     if (!ps->readin)
       {
-       output_source_filename (ps->filename, &first);
+       const char *fullname = psymtab_to_fullname (ps);
+       output_source_filename (fullname ? fullname : ps->filename, &first);
       }
   }
   printf_filtered ("\n");
@@ -2682,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)
 
@@ -2698,7 +3071,6 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
   struct symtab *s;
   struct partial_symtab *ps;
   struct blockvector *bv;
-  struct blockvector *prev_bv = 0;
   struct block *b;
   int i = 0;
   struct dict_iterator iter;
@@ -2730,7 +3102,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
   struct cleanup *old_chain = NULL;
 
   if (kind < VARIABLES_DOMAIN)
-    error ("must search on specific domain");
+    error (_("must search on specific domain"));
 
   ourtype = types[(int) (kind - VARIABLES_DOMAIN)];
   ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
@@ -2773,7 +3145,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
        }
 
       if (0 != (val = re_comp (regexp)))
-       error ("Invalid regexp (%s): %s", val, regexp);
+       error (_("Invalid regexp (%s): %s"), val, regexp);
     }
 
   /* Search through the partial symtabs *first* for all symbols
@@ -2813,15 +3185,18 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
            QUIT;
 
            /* If it would match (logic taken from loop below)
-              load the file and go on to the next one */
+              load the file and go on to the next one.  We check the
+              filename here, but that's a bit bogus: we don't know
+              what file it really comes from until we have full
+              symtabs.  The symbol might be in a header file included by
+              this psymtab.  This only affects Insight.  */
            if (file_matches (ps->filename, files, nfiles)
                && ((regexp == NULL
                     || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0)
                    && ((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;
@@ -2867,8 +3242,8 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                    if (kind == FUNCTIONS_DOMAIN
                        || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
                                          (struct block *) NULL,
-                                         VAR_DOMAIN,
-                                       0, (struct symtab **) NULL) == NULL)
+                                         VAR_DOMAIN, 0)
+                       == NULL)
                      found_misc = 1;
                  }
              }
@@ -2876,15 +3251,9 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
       }
     }
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     bv = BLOCKVECTOR (s);
-    /* Often many files share a blockvector.
-       Scan each blockvector only once so that
-       we don't get every symbol many times.
-       It happens that the first symtab in the list
-       for any given blockvector is the main file.  */
-    if (bv != prev_bv)
       for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
        {
          struct symbol_search *prevtail = tail;
@@ -2892,21 +3261,22 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
          b = BLOCKVECTOR_BLOCK (bv, i);
          ALL_BLOCK_SYMBOLS (b, iter, sym)
            {
+             struct symtab *real_symtab = SYMBOL_SYMTAB (sym);
              QUIT;
-             if (file_matches (s->filename, files, nfiles)
+
+             if (file_matches (real_symtab->filename, files, nfiles)
                  && ((regexp == NULL
                       || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
                      && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
                           && 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));
                  psr->block = i;
-                 psr->symtab = s;
+                 psr->symtab = real_symtab;
                  psr->symbol = sym;
                  psr->msymbol = NULL;
                  psr->next = NULL;
@@ -2934,7 +3304,6 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                tail = sort_search_symbols (prevtail, nfound);
            }
        }
-    prev_bv = bv;
   }
 
   /* If there are no eyes, avoid all contact.  I mean, if there are
@@ -2958,8 +3327,8 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                  {
                    /* Variables/Absolutes:  Look up by name */
                    if (lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
-                                      (struct block *) NULL, VAR_DOMAIN,
-                                      0, (struct symtab **) NULL) == NULL)
+                                      (struct block *) NULL, VAR_DOMAIN, 0)
+                        == NULL)
                      {
                        /* match */
                        psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
@@ -3030,15 +3399,16 @@ 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 (TARGET_ADDR_BIT <= 32)
-    tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
-                                  & (CORE_ADDR) 0xffffffff,
-                                  "08l");
+  if (gdbarch_addr_bit (gdbarch) <= 32)
+    tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+                            & (CORE_ADDR) 0xffffffff,
+                            8);
   else
-    tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
-                                  "016l");
+    tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+                            16);
   printf_filtered ("%s  %s\n",
                   tmp, SYMBOL_PRINT_NAME (msymbol));
 }
@@ -3153,7 +3523,13 @@ rbreak_command (char *regexp, int from_tty)
        }
       else
        {
-         break_command (SYMBOL_LINKAGE_NAME (p->msymbol), from_tty);
+         char *string = alloca (strlen (SYMBOL_LINKAGE_NAME (p->msymbol))
+                                + 3);
+         strcpy (string, "'");
+         strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol));
+         strcat (string, "'");
+
+         break_command (string, from_tty);
          printf_filtered ("<function, no debug info> %s;\n",
                           SYMBOL_PRINT_NAME (p->msymbol));
        }
@@ -3235,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?  */
@@ -3248,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)
@@ -3260,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));
@@ -3272,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.  */
@@ -3280,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);
     }
 }
@@ -3331,17 +3707,36 @@ language_search_unquoted_string (char *text, char *p)
   return p;
 }
 
+/* Type of the user_data argument passed to add_macro_name.  The
+   contents are simply whatever is needed by
+   completion_list_add_name.  */
+struct add_macro_name_data
+{
+  char *sym_text;
+  int sym_text_len;
+  char *text;
+  char *word;
+};
 
-/* Return a NULL terminated array of all symbols (regardless of class)
-   which begin by matching TEXT.  If the answer is no symbols, then
-   the return value is an array which contains only a NULL pointer.
-
-   Problem: All of the symbols have to be copied because readline frees them.
-   I'm not going to worry about this; hopefully there won't be that many.  */
+/* A callback used with macro_for_each and macro_for_each_in_scope.
+   This adds a macro's name to the current completion list.  */
+static void
+add_macro_name (const char *name, const struct macro_definition *ignore,
+               void *user_data)
+{
+  struct add_macro_name_data *datum = (struct add_macro_name_data *) user_data;
+  completion_list_add_name ((char *) name,
+                           datum->sym_text, datum->sym_text_len,
+                           datum->text, datum->word);
+}
 
 char **
-make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word)
 {
+  /* Problem: All of the symbols have to be copied because readline
+     frees them.  I'm not going to worry about this; hopefully there
+     won't be that many.  */
+
   struct symbol *sym;
   struct symtab *s;
   struct partial_symtab *ps;
@@ -3356,8 +3751,7 @@ make_symbol_completion_list (char *text, char *word)
   /* Length of sym_text.  */
   int sym_text_len;
 
-  /* Now look for the symbol we are supposed to complete on.
-     FIXME: This should be language-specific.  */
+  /* Now look for the symbol we are supposed to complete on.  */
   {
     char *p;
     char quote_found;
@@ -3455,7 +3849,7 @@ 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);
   }
 
@@ -3499,7 +3893,7 @@ make_symbol_completion_list (char *text, char *word)
   /* Go through the symtabs and check the externs and statics for
      symbols which match.  */
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     QUIT;
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
@@ -3509,7 +3903,7 @@ make_symbol_completion_list (char *text, char *word)
       }
   }
 
-  ALL_SYMTABS (objfile, s)
+  ALL_PRIMARY_SYMTABS (objfile, s)
   {
     QUIT;
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
@@ -3522,9 +3916,58 @@ make_symbol_completion_list (char *text, char *word)
       }
   }
 
+  if (current_language->la_macro_expansion == macro_expansion_c)
+    {
+      struct macro_scope *scope;
+      struct add_macro_name_data datum;
+
+      datum.sym_text = sym_text;
+      datum.sym_text_len = sym_text_len;
+      datum.text = text;
+      datum.word = word;
+
+      /* Add any macros visible in the default scope.  Note that this
+        may yield the occasional wrong result, because an expression
+        might be evaluated in a scope other than the default.  For
+        example, if the user types "break file:line if <TAB>", the
+        resulting expression will be evaluated at "file:line" -- but
+        at there does not seem to be a way to detect this at
+        completion time.  */
+      scope = default_macro_scope ();
+      if (scope)
+       {
+         macro_for_each_in_scope (scope->file, scope->line,
+                                  add_macro_name, &datum);
+         xfree (scope);
+       }
+
+      /* User-defined macros are always visible.  */
+      macro_for_each (macro_user_macros, add_macro_name, &datum);
+    }
+
   return (return_val);
 }
 
+/* Return a NULL terminated array of all symbols (regardless of class)
+   which begin by matching TEXT.  If the answer is no symbols, then
+   the return value is an array which contains only a NULL pointer.  */
+
+char **
+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.  */
 
@@ -3795,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;
@@ -3809,7 +4252,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
      - The minimal symbols and partial symbols, which can usually tell
        us the starting and ending addresses of a function.
      - If we know the function's start address, we can call the
-       architecture-defined SKIP_PROLOGUE function to analyze the
+       architecture-defined gdbarch_skip_prologue function to analyze the
        instruction stream and guess where the prologue ends.
      - Our `func_start' argument; if non-zero, this is the caller's
        best guess as to the function's entry point.  At the time of
@@ -3827,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 = SKIP_PROLOGUE (func_start);
+      prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
 
       return func_start <= pc && pc < prologue_end;
     }
@@ -3851,7 +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 = SKIP_PROLOGUE (func_addr);
+      CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
 
       return func_addr <= pc && pc < prologue_end;
     }
@@ -3860,26 +4303,117 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
   return func_addr <= pc && pc < sal.end;
 }
 
+/* Given PC at the function's start address, attempt to find the
+   prologue end using SAL information.  Return zero if the skip fails.
+
+   A non-optimized prologue traditionally has one SAL for the function
+   and a second for the function body.  A single line function has
+   them both pointing at the same line.
+
+   An optimized prologue is similar but the prologue may contain
+   instructions (SALs) from the instruction body.  Need to skip those
+   while not getting into the function body.
+
+   The functions end point and an increasing SAL line are used as
+   indicators of the prologue's endpoint.
+
+   This code is based on the function refine_prologue_limit (versions
+   found in both ia64 and ppc).  */
+
+CORE_ADDR
+skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
+{
+  struct symtab_and_line prologue_sal;
+  CORE_ADDR start_pc;
+  CORE_ADDR end_pc;
+  struct block *bl;
+
+  /* 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 (gdbarch);
+
+  prologue_sal = find_pc_line (start_pc, 0);
+  if (prologue_sal.line != 0)
+    {
+      /* For langauges other than assembly, treat two consecutive line
+        entries at the same address as a zero-instruction prologue.
+        The GNU assembler emits separate line notes for each instruction
+        in a multi-instruction macro, but compilers generally will not
+        do this.  */
+      if (prologue_sal.symtab->language != language_asm)
+       {
+         struct linetable *linetable = LINETABLE (prologue_sal.symtab);
+         int exact;
+         int idx = 0;
+
+         /* Skip any earlier lines, and any end-of-sequence marker
+            from a previous function.  */
+         while (linetable->item[idx].pc != prologue_sal.pc
+                || linetable->item[idx].line == 0)
+           idx++;
+
+         if (idx+1 < linetable->nitems
+             && linetable->item[idx+1].line != 0
+             && linetable->item[idx+1].pc == start_pc)
+           return start_pc;
+       }
+
+      /* If there is only one sal that covers the entire function,
+        then it is probably a single line function, like
+        "foo(){}". */
+      if (prologue_sal.end >= end_pc)
+       return 0;
+
+      while (prologue_sal.end < end_pc)
+       {
+         struct symtab_and_line sal;
+
+         sal = find_pc_line (prologue_sal.end, 0);
+         if (sal.line == 0)
+           break;
+         /* Assume that a consecutive SAL for the same (or larger)
+            line mark the prologue -> body transition.  */
+         if (sal.line >= prologue_sal.line)
+           break;
+         /* The case in which compiler's optimizer/scheduler has
+            moved instructions into the prologue.  We look ahead in
+            the function looking for address ranges whose
+            corresponding line number is less the first one that we
+            found for the function.  This is more conservative then
+            refine_prologue_limit which scans a large number of SALs
+            looking for any in the prologue */
+         prologue_sal = sal;
+       }
+    }
+
+  if (prologue_sal.end < end_pc)
+    /* Return the end of this line, or zero if we could not find a
+       line.  */
+    return prologue_sal.end;
+  else
+    /* Don't return END_PC, which is past the end of the function.  */
+    return prologue_sal.pc;
+}
 \f
 struct symtabs_and_lines
 decode_line_spec (char *string, int funfirstline)
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line cursal;
-  
+
   if (string == 0)
-    error ("Empty line specification.");
-    
+    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);
 
   if (*string)
-    error ("Junk at end of line specification: %s", string);
+    error (_("Junk at end of line specification: %s"), string);
   return sals;
 }
 
@@ -3900,29 +4434,258 @@ set_main_name (const char *name)
     }
 }
 
+/* Deduce the name of the main procedure, and set NAME_OF_MAIN
+   accordingly.  */
+
+static void
+find_main_name (void)
+{
+  const char *new_main_name;
+
+  /* Try to see if the main procedure is in Ada.  */
+  /* FIXME: brobecker/2005-03-07: Another way of doing this would
+     be to add a new method in the language vector, and call this
+     method for each language until one of them returns a non-empty
+     name.  This would allow us to remove this hard-coded call to
+     an Ada function.  It is not clear that this is a better approach
+     at this point, because all methods need to be written in a way
+     such that false positives never be returned. For instance, it is
+     important that a method does not return a wrong name for the main
+     procedure if the main procedure is actually written in a different
+     language.  It is easy to guaranty this with Ada, since we use a
+     special symbol generated only when the main in Ada to find the name
+     of the main procedure. It is difficult however to see how this can
+     be guarantied for languages such as C, for instance.  This suggests
+     that order of call for these methods becomes important, which means
+     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;
+    }
+
+  /* The languages above didn't identify the name of the main procedure.
+     Fallback to "main".  */
+  set_main_name ("main");
+}
+
 char *
 main_name (void)
 {
-  if (name_of_main != NULL)
-    return name_of_main;
+  if (name_of_main == NULL)
+    find_main_name ();
+
+  return name_of_main;
+}
+
+/* Handle ``executable_changed'' events for the symtab module.  */
+
+static void
+symtab_observer_executable_changed (void)
+{
+  /* NAME_OF_MAIN may no longer be the same, so reset it for now.  */
+  set_main_name (NULL);
+}
+
+/* Helper to expand_line_sal below.  Appends new sal to SAL,
+   initializing it from SYMTAB, LINENO and PC.  */
+static void
+append_expanded_sal (struct symtabs_and_lines *sal,
+                    struct symtab *symtab,
+                    int lineno, CORE_ADDR pc)
+{
+  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].pc = pc;
+  ++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
+   the entire program that correspond to same file
+   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)
+{
+  struct symtabs_and_lines ret, this_line;
+  int i, j;
+  struct objfile *objfile;
+  struct partial_symtab *psymtab;
+  struct symtab *symtab;
+  int lineno;
+  int deleted = 0;
+  struct block **blocks = NULL;
+  int *filter;
+
+  ret.nelts = 0;
+  ret.sals = NULL;
+
+  if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
+    {
+      ret.sals = xmalloc (sizeof (struct symtab_and_line));
+      ret.sals[0] = sal;
+      ret.nelts = 1;
+      return ret;
+    }
   else
-    return "main";
+    {
+      struct linetable_entry *best_item = 0;
+      struct symtab *best_symtab = 0;
+      int exact = 0;
+
+      lineno = sal.line;
+
+      /* 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,
+        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
+        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.  */
+
+      ALL_PSYMTABS (objfile, psymtab)
+       {
+         if (strcmp (sal.symtab->filename,
+                     psymtab->filename) == 0)
+           PSYMTAB_TO_SYMTAB (psymtab);
+       }
+
+      /* 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_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
+     disjoint ranges of PC values, even when no duplicate functions
+     or inline functions are involved.  For example, 'for (;;)' inside
+     non-template non-inline non-ctor-or-dtor function can result
+     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.  */
+
+  filter = alloca (ret.nelts * sizeof (int));
+  blocks = alloca (ret.nelts * sizeof (struct block *));
+  for (i = 0; i < ret.nelts; ++i)
+    {
+      filter[i] = 1;
+      blocks[i] = block_for_pc (ret.sals[i].pc);
+    }
+
+  for (i = 0; i < ret.nelts; ++i)
+    if (blocks[i] != NULL)
+      for (j = i+1; j < ret.nelts; ++j)
+       if (blocks[j] == blocks[i])
+         {
+           filter[j] = 0;
+           ++deleted;
+           break;
+         }
+
+  {
+    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;
+  }
+
+  return ret;
 }
 
 
 void
 _initialize_symtab (void)
 {
-  add_info ("variables", variables_info,
-        "All global and static variable names, or those matching REGEXP.");
+  add_info ("variables", variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
   if (dbx_commands)
-    add_com ("whereis", class_info, variables_info,
-        "All global and static variable names, or those matching REGEXP.");
+    add_com ("whereis", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
 
   add_info ("functions", functions_info,
-           "All function names, or those matching REGEXP.");
+           _("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
@@ -3932,22 +4695,34 @@ _initialize_symtab (void)
      I also think "ptype" or "whatis" is more likely to be useful (but if
      there is much disagreement "info types" can be fixed).  */
   add_info ("types", types_info,
-           "All type names, or those matching REGEXP.");
+           _("All type names, or those matching REGEXP."));
 
   add_info ("sources", sources_info,
-           "Source files in the program.");
+           _("Source files in the program."));
 
   add_com ("rbreak", class_breakpoint, rbreak_command,
-          "Set a breakpoint for all functions matching REGEXP.");
+          _("Set a breakpoint for all functions matching REGEXP."));
 
   if (xdb_commands)
     {
-      add_com ("lf", class_info, sources_info, "Source files in the program");
-      add_com ("lg", class_info, variables_info,
-        "All global and static variable names, or those matching REGEXP.");
+      add_com ("lf", class_info, sources_info,
+              _("Source files in the program"));
+      add_com ("lg", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
     }
 
+  add_setshow_enum_cmd ("multiple-symbols", no_class,
+                        multiple_symbols_modes, &multiple_symbols_mode,
+                        _("\
+Set the debugger behavior when more than one symbol are possible matches\n\
+in an expression."), _("\
+Show how the debugger handles ambiguities in expressions."), _("\
+Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
+                        NULL, NULL, &setlist, &showlist);
+
   /* Initialize the one built-in type that isn't language dependent... */
   builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
                                  "<unknown type>", (struct objfile *) NULL);
+
+  observer_attach_executable_changed (symtab_observer_executable_changed);
 }
This page took 0.093838 seconds and 4 git commands to generate.