Fix for PR gdb/209, PR gdb/156:
[deliverable/binutils-gdb.git] / gdb / symfile.c
index e28158ae0214d64cb8566bbebff76d3913afcb8b..d5aeba3a1f378b6161fa763219e12a437c9db09e 100644 (file)
@@ -1,5 +1,6 @@
 /* Generic symbol file reading for the GNU debugger, GDB.
-   Copyright 1990-1996, 1998, 2000 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
    This file is part of GDB.
@@ -36,8 +37,8 @@
 #include "inferior.h"          /* for write_pc */
 #include "gdb-stabs.h"
 #include "obstack.h"
+#include "completer.h"
 
-#include <assert.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -94,8 +95,6 @@ struct complaint unknown_option_complaint =
 
 /* External variables and functions referenced. */
 
-extern int info_verbose;
-
 extern void report_transfer_performance (unsigned long, time_t, time_t);
 
 /* Functions this file defines */
@@ -109,16 +108,14 @@ static void set_initial_language (void);
 
 static void load_command (char *, int);
 
+static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
+
 static void add_symbol_file_command (char *, int);
 
 static void add_shared_symbol_files_command (char *, int);
 
 static void cashier_psymtab (struct partial_symtab *);
 
-static int compare_psymbols (const void *, const void *);
-
-static int compare_symbols (const void *, const void *);
-
 bfd *symfile_bfd_open (char *);
 
 static void find_sym_fns (struct objfile *);
@@ -178,27 +175,27 @@ int symbol_reloading = SYMBOL_RELOADING_DEFAULT;
 int symbol_reloading = 0;
 #endif
 
-/* If non-zero, then on HP-UX (i.e., platforms that use somsolib.c),
-   this variable is interpreted as a threshhold.  If adding a new
-   library's symbol table to those already known to the debugger would
-   exceed this threshhold, then the shlib's symbols are not added.
-
-   If non-zero on other platforms, shared library symbols will be added
-   automatically when the inferior is created, new libraries are loaded,
-   or when attaching to the inferior.  This is almost always what users
-   will want to have happen; but for very large programs, the startup
-   time will be excessive, and so if this is a problem, the user can
-   clear this flag and then add the shared library symbols as needed.
-   Note that there is a potential for confusion, since if the shared
+/* If non-zero, shared library symbols will be added automatically
+   when the inferior is created, new libraries are loaded, or when
+   attaching to the inferior.  This is almost always what users will
+   want to have happen; but for very large programs, the startup time
+   will be excessive, and so if this is a problem, the user can clear
+   this flag and then add the shared library symbols as needed.  Note
+   that there is a potential for confusion, since if the shared
    library symbols are not loaded, commands like "info fun" will *not*
-   report all the functions that are actually present. 
-
-   Note that HP-UX interprets this variable to mean, "threshhold size
-   in megabytes, where zero means never add".  Other platforms interpret
-   this variable to mean, "always add if non-zero, never add if zero."
- */
+   report all the functions that are actually present. */
 
 int auto_solib_add = 1;
+
+/* For systems that support it, a threshold size in megabytes.  If
+   automatically adding a new library's symbol table to those already
+   known to the debugger would cause the total shared library symbol
+   size to exceed this threshhold, then the shlib's symbols are not
+   added.  The threshold is ignored if the user explicitly asks for a
+   shlib to be added, such as when using the "sharedlibrary"
+   command. */
+
+int auto_solib_limit;
 \f
 
 /* Since this function is called from within qsort, in an ANSI environment
@@ -206,14 +203,13 @@ int auto_solib_add = 1;
    comparison function takes two "void *" pointers. */
 
 static int
-compare_symbols (const PTR s1p, const PTR s2p)
+compare_symbols (const void *s1p, const void *s2p)
 {
   register struct symbol **s1, **s2;
 
   s1 = (struct symbol **) s1p;
   s2 = (struct symbol **) s2p;
-
-  return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
+  return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
 }
 
 /*
@@ -239,10 +235,16 @@ compare_symbols (const PTR s1p, const PTR s2p)
  */
 
 static int
