]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Speed up GDB startup time by not demangling partial symbols.
authorPeter Schauer <Peter.Schauer@mytum.de>
Sat, 8 Oct 1994 11:54:29 +0000 (11:54 +0000)
committerPeter Schauer <Peter.Schauer@mytum.de>
Sat, 8 Oct 1994 11:54:29 +0000 (11:54 +0000)
* symfile.h (ADD_PSYMBOL_VT_TO_LIST),
symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
No longer demangle partial symbols.
* symtab.c (lookup_symbol, list_symbols): Handle mangled
variables, e.g. C++ static members, via the minimal symbols.

Handle reordered functions in an objfile, for Irix 5.2 shared
libraries.
* objfiles.h (OBJF_REORDERED):  New bit in the objfile flags,
set if the functions in an objfile are reordered.
* mdebugread.c (parse_partial_symbols):  Detect reordered
functions in an objfile.
* symtab.c (find_pc_psymtab, find_pc_symtab):  Use expensive
lookup algorithm if the functions in the objfile are reordered.

* xcoffexec.c (exec_close):  If the current target has a copy
of the exec_ops sections, reflect the freeing of the sections
in current_target.

* valops.c (call_function_by_hand):  Use `sizeof dummy1', not
`sizeof dummy', for constructing the call dummy code.

* config/sparc/tm-sparc.h:  Add PARAMS declarations to all
function declarations.
* sparc-tdep.c (sparc_pop_frame):  Cast result of
read_memory_integer to CORE_ADDR when passing it to PC_ADJUST.

* irix5-nat.c (enable_break):  Set breakpoint at the entry point
of the executable, to handle the case where main resides in a
shared library.
* irix5-nat.c (solib_create_inferior_hook):  Reset stop_soon_quietly
after shared library symbol reading, to get rid of a warning from
heuristic_proc_start if the startup code has no symbolic debug info.

* breakpoint.h (struct breakpoint):  Add new fields language
and input_radix, to enable breakpoint resetting with the
proper language and radix.
* breakpoint.c (set_raw_breakpoint):  Initialize them.
(breakpoint_re_set_one):  Use them when resetting the breakpoint.
(breakpoint_re_set):  Preserve current language and input_radix
across breakpoint_re_set_one calls.

* symtab.c (decode_line_1):  Do not build a canonical line
specification for `*expr' line specifications.

* breakpoint.h (bpstat_stop_status):  Fix prototype declaration.

gdb/ChangeLog
gdb/irix5-nat.c
gdb/mdebugread.c
gdb/objfiles.h
gdb/sparc-tdep.c
gdb/symfile.c
gdb/symtab.c
gdb/xcoffexec.c

index 9a5013edbe97af34b434f4cd00ae3fe085461362..1459919d87213a5eb33a6aa7001dfd22869950b1 100644 (file)
@@ -1,3 +1,53 @@
+Sat Oct  8 04:27:21 1994  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
+
+       Speed up GDB startup time by not demangling partial symbols.
+       * symfile.h (ADD_PSYMBOL_VT_TO_LIST),
+       symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):
+       No longer demangle partial symbols.
+       * symtab.c (lookup_symbol, list_symbols): Handle mangled
+       variables, e.g. C++ static members, via the minimal symbols.
+
+       Handle reordered functions in an objfile, for Irix 5.2 shared
+       libraries.
+       * objfiles.h (OBJF_REORDERED):  New bit in the objfile flags,
+       set if the functions in an objfile are reordered.
+       * mdebugread.c (parse_partial_symbols):  Detect reordered
+       functions in an objfile.
+       * symtab.c (find_pc_psymtab, find_pc_symtab):  Use expensive
+       lookup algorithm if the functions in the objfile are reordered.
+
+       * xcoffexec.c (exec_close):  If the current target has a copy
+       of the exec_ops sections, reflect the freeing of the sections
+       in current_target.
+
+       * valops.c (call_function_by_hand):  Use `sizeof dummy1', not
+       `sizeof dummy', for constructing the call dummy code.
+
+       * config/sparc/tm-sparc.h:  Add PARAMS declarations to all
+       function declarations.
+       * sparc-tdep.c (sparc_pop_frame):  Cast result of
+       read_memory_integer to CORE_ADDR when passing it to PC_ADJUST.
+
+       * irix5-nat.c (enable_break):  Set breakpoint at the entry point
+       of the executable, to handle the case where main resides in a
+       shared library.
+       * irix5-nat.c (solib_create_inferior_hook):  Reset stop_soon_quietly
+       after shared library symbol reading, to get rid of a warning from
+       heuristic_proc_start if the startup code has no symbolic debug info.
+
+       * breakpoint.h (struct breakpoint):  Add new fields language
+       and input_radix, to enable breakpoint resetting with the
+       proper language and radix.
+       * breakpoint.c (set_raw_breakpoint):  Initialize them.
+       (breakpoint_re_set_one):  Use them when resetting the breakpoint.
+       (breakpoint_re_set):  Preserve current language and input_radix
+       across breakpoint_re_set_one calls.
+
+       * symtab.c (decode_line_1):  Do not build a canonical line
+       specification for `*expr' line specifications.
+
+       * breakpoint.h (bpstat_stop_status):  Fix prototype declaration.
+
 Fri Oct  7 08:48:18 1994  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        The point of these changes is to avoid reading the frame pointer
index 38cc0949ab9592b3dec395a18cc074b130156f2f..f4137383b9195d75671e498fa1e361753d93c187 100644 (file)
@@ -194,21 +194,6 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
 #include "inferior.h"
 #include "language.h"
 
-/* We need to set a breakpoint at a point when we know that the
-   mapping of shared libraries is complete.  dbx simply breaks at main
-   (or, for FORTRAN, MAIN__), so we do the same.  We can not break at
-   the very beginning of main, because the startup code will jump into
-   main after the GP initialization instructions.  SOLIB_BKPT_OFFSET
-   is used to skip those instructions.  */
-
-#define SOLIB_BKPT_OFFSET 12
-
-static char *bkpt_names[] = {
-  "main",
-  "MAIN__",
-  NULL
-};
-
 /* The symbol which starts off the list of shared libraries.  */
 #define DEBUG_BASE "__rld_obj_head"
 
@@ -878,84 +863,22 @@ SYNOPSIS
 
 DESCRIPTION
 
-       Both the SunOS and the SVR4 dynamic linkers have, as part of their
-       debugger interface, support for arranging for the inferior to hit
-       a breakpoint after mapping in the shared libraries.  This function
-       enables that breakpoint.
-
-       For SunOS, there is a special flag location (in_debugger) which we
-       set to 1.  When the dynamic linker sees this flag set, it will set
-       a breakpoint at a location known only to itself, after saving the
-       original contents of that place and the breakpoint address itself,
-       in it's own internal structures.  When we resume the inferior, it
-       will eventually take a SIGTRAP when it runs into the breakpoint.
-       We handle this (in a different place) by restoring the contents of
-       the breakpointed location (which is only known after it stops),
-       chasing around to locate the shared libraries that have been
-       loaded, then resuming.
-
-       For SVR4, the debugger interface structure contains a member (r_brk)
-       which is statically initialized at the time the shared library is
-       built, to the offset of a function (_r_debug_state) which is guaran-
-       teed to be called once before mapping in a library, and again when
-       the mapping is complete.  At the time we are examining this member,
-       it contains only the unrelocated offset of the function, so we have
-       to do our own relocation.  Later, when the dynamic linker actually
-       runs, it relocates r_brk to be the actual address of _r_debug_state().
-
-       The debugger interface structure also contains an enumeration which
-       is set to either RT_ADD or RT_DELETE prior to changing the mapping,
-       depending upon whether or not the library is being mapped or unmapped,
-       and then set to RT_CONSISTENT after the library is mapped/unmapped.
-
-       Irix 5, on the other hand, has no such features.  Instead, we
-       set a breakpoint at main.
+       This functions inserts a breakpoint at the entry point of the
+       main executable, where all shared libraries are mapped in.
 */
 
 static int
 enable_break ()
 {
-  int success = 0;
-  struct minimal_symbol *msymbol;
-  char **bkpt_namep;
-  CORE_ADDR bkpt_addr;
-
-  /* Scan through the list of symbols, trying to look up the symbol and
-     set a breakpoint there.  Terminate loop when we/if we succeed. */
-
-  breakpoint_addr = 0;
-  for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
+  if (symfile_objfile != NULL
+      && target_insert_breakpoint (symfile_objfile->ei.entry_point,
+                                  shadow_contents) == 0)
     {
-      msymbol = lookup_minimal_symbol (*bkpt_namep, symfile_objfile);
-      if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
-       {
-         bkpt_addr = SYMBOL_VALUE_ADDRESS (msymbol);
-#ifdef SOLIB_BKPT_OFFSET
-         /* We only want to skip if bkpt_addr is currently pointing
-            at a GP setting instruction.  */
-         {
-           char buf[4];
-
-           if (target_read_memory (bkpt_addr, buf, 4) == 0)
-             {
-               unsigned long insn;
-
-               insn = extract_unsigned_integer (buf, 4);
-               if ((insn & 0xffff0000) == 0x3c1c0000) /* lui $gp,n */
-                 bkpt_addr += SOLIB_BKPT_OFFSET;
-             }
-         }
-#endif
-         if (target_insert_breakpoint (bkpt_addr, shadow_contents) == 0)
-           {
-             breakpoint_addr = bkpt_addr;
-             success = 1;
-             break;
-           }
-       }
+      breakpoint_addr = symfile_objfile->ei.entry_point;
+      return 1;
     }
 
-  return (success);
+  return 0;
 }
   
 /*
@@ -1033,7 +956,6 @@ solib_create_inferior_hook()
       wait_for_inferior ();
     }
   while (stop_signal != SIGTRAP);
-  stop_soon_quietly = 0;
   
   /* We are now either at the "mapping complete" breakpoint (or somewhere
      else, a condition we aren't prepared to deal with anyway), so adjust
@@ -1051,7 +973,14 @@ solib_create_inferior_hook()
       warning ("shared library handler failed to disable breakpoint");
     }
 
+  /*  solib_add will call reinit_frame_cache.
+      But we are stopped in the startup code and we might not have symbols
+      for the startup code, so heuristic_proc_start could be called
+      and will put out an annoying warning.
+      Delaying the resetting of stop_soon_quietly until after symbol loading
+      suppresses the warning.  */
   solib_add ((char *) 0, 0, (struct target_ops *) 0);
+  stop_soon_quietly = 0;
 }
 
 /*
index 5d1325d68d85b5c086fd38b18dca83342913aad4..7b30ec30cb3f9160d737d12e3e2c1280372ed925 100644 (file)
@@ -2793,6 +2793,35 @@ parse_partial_symbols (objfile, section_offsets)
          objfile->ei.entry_file_lowpc = save_pst->textlow;
          objfile->ei.entry_file_highpc = save_pst->texthigh;
        }
+
+      /* The objfile has its functions reordered if this partial symbol
+        table overlaps any other partial symbol table.
+        We cannot assume a reordered objfile if a partial symbol table
+        is contained within another partial symbol table, as partial symbol
+        tables for include files with executable code are contained
+        within the partial symbol table for the including source file,
+        and we do not want to flag the objfile reordered for these cases.
+
+        This strategy works well for Irix-5.2 shared libraries, but we
+        might have to use a more elaborate (and slower) algorithm for
+        other cases.  */
+      save_pst = fdr_to_pst[f_idx].pst;
+      if (save_pst != NULL
+         && save_pst->textlow != 0
+         && !(objfile->flags & OBJF_REORDERED))
+       {
+         ALL_OBJFILE_PSYMTABS (objfile, pst)
+           {
+             if (save_pst != pst
+                 && save_pst->textlow >= pst->textlow
+                 && save_pst->textlow < pst->texthigh
+                 && save_pst->texthigh > pst->texthigh)
+               {
+                 objfile->flags |= OBJF_REORDERED;
+                 break;
+               }
+           }
+       }
     }
 
   /* Now scan the FDRs for dependencies */
index f7cd113eda683c6854317d5920ee3095f08e6894..a4b3d2cd99f4b206088a83898f6d42b8d0cdc5d0 100644 (file)
@@ -343,6 +343,14 @@ struct objfile
 
 #define OBJF_SYMS      (1 << 1)        /* Have tried to read symbols */
 
