/* Program and address space management, for GDB, the GNU debugger.
- Copyright (C) 2009-2019 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "registry.h"
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/safe-iterator.h"
+#include <list>
+#include <vector>
struct target_ops;
struct bfd;
struct address_space;
struct program_space_data;
struct address_space_data;
+struct so_list;
+
+typedef std::list<std::shared_ptr<objfile>> objfile_list;
+
+/* An iterator that wraps an iterator over std::shared_ptr<objfile>,
+ and dereferences the returned object. This is useful for iterating
+ over a list of shared pointers and returning raw pointers -- which
+ helped avoid touching a lot of code when changing how objfiles are
+ managed. */
+
+class unwrapping_objfile_iterator
+{
+public:
+
+ typedef unwrapping_objfile_iterator self_type;
+ typedef typename ::objfile *value_type;
+ typedef typename ::objfile &reference;
+ typedef typename ::objfile **pointer;
+ typedef typename objfile_list::iterator::iterator_category iterator_category;
+ typedef typename objfile_list::iterator::difference_type difference_type;
+
+ unwrapping_objfile_iterator (const objfile_list::iterator &iter)
+ : m_iter (iter)
+ {
+ }
+
+ objfile *operator* () const
+ {
+ return m_iter->get ();
+ }
+
+ unwrapping_objfile_iterator operator++ ()
+ {
+ ++m_iter;
+ return *this;
+ }
+
+ bool operator!= (const unwrapping_objfile_iterator &other) const
+ {
+ return m_iter != other.m_iter;
+ }
+
+private:
+
+ /* The underlying iterator. */
+ objfile_list::iterator m_iter;
+};
+
+
+/* A range that returns unwrapping_objfile_iterators. */
+
+struct unwrapping_objfile_range
+{
+ typedef unwrapping_objfile_iterator iterator;
+
+ unwrapping_objfile_range (objfile_list &ol)
+ : m_list (ol)
+ {
+ }
+
+ iterator begin () const
+ {
+ return iterator (m_list.begin ());
+ }
+
+ iterator end () const
+ {
+ return iterator (m_list.end ());
+ }
+
+private:
+
+ objfile_list &m_list;
+};
/* A program space represents a symbolic view of an address space.
Roughly speaking, it holds all the data associated with a
struct program_space
{
- program_space (address_space *aspace_);
+ /* Constructs a new empty program space, binds it to ASPACE, and
+ adds it to the program space list. */
+ explicit program_space (address_space *aspace);
+
+ /* Releases a program space, and all its contents (shared libraries,
+ objfiles, and any other references to the program space in other
+ modules). It is an internal error to call this when the program
+ space is the current program space, since there should always be
+ a program space. */
~program_space ();
- typedef next_adapter<struct objfile> objfiles_range;
+ typedef unwrapping_objfile_range objfiles_range;
/* Return an iterable object that can be used to iterate over all
objfiles. The basic use is in a foreach, like:
for (objfile *objf : pspace->objfiles ()) { ... } */
objfiles_range objfiles ()
{
- return objfiles_range (objfiles_head);
+ return unwrapping_objfile_range (objfiles_list);
}
- typedef next_adapter<struct objfile,
- basic_safe_iterator<next_iterator<objfile>>>
- objfiles_safe_range;
+ typedef basic_safe_range<objfiles_range> objfiles_safe_range;
/* An iterable object that can be used to iterate over all objfiles.
The basic use is in a foreach, like:
deleted during iteration. */
objfiles_safe_range objfiles_safe ()
{
- return objfiles_safe_range (objfiles_head);
+ return objfiles_safe_range (objfiles_list);
}
/* Add OBJFILE to the list of objfiles, putting it just before
BEFORE. If BEFORE is nullptr, it will go at the end of the
list. */
- void add_objfile (struct objfile *objfile, struct objfile *before);
+ void add_objfile (std::shared_ptr<objfile> &&objfile,
+ struct objfile *before);
+ /* Remove OBJFILE from the list of objfiles. */
+ void remove_objfile (struct objfile *objfile);
- /* Pointer to next in linked list. */
- struct program_space *next = NULL;
+ /* Return true if there is more than one object file loaded; false
+ otherwise. */
+ bool multi_objfile_p () const
+ {
+ return objfiles_list.size () > 1;
+ }
+
+ /* Free all the objfiles associated with this program space. */
+ void free_all_objfiles ();
+
+ /* Return a range adapter for iterating over all the solibs in this
+ program space. Use it like:
+
+ for (so_list *so : pspace->solibs ()) { ... } */
+ next_adapter<struct so_list> solibs () const;
+
+ /* Close and clear exec_bfd. If we end up with no target sections
+ to read memory from, this unpushes the exec_ops target. */
+ void exec_close ();
+
+ /* Return the exec BFD for this program space. */
+ bfd *exec_bfd () const
+ {
+ return ebfd.get ();
+ }
+
+ /* Set the exec BFD for this program space to ABFD. */
+ void set_exec_bfd (gdb_bfd_ref_ptr &&abfd)
+ {
+ ebfd = std::move (abfd);
+ }
+
+ /* Reset saved solib data at the start of an solib event. This lets
+ us properly collect the data when calling solib_add, so it can then
+ later be printed. */
+ void clear_solib_cache ();
+
+ /* Returns true iff there's no inferior bound to this program
+ space. */
+ bool empty ();
+
+ /* Remove all target sections owned by OWNER. */
+ void remove_target_sections (void *owner);
+
+ /* Add the sections array defined by SECTIONS to the
+ current set of target sections. */
+ void add_target_sections (void *owner,
+ const target_section_table §ions);
+
+ /* Add the sections of OBJFILE to the current set of target
+ sections. They are given OBJFILE as the "owner". */
+ void add_target_sections (struct objfile *objfile);
+
+ /* Clear all target sections from M_TARGET_SECTIONS table. */
+ void clear_target_sections ()
+ {
+ m_target_sections.clear ();
+ }
+
+ /* Return a reference to the M_TARGET_SECTIONS table. */
+ target_section_table &target_sections ()
+ {
+ return m_target_sections;
+ }
/* Unique ID number. */
int num = 0;
managed by the exec target. */
/* The BFD handle for the main executable. */
- bfd *ebfd = NULL;
+ gdb_bfd_ref_ptr ebfd;
/* The last-modified time, from when the exec was brought in. */
long ebfd_mtime = 0;
/* Similar to bfd_get_filename (exec_bfd) but in original form given
- by user, without symbolic links and pathname resolved.
- It needs to be freed by xfree. It is not NULL iff EBFD is not NULL. */
- char *pspace_exec_filename = NULL;
+ by user, without symbolic links and pathname resolved. It is not
+ NULL iff EBFD is not NULL. */
+ gdb::unique_xmalloc_ptr<char> exec_filename;
/* Binary file diddling handle for the core file. */
gdb_bfd_ref_ptr cbfd;
(e.g. the argument to the "symbol-file" or "file" command). */
struct objfile *symfile_object_file = NULL;
- /* All known objfiles are kept in a linked list. This points to
- the head of this list. */
- struct objfile *objfiles_head = NULL;
-
- /* The set of target sections matching the sections mapped into
- this program space. Managed by both exec_ops and solib.c. */
- struct target_section_table target_sections {};
+ /* All known objfiles are kept in a linked list. */
+ std::list<std::shared_ptr<objfile>> objfiles_list;
/* List of shared objects mapped into this space. Managed by
solib.c. */
/* Per pspace data-pointers required by other GDB modules. */
REGISTRY_FIELDS {};
+
+private:
+ /* The set of target sections matching the sections mapped into
+ this program space. Managed by both exec_ops and solib.c. */
+ target_section_table m_target_sections;
};
/* An address space. It is used for comparing if
REGISTRY_FIELDS;
};
-/* The object file that the main symbol table was loaded from (e.g. the
- argument to the "symbol-file" or "file" command). */
-
-#define symfile_objfile current_program_space->symfile_object_file
-
-/* All known objfiles are kept in a linked list. This points to the
- root of this list. */
-#define object_files current_program_space->objfiles_head
-
-/* The set of target sections matching the sections mapped into the
- current program space. */
-#define current_target_sections (¤t_program_space->target_sections)
-
/* The list of all program spaces. There's always at least one. */
-extern struct program_space *program_spaces;
+extern std::vector<struct program_space *>program_spaces;
/* The current program space. This is always non-null. */
extern struct program_space *current_program_space;
-#define ALL_PSPACES(pspace) \
- for ((pspace) = program_spaces; (pspace) != NULL; (pspace) = (pspace)->next)
-
-/* Remove a program space from the program spaces list and release it. It is
- an error to call this function while PSPACE is the current program space. */
-extern void delete_program_space (struct program_space *pspace);
-
-/* Returns the number of program spaces listed. */
-extern int number_of_program_spaces (void);
-
-/* Returns true iff there's no inferior bound to PSPACE. */
-extern int program_space_empty_p (struct program_space *pspace);
-
/* Copies program space SRC to DEST. Copies the main executable file,
and the main symbol file. Returns DEST. */
extern struct program_space *clone_program_space (struct program_space *dest,
mappings. */
extern void update_address_spaces (void);
-/* Reset saved solib data at the start of an solib event. This lets
- us properly collect the data when calling solib_add, so it can then
- later be printed. */
-extern void clear_program_space_solib_cache (struct program_space *);
-
/* Keep a registry of per-pspace data-pointers required by other GDB
modules. */