* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / symfile.c
index b09c691d0fc0af14953dd498c2144f28eea2024e..c2ea7dcad2a9974ba66b9c8503a4a32ac88d0a9c 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic symbol file reading for the GNU debugger, GDB.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 This file is part of GDB.
@@ -42,6 +42,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/stat.h>
 #include <ctype.h>
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 /* Global variables owned by this file */
 
 int readnow_symbol_files;              /* Read full symbols immediately */
@@ -84,9 +88,6 @@ symfile_bfd_open PARAMS ((char *));
 static void
 find_sym_fns PARAMS ((struct objfile *));
 
-void
-clear_symtab_users_once PARAMS ((void));
-
 /* List of all available sym_fns.  On gdb startup, each object file reader
    calls add_symtab_fns() to register information on each format it is
    prepared to read. */
@@ -107,12 +108,7 @@ int symbol_reloading = 0;
 #endif
 
 \f
-/* In the following sort, we always make sure that
-   register debug symbol declarations always come before regular
-   debug symbol declarations (as might happen when parameters are
-   then put into registers by the compiler).
-
-   Since this function is called from within qsort, in an ANSI environment
+/* Since this function is called from within qsort, in an ANSI environment
    it must conform to the prototype for qsort, which specifies that the
    comparison function takes two "void *" pointers. */
 