+/* When an object file has its functions reordered (currently Irix-5.2
+   shared libraries exhibit this behaviour), we will need an expensive
+   algorithm to locate a partial symtab or symtab via an address.
+   To avoid this penalty for normal object files, we use this flag,
+   whose setting is determined upon symbol table read in.  */
+
+#define OBJF_REORDERED (2 << 1)        /* Functions are reordered */
+
 /* The object file that the main symbol table was loaded from (e.g. the
    argument to the "symbol-file" or "file" command).  */
 
index e67fae74513359f8e1d928679087692c4347fe8d..a0cb2cc11802d3a780fff3cf6fdb2be1f54f36d2 100644 (file)
@@ -572,7 +572,7 @@ sparc_pop_frame ()
   else if (fsr.regs[I7_REGNUM])
     {
       /* Return address in %i7 -- adjust it, then restore PC and NPC from it */
-      pc = PC_ADJUST (read_memory_integer (fsr.regs[I7_REGNUM], 4));
+      pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (fsr.regs[I7_REGNUM], 4));
       write_register (PC_REGNUM,  pc);
       write_register (NPC_REGNUM, pc + 4);
     }
index 577aaa486c03ec013a21a313c87cd2b603264fdf..24e7c6e3f625b667288bf18292c9dfc77787fc79 100644 (file)
@@ -620,11 +620,6 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
     }
 
   new_symfile_objfile (objfile, mainline, from_tty);
-      
-  /* Getting new symbols may change our opinion about what is
-     frameless.  */
-
-  reinit_frame_cache ();
 
   return (objfile);
 }
@@ -710,6 +705,11 @@ symbol_file_command (args, from_tty)
               else
                 symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation,
                                 0, mapped, readnow);
+
+             /* Getting new symbols may change our opinion about what is
+                frameless.  */
+             reinit_frame_cache ();
+
               set_initial_language ();
            }
          argv++;
@@ -1025,6 +1025,10 @@ add_symbol_file_command (args, from_tty)
     error ("Not confirmed.");
 
   symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
+
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
 }
 \f
 static void
@@ -1079,6 +1083,7 @@ reread_symbols ()
          struct section_offsets *offsets;
          int num_offsets;
          int section_offsets_size;
+         char *obfd_filename;
 
          printf_filtered ("`%s' has changed; re-reading symbols.\n",
                           objfile->name);
@@ -1100,9 +1105,10 @@ reread_symbols ()
          /* Clean up any state BFD has sitting around.  We don't need
             to close the descriptor but BFD lacks a way of closing the
             BFD without closing the descriptor.  */
+         obfd_filename = bfd_get_filename (objfile->obfd);
          if (!bfd_close (objfile->obfd))
            error ("Can't close BFD for %s.", objfile->name);
-         objfile->obfd = bfd_openr (objfile->name, gnutarget);
+         objfile->obfd = bfd_openr (obfd_filename, gnutarget);
          if (objfile->obfd == NULL)
            error ("Can't open %s to read symbols.", objfile->name);
          /* bfd_openr sets cacheable to true, which is what we want.  */
@@ -1237,6 +1243,8 @@ deduce_language_from_filename (filename)
     return language_cplus;
   else if (STREQ (c, ".ch") || STREQ (c, ".c186") || STREQ (c, ".c286"))
     return language_chill;
+  else if (STREQ (c, ".f") || STREQ (c, ".F"))
+    return language_fortran;
   else if (STREQ (c, ".mod"))
     return language_m2;
   else if (STREQ (c, ".s") || STREQ (c, ".S"))
@@ -1603,7 +1611,7 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
   SYMBOL_LANGUAGE (psym) = language;
   PSYMBOL_NAMESPACE (psym) = namespace;
   PSYMBOL_CLASS (psym) = class;
-  SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
+  SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language);
 }
 
 /* Add a symbol with a CORE_ADDR value to a psymtab. */
@@ -1637,7 +1645,7 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
   SYMBOL_LANGUAGE (psym) = language;
   PSYMBOL_NAMESPACE (psym) = namespace;
   PSYMBOL_CLASS (psym) = class;
-  SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
+  SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language);
 }
 
 #endif /* !INLINE_ADD_PSYMBOL */
