The list of changes is too long to fit in the cvs log (since it truncates!).
[deliverable/binutils-gdb.git] / gdb / symfile.c
index d2f82552e983985342f9e0a6000af656e450f9e2..734d36a7641fd75da2e6dd50d6f3d99678a18cbb 100644 (file)
@@ -47,6 +47,7 @@ extern char *getenv ();
 /* Functions this file defines */
 static bfd *symfile_open();
 static struct sym_fns *symfile_init();
+static void clear_symtab_users_once();
 
 /* List of all available sym_fns.  */
 
@@ -81,7 +82,7 @@ char *symfile = 0;
 
 /* The modification date of the file when they were loaded.  */
 
-int symfile_mtime = 0;
+long /* really time_t */ symfile_mtime = 0;
 
 /* Structures with which to manage partial symbol allocation.  */
 
@@ -93,6 +94,14 @@ struct complaint complaint_root[1] = {
   {(char *)0, 0, complaint_root},
 };
 
+/* Some actual complaints.  */
+
+struct complaint oldsyms_complaint = {
+       "Replacing old symbols for `%s'", 0, 0 };
+
+struct complaint empty_symtab_complaint = {
+       "Empty symbol table found for `%s'", 0, 0 };
+
 \f
 /* In the following sort, we always make sure that
    register debug symbol declarations always come before regular
@@ -370,10 +379,11 @@ psymtab_to_symtab (pst)
 /* Process a symbol file, as either the main file or as a dynamically
    loaded file.
 
-   NAME is the file name (which will be tilde-expanded and made absolute
-   herein).  FROM_TTY says how verbose to be.  MAINLINE specifies whether
-   this is the main symbol file, or whether it's an extra symbol file
-   such as dynamically loaded code.  If !mainline, ADDR is the address
+   NAME is the file name (which will be tilde-expanded and made
+   absolute herein) (but we don't free or modify NAME itself).
+   FROM_TTY says how verbose to be.  MAINLINE specifies whether this
+   is the main symbol file, or whether it's an extra symbol file such
+   as dynamically loaded code.  If !mainline, ADDR is the address
    where the text segment was loaded.  */
 
 void
@@ -501,6 +511,10 @@ symbol_file_command (name, from_tty)
       return;
     }
 
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
+
   symbol_file_add (name, from_tty, (CORE_ADDR)0, 1);
 }
 
@@ -581,6 +595,7 @@ symfile_init (sym_bfd)
        }
     }
   error ("I'm sorry, Dave, I can't do that.  Symbol format unknown.");
+  return 0; /* Appease lint.  */
 }
 \f
 /* This function runs the load command of our current target.  */
@@ -596,15 +611,20 @@ load_command (arg, from_tty)
 /* This function runs the add_syms command of our current target.  */
 
 void
-add_syms_command (args, from_tty)
+add_symbol_file_command (args, from_tty)
      char *args;
      int from_tty;
 {
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
+
   target_add_syms (args, from_tty);
 }
 
 /* This function allows the addition of incrementally linked object files.  */
 
+/* ARGSUSED */
 void
 add_syms_addr_command (arg_string, from_tty)
      char* arg_string;
@@ -614,7 +634,7 @@ add_syms_addr_command (arg_string, from_tty)
   CORE_ADDR text_addr;
   
   if (arg_string == 0)
-    error ("add-syms takes a file name and an address");
+    error ("add-symbol-file takes a file name and an address");
 
   arg_string = tilde_expand (arg_string);
   make_cleanup (free, arg_string);
@@ -625,7 +645,7 @@ add_syms_addr_command (arg_string, from_tty)
   *arg_string++ = (char) 0;
 
   if (name[0] == 0)
-    error ("add-syms takes a file name and an address");
+    error ("add-symbol-file takes a file name and an address");
 
   text_addr = parse_and_eval_address (arg_string);
 
@@ -663,18 +683,28 @@ reread_symbols ()
     }
 }
 
-
 /* This function is really horrible, but to avoid it, there would need
    to be more filling in of forward references.  */
-int
+void
 fill_in_vptr_fieldno (type)
      struct type *type;
 {
-  check_stub_type (type);
   if (TYPE_VPTR_FIELDNO (type) < 0)
-    TYPE_VPTR_FIELDNO (type) =
-      fill_in_vptr_fieldno (TYPE_BASECLASS (type, 1));
-  return TYPE_VPTR_FIELDNO (type);
+    {
+      int i;
+      for (i = 1; i < TYPE_N_BASECLASSES (type); i++)
+       {
+         fill_in_vptr_fieldno (TYPE_BASECLASS (type, i));
+         if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0)
+           {
+             TYPE_VPTR_FIELDNO (type)
+               = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i));
+             TYPE_VPTR_BASETYPE (type)
+               = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i));
+             break;
+           }
+       }
+    }
 }
 \f
 /* Functions to handle complaints during symbol reading.  */
@@ -723,6 +753,183 @@ clear_complaints ()
     p->counter = 0;
 }
 \f