@@ -122,22 +118,11 @@ compare_symbols (s1p, s2p)
      const PTR s2p;
 {
   register struct symbol **s1, **s2;
-  register int namediff;
 
   s1 = (struct symbol **) s1p;
   s2 = (struct symbol **) s2p;
 
-  /* Compare the initial characters.  */
-  namediff = SYMBOL_NAME (*s1)[0] - SYMBOL_NAME (*s2)[0];
-  if (namediff != 0) return namediff;
-
-  /* If they match, compare the rest of the names.  */
-  namediff = STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
-  if (namediff != 0) return namediff;
-
-  /* For symbols of the same name, registers should come first.  */
-  return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
-         - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
+  return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
 }
 
 /*
@@ -255,7 +240,7 @@ obsavestring (ptr, size, obstackp)
      struct obstack *obstackp;
 {
   register char *p = (char *) obstack_alloc (obstackp, size + 1);
-  /* Open-coded bcopy--saves function call time.
+  /* Open-coded memcpy--saves function call time.
      These strings are usually short.  */
   {
     register char *p1 = ptr;
@@ -374,27 +359,21 @@ syms_from_objfile (objfile, addr, mainline, verbo)
 {
   struct section_offsets *section_offsets;
   asection *lowest_sect;
-
-  /* There is a distinction between having no symbol table
-     (we refuse to read the file, leaving the old set of symbols around)
-     and having no debugging symbols in your symbol table (we read
-     the file and end up with a mostly empty symbol table).
-
-     FIXME:  This strategy works correctly when the debugging symbols are
-     intermixed with "normal" symbols.  However, when the debugging symbols
-     are separate, such as with ELF/DWARF, it is perfectly plausible for
-     the symbol table to be missing but still have all the DWARF info
-     intact.  Thus in general it is wrong to assume that having no symbol
-     table implies no debugging information. */
-
-  if (!(bfd_get_file_flags (objfile -> obfd) & HAS_SYMS))
-    return;
+  struct cleanup *old_chain;
 
   init_entry_point_info (objfile);
   find_sym_fns (objfile);
 
+  /* Make sure that partially constructed symbol tables will be cleaned up
+     if an error occurs during symbol reading.  */
+  old_chain = make_cleanup (free_objfile, objfile);
+
   if (mainline) 
     {
+      /* We will modify the main symbol table, make sure that all its users
+        will be cleaned up if an error occurs during symbol reading.  */
+      make_cleanup (clear_symtab_users, 0);
+
       /* Since no error yet, throw away the old symbol table.  */
 
       if (symfile_objfile != NULL)
@@ -440,48 +419,53 @@ syms_from_objfile (objfile, addr, mainline, verbo)
        addr -= bfd_section_vma (objfile->obfd, lowest_sect);
     }
 
-  {
-  /* Debugging check inserted for testing elimination of NAMES_HAVE_UNDERSCORE.
-     Complain if the dynamic setting of NAMES_HAVE_UNDERSCORE from BFD
-     doesn't match the static setting from the GDB config files, but only
-     if we are using the first BFD target (the default target selected by
-     the same configuration that decided whether NAMES_HAVE_UNDERSCORE is
-     defined or not).  For other targets (such as when the user sets GNUTARGET
-     or we are reading a "foreign" object file), it is likely that the value
-     of bfd_get_symbol_leading_char has no relation to the value of
-     NAMES_HAVE_UNDERSCORE for the target for which this gdb was built.
-     Hack alert: the only way to currently do this with bfd is to ask it to
-     produce a list of known target names and compare the first one in the
-     list with the one for the bfd we are using.
-     FIXME:  Remove this check after a round of testing.  
-                                               -- gnu@cygnus.com, 16dec92 */
-    char **targets = bfd_target_list ();
-    if (targets != NULL && *targets != NULL)
-      {
-       if (bfd_get_symbol_leading_char (objfile->obfd) !=
-#ifdef NAMES_HAVE_UNDERSCORE
-           '_'
-#else
-           0
-#endif
-           && STREQ (bfd_get_target (objfile->obfd), *targets))
-         {
-           fprintf (stderr, "GDB internal error!  NAMES_HAVE_UNDERSCORE set wrong for %s BFD:\n%s\n",
-                    bfd_get_target (objfile->obfd),
-                    bfd_get_filename (objfile->obfd));
-         }
-       free (targets);
-      }
-    /* End of debugging check.  FIXME.  */
-  }
-
   /* Initialize symbol reading routines for this objfile, allow complaints to
      appear for this new file, and record how verbose to be, then do the
      initial symbol reading for this file. */
 
   (*objfile -> sf -> sym_init) (objfile);
   clear_complaints (1, verbo);
+
+  /* If objfile->sf->sym_offsets doesn't set this, we don't care
+     (currently).  */
+  objfile->num_sections = 0;  /* krp-FIXME: why zero? */
   section_offsets = (*objfile -> sf -> sym_offsets) (objfile, addr);
+  objfile->section_offsets = section_offsets;
+
+#ifndef IBM6000_TARGET
+  /* This is a SVR4/SunOS specific hack, I think.  In any event, it
+     screws RS/6000.  sym_offsets should be doing this sort of thing,
+     because it knows the mapping between bfd sections and
+     section_offsets.  */
+  /* This is a hack.  As far as I can tell, section offsets are not
+     target dependent.  They are all set to addr with a couple of
+     exceptions.  The exceptions are sysvr4 shared libraries, whose
+     offsets are kept in solib structures anyway and rs6000 xcoff
+     which handles shared libraries in a completely unique way.
+
+     Section offsets are built similarly, except that they are built
+     by adding addr in all cases because there is no clear mapping
+     from section_offsets into actual sections.  Note that solib.c
+     has a different algorythm for finding section offsets.
+
+     These should probably all be collapsed into some target
+     independent form of shared library support.  FIXME.  */
+
+  if (addr)
+    {
+      struct obj_section *s;
+
+      for (s = objfile->sections; s < objfile->sections_end; ++s)
+       {
+         s->addr -= s->offset;
+         s->addr += addr;
+         s->endaddr -= s->offset;
+         s->endaddr += addr;
+         s->offset += addr;
+       }
+    }
+#endif /* not IBM6000_TARGET */
+
   (*objfile -> sf -> sym_read) (objfile, section_offsets, mainline);
 
   /* Don't allow char * to have a typename (else would get caddr_t.)  */
@@ -494,9 +478,13 @@ syms_from_objfile (objfile, addr, mainline, verbo)
      that this does not mean we found any symbols... */
 
   objfile -> flags |= OBJF_SYMS;
+
+  /* Discard cleanups as symbol reading was successful.  */
+
+  discard_cleanups (old_chain);
 }
 
-/* Perform required actions immediately after either reading in the initial
+/* Perform required actions after either reading in the initial
    symbols for a new objfile, or mapping in the symbols from a reusable
    objfile. */
    
@@ -506,22 +494,24 @@ new_symfile_objfile (objfile, mainline, verbo)
      int mainline;
      int verbo;
 {
+
+  /* If this is the main symbol file we have to clean up all users of the
+     old main symbol file. Otherwise it is sufficient to fixup all the
+     breakpoints that may have been redefined by this symbol file.  */
   if (mainline)
     {
       /* OK, make it the "real" symbol file.  */
       symfile_objfile = objfile;
-    }
 
-  /* If we have wiped out any old symbol tables, clean up.  */
-  clear_symtab_users_once ();
+      clear_symtab_users ();
+    }
+  else
+    {
+      breakpoint_re_set ();
+    }
 
   /* We're done reading the symbol file; finish off complaints.  */
   clear_complaints (0, verbo);
-
-  /* Fixup all the breakpoints that may have been redefined by this
-     symbol file. */
-
-  breakpoint_re_set ();
 }
 
 /* Process a symbol file, as either the main file or as a dynamically
@@ -550,37 +540,16 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
   struct partial_symtab *psymtab;
   bfd *abfd;
 
-  /* Open a bfd for the file and then check to see if the file has a
-     symbol table.  There is a distinction between having no symbol table
-     (we refuse to read the file, leaving the old set of symbols around)
-     and having no debugging symbols in the symbol table (we read the file
-     and end up with a mostly empty symbol table, but with lots of stuff in
-     the minimal symbol table).  We need to make the decision about whether
-     to continue with the file before allocating and building a objfile.
-
-     FIXME:  This strategy works correctly when the debugging symbols are
-     intermixed with "normal" symbols.  However, when the debugging symbols
-     are separate, such as with ELF/DWARF, it is perfectly plausible for
-     the symbol table to be missing but still have all the DWARF info
-     intact.  Thus in general it is wrong to assume that having no symbol
-     table implies no debugging information. */
+  /* Open a bfd for the file, and give user a chance to burp if we'd be
+     interactively wiping out any existing symbols.  */
 
   abfd = symfile_bfd_open (name);