index 0a639641d71abd0644fa5cb6a52e291259b0768f..3f6c00efeb7053560df1afc433198368feff76c5 100644 (file)
@@ -35,7 +35,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "demangle.h"
 
 #include <obstack.h>
-#include <assert.h>
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -291,7 +290,6 @@ gdb_mangle_name (type, i, j)
   if (!is_destructor)
     is_destructor = (strncmp(physname, "__dt", 4) == 0); 
 
-#ifndef GCC_MANGLE_BUG
   if (is_destructor || is_full_physname_constructor)
     {
       mangled_name = (char*) xmalloc(strlen(physname)+1);
@@ -305,6 +303,13 @@ gdb_mangle_name (type, i, j)
       if (strcmp(buf, "__") == 0)
        buf[0] = '\0';
     }
+  else if (newname != NULL && strchr (newname, '<') != NULL)
+    {
+      /* Template methods are fully mangled.  */
+      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      newname = NULL;
+      len = 0;
+    }
   else
     {
       sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
@@ -343,51 +348,6 @@ gdb_mangle_name (type, i, j)
   if (newname != NULL)
     strcat (mangled_name, newname);
 
-#else
-
-  if (is_constructor)
-    {
-      buf[0] = '\0';
-    }
-  else
-    {
-      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
-    }
-
-  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
-                     + strlen (buf) + strlen (physname) + 1);
-
-  /* Only needed for GNU-mangled names.  ANSI-mangled names
-     work with the normal mechanisms.  */
-  if (OPNAME_PREFIX_P (field_name))
-    {
-      char *opname;
-      opname = cplus_mangle_opname (field_name + 3, 0);
-      if (opname == NULL)
-       {
-         error ("No mangling for \"%s\"", field_name);
-       }
-      mangled_name_len += strlen (opname);
-      mangled_name = (char *) xmalloc (mangled_name_len);
-
-      strncpy (mangled_name, field_name, 3);
-      strcpy (mangled_name + 3, opname);
-    }
-  else
-    {
-      mangled_name = (char *) xmalloc (mangled_name_len);
-      if (is_constructor)
-       {
-         mangled_name[0] = '\0';
-       }
-      else
-       {
-         strcpy (mangled_name, field_name);
-       }
-    }
-  strcat (mangled_name, buf);
-
-#endif
   strcat (mangled_name, physname);
   return (mangled_name);
 }