+/* clear_symtab_users_once:
+
+   This function is run after symbol reading, or from a cleanup.
+   If an old symbol table was obsoleted, the old symbol table
+   has been blown away, but the other GDB data structures that may 
+   reference it have not yet been cleared or re-directed.  (The old
+   symtab was zapped, and the cleanup queued, in free_named_symtab()
+   below.)
+
+   This function can be queued N times as a cleanup, or called
+   directly; it will do all the work the first time, and then will be a
+   no-op until the next time it is queued.  This works by bumping a
+   counter at queueing time.  Much later when the cleanup is run, or at
+   the end of symbol processing (in case the cleanup is discarded), if
+   the queued count is greater than the "done-count", we do the work
+   and set the done-count to the queued count.  If the queued count is
+   less than or equal to the done-count, we just ignore the call.  This
+   is needed because reading a single .o file will often replace many
+   symtabs (one per .h file, for example), and we don't want to reset
+   the breakpoints N times in the user's face.
+
+   The reason we both queue a cleanup, and call it directly after symbol
+   reading, is because the cleanup protects us in case of errors, but is
+   discarded if symbol reading is successful.  */
+
+static int clear_symtab_users_queued;
+static int clear_symtab_users_done;
+
+static void
+clear_symtab_users_once ()
+{
+  /* Enforce once-per-`do_cleanups'-semantics */
+  if (clear_symtab_users_queued <= clear_symtab_users_done)
+    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;
+}
+
+/* Delete the specified psymtab, and any others that reference it.  */
+
+static void
+cashier_psymtab (pst)
+     struct partial_symtab *pst;
+{
+  struct partial_symtab *ps, *pprev;
+  int i;
+
+  /* Find its previous psymtab in the chain */
+  for (ps = partial_symtab_list; ps; ps = ps->next) {
+    if (ps == pst)
+      break;
+    pprev = ps;
+  }
+
+  if (ps) {
+    /* Unhook it from the chain.  */
+    if (ps == partial_symtab_list)
+      partial_symtab_list = ps->next;
+    else
+      pprev->next = ps->next;
+
+    /* FIXME, we can't conveniently deallocate the entries in the
+       partial_symbol lists (global_psymbols/static_psymbols) that
+       this psymtab points to.  These just take up space until all
+       the psymtabs are reclaimed.  Ditto the dependencies list and
+       filename, which are all in the psymbol_obstack.  */
+
+    /* We need to cashier any psymtab that has this one as a dependency... */
+again:
+    for (ps = partial_symtab_list; ps; ps = ps->next) {
+      for (i = 0; i < ps->number_of_dependencies; i++) {
+       if (ps->dependencies[i] == pst) {
+         cashier_psymtab (ps);
+         goto again;           /* Must restart, chain has been munged. */
+       }
+      }
+    }
+  }
+}
+
+/* If a symtab or psymtab for filename NAME is found, free it along
+   with any dependent breakpoints, displays, etc.
+   Used when loading new versions of object modules with the "add-file"
+   command.  This is only called on the top-level symtab or psymtab's name;
+   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.  I think this is not the best way to do this.  We should
+   work on being gentler to the environment while still cleaning up
+   all stray pointers into the freed symtab.  */
+
+int
+free_named_symtabs (name)
+     char *name;
+{
+  register struct symtab *s;
+  register struct symtab *prev;
+  register struct partial_symtab *ps;
+  struct blockvector *bv;
+  int blewit = 0;
+
+  /* Look for a psymtab with the specified name.  */
+
+again2:
+  for (ps = partial_symtab_list; ps; ps = ps->next) {
+    if (!strcmp (name, ps->filename)) {
+      cashier_psymtab (ps);    /* Blow it away...and its little dog, too.  */
+      goto again2;             /* Must restart, chain has been munged */
+    }
+  }
+
+  /* Look for a symtab with the specified name.  */
+
+  for (s = symtab_list; s; s = s->next)
+    {
+      if (!strcmp (name, s->filename))
+       break;
+      prev = s;
+    }
+
+  if (s)
+    {
+      if (s == symtab_list)
+       symtab_list = s->next;
+      else
+       prev->next = s->next;
+
+      /* For now, queue a delete for all breakpoints, displays, etc., whether
+        or not they depend on the symtab being freed.  This should be
+        changed so that only those data structures affected are deleted.  */
+
+      /* But don't delete anything if the symtab is empty.
+        This test is necessary due to a bug in "dbxread.c" that
+        causes empty symtabs to be created for N_SO symbols that
+        contain the pathname of the object file.  (This problem
+        has been fixed in GDB 3.9x).  */
+
+      bv = BLOCKLIST (s);
+      if (BLOCKLIST_NBLOCKS (bv) > 2
+         || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
+         || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
+       {
+         complain (&oldsyms_complaint, name);
+
+         clear_symtab_users_queued++;
+         make_cleanup (clear_symtab_users_once, 0);
+         blewit = 1;
+       } else {
+         complain (&empty_symtab_complaint, name);
+       }
+
+      free_symtab (s);
+    }
+  else
+    /* It is still possible that some breakpoints will be affected
+       even though no symtab was found, since the file might have
+       been compiled without debugging, and hence not be associated
+       with a symtab.  In order to handle this correctly, we would need
+       to keep a list of text address ranges for undebuggable files.
+       For now, we do nothing, since this is a fairly obscure case.  */
+    ;
+
+  /* FIXME, what about the misc function vector? */
+  return blewit;
+}
+\f
 void
 _initialize_symfile ()
 {
@@ -732,7 +939,7 @@ _initialize_symfile ()
 The `file' command can also load symbol tables, as well as setting the file\n\
 to execute.");
 
-  add_com ("add-syms", class_files, add_syms_command,
+  add_com ("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.");
 
This page took 0.027496 seconds and 4 git commands to generate.