#include "gdb_bfd.h"
#include "cli/cli-utils.h"
#include "common/byte-vector.h"
-#include "selftest.h"
+#include "common/pathstuff.h"
+#include "common/selftest.h"
#include "cli/cli-style.h"
+#include "common/forward-scope-exit.h"
#include <sys/types.h>
#include <fcntl.h>
void (*deprecated_pre_add_symbol_hook) (const char *);
void (*deprecated_post_add_symbol_hook) (void);
-static void clear_symtab_users_cleanup (void *ignore);
+using clear_symtab_users_cleanup
+ = FORWARD_SCOPE_EXIT (clear_symtab_users);
/* Global variables owned by this file. */
int readnow_symbol_files; /* Read full symbols immediately. */
symfile_add_flags add_flags)
{
section_addr_info local_addr;
- struct cleanup *old_chain;
const int mainline = add_flags & SYMFILE_MAINLINE;
objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
/* Make sure that partially constructed symbol tables will be cleaned up
if an error occurs during symbol reading. */
- old_chain = make_cleanup (null_cleanup, NULL);
+ gdb::optional<clear_symtab_users_cleanup> defer_clear_users;
+
std::unique_ptr<struct objfile> objfile_holder (objfile);
/* If ADDRS is NULL, put together a dummy address list.
{
/* 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_cleanup, 0 /*ignore*/);
+ defer_clear_users.emplace ((symfile_add_flag) 0);
/* Since no error yet, throw away the old symbol table. */
/* Discard cleanups as symbol reading was successful. */
objfile_holder.release ();
- discard_cleanups (old_chain);
+ if (defer_clear_users)
+ defer_clear_users->release ();
}
/* Same as syms_from_objfile_1, but also initializes the objfile
Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
cause "/..." lookups. */
+ bool target_prefix = startswith (dir, "target:");
+ const char *dir_notarget = target_prefix ? dir + strlen ("target:") : dir;
std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
= dirnames_to_char_ptr_vec (debug_file_directory);
+ gdb::unique_xmalloc_ptr<char> canon_sysroot = gdb_realpath (gdb_sysroot);
+
+ /* MS-Windows/MS-DOS don't allow colons in file names; we must
+ convert the drive letter into a one-letter directory, so that the
+ file name resulting from splicing below will be valid.
+
+ FIXME: The below only works when GDB runs on MS-Windows/MS-DOS.
+ There are various remote-debugging scenarios where such a
+ transformation of the drive letter might be required when GDB runs
+ on a Posix host, see
+
+ https://sourceware.org/ml/gdb-patches/2019-04/msg00605.html
+
+ If some of those scenarions need to be supported, we will need to
+ use a different condition for HAS_DRIVE_SPEC and a different macro
+ instead of STRIP_DRIVE_SPEC, which work on Posix systems as well. */
+ std::string drive;
+ if (HAS_DRIVE_SPEC (dir_notarget))
+ {
+ drive = dir_notarget[0];
+ dir_notarget = STRIP_DRIVE_SPEC (dir_notarget);
+ }
for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
{
- debugfile = debugdir.get ();
+ debugfile = target_prefix ? "target:" : "";
+ debugfile += debugdir.get ();
debugfile += "/";
- debugfile += dir;
+ debugfile += drive;
+ debugfile += dir_notarget;
debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
- /* If the file is in the sysroot, try using its base path in the
- global debugfile directory. */
- if (canon_dir != NULL
- && filename_ncmp (canon_dir, gdb_sysroot,
- strlen (gdb_sysroot)) == 0
- && IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)]))
+ const char *base_path = NULL;
+ if (canon_dir != NULL)
+ {
+ if (canon_sysroot.get () != NULL)
+ base_path = child_path (canon_sysroot.get (), canon_dir);
+ else
+ base_path = child_path (gdb_sysroot, canon_dir);
+ }
+ if (base_path != NULL)
{
- debugfile = debugdir.get ();
- debugfile += (canon_dir + strlen (gdb_sysroot));
+ /* If the file is in the sysroot, try using its base path in
+ the global debugfile directory. */
+ debugfile = target_prefix ? "target:" : "";
+ debugfile += debugdir.get ();
+ debugfile += "/";
+ debugfile += base_path;
+ debugfile += "/";
+ debugfile += debuglink;
+
+ if (separate_debug_file_exists (debugfile, crc32, objfile))
+ return debugfile;
+
+ /* If the file is in the sysroot, try using its base path in
+ the sysroot's global debugfile directory. */
+ debugfile = target_prefix ? "target:" : "";
+ debugfile += gdb_sysroot;
+ debugfile += debugdir.get ();
+ debugfile += "/";
+ debugfile += base_path;
debugfile += "/";
debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
}
+
}
return std::string ();
addr = parse_and_eval_address (argv[1]);
- ALL_OBJFILES (objf)
+ for (objfile *objfile : current_program_space->objfiles ())
{
- if ((objf->flags & OBJF_USERLOADED) != 0
- && (objf->flags & OBJF_SHARED) != 0
- && objf->pspace == pspace && is_addr_in_objfile (addr, objf))
- break;
+ if ((objfile->flags & OBJF_USERLOADED) != 0
+ && (objfile->flags & OBJF_SHARED) != 0
+ && objfile->pspace == pspace
+ && is_addr_in_objfile (addr, objfile))
+ {
+ objf = objfile;
+ break;
+ }
}
}
else if (argv[0] != NULL)
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
- ALL_OBJFILES (objf)
+ for (objfile *objfile : current_program_space->objfiles ())
{
- if ((objf->flags & OBJF_USERLOADED) != 0
- && (objf->flags & OBJF_SHARED) != 0
- && objf->pspace == pspace
- && filename_cmp (filename.get (), objfile_name (objf)) == 0)
- break;
+ if ((objfile->flags & OBJF_USERLOADED) != 0
+ && (objfile->flags & OBJF_SHARED) != 0
+ && objfile->pspace == pspace
+ && filename_cmp (filename.get (), objfile_name (objfile)) == 0)
+ {
+ objf = objfile;
+ break;
+ }
}
}
void
reread_symbols (void)
{
- struct objfile *objfile;
long new_modtime;
struct stat new_statbuf;
int res;
std::vector<struct objfile *> new_objfiles;
- /* With the addition of shared libraries, this should be modified,
- the load time should be saved in the partial symbol tables, since
- different tables may come from different source files. FIXME.
- This routine should then walk down each partial symbol table
- and see if the symbol table that it originates from has been changed. */
-
- for (objfile = object_files; objfile; objfile = objfile->next)
+ for (objfile *objfile : current_program_space->objfiles ())
{
if (objfile->obfd == NULL)
continue;
new_modtime = new_statbuf.st_mtime;
if (new_modtime != objfile->mtime)
{
- struct cleanup *old_cleanups;
struct section_offsets *offsets;
int num_offsets;
std::unique_ptr<struct objfile> objfile_holder (objfile);
/* We need to do this whenever any symbols go away. */
- old_cleanups = make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+ clear_symtab_users_cleanup defer_clear_users (0);
if (exec_bfd != NULL
&& filename_cmp (bfd_get_filename (objfile->obfd),
memcpy (offsets, objfile->section_offsets,
SIZEOF_N_SECTION_OFFSETS (num_offsets));
- /* FIXME: Do we have to free a whole linked list, or is this
- enough? */
- objfile->global_psymbols.clear ();
- objfile->static_psymbols.clear ();
-
- /* Free the obstacks for non-reusable objfiles. */
- psymbol_bcache_free (objfile->psymbol_cache);
- objfile->psymbol_cache = psymbol_bcache_init ();
+ objfile->reset_psymtabs ();
/* NB: after this call to obstack_free, objfiles_changed
will need to be called (see discussion below). */
obstack_free (&objfile->objfile_obstack, 0);
objfile->sections = NULL;
objfile->compunit_symtabs = NULL;
- objfile->psymtabs = NULL;
- objfile->psymtabs_addrmap = NULL;
- objfile->free_psymtabs = NULL;
objfile->template_symbols = NULL;
- objfile->static_links = NULL;
+ objfile->static_links.reset (nullptr);
/* obstack_init also initializes the obstack so it is
empty. We could use obstack_specify_allocation but
objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
build_objfile_section_table (objfile);
- terminate_minimal_symbol_table (objfile);
/* We use the same section offsets as from last time. I'm not
sure whether that is always correct for shared libraries. */
/* Discard cleanups as symbol reading was successful. */
objfile_holder.release ();
- discard_cleanups (old_cleanups);
+ defer_clear_users.release ();
/* 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
= OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab);
symtab->filename
- = (const char *) bcache (filename, strlen (filename) + 1,
- objfile->per_bfd->filename_cache);
+ = ((const char *) objfile->per_bfd->filename_cache.insert
+ (filename, strlen (filename) + 1));
symtab->fullname = NULL;
symtab->language = deduce_language_from_filename (filename);
clear_pc_function_cache ();
gdb::observers::new_objfile.notify (NULL);
- /* Clear globals which might have pointed into a removed objfile.
- FIXME: It's not clear which of these are supposed to persist
- between expressions and which ought to be reset each time. */
- expression_context_block = NULL;
- innermost_block.reset ();
-
/* Varobj may refer to old symbols, perform a cleanup. */
varobj_invalidate ();
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
breakpoint_re_set ();
}
-
-static void
-clear_symtab_users_cleanup (void *ignore)
-{
- clear_symtab_users (0);
-}
\f
/* OVERLAYS:
The following code implements an abstraction for debugging overlay sections.
static void
overlay_invalidate_all (void)
{
- struct objfile *objfile;
struct obj_section *sect;
- ALL_OBJSECTIONS (objfile, sect)
- if (section_is_overlay (sect))
- sect->ovly_mapped = -1;
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, sect)
+ if (section_is_overlay (sect))
+ sect->ovly_mapped = -1;
}
/* Function: section_is_mapped (SECTION)
struct obj_section *
find_pc_overlay (CORE_ADDR pc)
{
- struct objfile *objfile;
struct obj_section *osect, *best_match = NULL;
if (overlay_debugging)
{
- ALL_OBJSECTIONS (objfile, osect)
- if (section_is_overlay (osect))
- {
- if (pc_in_mapped_range (pc, osect))
- {
- if (section_is_mapped (osect))
- return osect;
- else
- best_match = osect;
- }
- else if (pc_in_unmapped_range (pc, osect))
- best_match = osect;
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ if (section_is_overlay (osect))
+ {
+ if (pc_in_mapped_range (pc, osect))
+ {
+ if (section_is_mapped (osect))
+ return osect;
+ else
+ best_match = osect;
+ }
+ else if (pc_in_unmapped_range (pc, osect))
+ best_match = osect;
+ }
}
return best_match;
}
struct obj_section *
find_pc_mapped_section (CORE_ADDR pc)
{
- struct objfile *objfile;
struct obj_section *osect;
if (overlay_debugging)
{
- ALL_OBJSECTIONS (objfile, osect)
- if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
- return osect;
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
+ return osect;
}
return NULL;
list_overlays_command (const char *args, int from_tty)
{
int nmapped = 0;
- struct objfile *objfile;
struct obj_section *osect;
if (overlay_debugging)
{
- ALL_OBJSECTIONS (objfile, osect)
- if (section_is_mapped (osect))
- {
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
- const char *name;
- bfd_vma lma, vma;
- int size;
-
- vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
- lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
- size = bfd_get_section_size (osect->the_bfd_section);
- name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
-
- printf_filtered ("Section %s, loaded at ", name);
- fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
- puts_filtered (" - ");
- fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
- printf_filtered (", mapped at ");
- fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
- puts_filtered (" - ");
- fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
- puts_filtered ("\n");
-
- nmapped++;
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ if (section_is_mapped (osect))
+ {
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const char *name;
+ bfd_vma lma, vma;
+ int size;
+
+ vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+ lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+ size = bfd_get_section_size (osect->the_bfd_section);
+ name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+ printf_filtered ("Section %s, loaded at ", name);
+ fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
+ puts_filtered (" - ");
+ fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
+ printf_filtered (", mapped at ");
+ fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
+ puts_filtered (" - ");
+ fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
+ puts_filtered ("\n");
+
+ nmapped++;
+ }
}
if (nmapped == 0)
printf_filtered (_("No sections are mapped.\n"));
static void
map_overlay_command (const char *args, int from_tty)
{
- struct objfile *objfile, *objfile2;
struct obj_section *sec, *sec2;
if (!overlay_debugging)
error (_("Argument required: name of an overlay section"));
/* First, find a section matching the user supplied argument. */
- ALL_OBJSECTIONS (objfile, sec)
- if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
- {
- /* Now, check to see if the section is an overlay. */
- if (!section_is_overlay (sec))
- continue; /* not an overlay section */
-
- /* Mark the overlay as "mapped". */
- sec->ovly_mapped = 1;
-
- /* Next, make a pass and unmap any sections that are
- overlapped by this new section: */
- ALL_OBJSECTIONS (objfile2, sec2)
- if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec, sec2))
+ for (objfile *obj_file : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (obj_file, sec)
+ if (!strcmp (bfd_section_name (obj_file->obfd, sec->the_bfd_section),
+ args))
{
- if (info_verbose)
- printf_unfiltered (_("Note: section %s unmapped by overlap\n"),
- bfd_section_name (objfile->obfd,
- sec2->the_bfd_section));
- sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2. */
+ /* Now, check to see if the section is an overlay. */
+ if (!section_is_overlay (sec))
+ continue; /* not an overlay section */
+
+ /* Mark the overlay as "mapped". */
+ sec->ovly_mapped = 1;
+
+ /* Next, make a pass and unmap any sections that are
+ overlapped by this new section: */
+ for (objfile *objfile2 : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile2, sec2)
+ if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec,
+ sec2))
+ {
+ if (info_verbose)
+ printf_unfiltered (_("Note: section %s unmapped by overlap\n"),
+ bfd_section_name (obj_file->obfd,
+ sec2->the_bfd_section));
+ sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2. */
+ }
+ return;
}
- return;
- }
error (_("No overlay section called %s"), args);
}
static void
unmap_overlay_command (const char *args, int from_tty)
{
- struct objfile *objfile;
struct obj_section *sec = NULL;
if (!overlay_debugging)
error (_("Argument required: name of an overlay section"));
/* First, find a section matching the user supplied argument. */
- ALL_OBJSECTIONS (objfile, sec)
- if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
- {
- if (!sec->ovly_mapped)
- error (_("Section %s is not mapped"), args);
- sec->ovly_mapped = 0;
- return;
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ if (!sec->ovly_mapped)
+ error (_("Section %s is not mapped"), args);
+ sec->ovly_mapped = 0;
+ return;
+ }
error (_("No overlay section called %s"), args);
}
void
simple_overlay_update (struct obj_section *osect)
{
- struct objfile *objfile;
-
/* Were we given an osect to look up? NULL means do all of them. */
if (osect)
/* Have we got a cached copy of the target's overlay table? */
return;
/* Now may as well update all sections, even if only one was requested. */
- ALL_OBJSECTIONS (objfile, osect)
- if (section_is_overlay (osect))
- {
- int i;
- asection *bsect = osect->the_bfd_section;
-
- for (i = 0; i < cache_novlys; i++)
- if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
- && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect))
- { /* obj_section matches i'th entry in ovly_table. */
- osect->ovly_mapped = cache_ovly_table[i][MAPPED];
- break; /* finished with inner for loop: break out. */
- }
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ if (section_is_overlay (osect))
+ {
+ int i;
+ asection *bsect = osect->the_bfd_section;
+
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect))
+ { /* obj_section matches i'th entry in ovly_table. */
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ break; /* finished with inner for loop: break out. */
+ }
+ }
}
/* Set the output sections and output offsets for section SECTP in
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind)
{
- struct objfile *objfile;
-
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
- lookup_name,
- symbol_matcher,
- expansion_notify, kind);
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ if (objfile->sf)
+ objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
+ lookup_name,
+ symbol_matcher,
+ expansion_notify, kind);
+ }
}
/* Wrapper around the quick_symbol_functions map_symbol_filenames "method".
map_symbol_filenames (symbol_filename_ftype *fun, void *data,
int need_fullname)
{
- struct objfile *objfile;
-
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
- need_fullname);
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ if (objfile->sf)
+ objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
+ need_fullname);
+ }
}
#if GDB_SELF_TEST