/* Generic symbol file reading for the GNU debugger, GDB.
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2012 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
#include "elf-bfd.h"
#include "solib.h"
#include "remote.h"
+#include "stack.h"
#include <sys/types.h>
#include <fcntl.h>
struct other_sections *osp;
osp = &addrs->other[i];
- if (osp->addr == 0)
+ if (osp->sectindex == -1)
continue;
/* Record all sections in offsets. */
if (retval)
return retval;
- /* SECTINDEX is undefined iff ADDR is zero. */
- a_idx = a->addr == 0 ? 0 : a->sectindex;
- b_idx = b->addr == 0 ? 0 : b->sectindex;
- return a_idx - b_idx;
+ return a->sectindex - b->sectindex;
}
/* Provide sorted array of pointers to sections of ADDRS. The array is
bfd_get_filename (abfd));
addrs->other[i].addr = 0;
-
- /* SECTINDEX is invalid if ADDR is zero. */
+ addrs->other[i].sectindex = -1;
}
}
(*objfile->sf->sym_read) (objfile, add_flags);
+ if ((add_flags & SYMFILE_NO_READ) == 0)
+ require_partial_symbols (objfile, 0);
+
/* Discard cleanups as symbol reading was successful. */
discard_cleanups (old_chain);
syms_from_objfile, above.
ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS.
+ PARENT is the original objfile if ABFD is a separate debug info file.
+ Otherwise PARENT is NULL.
+
Upon success, returns a pointer to the objfile that was added.
Upon failure, jumps back to command level (never returns). */
struct section_addr_info *addrs,
struct section_offsets *offsets,
int num_offsets,
- int flags)
+ int flags, struct objfile *parent)
{
struct objfile *objfile;
struct cleanup *my_cleanups;
const char *name = bfd_get_filename (abfd);
const int from_tty = add_flags & SYMFILE_VERBOSE;
+ const int mainline = add_flags & SYMFILE_MAINLINE;
+ const int should_print = ((from_tty || info_verbose)
+ && (readnow_symbol_files
+ || (add_flags & SYMFILE_NO_READ) == 0));
if (readnow_symbol_files)
- flags |= OBJF_READNOW;
+ {
+ flags |= OBJF_READNOW;
+ add_flags &= ~SYMFILE_NO_READ;
+ }
my_cleanups = make_cleanup_bfd_close (abfd);
interactively wiping out any existing symbols. */
if ((have_full_symbols () || have_partial_symbols ())
- && (add_flags & SYMFILE_MAINLINE)
+ && mainline
&& from_tty
&& !query (_("Load new symbol table from \"%s\"? "), name))
error (_("Not confirmed."));
- objfile = allocate_objfile (abfd, flags);
+ objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0));
discard_cleanups (my_cleanups);
+ if (parent)
+ add_separate_debug_objfile (objfile, parent);
+
/* We either created a new mapped symbol table, mapped an existing
symbol table file which has not had initial symbol reading
performed, or need to read an unmapped symbol table. */
- if (from_tty || info_verbose)
+ if (should_print)
{
if (deprecated_pre_add_symbol_hook)
deprecated_pre_add_symbol_hook (name);
if ((flags & OBJF_READNOW))
{
- if (from_tty || info_verbose)
+ if (should_print)
{
printf_unfiltered (_("expanding to full symbols..."));
wrap_here ("");
objfile->sf->qf->expand_all_symtabs (objfile);
}
- if ((from_tty || info_verbose)
- && !objfile_has_symbols (objfile))
+ if (should_print && !objfile_has_symbols (objfile))
{
wrap_here ("");
printf_unfiltered (_("(no debugging symbols found)..."));
wrap_here ("");
}
- if (from_tty || info_verbose)
+ if (should_print)
{
if (deprecated_post_add_symbol_hook)
deprecated_post_add_symbol_hook ();
time. */
gdb_flush (gdb_stdout);
- do_cleanups (my_cleanups);
-
if (objfile->sf == NULL)
{
observer_notify_new_objfile (objfile);
(bfd, symfile_flags,
sap, NULL, 0,
objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
- | OBJF_USERLOADED));
+ | OBJF_USERLOADED),
+ objfile);
do_cleanups (my_cleanup);
-
- add_separate_debug_objfile (new_objfile, objfile);
}
/* Process the symbol file ABFD, as either the main file or as a
struct objfile *
symbol_file_add_from_bfd (bfd *abfd, int add_flags,
struct section_addr_info *addrs,
- int flags)
+ int flags, struct objfile *parent)
{
return symbol_file_add_with_addrs_or_offsets (abfd, add_flags, addrs, 0, 0,
- flags);
+ flags, parent);
}
int flags)
{
return symbol_file_add_from_bfd (symfile_bfd_open (name), add_flags, addrs,
- flags);
+ flags, NULL);
}
return contents;
}
+/* Return 32-bit CRC for ABFD. If successful store it to *FILE_CRC_RETURN and
+ return 1. Otherwise print a warning and return 0. ABFD seek position is
+ not preserved. */
+
+static int
+get_file_crc (bfd *abfd, unsigned long *file_crc_return)
+{
+ unsigned long file_crc = 0;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ {
+ warning (_("Problem reading \"%s\" for CRC: %s"),
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ return 0;
+ }
+
+ for (;;)
+ {
+ gdb_byte buffer[8 * 1024];
+ bfd_size_type count;
+
+ count = bfd_bread (buffer, sizeof (buffer), abfd);
+ if (count == (bfd_size_type) -1)
+ {
+ warning (_("Problem reading \"%s\" for CRC: %s"),
+ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ return 0;
+ }
+ if (count == 0)
+ break;
+ file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+ }
+
+ *file_crc_return = file_crc;
+ return 1;
+}
+
static int
separate_debug_file_exists (const char *name, unsigned long crc,
struct objfile *parent_objfile)
{
- unsigned long file_crc = 0;
+ unsigned long file_crc;
+ int file_crc_p;
bfd *abfd;
- gdb_byte buffer[8*1024];
- int count;
struct stat parent_stat, abfd_stat;
+ int verified_as_different;
/* Find a separate debug info file as if symbols would be present in
PARENT_OBJFILE itself this function would not be called. .gnu_debuglink
".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where
the separate debug infos with the same basename can exist. */
- if (strcmp (name, parent_objfile->name) == 0)
+ if (filename_cmp (name, parent_objfile->name) == 0)
return 0;
abfd = bfd_open_maybe_remote (name);
if (!abfd)
return 0;
- /* Verify symlinks were not the cause of strcmp name difference above.
+ /* Verify symlinks were not the cause of filename_cmp name difference above.
Some operating systems, e.g. Windows, do not provide a meaningful
st_ino; they always set it to zero. (Windows does provide a
negatives. */
if (bfd_stat (abfd, &abfd_stat) == 0
- && bfd_stat (parent_objfile->obfd, &parent_stat) == 0
- && abfd_stat.st_dev == parent_stat.st_dev
- && abfd_stat.st_ino == parent_stat.st_ino
- && abfd_stat.st_ino != 0)
+ && abfd_stat.st_ino != 0
+ && bfd_stat (parent_objfile->obfd, &parent_stat) == 0)
{
- bfd_close (abfd);
- return 0;
+ if (abfd_stat.st_dev == parent_stat.st_dev
+ && abfd_stat.st_ino == parent_stat.st_ino)
+ {
+ bfd_close (abfd);
+ return 0;
+ }
+ verified_as_different = 1;
}
+ else
+ verified_as_different = 0;
- while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0)
- file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+ file_crc_p = get_file_crc (abfd, &file_crc);
bfd_close (abfd);
+ if (!file_crc_p)
+ return 0;
+
if (crc != file_crc)
{
- warning (_("the debug information found in \"%s\""
- " does not match \"%s\" (CRC mismatch).\n"),
- name, parent_objfile->name);
+ /* If one (or both) the files are accessed for example the via "remote:"
+ gdbserver way it does not support the bfd_stat operation. Verify
+ whether those two files are not the same manually. */
+
+ if (!verified_as_different && !parent_objfile->crc32_p)
+ {
+ parent_objfile->crc32_p = get_file_crc (parent_objfile->obfd,
+ &parent_objfile->crc32);
+ if (!parent_objfile->crc32_p)
+ return 0;
+ }
+
+ if (verified_as_different || parent_objfile->crc32 != file_crc)
+ warning (_("the debug information found in \"%s\""
+ " does not match \"%s\" (CRC mismatch).\n"),
+ name, parent_objfile->name);
+
return 0;
}
/* If the file is in the sysroot, try using its base path in the
global debugfile directory. */
if (canon_name
- && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
+ && filename_ncmp (canon_name, gdb_sysroot,
+ strlen (gdb_sysroot)) == 0
&& IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
{
memcpy (debugfile, debugdir, debugdir_end - debugdir);
{
/* The write is just starting. Let the user know we've started
this section. */
- ui_out_message (uiout, 0, "Loading section %s, size %s lma %s\n",
+ ui_out_message (current_uiout, 0, "Loading section %s, size %s lma %s\n",
args->section_name, hex_string (args->section_size),
paddress (target_gdbarch, args->lma));
return;
struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
struct load_section_data cbdata;
struct load_progress_data total_progress;
+ struct ui_out *uiout = current_uiout;
CORE_ADDR entry;
char **argv;
const struct timeval *end_time)
{
ULONGEST time_count;
+ struct ui_out *uiout = current_uiout;
/* Compute the elapsed time in milliseconds, as a tradeoff between
accuracy and overflow. */
}
else
error (_("USAGE: add-symbol-file <filename> <textaddress>"
- " [-mapped] [-readnow] [-s <secname> <addr>]*"));
+ " [-readnow] [-s <secname> <addr>]*"));
}
}
}
}
\f
+typedef struct objfile *objfilep;
+
+DEF_VEC_P (objfilep);
+
/* Re-read symbols if a symbol-file has changed. */
void
reread_symbols (void)
{
struct objfile *objfile;
long new_modtime;
- int reread_one = 0;
struct stat new_statbuf;
int res;
+ VEC (objfilep) *new_objfiles = NULL;
+ struct cleanup *all_cleanups;
+
+ all_cleanups = make_cleanup (VEC_cleanup (objfilep), &new_objfiles);
/* With the addition of shared libraries, this should be modified,
the load time should be saved in the partial symbol tables, since
/* We need to do this whenever any symbols go away. */
make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
- if (exec_bfd != NULL && strcmp (bfd_get_filename (objfile->obfd),
- bfd_get_filename (exec_bfd)) == 0)
+ if (exec_bfd != NULL
+ && filename_cmp (bfd_get_filename (objfile->obfd),
+ bfd_get_filename (exec_bfd)) == 0)
{
/* Reload EXEC_BFD without asking anything. */
exec_file_attach (bfd_get_filename (objfile->obfd), 0);
}
+ /* Keep the calls order approx. the same as in free_objfile. */
+
+ /* Free the separate debug objfiles. It will be
+ automatically recreated by sym_read. */
+ free_objfile_separate_debug (objfile);
+
+ /* Remove any references to this objfile in the global
+ value lists. */
+ preserve_values (objfile);
+
+ /* 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.
+
+ Try to keep the freeing order compatible with free_objfile. */
+
+ if (objfile->sf != NULL)
+ {
+ (*objfile->sf->sym_finish) (objfile);
+ }
+
+ clear_objfile_data (objfile);
+
/* 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. */
memcpy (offsets, objfile->section_offsets,
SIZEOF_N_SECTION_OFFSETS (num_offsets));
- /* Remove any references to this objfile in the global
- value lists. */
- preserve_values (objfile);
-
- /* 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.
-
- Try to keep the freeing order compatible with free_objfile. */
-
- if (objfile->sf != NULL)
- {
- (*objfile->sf->sym_finish) (objfile);
- }
-
- clear_objfile_data (objfile);
-
- /* Free the separate debug objfiles. It will be
- automatically recreated by sym_read. */
- free_objfile_separate_debug (objfile);
-
/* FIXME: Do we have to free a whole linked list, or is this
enough? */
if (objfile->global_psymbols.list)
objfile->psymtabs = NULL;
objfile->psymtabs_addrmap = NULL;
objfile->free_psymtabs = NULL;
- objfile->cp_namespace_symtab = NULL;
objfile->template_symbols = NULL;
objfile->msymbols = NULL;
objfile->deprecated_sym_private = NULL;
memset (&objfile->msymbol_demangled_hash, 0,
sizeof (objfile->msymbol_demangled_hash));
- objfile->psymbol_cache = psymbol_bcache_init ();
- objfile->macro_cache = bcache_xmalloc (NULL, NULL);
- objfile->filename_cache = bcache_xmalloc (NULL, NULL);
/* obstack_init also initializes the obstack so it is
empty. We could use obstack_specify_allocation but
gdb_obstack.h specifies the alloc/dealloc
/* Do not set flags as this is safe and we don't want to be
verbose. */
(*objfile->sf->sym_read) (objfile, 0);
+ if ((objfile->flags & OBJF_PSYMTABS_READ) != 0)
+ {
+ objfile->flags &= ~OBJF_PSYMTABS_READ;
+ require_partial_symbols (objfile, 0);
+ }
+
if (!objfile_has_symbols (objfile))
{
wrap_here ("");
and now, we *want* this to be out of date, so don't call stat
again now. */
objfile->mtime = new_modtime;
- reread_one = 1;
init_entry_point_info (objfile);
+
+ VEC_safe_push (objfilep, new_objfiles, objfile);
}
}
- if (reread_one)
+ if (new_objfiles)
{
+ int ix;
+
/* Notify objfiles that we've modified objfile sections. */
objfiles_changed ();
clear_symtab_users (0);
+
+ /* clear_objfile_data for each objfile was called before freeing it and
+ observer_notify_new_objfile (NULL) has been called by
+ clear_symtab_users above. Notify the new files now. */
+ for (ix = 0; VEC_iterate (objfilep, new_objfiles, ix, objfile); ix++)
+ observer_notify_new_objfile (objfile);
+
/* At least one objfile has changed, so we can consider that
the executable we're debugging has changed too. */
observer_notify_executable_changed ();
}
+
+ do_cleanups (all_cleanups);
}
\f
clear_displays ();
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
breakpoint_re_set ();
- set_default_breakpoint (0, NULL, 0, 0, 0);
+ clear_last_displayed_sal ();
clear_pc_function_cache ();
observer_notify_new_objfile (NULL);