-  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
-    {
-      error ("%s has no symbol-table", name);
-    }
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
       && from_tty
       && !query ("Load new symbol table from \"%s\"? ", name))
       error ("Not confirmed.");
-      
-  /* Getting new symbols may change our opinion about what is
-     frameless.  */
-
-  reinit_frame_cache ();
 
   objfile = allocate_objfile (abfd, mapped);
 
@@ -616,8 +585,6 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
       syms_from_objfile (objfile, addr, mainline, from_tty);
     }      
 
-  new_symfile_objfile (objfile, mainline, from_tty);
-
   /* We now have at least a partial symbol table.  Check to see if the
      user requested that all symbols be read on initial access via either
      the gdb startup command line or on a per symbol file basis.  Expand
@@ -646,6 +613,13 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
       fflush (stdout);
     }
 
+  new_symfile_objfile (objfile, mainline, from_tty);
+      
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+
+  reinit_frame_cache ();
+
   return (objfile);
 }
 
@@ -674,8 +648,6 @@ symbol_file_command (args, from_tty)
        error ("Not confirmed.");
       free_all_objfiles ();
       symfile_objfile = NULL;
-      current_source_symtab = NULL;
-      current_source_line = 0;
       if (from_tty)
        {
          printf ("No symbol file now.\n");
@@ -771,7 +743,7 @@ symfile_bfd_open (name)
   name = tilde_expand (name);  /* Returns 1st new malloc'd copy */
 
   /* Look down path for it, allocate 2nd new malloc'd copy.  */
