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
 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"
 
 #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"
 
 /* The symbol which starts off the list of shared libraries.  */
 #define DEBUG_BASE "__rld_obj_head"
 
@@ -878,84 +863,22 @@ SYNOPSIS
 
 DESCRIPTION
 
 
 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 ()
 {
 */
 
 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);
       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
   
   /* 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");
     }
 
       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);
   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;
        }
          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 */
     }
 
   /* 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 */
 
 
 #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).  */
 
 /* 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 */
   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);
     }
       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);
     }
 
   new_symfile_objfile (objfile, mainline, from_tty);
-      
-  /* Getting new symbols may change our opinion about what is
-     frameless.  */
-
-  reinit_frame_cache ();
 
   return (objfile);
 }
 
   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);
               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++;
               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);
     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
 }
 \f
 static void
@@ -1079,6 +1083,7 @@ reread_symbols ()
          struct section_offsets *offsets;
          int num_offsets;
          int section_offsets_size;
          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);
 
          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.  */
          /* 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);
          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.  */
          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;
     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"))
   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_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. */
 }
 
 /* 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_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 */
 }
 
 #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 "demangle.h"
 
 #include <obstack.h>
-#include <assert.h>
 
 #include <sys/types.h>
 #include <fcntl.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); 
 
   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);
   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';
     }
       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);
   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);
 
   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);
 }
   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)
   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);
 }
     }
   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)
     {
   
   if (namespace == VAR_NAMESPACE)
     {
@@ -600,10 +589,9 @@ found:
       if (msymbol != NULL)
        {
          s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
       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)
            {
          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),
              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;
            }
                *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;
       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;
          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;
            }
        }
              bottom = center + 1;
            }
        }
-      assert (top == bottom);
+      if (!(top == bottom))
+       abort ();
       while (STREQ (SYMBOL_NAME (top), name))
        {
          if (SYMBOL_NAMESPACE (top) == namespace)
       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.
      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)
     {
 
   ALL_SYMTABS (objfile, s)
     {
@@ -1015,6 +1024,18 @@ find_pc_symtab (pc)
          && (distance == 0
              || BLOCK_END (b) - BLOCK_START (b) < distance))
        {
          && (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;
        }
          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;
 }
   *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
 \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
    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.
 
    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 == '*')
     {
-      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;
       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;
     }
 
       return values;
     }
 
@@ -1871,7 +1934,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
     {
       if (p[0] == '<') 
        {
     {
       if (p[0] == '<') 
        {
-         while(!++p && *p != '>');
+         while(++p && *p != '>');
          if (!p)
            {
              error ("non-matching '<' and '>' in command");
          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)
                    {
 
                  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 = (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
                    {
                    }
                  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 */
       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 = (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
          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;
        }
            }
          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);
     }
 
   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;
      char ***canonical;
 {
   struct symtabs_and_lines values, return_values;
-  register CORE_ADDR pc;
   char *args, *arg1;
   int i;
   char *prompt;
   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)
        {
     {
       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++;
     }
   
       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)
        {
     {
       ALL_MSYMBOLS (objfile, msymbol)
        {
@@ -2671,7 +2710,12 @@ list_symbols (regexp, class, bpt, from_tty)
                {
                  if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
                    {
                {
                  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
                               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))
                            char *string =
                              (char *) alloca (strlen (s->filename)
                                               + strlen (SYMBOL_NAME(sym))
-                                              + 2);
+                                              + 4);
                            strcpy (string, s->filename);
                            strcpy (string, s->filename);
-                           strcat (string, ":");
+                           strcat (string, ":'");
                            strcat (string, SYMBOL_NAME(sym));
                            strcat (string, SYMBOL_NAME(sym));
+                           strcat (string, "'");
                            break_command (string, from_tty);
                          }
                      }
                            break_command (string, from_tty);
                          }
                      }
index 775ccf8f0d78c1542d9e213e209f915ed34c263e..35c8902fd7b7244ea9f5ded54a9c6967dd4d35c6 100644 (file)
@@ -111,6 +111,16 @@ exec_close (quitting)
 
   if (exec_ops.to_sections)
     {
 
   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;
       free (exec_ops.to_sections);
       exec_ops.to_sections = NULL;
       exec_ops.to_sections_end = NULL;