@@ -405,7 +365,36 @@ find_pc_psymtab (pc)
   ALL_PSYMTABS (objfile, pst)
     {
       if (pc >= pst->textlow && pc < pst->texthigh)
-       return (pst);
+       {
+         struct minimal_symbol *msymbol;
+         struct partial_symtab *tpst;
+
+         /* 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))
+           return (pst);
+
+         msymbol = lookup_minimal_symbol_by_pc (pc);
+         if (msymbol == NULL)
+           return (pst);
+
+         for (tpst = pst; tpst != NULL; tpst = tpst->next)
+           {
+             if (pc >= tpst->textlow && pc < tpst->texthigh)
+               {
+                 struct partial_symbol *p;
+
+                 p = find_pc_psymbol (tpst, pc);
+                 if (p != NULL
+                     && SYMBOL_VALUE_ADDRESS(p)
+                        == SYMBOL_VALUE_ADDRESS (msymbol))
+                   return (tpst);
+               }
+           }
+         return (pst);
+       }
     }
   return (NULL);
 }
@@ -590,9 +579,9 @@ found:
        }
     }
 
-  /* Check for the possibility of the symbol being a global function
-     that is stored in one of the minimal symbol tables.  Eventually, all
-     global symbols might be resolved in this way.  */
+  /* 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.  */
   
   if (namespace == VAR_NAMESPACE)
     {
@@ -600,10 +589,9 @@ found:
       if (msymbol != NULL)
        {
          s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
-         /* If S is NULL, there are no debug symbols for this file.
-            Skip this stuff and check for matching static symbols below. */
          if (s != NULL)
            {
+             /* This is a function which has a symtab for its address.  */
              bv = BLOCKVECTOR (s);
              block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
              sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
@@ -633,6 +621,18 @@ found:
                *symtab = s;
              return sym;
            }
+         else if (MSYMBOL_TYPE (msymbol) != mst_text
+                  && MSYMBOL_TYPE (msymbol) != mst_file_text
+                  && !STREQ (name, SYMBOL_NAME (msymbol)))
+           {
+             /* This is a mangled variable, look it up by its
+                mangled name.  */
+             return lookup_symbol (SYMBOL_NAME (msymbol), block,
+                                   namespace, is_a_field_of_this, symtab);
+           }
+         /* There are no debug symbols for this file, or we are looking
+            for an unmangled variable.
+            Try to find a matching static symbol below. */
        }
     }
       
@@ -765,7 +765,8 @@ lookup_partial_symbol (pst, name, global, namespace)
       while (top > bottom)
        {
          center = bottom + (top - bottom) / 2;
-         assert (center < top);
+         if (!(center < top))
+           abort ();
          if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus)
            {
              do_linear_search = 1;
@@ -779,7 +780,8 @@ lookup_partial_symbol (pst, name, global, namespace)
              bottom = center + 1;
            }
        }
-      assert (top == bottom);
+      if (!(top == bottom))
+       abort ();
       while (STREQ (SYMBOL_NAME (top), name))
        {
          if (SYMBOL_NAMESPACE (top) == namespace)
@@ -1003,8 +1005,15 @@ find_pc_symtab (pc)
      to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
      and symtab b is at 0x2000-0x3000.  So the GLOBAL_BLOCK for a is from
      0x1000-0x4000, but for address 0x2345 we want to return symtab b.
-     This is said to happen for the mips; it might be swifter to create
-     several symtabs with the same name like xcoff does (I'm not sure).  */
+
+     This happens for native ecoff format, where code from included files
+     gets its own symtab. The symtab for the included file should have
+     been read in already via the dependency mechanism.
+     It might be swifter to create several symtabs with the same name
+     like xcoff does (I'm not sure).
+
+     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)
     {
@@ -1015,6 +1024,18 @@ find_pc_symtab (pc)
          && (distance == 0
              || BLOCK_END (b) - BLOCK_START (b) < distance))
        {
+         /* For an objfile that has its functions reordered,
+            find_pc_psymtab will find the proper partial symbol table
+            and we simply return its corresponding symtab.  */
+         if (objfile->flags & OBJF_REORDERED)
+           {
+             ps = find_pc_psymtab (pc);
+             if (ps)
+               s = PSYMTAB_TO_SYMTAB (ps);
+             else
+               s = NULL;
+             return (s);
+           }
          distance = BLOCK_END (b) - BLOCK_START (b);
          best_s = s;
        }
@@ -1500,6 +1521,51 @@ find_pc_line_pc_range (pc, startptr, endptr)
   *endptr = sal.end;
   return sal.symtab != 0;
 }
+
+/* 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
+   of real code inside the function.  */
+
+static struct symtab_and_line
+find_function_start_sal PARAMS ((struct symbol *sym, int));
+
+static struct symtab_and_line
+find_function_start_sal (sym, funfirstline)
+     struct symbol *sym;
+     int funfirstline;
+{
+  CORE_ADDR pc;
+  struct symtab_and_line sal;
+
+  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+  if (funfirstline)
+    {
+      pc += FUNCTION_START_OFFSET;
+      SKIP_PROLOGUE (pc);
+    }
+  sal = find_pc_line (pc, 0);
+
+#ifdef PROLOGUE_FIRSTLINE_OVERLAP
+  /* Convex: no need to suppress code on first line, if any */
+  sal.pc = pc;
+#else
+  /* Check if 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)))
+    {
+      /* First pc of next line */
+      pc = sal.end;
+      /* Recalculate the line number (might not be N+1).  */
+      sal = find_pc_line (pc, 0);
+    }
+  sal.pc = pc;
+#endif
+
+  return sal;
+}
 \f
 /* If P is of the form "operator[ \t]+..." where `...' is
    some legitimate operator text, return a pointer to the
@@ -1752,7 +1818,8 @@ build_canonical_line_spec (sal, symname, canonical)
    FUNCTION may be an undebuggable function found in minimal symbol table.
 
    If the argument FUNFIRSTLINE is nonzero, we want the first line
-   of real code inside a function when a function is specified.
+   of real code inside a function when a function is specified, and it is
+   not OK to specify a variable or type to get its line number.
 
    DEFAULT_SYMTAB specifies the file to use if none is specified.
    It defaults to current_source_symtab.
@@ -1846,17 +1913,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
 
   if (**argptr == '*')
     {
-      if (**argptr == '*')
-       {
-         (*argptr)++;
-       }
+      (*argptr)++;
       pc = parse_and_eval_address_1 (argptr);
       values.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
       values.nelts = 1;
       values.sals[0] = find_pc_line (pc, 0);
       values.sals[0].pc = pc;
-      build_canonical_line_spec (values.sals, NULL, canonical);
       return values;
     }
 
@@ -1871,7 +1934,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
     {
       if (p[0] == '<') 
        {
-         while(!++p && *p != '>');
+         while(++p && *p != '>');
          if (!p)
            {
              error ("non-matching '<' and '>' in command");
@@ -1988,17 +2051,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
 
                  if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
                    {
-                     /* Arg is the name of a function */
-                     pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-                     if (funfirstline)
-                       {
-                         pc += FUNCTION_START_OFFSET;
-                         SKIP_PROLOGUE (pc);
-                       }
                      values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
                      values.nelts = 1;
-                     values.sals[0] = find_pc_line (pc, 0);
-                     values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc;
+                     values.sals[0] = find_function_start_sal (sym,
+                                                               funfirstline);
                    }
                  else
                    {
@@ -2185,32 +2241,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
       if (SYMBOL_CLASS (sym) == LOC_BLOCK)
        {
          /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-         if (funfirstline)
-           {
-             pc += FUNCTION_START_OFFSET;
-             SKIP_PROLOGUE (pc);
-           }
-         val = find_pc_line (pc, 0);
-#ifdef PROLOGUE_FIRSTLINE_OVERLAP
-         /* Convex: no need to suppress code on first line, if any */
-         val.pc = pc;
-#else
-         /* Check if SKIP_PROLOGUE left us in mid-line, and the next
-            line is still part of the same function.  */
-         if (val.pc != pc
-             && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= val.end
-             && val.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
-           {
-             /* First pc of next line */
-             pc = val.end;
-             /* Recalculate the line number (might not be N+1).  */
-             val = find_pc_line (pc, 0);
-           }
-         val.pc = pc;
-#endif
          values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
-         values.sals[0] = val;
+         values.sals[0] = find_function_start_sal (sym, funfirstline);
          values.nelts = 1;
 
          /* Don't use the SYMBOL_LINE; if used at all it points to
@@ -2228,23 +2260,29 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
            }
          return values;
        }
-      else if (SYMBOL_LINE (sym) != 0)
+      else
        {
-         /* We know its line number.  */
-         values.sals = (struct symtab_and_line *)
-           xmalloc (sizeof (struct symtab_and_line));
-         values.nelts = 1;
-         memset (&values.sals[0], 0, sizeof (values.sals[0]));
-         values.sals[0].symtab = sym_symtab;
-         values.sals[0].line = SYMBOL_LINE (sym);
-         return values;
+         if (funfirstline)
+           error ("\"%s\" is not a function", copy);
+         else if (SYMBOL_LINE (sym) != 0)
+           {
+             /* We know its line number.  */
+             values.sals = (struct symtab_and_line *)
+               xmalloc (sizeof (struct symtab_and_line));
+             values.nelts = 1;
+             memset (&values.sals[0], 0, sizeof (values.sals[0]));
+             values.sals[0].symtab = sym_symtab;
+             values.sals[0].line = SYMBOL_LINE (sym);
+             return values;
+           }
+         else
+           /* This can happen if it is compiled with a compiler which doesn't
+              put out line numbers for variables.  */
+           /* FIXME: Shouldn't we just set .line and .symtab to zero
+              and return?  For example, "info line foo" could print
+              the address.  */
+           error ("Line number not known for symbol \"%s\"", copy);
        }
-      else
-       /* This can happen if it is compiled with a compiler which doesn't
-          put out line numbers for variables.  */
-       /* FIXME: Shouldn't we just set .line and .symtab to zero and
-          return?  For example, "info line foo" could print the address.  */
-       error ("Line number not known for symbol \"%s\"", copy);
     }
 
   msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL);