-compare_psymbols (const PTR s1p, const PTR s2p)
+compare_psymbols (const void *s1p, const void *s2p)
 {
-  register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
-  register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
+  register struct partial_symbol **s1, **s2;
+  register char *st1, *st2;
+
+  s1 = (struct partial_symbol **) s1p;
+  s2 = (struct partial_symbol **) s2p;
+  st1 = SYMBOL_SOURCE_NAME (*s1);
+  st2 = SYMBOL_SOURCE_NAME (*s2);
+
 
   if ((st1[0] - st2[0]) || !st1[0])
     {
@@ -254,18 +256,6 @@ compare_psymbols (const PTR s1p, const PTR s2p)
     }
   else
     {
-      /* Note: I replaced the STRCMP line (commented out below)
-       * with a simpler "strcmp()" which compares the 2 strings
-       * from the beginning. (STRCMP is a macro which first compares
-       * the initial characters, then falls back on strcmp).
-       * The reason is that the STRCMP line was tickling a C compiler
-       * bug on HP-UX 10.30, which is avoided with the simpler
-       * code. The performance gain from the more complicated code
-       * is negligible, given that we have already checked the
-       * initial 2 characters above. I reported the compiler bug,
-       * and once it is fixed the original line can be put back. RT
-       */
-      /* return ( STRCMP (st1 + 2, st2 + 2)); */
       return (strcmp (st1, st2));
     }
 }
@@ -485,8 +475,8 @@ free_section_addr_info (struct section_addr_info *sap)
 
   for (idx = 0; idx < MAX_SECTIONS; idx++)
     if (sap->other[idx].name)
-      free (sap->other[idx].name);
-  free (sap);
+      xfree (sap->other[idx].name);
+  xfree (sap);
 }
 
 
@@ -521,7 +511,7 @@ default_symfile_offsets (struct objfile *objfile,
       /* Record all sections in offsets */
       /* The section_offsets in the objfile are here filled in using
          the BFD index. */
-      ANOFFSET (objfile->section_offsets, osp->sectindex) = osp->addr;
+      (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
     }
 
   /* Remember the bfd indexes for the .text, .data, .bss and
@@ -757,7 +747,7 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
   discard_cleanups (old_chain);
 
   /* Call this after reading in a new symbol table to give target
-     dependant code a crack at the new symbols.  For instance, this
+     dependent code a crack at the new symbols.  For instance, this
      could be used to update the values of target-specific symbols GDB
      needs to keep track of (such as _sigtramp, or whatever).  */
 
@@ -903,6 +893,62 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
   return (objfile);
 }
 
+/* Call symbol_file_add() with default values and update whatever is
+   affected by the loading of a new main().
+   Used when the file is supplied in the gdb command line
+   and by some targets with special loading requirements.
+   The auxiliary function, symbol_file_add_main_1(), has the flags
+   argument for the switches that can only be specified in the symbol_file
+   command itself.  */
+   
+void
+symbol_file_add_main (char *args, int from_tty)
+{
+  symbol_file_add_main_1 (args, from_tty, 0);
+}
+
+static void
+symbol_file_add_main_1 (char *args, int from_tty, int flags)
+{
+  symbol_file_add (args, from_tty, NULL, 1, flags);
+
+#ifdef HPUXHPPA
+  RESET_HP_UX_GLOBALS ();
+#endif
+
+  /* Getting new symbols may change our opinion about
+     what is frameless.  */
+  reinit_frame_cache ();
+
+  set_initial_language ();
+}
+
+void
+symbol_file_clear (int from_tty)
+{
+  if ((have_full_symbols () || have_partial_symbols ())
+      && from_tty
+      && !query ("Discard symbol table from `%s'? ",
+                symfile_objfile->name))
+    error ("Not confirmed.");
+    free_all_objfiles ();
+
+    /* solib descriptors may have handles to objfiles.  Since their
+       storage has just been released, we'd better wipe the solib
+       descriptors as well.
+     */
+#if defined(SOLIB_RESTART)
+    SOLIB_RESTART ();
+#endif
+
+    symfile_objfile = NULL;
+    if (from_tty)
+      printf_unfiltered ("No symbol file now.\n");
+#ifdef HPUXHPPA
+    RESET_HP_UX_GLOBALS ();
+#endif
+}
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -929,27 +975,7 @@ symbol_file_command (char *args, int from_tty)
 
   if (args == NULL)
     {
-      if ((have_full_symbols () || have_partial_symbols ())
-         && from_tty
-         && !query ("Discard symbol table from `%s'? ",
-                    symfile_objfile->name))
-       error ("Not confirmed.");
-      free_all_objfiles ();
-
-      /* solib descriptors may have handles to objfiles.  Since their
-         storage has just been released, we'd better wipe the solib
-         descriptors as well.
-       */
-#if defined(SOLIB_RESTART)
-      SOLIB_RESTART ();
-#endif
-
-      symfile_objfile = NULL;
-      if (from_tty)
-         printf_unfiltered ("No symbol file now.\n");
-#ifdef HPUXHPPA
-      RESET_HP_UX_GLOBALS ();
-#endif
+      symbol_file_clear (from_tty);
     }
   else
     {
@@ -971,15 +997,8 @@ symbol_file_command (char *args, int from_tty)
              else
                {
                   name = *argv;
-                 symbol_file_add (name, from_tty, NULL, 1, flags);
-#ifdef HPUXHPPA
-                 RESET_HP_UX_GLOBALS ();
-#endif
-                 /* Getting new symbols may change our opinion about
-                    what is frameless.  */
-                 reinit_frame_cache ();
 
-                 set_initial_language ();
+                 symbol_file_add_main_1 (name, from_tty, flags);
                }
          argv++;
        }