-  desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
+  desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
   if (desc < 0)
     {
       make_cleanup (free, name);
@@ -781,7 +753,7 @@ symfile_bfd_open (name)
   name = absolute_name;                /* Keep 2nd malloc'd copy in bfd */
                                /* It'll be freed in free_objfile(). */
 
-  sym_bfd = bfd_fdopenr (name, NULL, desc);
+  sym_bfd = bfd_fdopenr (name, gnutarget, desc);
   if (!sym_bfd)
     {
       close (desc);
@@ -850,6 +822,81 @@ load_command (arg, from_tty)
   target_load (arg, from_tty);
 }
 
+/* This version of "load" should be usable for any target.  Currently
+   it is just used for remote targets, not inftarg.c or core files,
+   on the theory that only in that case is it useful.
+
+   Avoiding xmodem and the like seems like a win (a) because we don't have
+   to worry about finding it, and (b) On VMS, fork() is very slow and so
+   we don't want to run a subprocess.  On the other hand, I'm not sure how
+   performance compares.  */
+void
+generic_load (filename, from_tty)
+    char *filename;
+    int from_tty;
+{
+  struct cleanup *old_cleanups;
+  asection *s;
+  bfd *loadfile_bfd = bfd_openr (filename, gnutarget);
+  if (loadfile_bfd == NULL)
+    {
+      perror_with_name (filename);
+      return;
+    }
+  old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
+
+  if (!bfd_check_format (loadfile_bfd, bfd_object)) 
+    {
+      error ("\"%s\" is not an object file: %s", filename,
+            bfd_errmsg (bfd_error));
+    }
+  
+  for (s = loadfile_bfd->sections; s; s = s->next) 
+    {
+      if (s->flags & SEC_LOAD) 
+       {
+         bfd_size_type size;
+
+         size = bfd_get_section_size_before_reloc (s);
+         if (size > 0)
+           {
+             char *buffer;
+             struct cleanup *old_chain;
+             bfd_vma vma;
+
+             buffer = xmalloc (size);
+             old_chain = make_cleanup (free, buffer);
+
+             vma = bfd_get_section_vma (loadfile_bfd, s);
+
+             /* Is this really necessary?  I guess it gives the user something
+                to look at during a long download.  */
+             printf_filtered ("Loading section %s, size 0x%x vma 0x%x\n",
+                              bfd_get_section_name (loadfile_bfd, s),
+                              size, vma);
+
+             bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+             target_write_memory (vma, buffer, size);
+
+             do_cleanups (old_chain);
+           }
+       }
+    }
+
+  /* We were doing this in remote-mips.c, I suspect it is right
+     for other targets too.  */
+  write_pc (loadfile_bfd->start_address);
+
+  /* FIXME: are we supposed to call symbol_file_add or not?  According to
+     a comment from remote-mips.c (where a call to symbol_file_add was
+     commented out), making the call confuses GDB if more than one file is
+     loaded in.  remote-nindy.c had no call to symbol_file_add, but remote-vx.c
+     does.  */
+
+  do_cleanups (old_cleanups);
+}
+
 /* This function allows the addition of incrementally linked object files.
    It does not modify any state in the target, only in the debugger.  */
 
@@ -986,19 +1033,20 @@ enum language
 deduce_language_from_filename (filename)
      char *filename;
 {
-  char *c = strrchr (filename, '.');
+  char *c;
   
-  if (!c) ; /* Get default. */
+  if (0 == filename) 
+    ; /* Get default */
+  else if (0 == (c = strrchr (filename, '.')))
+    ; /* Get default. */
   else if(STREQ(c,".mod"))
-     return language_m2;
+    return language_m2;
   else if(STREQ(c,".c"))
-     return language_c;
+    return language_c;
   else if(STREQ(c,".cc") || STREQ(c,".C"))
-     return language_cplus;
-  /* start-sanitize-chill */
+    return language_cplus;
   else if(STREQ(c,".ch") || STREQ(c,".c186") || STREQ(c,".c286"))
-     return language_chill;
-  /* end-sanitize-chill */
+    return language_chill;
 
   return language_unknown;             /* default */
 }
@@ -1078,6 +1126,23 @@ allocate_psymtab (filename, objfile)
 }
 
 \f
+/* Reset all data structures in gdb which may contain references to symbol
+   table date.  */
+
+void
+clear_symtab_users ()
+{
+  /* Someday, we should do better than this, by only blowing away
+     the things that really need to be blown.  */
+  clear_value_history ();
+  clear_displays ();
+  clear_internalvars ();
+  breakpoint_re_set ();
+  set_default_breakpoint (0, 0, 0, 0);
+  current_source_symtab = 0;
+  current_source_line = 0;
+}
+
 /* clear_symtab_users_once:
 
    This function is run after symbol reading, or from a cleanup.
@@ -1103,10 +1168,16 @@ allocate_psymtab (filename, objfile)
    reading, is because the cleanup protects us in case of errors, but is
    discarded if symbol reading is successful.  */
 
