+ struct cleanup *old_cleanups;
+ struct section_offsets *offsets;
+ int num_offsets;
+ int section_offsets_size;
+ char *obfd_filename;
+
+ 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 ((make_cleanup_func) free_objfile,
+ objfile);
+ /* We need to do this whenever any symbols go away. */
+ make_cleanup ((make_cleanup_func) 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. */
+ obfd_filename = bfd_get_filename (objfile->obfd);
+ if (!bfd_close (objfile->obfd))
+ error ("Can't close BFD for %s: %s", objfile->name,
+ bfd_errmsg (bfd_get_error ()));
+ objfile->obfd = bfd_openr (obfd_filename, 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_get_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);
+ memset (&objfile->global_psymbols, 0,
+ sizeof (objfile->global_psymbols));
+ if (objfile->static_psymbols.list)
+ mfree (objfile->md, objfile->static_psymbols.list);
+ memset (&objfile->static_psymbols, 0,
+ sizeof (objfile->static_psymbols));
+
+ /* Free the obstacks for non-reusable objfiles */
+ obstack_free (&objfile->psymbol_cache.cache, 0);
+ memset (&objfile->psymbol_cache, 0,
+ sizeof (objfile->psymbol_cache));
+ 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_cache.cache, 0, 0,
+ xmalloc, free);
+ 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_get_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);