@@ -988,7 +1007,6 @@ symbol_file_command (char *args, int from_tty)
        {
          error ("no symbol file name was specified");
        }
-      TUIDO (((TuiOpaqueFuncPtr) tuiDisplayMainFunction));
       do_cleanups (cleanups);
     }
 }
@@ -1044,7 +1062,7 @@ symfile_bfd_open (char *name)
 
   /* Look down path for it, allocate 2nd new malloc'd copy.  */
   desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
-#if defined(__GO32__) || defined(_WIN32)
+#if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
   if (desc < 0)
     {
       char *exename = alloca (strlen (name) + 5);
@@ -1055,10 +1073,10 @@ symfile_bfd_open (char *name)
 #endif
   if (desc < 0)
     {
-      make_cleanup (free, name);
+      make_cleanup (xfree, name);
       perror_with_name (name);
     }
-  free (name);                 /* Free 1st new malloc'd copy */
+  xfree (name);                        /* Free 1st new malloc'd copy */
   name = absolute_name;                /* Keep 2nd malloc'd copy in bfd */
   /* It'll be freed in free_objfile(). */
 
@@ -1066,7 +1084,7 @@ symfile_bfd_open (char *name)
   if (!sym_bfd)
     {
       close (desc);
-      make_cleanup (free, name);
+      make_cleanup (xfree, name);
       error ("\"%s\": can't open to read symbols: %s.", name,
             bfd_errmsg (bfd_get_error ()));
     }
@@ -1078,7 +1096,7 @@ symfile_bfd_open (char *name)
          on error it does not free all the storage associated with the
          bfd).  */
       bfd_close (sym_bfd);     /* This also closes desc */
-      make_cleanup (free, name);
+      make_cleanup (xfree, name);
       error ("\"%s\": can't read symbols: %s.", name,
             bfd_errmsg (bfd_get_error ()));
     }
@@ -1134,6 +1152,10 @@ load_command (char *arg, int from_tty)
   if (arg == NULL)
     arg = get_exec_file (1);
   target_load (arg, from_tty);
+
+  /* After re-loading the executable, we don't really know which
+     overlays are mapped any more.  */
+  overlay_cache_invalid = 1;
 }
 
 /* This version of "load" should be usable for any target.  Currently
@@ -1166,7 +1188,7 @@ generic_load (char *args, int from_tty)
   /* Parse the input argument - the user can specify a load offset as
      a second argument. */
   filename = xmalloc (strlen (args) + 1);
-  old_cleanups = make_cleanup (free, filename);
+  old_cleanups = make_cleanup (xfree, filename);
   strcpy (filename, args);
   offptr = strchr (filename, ' ');
   if (offptr != NULL)
@@ -1226,7 +1248,7 @@ generic_load (char *args, int from_tty)
                block_size = size;
 
              buffer = xmalloc (size);
-             old_chain = make_cleanup (free, buffer);
+             old_chain = make_cleanup (xfree, buffer);
 
              /* Is this really necessary?  I guess it gives the user something
                 to look at during a long download.  */
@@ -1263,7 +1285,7 @@ generic_load (char *args, int from_tty)
                          that.  remote.c could implement that method
                          using the ``qCRC'' packet.  */
                      char *check = xmalloc (len);
-                     struct cleanup *verify_cleanups = make_cleanup (free, check);
+                     struct cleanup *verify_cleanups = make_cleanup (xfree, check);
                      if (target_read_memory (lma, check, len) != 0)
                        error ("Download verify read failed at 0x%s",
                               paddr (lma));