+#if 0
+/* FIXME:  As free_named_symtabs is currently a big noop this function
+   is no longer needed.  */
+static void
+clear_symtab_users_once PARAMS ((void));
+
 static int clear_symtab_users_queued;
 static int clear_symtab_users_done;
 
-void
+static void
 clear_symtab_users_once ()
 {
   /* Enforce once-per-`do_cleanups'-semantics */
@@ -1114,17 +1185,9 @@ clear_symtab_users_once ()
     return;
   clear_symtab_users_done = clear_symtab_users_queued;
 
-  printf ("Resetting debugger state after updating old symbol tables\n");
-
-  /* Someday, we should do better than this, by only blowing away
-     the things that really need to be blown.  */
-  clear_value_history ();
-  clear_displays ();
-  clear_internalvars ();
-  breakpoint_re_set ();
-  set_default_breakpoint (0, 0, 0, 0);
-  current_source_symtab = 0;
+  clear_symtab_users ();
 }
+#endif
 
 /* Delete the specified psymtab, and any others that reference it.  */
 
@@ -1132,7 +1195,7 @@ static void
 cashier_psymtab (pst)
      struct partial_symtab *pst;
 {
-  struct partial_symtab *ps, *pprev;
+  struct partial_symtab *ps, *pprev = NULL;
   int i;
 
   /* Find its previous psymtab in the chain */
@@ -1345,22 +1408,7 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
   SYMBOL_LANGUAGE (psym) = language;
   PSYMBOL_NAMESPACE (psym) = namespace;
   PSYMBOL_CLASS (psym) = class;
-  if (language == language_cplus)
-    {
-      demangled_name =
-       cplus_demangle (SYMBOL_NAME (psym), DMGL_PARAMS | DMGL_ANSI);
-      if (demangled_name == NULL)
-       {
-         SYMBOL_DEMANGLED_NAME (psym) = NULL;
-       }
-      else
-       {
-         SYMBOL_DEMANGLED_NAME (psym) =
-           obsavestring (demangled_name, strlen (demangled_name),
-                         &objfile->psymbol_obstack);
-         free (demangled_name);
-       }
-    }  
+  SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
 }
 
 /* Add a symbol with a CORE_ADDR value to a psymtab. */
@@ -1394,22 +1442,7 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
   SYMBOL_LANGUAGE (psym) = language;
   PSYMBOL_NAMESPACE (psym) = namespace;
   PSYMBOL_CLASS (psym) = class;
-  if (language == language_cplus)
-    {
-      demangled_name =
-       cplus_demangle (SYMBOL_NAME (psym), DMGL_PARAMS | DMGL_ANSI);
-      if (demangled_name == NULL)
-       {
-         SYMBOL_DEMANGLED_NAME (psym) = NULL;
-       }
-      else
-       {
-         SYMBOL_DEMANGLED_NAME (psym) =
-           obsavestring (demangled_name, strlen (demangled_name),
-                         &objfile->psymbol_obstack);
-         free (demangled_name);
-       }
-    }  
+  SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack);
 }
 
 #endif /* !INLINE_ADD_PSYMBOL */
@@ -1418,19 +1451,24 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
 void
 _initialize_symfile ()
 {
-
-  add_com ("symbol-file", class_files, symbol_file_command,
+  struct cmd_list_element *c;
+  
+  c = add_cmd ("symbol-file", class_files, symbol_file_command,
    "Load symbol table from executable file FILE.\n\
 The `file' command can also load symbol tables, as well as setting the file\n\
-to execute.");
+to execute.", &cmdlist);
+  c->completer = filename_completer;
 
-  add_com ("add-symbol-file", class_files, add_symbol_file_command,
+  c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
    "Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
-The second argument provides the starting address of the file's text.");
+The second argument provides the starting address of the file's text.",
+              &cmdlist);
+  c->completer = filename_completer;
 
-  add_com ("load", class_files, load_command,
+  c = add_cmd ("load", class_files, load_command,
    "Dynamically load FILE into the running program, and record its symbols\n\
-for access from GDB.");
+for access from GDB.", &cmdlist);
+  c->completer = filename_completer;
 
   add_show_from_set
     (add_set_cmd ("symbol-reloading", class_support, var_boolean,
This page took 0.029243 seconds and 4 git commands to generate.