@@ -2301,7 +2339,6 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
      char ***canonical;
 {
   struct symtabs_and_lines values, return_values;
-  register CORE_ADDR pc;
   char *args, *arg1;
   int i;
   char *prompt;
@@ -2327,20 +2364,15 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
     {
       if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
        {
-         /* Arg is the name of a function */
-         pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i]));
-         if (funfirstline)
-           {
-             pc += FUNCTION_START_OFFSET;
-             SKIP_PROLOGUE (pc);
-           }
-         values.sals[i] = find_pc_line (pc, 0);
-         values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ?
-                              values.sals[i].end                      :  pc;
-         printf_unfiltered("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]),
-                values.sals[i].symtab->filename, values.sals[i].line);
+         values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
+         printf_unfiltered ("[%d] %s at %s:%d\n",
+                            (i+2),
+                            SYMBOL_SOURCE_NAME (sym_arr[i]),
+                            values.sals[i].symtab->filename,
+                            values.sals[i].line);
        }
-      else printf_unfiltered ("?HERE\n");
+      else
+       printf_unfiltered ("?HERE\n");
       i++;
     }
   
@@ -2652,13 +2684,20 @@ list_symbols (regexp, class, bpt, from_tty)
        }
     }
 
-  /* Here, we search through the minimal symbol tables for functions that
-     match, and call find_pc_symtab on them to force their symbols to
-     be read.  The symbol will then be found during the scan of symtabs
-     below.  If find_pc_symtab fails, set found_misc so that we will
-     rescan to print any matching symbols without debug info.  */
+  /* Here, we search through the minimal symbol tables for functions
+     and variables that match, and force their symbols to be read.
+     This is in particular necessary for demangled variable names,
+     which are no longer put into the partial symbol tables.
+     The symbol will then be found during the scan of symtabs below.
+
+     For functions, find_pc_symtab should succeed if we have debug info
+     for the function, for variables we have to call lookup_symbol
+     to determine if the variable has debug info.
+     If the lookup fails, set found_misc so that we will rescan to print
+     any matching symbols without debug info.
+  */
 