@@ -1411,7 +1433,7 @@ add_symbol_file_command (char *args, int from_tty)
   } sect_opts[SECT_OFF_MAX];
 
   struct section_addr_info section_addrs;
-  struct cleanup *my_cleanups;
+  struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
 
   dont_repeat ();
 
@@ -1447,7 +1469,7 @@ add_symbol_file_command (char *args, int from_tty)
        {
          /* The first argument is the file name. */
          filename = tilde_expand (arg);
-         my_cleanups = make_cleanup (free, filename);
+         make_cleanup (xfree, filename);
        }
       else
        if (argcnt == 1)
@@ -1679,13 +1701,13 @@ reread_symbols (void)
              /* obstack_specify_allocation also initializes the obstack so
                 it is empty.  */
              obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
-                                         xmalloc, free);
+                                         xmalloc, xfree);
              obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0,
-                                         xmalloc, free);
+                                         xmalloc, xfree);
              obstack_specify_allocation (&objfile->symbol_obstack, 0, 0,
-                                         xmalloc, free);
+                                         xmalloc, xfree);
              obstack_specify_allocation (&objfile->type_obstack, 0, 0,
-                                         xmalloc, free);
+                                         xmalloc, xfree);
              if (build_objfile_section_table (objfile))
                {
                  error ("Can't find the file sections in `%s': %s",
@@ -1742,7 +1764,7 @@ reread_symbols (void)
              reread_one = 1;
 
              /* Call this after reading in a new symbol table to give target
-                dependant code a crack at the new symbols.  For instance, this
+                dependent code a crack at the new symbols.  For instance, this
                 could be used to update the values of target-specific symbols GDB
                 needs to keep track of (such as _sigtramp, or whatever).  */
 
@@ -1773,11 +1795,11 @@ add_filename_language (char *ext, enum language lang)
   if (fl_table_next >= fl_table_size)
     {
       fl_table_size += 10;
-      filename_language_table = realloc (filename_language_table,
-                                        fl_table_size);
+      filename_language_table = xrealloc (filename_language_table,
+                                         fl_table_size);
     }
 
-  filename_language_table[fl_table_next].ext = strsave (ext);
+  filename_language_table[fl_table_next].ext = xstrdup (ext);
   filename_language_table[fl_table_next].lang = lang;
   fl_table_next++;
 }
@@ -1835,8 +1857,8 @@ set_ext_lang_command (char *args, int from_tty)
       /*   query ("Really make files of type %s '%s'?", */
       /*          ext_args, language_str (lang));           */
 
-      free (filename_language_table[i].ext);
-      filename_language_table[i].ext = strsave (ext_args);
+      xfree (filename_language_table[i].ext);
+      filename_language_table[i].ext = xstrdup (ext_args);
       filename_language_table[i].lang = lang;
     }
 }
@@ -2138,7 +2160,7 @@ cashier_psymtab (struct partial_symtab *pst)
    it is not called for subsidiary files such as .h files.
 
    Return value is 1 if we blew away the environment, 0 if not.
-   FIXME.  The return valu appears to never be used.
+   FIXME.  The return value appears to never be used.
 
    FIXME.  I think this is not the best way to do this.  We should
    work on being gentler to the environment while still cleaning up
@@ -2466,6 +2488,7 @@ init_psymbol_list (struct objfile *objfile, int total_symbols)
    section_is_overlay(sect):      true if section's VMA != LMA
    pc_in_mapped_range(pc,sec):    true if pc belongs to section's VMA
    pc_in_unmapped_range(...):     true if pc belongs to section's LMA
+   sections_overlap(sec1, sec2):  true if mapped sec1 and sec2 ranges overlap
    overlay_mapped_address(...):   map an address from section's LMA to VMA
    overlay_unmapped_address(...): map an address from section's VMA to LMA
    symbol_overlayed_address(...): Return a "current" address for symbol:
@@ -2605,6 +2628,20 @@ pc_in_mapped_range (CORE_ADDR pc, asection *section)
   return 0;
 }
 
