Fix for PR gdb/209, PR gdb/156:
[deliverable/binutils-gdb.git] / gdb / symfile.c
index abeca3c9c5d8d3ca96b9f6b6acae16494b1b465c..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.
@@ -38,7 +39,6 @@
 #include "obstack.h"
 #include "completer.h"
 
-#include <assert.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -95,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 */
@@ -110,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 *);
@@ -179,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
@@ -207,7 +203,7 @@ 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;
 
@@ -239,7 +235,7 @@ 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 struct partial_symbol **s1, **s2;
   register char *st1, *st2;
@@ -897,13 +893,34 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
   return (objfile);
 }
 
-/* Just call the above with default values.
-   Used when the file is supplied in the gdb command line. */
+/* 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 (args, from_tty, NULL, 1, 0);
+  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
@@ -980,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++;
        }
@@ -997,7 +1007,6 @@ symbol_file_command (char *args, int from_tty)
        {
          error ("no symbol file name was specified");
        }
-      TUIDO (((TuiOpaqueFuncPtr) tuiDisplayMainFunction));
       do_cleanups (cleanups);
     }
 }
@@ -1053,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);
@@ -1143,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
@@ -1420,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 ();
 
@@ -1456,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 (xfree, filename);
+         make_cleanup (xfree, filename);
        }
       else
        if (argcnt == 1)
@@ -1782,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++;
 }
@@ -1845,7 +1858,7 @@ set_ext_lang_command (char *args, int from_tty)
       /*          ext_args, language_str (lang));           */
 
       xfree (filename_language_table[i].ext);
-      filename_language_table[i].ext = strsave (ext_args);
+      filename_language_table[i].ext = xstrdup (ext_args);
       filename_language_table[i].lang = lang;
     }
 }
@@ -2475,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:
@@ -2614,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.  */
@@ -2792,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",
@@ -2995,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 */
 }
 
@@ -3119,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.033595 seconds and 4 git commands to generate.