-  if (class == 1)
+  if (class == 0 || class == 1)
     {
       ALL_MSYMBOLS (objfile, msymbol)
        {
@@ -2671,7 +2710,12 @@ list_symbols (regexp, class, bpt, from_tty)
                {
                  if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
                    {
-                     found_misc = 1;
+                     if (class == 1
+                         || lookup_symbol (SYMBOL_NAME (msymbol), 
+                                           (struct block *) NULL,
+                                           VAR_NAMESPACE,
+                                           0, (struct symtab **) NULL) == NULL)
+                       found_misc = 1;
                    }
                }
            }
@@ -2724,14 +2768,18 @@ list_symbols (regexp, class, bpt, from_tty)
                               same name but in different files.  In order to
                               set breakpoints on all of them, we must give
                               both the file name and the function name to
-                              break_command.  */
+                              break_command.
+                              Quoting the symbol name gets rid of problems
+                              with mangled symbol names that contain
+                              CPLUS_MARKER characters.  */
                            char *string =
                              (char *) alloca (strlen (s->filename)
                                               + strlen (SYMBOL_NAME(sym))
-                                              + 2);
+                                              + 4);
                            strcpy (string, s->filename);
-                           strcat (string, ":");
+                           strcat (string, ":'");
                            strcat (string, SYMBOL_NAME(sym));
+                           strcat (string, "'");
                            break_command (string, from_tty);
                          }
                      }
index 775ccf8f0d78c1542d9e213e209f915ed34c263e..35c8902fd7b7244ea9f5ded54a9c6967dd4d35c6 100644 (file)
@@ -111,6 +111,16 @@ exec_close (quitting)
 
   if (exec_ops.to_sections)
     {
+      /* Reflect to_sections freeing in current_target if it is
+        the exec target. Otherwise target_xfer_memory (eventually
+        called from clear_symtab_users) might access the freed
+        exec_ops.to_sections via the copy in current_target.  */
+      if (current_target.to_sections == exec_ops.to_sections)
+       {
+         current_target.to_sections = NULL;
+         current_target.to_sections_end = NULL;
+       }
+
       free (exec_ops.to_sections);
       exec_ops.to_sections = NULL;
       exec_ops.to_sections_end = NULL;