+
+/* Return true if the mapped ranges of sections A and B overlap, false
+   otherwise.  */
+int
+sections_overlap (asection *a, asection *b)
+{
+  CORE_ADDR a_start = a->vma;
+  CORE_ADDR a_end = a->vma + bfd_get_section_size_before_reloc (a);
+  CORE_ADDR b_start = b->vma;
+  CORE_ADDR b_end = b->vma + bfd_get_section_size_before_reloc (b);
+
+  return (a_start < b_end && b_start < a_end);
+}
+
 /* Function: overlay_unmapped_address (PC, SECTION)
    Returns the address corresponding to PC in the unmapped (load) range.
    May be the same as PC.  */
@@ -2783,11 +2820,11 @@ the 'overlay manual' command.");
       /* Next, make a pass and unmap any sections that are
          overlapped by this new section: */
       ALL_OBJSECTIONS (objfile2, sec2)
-       if (sec2->ovly_mapped &&
-           sec != sec2 &&
-           sec->the_bfd_section != sec2->the_bfd_section &&
-           (pc_in_mapped_range (sec2->addr, sec->the_bfd_section) ||
-            pc_in_mapped_range (sec2->endaddr, sec->the_bfd_section)))
+       if (sec2->ovly_mapped
+            && sec != sec2
+            && sec->the_bfd_section != sec2->the_bfd_section
+            && sections_overlap (sec->the_bfd_section,
+                                 sec2->the_bfd_section))
        {
          if (info_verbose)
            printf_filtered ("Note: section %s unmapped by overlap\n",
@@ -2948,7 +2985,7 @@ static void
 simple_free_overlay_table (void)
 {
   if (cache_ovly_table)
-    free (cache_ovly_table);
+    xfree (cache_ovly_table);
   cache_novlys = 0;
   cache_ovly_table = NULL;
   cache_ovly_table_base = 0;
@@ -2960,7 +2997,7 @@ static void
 simple_free_overlay_region_table (void)
 {
   if (cache_ovly_region_table)
-    free (cache_ovly_region_table);
+    xfree (cache_ovly_region_table);
   cache_novly_regions = 0;
   cache_ovly_region_table = NULL;
   cache_ovly_region_table_base = 0;
@@ -2986,30 +3023,35 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len)
 static int
 simple_read_overlay_table (void)
 {
-  struct minimal_symbol *msym;
+  struct minimal_symbol *novlys_msym, *ovly_table_msym;
 
   simple_free_overlay_table ();
-  msym = lookup_minimal_symbol ("_novlys", 0, 0);
-  if (msym != NULL)
-    cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
-  else
-    return 0;                  /* failure */
-  cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
-  if (cache_ovly_table != NULL)
+  novlys_msym = lookup_minimal_symbol ("_novlys", 0, 0);
+  if (! novlys_msym)
     {
-      msym = lookup_minimal_symbol ("_ovly_table", 0, 0);
-      if (msym != NULL)
-       {
-         cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (msym);
-         read_target_long_array (cache_ovly_table_base,
-                                 (int *) cache_ovly_table,
-                                 cache_novlys * 4);
-       }
-      else
-       return 0;               /* failure */
+      error ("Error reading inferior's overlay table: "
+             "couldn't find `_novlys' variable\n"
+             "in inferior.  Use `overlay manual' mode.");
+      return 0;
     }
-  else
-    return 0;                  /* failure */
+
+  ovly_table_msym = lookup_minimal_symbol ("_ovly_table", 0, 0);
+  if (! ovly_table_msym)
+    {
+      error ("Error reading inferior's overlay table: couldn't find "
+             "`_ovly_table' array\n"
+             "in inferior.  Use `overlay manual' mode.");
+      return 0;
+    }
+
+  cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), 4);
+  cache_ovly_table
+    = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+  cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
+  read_target_long_array (cache_ovly_table_base,
+                          (int *) cache_ovly_table,
+                          cache_novlys * 4);
+
   return 1;                    /* SUCCESS */
 }
 
@@ -3110,11 +3152,9 @@ simple_overlay_update (struct obj_section *osect)
      Or else we want all the sections, in which case it's actually
      more efficient to read the whole table in one block anyway.  */
 
-  if (simple_read_overlay_table () == 0)       /* read failed?  No table? */
-    {
-      warning ("Failed to read the target overlay mapping table.");
-      return;
-    }
+  if (! simple_read_overlay_table ())
+    return;
+
   /* Now may as well update all sections, even if only one was requested. */
   ALL_OBJSECTIONS (objfile, osect)
     if (section_is_overlay (osect->the_bfd_section))
This page took 0.031452 seconds and 4 git commands to generate.