* symfile.c (reread_symbols): When re-reading symbols, do all the
authorJim Kingdon <jkingdon@engr.sgi.com>
Sat, 30 Oct 1993 20:21:19 +0000 (20:21 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Sat, 30 Oct 1993 20:21:19 +0000 (20:21 +0000)
right operations ourself, rather than calling symbol_file_command.
If we re-read something, call clear_symtab_users not just
breakpoint_re_set.
* objfiles.h, objfiles.c (build_objfile_section_table): No longer
static.
* symfile.c (clear_symtab_users): Call clear_pc_function_cache.
* coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c
(*_symfile_offsets): Set objfile->num_sections.
* remote.c (remote_wait), symfile.c (syms_from_objfile):
Don't muck with objfile->num_sections now that all the symbol
readers set it.
* elfread.c: Clean up obsolete comment about handling only DWARF.
* paread.c: Remove comment about how we should use an "ordinary"
file format with an hppa suffix.  There is nothing ordinary about SOM.

gdb/ChangeLog
gdb/coffread.c
gdb/dbxread.c
gdb/elfread.c
gdb/mipsread.c
gdb/nlmread.c
gdb/objfiles.c
gdb/objfiles.h
gdb/paread.c
gdb/remote.c
gdb/symfile.c

index 1788c7f959f9719ffafb2ff976f2bd5e9f07b581..11a21e1327a17b1537e8f54ef995238341bfbc49 100644 (file)
@@ -1,3 +1,25 @@
+Sat Oct 30 08:32:53 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+       * symfile.c (reread_symbols): When re-reading symbols, do all the
+       right operations ourself, rather than calling symbol_file_command.
+       If we re-read something, call clear_symtab_users not just
+       breakpoint_re_set.
+       * objfiles.h, objfiles.c (build_objfile_section_table): No longer
+       static.
+       * symfile.c (clear_symtab_users): Call clear_pc_function_cache.
+       * coffread.c, dbxread.c, elfread.c, mipsread.c, nlmread.c, paread.c
+       (*_symfile_offsets): Set objfile->num_sections.
+       * remote.c (remote_wait), symfile.c (syms_from_objfile):
+       Don't muck with objfile->num_sections now that all the symbol
+       readers set it.
+       * elfread.c: Clean up obsolete comment about handling only DWARF.
+       * paread.c: Remove comment about how we should use an "ordinary"
+       file format with an hppa suffix.  There is nothing ordinary about SOM.
+
+       * config/i386/{i386m3.mh,i386mk.mh}, config/mips/mipsm3.mh,
+       config/ns32k/ns32km3.mh: Change MMALLOC_LIB to MMALLOC.
+       * TODO: Update Mach stuff.
+
 Fri Oct 29 16:30:36 1993  Stan Shebs  (shebs@rtl.cygnus.com)
 
        LynxOS support:
index 48b3ca5b6be861b31493952d3e21bca2804451f9..102d752fcd9e33ea6c6c33e1c8b9bc81123a57a7 100644 (file)
@@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "objfiles.h"
 #include "buildsym.h"
 #include "gdb-stabs.h"
+#include "stabsread.h"
 #include "complaints.h"
 #include <obstack.h>
 
@@ -2044,11 +2045,12 @@ coff_symfile_offsets (objfile, addr)
 {
   struct section_offsets *section_offsets;
   int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile -> psymbol_obstack,
-                  sizeof (struct section_offsets) +
-                         sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+                  sizeof (struct section_offsets)
+                  + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
 
   for (i = 0; i < SECT_OFF_MAX; i++)
     ANOFFSET (section_offsets, i) = addr;
index 9d1a423607f7f94899a702237a253363fd8ef19f..d423eec5e6e4e0aaf63e2ee410e3b44ea08caa97 100644 (file)
@@ -212,9 +212,6 @@ free_header_files PARAMS ((void));
 static void
 init_header_files PARAMS ((void));
 
-static struct pending *
-copy_pending PARAMS ((struct pending *, int, struct pending *));
-
 static void
 read_ofile_symtab PARAMS ((struct partial_symtab *));
 
@@ -1547,7 +1544,7 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
 
   /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
      file.  Used to detect the SunPRO solaris compiler.  */
-  int n_opt_found;
+  static int n_opt_found;
 
   /* The stab type used for the definition of the last function.
      N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers.  */
@@ -1763,52 +1760,12 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
       break;
 
     case N_BCOMM:
-      if (common_block)
-       {
-         /* Note: this does not detect nesting if the previous N_BCOMM
-            was at the beginning of a scope (and thus common_block was
-            NULL).  Not necessarily worth worrying about unless we run
-            into a compiler which actually has this bug.  */
-         static struct complaint msg = {
-           "Invalid symbol data: common within common at symtab pos %d",
-           0, 0};
-         complain (&msg, symnum);
-       }
-      common_block = local_symbols;
-      common_block_i = local_symbols ? local_symbols->nsyms : 0;
+      common_block_start (name, objfile);
       break;
 
     case N_ECOMM:
-
-      /* Symbols declared since the BCOMM are to have the common block
-        start address added in when we know it.  common_block and
-        common_block_i point to the first symbol after the BCOMM in
-        the local_symbols list; copy the list and hang it off the
-        symbol for the common block name for later fixup.  */
-
-      /* If there is a N_ECOMM unmatched by a N_BCOMM, we treat all
-        the local_symbols as part of the common block.  It might be
-        better to just ignore the N_ECOMM, but then we'd need to
-        distinguish between a N_BCOMM at the start of a scope, or no
-        N_BCOMM at all (currently they both have common_block NULL).
-        Not necessarily worth worrying about unless we run into a
-        compiler which actually has this bug.  */
-
-      {
-       int i;
-       struct symbol *sym =
-         (struct symbol *) xmmalloc (objfile -> md, sizeof (struct symbol));
-       memset (sym, 0, sizeof *sym);
-       SYMBOL_NAME (sym) = savestring (name, strlen (name));
-       SYMBOL_CLASS (sym) = LOC_BLOCK;
-       SYMBOL_NAMESPACE (sym) = (enum namespace)((long)
-         copy_pending (local_symbols, common_block_i, common_block));
-       i = hashname (SYMBOL_NAME (sym));
-       SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
-       global_sym_chain[i] = sym;
-       common_block = 0;
-       break;
-      }
+      common_block_end (objfile);
+      break;
 
     /* The following symbol types need to have the appropriate offset added
        to their value; then we process symbol definitions in the name.  */
@@ -1816,28 +1773,23 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
     case N_STSYM:              /* Static symbol in data seg */
     case N_LCSYM:              /* Static symbol in BSS seg */
     case N_ROSYM:              /* Static symbol in Read-only data seg */
-     /* HORRID HACK DEPT.  However, it's Sun's furgin' fault.  FIXME.
-       Solaris2's stabs-in-coff makes *most* symbols relative
-       but leaves a few absolute.  N_STSYM and friends sit on the fence.
+     /* HORRID HACK DEPT.  However, it's Sun's furgin' fault.
+       Solaris2's stabs-in-elf makes *most* symbols relative
+       but leaves a few absolute (at least for Solaris 2.1 and version
+       2.0.1 of the SunPRO compiler).  N_STSYM and friends sit on the fence.
        .stab "foo:S...",N_STSYM        is absolute (ld relocates it)
        .stab "foo:V...",N_STSYM        is relative (section base subtracted).
        This leaves us no choice but to search for the 'S' or 'V'...
        (or pass the whole section_offsets stuff down ONE MORE function
-       call level, which we really don't want to do).
-
-       The above is indeed true for Solaris 2.1.  I'm not sure what
-       happens in Solaris 2.3, in which ld stops relocating stabs.  */
+       call level, which we really don't want to do).  */
       {
        char *p;
        p = strchr (name, ':');
        if (p != 0 && p[1] == 'S')
          {
-           /* FIXME!  We relocate it by the TEXT offset, in case the
-              whole module moved in memory.  But this is wrong, since
-              the sections can side around independently.  (I suspect that
-              the text offset is always zero anyway--elfread.c doesn't
-              process (and Sun cc doesn't produce) Ttext.text symbols).  */
-           valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+           /* The linker relocated it.  There used to be a kludge here
+              to add the text offset, but that will break if we ever
+              start using the text offset (currently it is always zero).  */
            goto define_a_symbol;
          }
        /* Since it's not the kludge case, re-dispatch to the right handler. */
@@ -2026,36 +1978,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
   previous_stab_code = type;
 }
 \f
-/* Copy a pending list, used to record the contents of a common
-   block for later fixup.  We copy the symbols starting with all
-   symbols in BEG, and ending with the symbols which are in 
-   END at index ENDI.  */
-static struct pending *
-copy_pending (beg, endi, end)
-    struct pending *beg;
-    int endi;
-    struct pending *end;
-{
-  struct pending *new = 0;
-  struct pending *next;
-  int j;
-
-  /* Copy all the struct pendings before end.  */
-  for (next = beg; next != NULL && next != end; next = next->next)
-    {
-      for (j = 0; j < next->nsyms; j++)
-       add_symbol_to_list (next->symbol[j], &new);
-    }
-
-  /* Copy however much of END we need.  If END is NULL, it means copy
-     all the local symbols (which we already did above).  */
-  if (end != NULL)
-    for (j = endi; j < end->nsyms; j++)
-      add_symbol_to_list (end->symbol[j], &new);
-
-  return new;
-}
-\f
 /* FIXME: The only difference between this and elfstab_build_psymtabs is
    the call to install_minimal_symbols for elf.  If the differences are
    really that small, the code should be shared.  */
@@ -2253,11 +2175,12 @@ dbx_symfile_offsets (objfile, addr)
 {
   struct section_offsets *section_offsets;
   int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile -> psymbol_obstack,
-                  sizeof (struct section_offsets) +
-                         sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+                  sizeof (struct section_offsets)
+                  + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
 
   for (i = 0; i < SECT_OFF_MAX; i++)
     ANOFFSET (section_offsets, i) = addr;
index 230afecefb2ef5ee4ef0d64381b6af5d4fff2fec..bbf4655fd26b02a2862e635e35c34919c4aad15f 100644 (file)
@@ -615,15 +615,16 @@ elf_symfile_offsets (objfile, addr)
 {
   struct section_offsets *section_offsets;
   int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile -> psymbol_obstack,
-                  sizeof (struct section_offsets) +
-                         sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+                  sizeof (struct section_offsets)
+                  + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
 
   for (i = 0; i < SECT_OFF_MAX; i++)
     ANOFFSET (section_offsets, i) = addr;
-  
+
   return section_offsets;
 }
 \f
@@ -694,21 +695,7 @@ elfstab_offset_sections (objfile, pst)
     complain (&stab_info_mismatch_complaint, filename);
 }
 \f
-/*  Register that we are able to handle ELF object file formats and DWARF
-    debugging formats.
-
-    Unlike other object file formats, where the debugging information format
-    is implied by the object file format, the ELF object file format and the
-    DWARF debugging information format are two distinct, and potentially
-    separate entities.  I.E. it is perfectly possible to have ELF objects
-    with debugging formats other than DWARF.  And it is conceivable that the
-    DWARF debugging format might be used with another object file format,
-    like COFF, by simply using COFF's custom section feature.
-
-    GDB, and to a lesser extent BFD, should support the notion of separate
-    object file formats and debugging information formats.  For now, we just
-    use "elf" in the same sense as "a.out" or "coff", to imply both the ELF
-    object file format and the DWARF debugging format. */
+/* Register that we are able to handle ELF object file formats.  */
 
 static struct sym_fns elf_sym_fns =
 {
index f7087a6f8ec0d3a007b2b1f7e6a4c3f8ccc80bf9..eb19789c67bc5d5cf162d67a86896dcaf5549cc4 100644 (file)
@@ -183,9 +183,6 @@ struct complaint unknown_type_qual_complaint =
 struct complaint array_index_type_complaint =
 {"illegal array index type for %s, assuming int", 0, 0};
 
-struct complaint array_bitsize_complaint =
-{"size of array target type for %s not known, assuming %d bits", 0, 0};
-
 struct complaint bad_tag_guess_complaint =
 {"guessed tag type of %s incorrectly", 0, 0};
 
@@ -590,7 +587,15 @@ static struct parse_stack
   struct parse_stack *next, *prev;
   struct symtab *cur_st;       /* Current symtab. */
   struct block *cur_block;     /* Block in it. */
-  int blocktype;               /* What are we parsing. */
+
+  /* What are we parsing.  stFile, or stBlock are for files and
+     blocks.  stProc or stStaticProc means we have seen the start of a
+     procedure, but not the start of the block within in.  When we see
+     the start of that block, we change it to stNil, without pushing a
+     new block, i.e. stNil means both a procedure and a block.  */
+
+  int blocktype;
+
   int maxsyms;                 /* Max symbols in this block. */
   struct type *cur_type;       /* Type we parse fields for. */
   int cur_field;               /* Field number in cur_type. */
@@ -1134,6 +1139,17 @@ parse_symbol (sh, ax, ext_sh, bigend)
       /* beginnning of (code) block. Value of symbol
         is the displacement from procedure start */
       push_parse_stack ();
+
+      /* Do not start a new block if this is the outermost block of a
+        procedure.  This allows the LOC_BLOCK symbol to point to the
+        block with the local variables, so funcname::var works.  */
+      if (top_stack->blocktype == stProc
+         || top_stack->blocktype == stStaticProc)
+       {
+         top_stack->blocktype = stNil;
+         break;
+       }
+
       top_stack->blocktype = stBlock;
       b = new_block (top_stack->maxsyms);
       BLOCK_START (b) = sh->value + top_stack->procadr;
@@ -1197,6 +1213,12 @@ parse_symbol (sh, ax, ext_sh, bigend)
          BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr;
          shrink_block (top_stack->cur_block, top_stack->cur_st);
        }
+      else if (sh->sc == scText && top_stack->blocktype == stNil)
+       {
+         /* End of outermost block.  Pop parse stack and ignore.  The
+            following stEnd of stProc will take care of the block.  */
+         ;
+       }
       else if (sh->sc == scText && top_stack->blocktype == stFile)
        {
          /* End of file.  Pop parse stack and ignore.  Higher
@@ -1676,20 +1698,19 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name)
 
       t = create_array_type ((struct type *) NULL, *tpp, range);
 
-      /* Check whether supplied array element bit size matches
-        the known size of the element type.  If this complaint
-        ends up not happening, we can remove this code.  It's
-        here because we aren't sure we understand this *&%&$
-        symbol format.  */
-      id = TYPE_LENGTH (TYPE_TARGET_TYPE (t)) << 3;    /* bitsize */
-      if (id == 0)
-       {
-         /* Most likely an undefined type */
-         id = rf;
-         TYPE_LENGTH (TYPE_TARGET_TYPE (t)) = id >> 3;
-       }
-      if (id != rf)
-       complain (&array_bitsize_complaint, sym_name, rf);
+      /* We used to fill in the supplied array element bitsize
+        here if the TYPE_LENGTH of the target type was zero.
+        This happens for a `pointer to an array of anonymous structs',
+        but in this case the array element bitsize is also zero,
+        so nothing is gained.
+        And we used to check the TYPE_LENGTH of the target type against
+        the supplied array element bitsize.
+        gcc causes a mismatch for `pointer to array of object',
+        since the sdb directives it uses do not have a way of
+        specifying the bitsize, but it does no harm (the
+        TYPE_LENGTH should be correct) and we should be able to
+        ignore the erroneous bitsize from the auxiliary entry safely.
+        dbx seems to ignore it too.  */
 
       *tpp = t;
       return 4 + off;
@@ -3595,6 +3616,7 @@ mipscoff_symfile_offsets (objfile, addr)
   struct section_offsets *section_offsets;
   int i;
 
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = ((struct section_offsets *)
                     obstack_alloc (&objfile->psymbol_obstack,
                                    (sizeof (struct section_offsets)
index 70328c9f4e6600ec65880facd197ff8778f56933..2ce4c2e277004ffd7de3f07124720675c1f04dee 100644 (file)
@@ -266,7 +266,8 @@ nlm_symfile_offsets (objfile, addr)
 {
   struct section_offsets *section_offsets;
   int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile -> psymbol_obstack,
                   sizeof (struct section_offsets) +
@@ -281,7 +282,7 @@ nlm_symfile_offsets (objfile, addr)
 }
 
 \f
-/*  Register that we are able to handle NLM file format. */
+/* Register that we are able to handle NLM file format. */
 
 static struct sym_fns nlm_sym_fns =
 {
index b890657c99efe1d922d1be48180ee3173f7f11c2..dfac45e8cff0264535800947e418e66c3418b02f 100644 (file)
@@ -92,9 +92,10 @@ add_to_objfile_sections (abfd, asect, objfile_p_char)
 }
 
 /* Builds a section table for OBJFILE.
-   Returns 0 if OK, 1 on error.  */
+   Returns 0 if OK, 1 on error (in which case bfd_error contains the
+   error).  */
 
-static int
+int
 build_objfile_section_table (objfile)
      struct objfile *objfile;
 {
@@ -356,6 +357,8 @@ free_objfile (objfile)
       (t->to_detach) (NULL, 0);
   }
 #endif
+  /* I *think* all our callers call clear_symtab_users.  If so, no need
+     to call this here.  */
   clear_pc_function_cache ();
 
   /* The last thing we do is free the objfile struct itself for the
index 50226ff47e779ffeceddf033b4103155799fcf0d..b5b06223728b3b432033e5078ff6e937922ca554 100644 (file)
@@ -357,14 +357,13 @@ extern struct objfile *object_files;
 
 /* Declarations for functions defined in objfiles.c */
 
-extern struct objfile *
-allocate_objfile PARAMS ((bfd *, int));
+extern struct objfile *allocate_objfile PARAMS ((bfd *, int));
 
-extern void
-unlink_objfile PARAMS ((struct objfile *));
+int build_objfile_section_table PARAMS ((struct objfile *));
 
-extern void
-free_objfile PARAMS ((struct objfile *));
+extern void unlink_objfile PARAMS ((struct objfile *));
+
+extern void free_objfile PARAMS ((struct objfile *));
 
 extern void
 free_all_objfiles PARAMS ((void));
index c79ddb538b59756d57205d3337ee33cfc45e160f..95489d925bb5edd3c35160d06f8861d0a86c63d9 100644 (file)
@@ -487,22 +487,22 @@ pa_symfile_offsets (objfile, addr)
 {
   struct section_offsets *section_offsets;
   int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
   section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile -> psymbol_obstack,
-                  sizeof (struct section_offsets) +
-                         sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
+                  sizeof (struct section_offsets)
+                  + sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
 
   for (i = 0; i < SECT_OFF_MAX; i++)
     ANOFFSET (section_offsets, i) = addr;
-  
+
   return section_offsets;
 }
 \f
-/*  Register that we are able to handle PA object file formats. */
+/* Register that we are able to handle SOM object file formats (does this
+   work for hp300, or just PA?  I suspect the latter).  */
 
-/* This is probably a mistake.  FIXME.  Why can't the HP's use an ordinary
-   file format name with an -hppa suffix?  */
 static struct sym_fns pa_sym_fns =
 {
   "som",               /* sym_name: name or name prefix of BFD target type */
index 189977ddb9698e9c21aa8d7ff23a98236b758a44..6fffc54c7f80c8ffa40a9ea8babfeb97385a04e0 100644 (file)
@@ -228,7 +228,12 @@ int icache;
    starts.  */
 serial_t remote_desc = NULL;
 
-#define        PBUFSIZ 1024
+/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
+   and i386-stub.c.  Normally, no one would notice because it only matters
+   for writing large chunks of memory (e.g. in downloads).  Also, this needs
+   to be more than 400 if required to hold the registers (see below, where
+   we round it up based on REGISTER_BYTES).  */
+#define        PBUFSIZ 400
 
 /* Maximum number of bytes to read/write at once.  The value here
    is chosen to fill up a packet (the headers account for the 32).  */
@@ -560,12 +565,6 @@ remote_wait (pid, status)
                 stuff.  (Just what does "text" as seen by the stub
                 mean, anyway?).  */
 
-             /* FIXME: Why don't the various symfile_offsets routines
-                in the sym_fns vectors set this?
-                (no good reason -kingdon).  */
-             if (symfile_objfile->num_sections == 0)
-               symfile_objfile->num_sections = SECT_OFF_MAX;
-
              offs = ((struct section_offsets *)
                      alloca (sizeof (struct section_offsets)
                              + (symfile_objfile->num_sections
@@ -798,9 +797,6 @@ remote_write_bytes (memaddr, myaddr, len)
   int i;
   char *p;
 
-  if (len > PBUFSIZ / 2 - 20)
-    abort ();
-
   sprintf (buf, "M%x,%x:", memaddr, len);
 
   /* We send target system values byte by byte, in increasing byte addresses,
index c2ea7dcad2a9974ba66b9c8503a4a32ac88d0a9c..5dbcbfa48748140a00683a783985307fb7d89ec4 100644 (file)
@@ -32,6 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "language.h"
 #include "complaints.h"
 #include "demangle.h"
+#include "inferior.h" /* for write_pc */
 
 #include <obstack.h>
 #include <assert.h>
@@ -214,21 +215,6 @@ sort_symtab_syms (s)
     }
 }
 
-void
-sort_all_symtab_syms ()
-{
-  register struct symtab *s;
-  register struct objfile *objfile;
-
-  for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
-    {
-      for (s = objfile -> symtabs; s != NULL; s = s -> next)
-       {
-         sort_symtab_syms (s);
-       }
-    }
-}
-
 /* Make a copy of the string at PTR with SIZE characters in the symbol obstack
    (and add a null character at the end in the copy).
    Returns the address of the copy.  */
@@ -317,6 +303,14 @@ init_entry_point_info (objfile)
     }
 }
 
+/* Get current entry point address.  */
+
+CORE_ADDR
+entry_point_address()
+{
+  return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
+}
+
 /* Remember the lowest-addressed loadable section we've seen.  
    This function is called via bfd_map_over_sections.  */
 
@@ -410,10 +404,10 @@ syms_from_objfile (objfile, addr, mainline, verbo)
       else if (0 == bfd_get_section_name (objfile->obfd, lowest_sect)
               || !STREQ (".text",
                              bfd_get_section_name (objfile->obfd, lowest_sect)))
-       warning ("Lowest section in %s is %s at 0x%x",
+       warning ("Lowest section in %s is %s at 0x%lx",
                 objfile->name,
                 bfd_section_name (objfile->obfd, lowest_sect),
-                bfd_section_vma (objfile->obfd, lowest_sect));
+                (unsigned long) bfd_section_vma (objfile->obfd, lowest_sect));
 
       if (lowest_sect)
        addr -= bfd_section_vma (objfile->obfd, lowest_sect);
@@ -426,9 +420,6 @@ syms_from_objfile (objfile, addr, mainline, verbo)
   (*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;
 
@@ -468,8 +459,10 @@ syms_from_objfile (objfile, addr, mainline, verbo)
 
   (*objfile -> sf -> sym_read) (objfile, section_offsets, mainline);
 
-  /* Don't allow char * to have a typename (else would get caddr_t.)  */
-  /* Ditto void *.  FIXME should do this for all the builtin types.  */
+  /* Don't allow char * to have a typename (else would get caddr_t).
+     Ditto void *.  FIXME: Check whether this is now done by all the
+     symbol readers themselves (many of them now do), and if so remove
+     it from here.  */
 
   TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
   TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0;
@@ -871,9 +864,9 @@ generic_load (filename, from_tty)
 
              /* 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",
+             printf_filtered ("Loading section %s, size 0x%lx vma 0x%lx\n",
                               bfd_get_section_name (loadfile_bfd, s),
-                              size, vma);
+                              (unsigned long) size, (unsigned long) vma);
 
              bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
 
@@ -967,7 +960,7 @@ add_symbol_file_command (args, from_tty)
   text_addr = parse_and_eval_address (args);
 
   if (!query ("add symbol table from file \"%s\" at text_addr = %s?\n",
-             name, local_hex_string (text_addr)))
+             name, local_hex_string ((unsigned long)text_addr)))
     error ("Not confirmed.");
 
   symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
@@ -989,7 +982,6 @@ reread_symbols ()
      This routine should then walk down each partial symbol table
      and see if the symbol table that it originates from has been changed */
 
-the_big_top:
   for (objfile = object_files; objfile; objfile = objfile->next) {
     if (objfile->obfd) {
 #ifdef IBM6000_TARGET
@@ -1008,24 +1000,142 @@ the_big_top:
        continue;
       }
       new_modtime = new_statbuf.st_mtime;
-      if (new_modtime != objfile->mtime) {
-       printf_filtered ("`%s' has changed; re-reading symbols.\n",
-                        objfile->name);
-       /* FIXME, this should use a different command...that would only
-          affect this objfile's symbols, and would reset objfile->mtime.
-                (objfile->mtime = new_modtime;)
-          HOWEVER, that command isn't written yet -- so call symbol_file_
-          command, and restart the scan from the top, because it munges
-          the object_files list.  */
-       symbol_file_command (objfile->name, 0);
-       reread_one = 1;
-       goto the_big_top;       /* Start over.  */
-      }
+      if (new_modtime != objfile->mtime)
+       {
+         struct cleanup *old_cleanups;
+         struct section_offsets *offsets;
+         int num_offsets;
+         int section_offsets_size;
+
+         printf_filtered ("`%s' has changed; re-reading symbols.\n",
+                          objfile->name);
+
+         /* There are various functions like symbol_file_add,
+            symfile_bfd_open, syms_from_objfile, etc., which might
+            appear to do what we want.  But they have various other
+            effects which we *don't* want.  So we just do stuff
+            ourselves.  We don't worry about mapped files (for one thing,
+            any mapped file will be out of date).  */
+
+         /* If we get an error, blow away this objfile (not sure if
+            that is the correct response for things like shared
+            libraries).  */
+         old_cleanups = make_cleanup (free_objfile, objfile);
+         /* We need to do this whenever any symbols go away.  */
+         make_cleanup (clear_symtab_users, 0);
+
+         /* 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.  */
+         if (!bfd_close (objfile->obfd))
+           error ("Can't close BFD for %s.", objfile->name);
+         objfile->obfd = bfd_openr (objfile->name, 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 (!bfd_check_format (objfile->obfd, bfd_object))
+           error ("Can't read symbols from %s: %s.", objfile->name,
+                  bfd_errmsg (bfd_error));
+
+         /* Save the offsets, we will nuke them with the rest of the
+            psymbol_obstack.  */
+         num_offsets = objfile->num_sections;
+         section_offsets_size =
+           sizeof (struct section_offsets)
+             + sizeof (objfile->section_offsets->offsets) * num_offsets;
+         offsets = (struct section_offsets *) alloca (section_offsets_size);
+         memcpy (offsets, objfile->section_offsets, section_offsets_size);
+
+         /* Nuke all the state that we will re-read.  Much of the following
+            code which sets things to NULL really is necessary to tell
+            other parts of GDB that there is nothing currently there.  */
+
+         /* FIXME: Do we have to free a whole linked list, or is this
+            enough?  */
+         if (objfile->global_psymbols.list)
+           mfree (objfile->md, objfile->global_psymbols.list);
+         objfile->global_psymbols.list = NULL;
+         objfile->global_psymbols.size = 0;
+         if (objfile->static_psymbols.list)
+           mfree (objfile->md, objfile->static_psymbols.list);
+         objfile->static_psymbols.list = NULL;
+         objfile->static_psymbols.size = 0;
+
+         /* Free the obstacks for non-reusable objfiles */
+         obstack_free (&objfile -> psymbol_obstack, 0);
+         obstack_free (&objfile -> symbol_obstack, 0);
+         obstack_free (&objfile -> type_obstack, 0);
+         objfile->sections = NULL;
+         objfile->symtabs = NULL;
+         objfile->psymtabs = NULL;
+         objfile->free_psymtabs = NULL;
+         objfile->msymbols = NULL;
+         objfile->minimal_symbol_count= 0;
+         objfile->fundamental_types = NULL;
+         if (objfile -> sf != NULL)
+           {
+             (*objfile -> sf -> sym_finish) (objfile);
+           }
+
+         /* We never make this a mapped file.  */
+         objfile -> md = NULL;
+         /* obstack_specify_allocation also initializes the obstack so
+            it is empty.  */
+         obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0,
+                                     xmalloc, free);
+         obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0,
+                                     xmalloc, free);
+         obstack_specify_allocation (&objfile -> type_obstack, 0, 0,
+                                     xmalloc, free);
+         if (build_objfile_section_table (objfile))
+           {
+             error ("Can't find the file sections in `%s': %s", 
+                    objfile -> name, bfd_errmsg (bfd_error));
+           }
+
+         /* We use the same section offsets as from last time.  I'm not
+            sure whether that is always correct for shared libraries.  */
+         objfile->section_offsets = (struct section_offsets *)
+           obstack_alloc (&objfile -> psymbol_obstack, section_offsets_size);
+         memcpy (objfile->section_offsets, offsets, section_offsets_size);
+         objfile->num_sections = num_offsets;
+
+         /* What the hell is sym_new_init for, anyway?  The concept of
+            distinguishing between the main file and additional files
+            in this way seems rather dubious.  */
+         if (objfile == symfile_objfile)
+           (*objfile->sf->sym_new_init) (objfile);
+
+         (*objfile->sf->sym_init) (objfile);
+         clear_complaints (1, 1);
+         /* The "mainline" parameter is a hideous hack; I think leaving it
+            zero is OK since dbxread.c also does what it needs to do if
+            objfile->global_psymbols.size is 0.  */
+         (*objfile->sf->sym_read) (objfile, objfile->section_offsets, 0);
+         objfile -> flags |= OBJF_SYMS;
+
+         /* We're done reading the symbol file; finish off complaints.  */
+         clear_complaints (0, 1);
+
+         /* Getting new symbols may change our opinion about what is
+            frameless.  */
+
+         reinit_frame_cache ();
+
+         /* Discard cleanups as symbol reading was successful.  */
+         discard_cleanups (old_cleanups);
+
+         /* If the mtime has changed between the time we set new_modtime
+            and now, we *want* this to be out of date, so don't call stat
+            again now.  */
+         objfile->mtime = new_modtime;
+         reread_one = 1;
+       }
     }
   }
 
   if (reread_one)
-    breakpoint_re_set ();
+    clear_symtab_users ();
 }
 
 \f
@@ -1039,13 +1149,13 @@ deduce_language_from_filename (filename)
     ; /* Get default */
   else if (0 == (c = strrchr (filename, '.')))
     ; /* Get default. */
-  else if(STREQ(c,".mod"))
+  else if (STREQ(c,".mod"))
     return language_m2;
-  else if(STREQ(c,".c"))
+  else if (STREQ(c,".c"))
     return language_c;
-  else if(STREQ(c,".cc") || STREQ(c,".C"))
+  else if (STREQ (c,".cc") || STREQ (c,".C") || STREQ (c, ".cxx"))
     return language_cplus;
-  else if(STREQ(c,".ch") || STREQ(c,".c186") || STREQ(c,".c286"))
+  else if (STREQ (c,".ch") || STREQ (c,".c186") || STREQ (c,".c286"))
     return language_chill;
 
   return language_unknown;             /* default */
@@ -1141,6 +1251,7 @@ clear_symtab_users ()
   set_default_breakpoint (0, 0, 0, 0);
   current_source_symtab = 0;
   current_source_line = 0;
+  clear_pc_function_cache ();
 }
 
 /* clear_symtab_users_once: