int bptoffset = 0;
if (!breakpoint_address_match (target_info->placed_address_space, 0,
- current_program_space->aspace, 0))
+ current_program_space->aspace.get (), 0))
{
/* The breakpoint is inserted in a different address space. */
return;
a breakpoint. */
if ((bl->loc_type == bp_loc_software_breakpoint
|| bl->loc_type == bp_loc_hardware_breakpoint)
- && stepping_past_instruction_at (bl->pspace->aspace,
+ && stepping_past_instruction_at (bl->pspace->aspace.get (),
bl->address)
/* The single-step breakpoint may be inserted at the location
we're trying to step if the instruction branches to itself.
read the breakpoint instead of returning the data saved in
the breakpoint location's shadow contents. */
bl->target_info.reqstd_address = bl->address;
- bl->target_info.placed_address_space = bl->pspace->aspace;
+ bl->target_info.placed_address_space = bl->pspace->aspace.get ();
bl->target_info.length = bl->length;
/* When working with target-side conditions, we must pass all the conditions
const address_space *aspace, CORE_ADDR pc)
{
if (bl->inserted
- && breakpoint_address_match (bl->pspace->aspace, bl->address,
+ && breakpoint_address_match (bl->pspace->aspace.get (), bl->address,
aspace, pc))
{
/* An unmapped overlay can't be a match. */
continue;
for (bp_location &loc : bpt.locations ())
- if (loc.pspace->aspace == aspace && loc.inserted)
+ if (loc.pspace->aspace.get () == aspace && loc.inserted)
{
CORE_ADDR l, h;
const address_space *aspace,
CORE_ADDR addr)
{
- return (breakpoint_address_match (bl->pspace->aspace, bl->address,
+ return (breakpoint_address_match (bl->pspace->aspace.get (), bl->address,
aspace, addr)
|| (bl->length
- && breakpoint_address_match_range (bl->pspace->aspace,
+ && breakpoint_address_match_range (bl->pspace->aspace.get (),
bl->address, bl->length,
aspace, addr)));
}
CORE_ADDR addr, int len)
{
if (gdbarch_has_global_breakpoints (current_inferior ()->arch ())
- || bl->pspace->aspace == aspace)
+ || bl->pspace->aspace.get () == aspace)
{
int bl_len = bl->length != 0 ? bl->length : 1;
/* We compare bp_location.length in order to cover ranged
breakpoints. Keep this in sync with
bp_location_is_less_than. */
- return (breakpoint_address_match (loc1->pspace->aspace, loc1->address,
- loc2->pspace->aspace, loc2->address)
+ return (breakpoint_address_match (loc1->pspace->aspace.get (),
+ loc1->address,
+ loc2->pspace->aspace.get (),
+ loc2->address)
&& (loc1->loc_type == loc2->loc_type || sw_hw_bps_match)
&& loc1->length == loc2->length);
}
|| ws.sig () != GDB_SIGNAL_TRAP)
return 0;
- return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
- bl->length, aspace, bp_addr);
+ return breakpoint_address_match_range (bl->pspace->aspace.get (),
+ bl->address, bl->length, aspace,
+ bp_addr);
}
/* Implement the "resources_needed" method for ranged breakpoints. */
|| ws.sig () != GDB_SIGNAL_TRAP)
return 0;
- if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
+ if (!breakpoint_address_match (bl->pspace->aspace.get (), bl->address,
aspace, bp_addr))
return 0;
for (displaced_step_buffer &candidate : m_buffers)
{
- bool bp_in_range = breakpoint_in_range_p (thread->inf->aspace, candidate.addr, len);
+ bool bp_in_range = breakpoint_in_range_p (thread->inf->aspace.get (),
+ candidate.addr, len);
bool is_free = candidate.current_thread == nullptr;
if (!bp_in_range)
if (sentinel_frame == NULL)
sentinel_frame =
- create_sentinel_frame (current_program_space, current_inferior ()->aspace,
+ create_sentinel_frame (current_program_space,
+ current_inferior ()->aspace.get (),
get_thread_regcache (inferior_thread ()),
0, 0).get ();
frame_info *fi = FRAME_OBSTACK_ZALLOC (struct frame_info);
fi->next = create_sentinel_frame (current_program_space,
- current_inferior ()->aspace,
+ current_inferior ()->aspace.get (),
get_thread_regcache (inferior_thread ()),
id.stack_addr, id.code_addr).get ();
struct inferior *
add_inferior_with_spaces (void)
{
- struct address_space *aspace;
struct program_space *pspace;
struct inferior *inf;
/* If all inferiors share an address space on this system, this
doesn't really return a new address space; otherwise, it
really does. */
- aspace = maybe_new_address_space ();
- pspace = new program_space (aspace);
+ pspace = new program_space (maybe_new_address_space ());
inf = add_inferior (0);
inf->pspace = pspace;
inf->aspace = pspace->aspace;
for (i = 0; i < copies; ++i)
{
- struct address_space *aspace;
struct program_space *pspace;
struct inferior *inf;
/* If all inferiors share an address space on this system, this
doesn't really return a new address space; otherwise, it
really does. */
- aspace = maybe_new_address_space ();
- pspace = new program_space (aspace);
+ pspace = new program_space (maybe_new_address_space ());
inf = add_inferior (0);
inf->pspace = pspace;
inf->aspace = pspace->aspace;
bool removable = false;
/* The address space bound to this inferior. */
- struct address_space *aspace = NULL;
+ address_space_ref_ptr aspace;
/* The program space bound to this inferior. */
struct program_space *pspace = NULL;
}
else
{
- child_inf->aspace = new address_space ();
- child_inf->pspace = new program_space (child_inf->aspace);
+ child_inf->pspace = new program_space (new_address_space ());
+ child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
}
child_inf->aspace = parent_inf->aspace;
child_inf->pspace = parent_inf->pspace;
- parent_inf->aspace = new address_space ();
- parent_inf->pspace = new program_space (parent_inf->aspace);
+ parent_inf->pspace = new program_space (new_address_space ());
+ parent_inf->aspace = parent_inf->pspace->aspace;
clone_program_space (parent_inf->pspace, child_inf->pspace);
/* The parent inferior is still the current one, so keep things
}
else
{
- child_inf->aspace = new address_space ();
- child_inf->pspace = new program_space (child_inf->aspace);
+ child_inf->pspace = new program_space (new_address_space ());
+ child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
clone_program_space (child_inf->pspace, parent_inf->pspace);
if (vfork_parent->pending_detach)
{
struct program_space *pspace;
- struct address_space *aspace;
/* follow-fork child, detach-on-fork on. */
of" a hack. */
pspace = inf->pspace;
- aspace = inf->aspace;
- inf->aspace = nullptr;
inf->pspace = nullptr;
+ address_space_ref_ptr aspace = std::move (inf->aspace);
if (print_inferior_events)
{
inferior_ptid.to_string ().c_str (),
paddress (gdbarch, pc));
- const address_space *aspace = tp->inf->aspace;
+ const address_space *aspace = tp->inf->aspace.get ();
/* Normally, by the time we reach `resume', the breakpoints are either
removed or inserted, as appropriate. The exception is if we're sitting
{
struct regcache *regcache = get_thread_regcache (tp);
- if (breakpoint_here_p (tp->inf->aspace,
+ if (breakpoint_here_p (tp->inf->aspace.get (),
regcache_read_pc (regcache))
== ordinary_breakpoint_here)
return true;
if (addr == (CORE_ADDR) -1)
{
- const address_space *aspace = cur_thr->inf->aspace;
+ const address_space *aspace = cur_thr->inf->aspace.get ();
if (cur_thr->stop_pc_p ()
&& pc == cur_thr->stop_pc ()
paddress (gdbarch, pc));
discard = 1;
}
- else if (!breakpoint_inserted_here_p (tp->inf->aspace, pc))
+ else if (!breakpoint_inserted_here_p (tp->inf->aspace.get (), pc))
{
infrun_debug_printf ("previous breakpoint of %s, at %s gone",
tp->ptid.to_string ().c_str (),
if (decr_pc == 0)
return;
- const address_space *aspace = thread->inf->aspace;
+ const address_space *aspace = thread->inf->aspace.get ();
/* Find the location where (if we've hit a breakpoint) the
breakpoint would be. */
infrun_debug_printf ("syscall number=%d", syscall_number);
ecs->event_thread->control.stop_bpstat
- = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace,
+ = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace.get (),
ecs->event_thread->stop_pc (),
ecs->event_thread, ecs->ws);
&& ws.sig () == GDB_SIGNAL_TRAP)
{
struct regcache *regcache = get_thread_regcache (tp);
- const address_space *aspace = tp->inf->aspace;
+ const address_space *aspace = tp->inf->aspace.get ();
CORE_ADDR pc = regcache_read_pc (regcache);
adjust_pc_after_break (tp, tp->pending_waitstatus ());
{
struct regcache *regcache = get_thread_regcache (ecs->event_thread);
- if (breakpoint_inserted_here_p (ecs->event_thread->inf->aspace,
+ if (breakpoint_inserted_here_p (ecs->event_thread->inf->aspace.get (),
regcache_read_pc (regcache)))
{
infrun_debug_printf ("Treating signal as SIGTRAP");
handle_solib_event ();
ecs->event_thread->set_stop_pc (regcache_read_pc (regcache));
+ address_space *aspace = ecs->event_thread->inf->aspace.get ();
ecs->event_thread->control.stop_bpstat
- = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace,
+ = bpstat_stop_status_nowatch (aspace,
ecs->event_thread->stop_pc (),
ecs->event_thread, ecs->ws);
(regcache_read_pc (get_thread_regcache (ecs->event_thread)));
ecs->event_thread->control.stop_bpstat
- = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace,
+ = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace.get (),
ecs->event_thread->stop_pc (),
ecs->event_thread, ecs->ws);
(regcache_read_pc (get_thread_regcache (ecs->event_thread)));
ecs->event_thread->control.stop_bpstat
- = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace,
+ = bpstat_stop_status_nowatch (ecs->event_thread->inf->aspace.get (),
ecs->event_thread->stop_pc (),
ecs->event_thread, ecs->ws);
CORE_ADDR pc;
regcache = get_thread_regcache (ecs->event_thread);
- const address_space *aspace = ecs->event_thread->inf->aspace;
+ const address_space *aspace = ecs->event_thread->inf->aspace.get ();
pc = regcache_read_pc (regcache);
inline function call sites). */
if (ecs->event_thread->control.step_range_end != 1)
{
- const address_space *aspace = ecs->event_thread->inf->aspace;
+ const address_space *aspace = ecs->event_thread->inf->aspace.get ();
/* skip_inline_frames is expensive, so we avoid it if we can
determine that the address is one where functions cannot have
/* See if there is a breakpoint/watchpoint/catchpoint/etc. that
handles this event. */
ecs->event_thread->control.stop_bpstat
- = bpstat_stop_status (ecs->event_thread->inf->aspace,
+ = bpstat_stop_status (ecs->event_thread->inf->aspace.get (),
ecs->event_thread->stop_pc (),
ecs->event_thread, ecs->ws, stop_chain);
if (remove_bp
&& (remove_wps || !use_displaced_stepping (ecs->event_thread)))
{
- set_step_over_info (ecs->event_thread->inf->aspace,
+ set_step_over_info (ecs->event_thread->inf->aspace.get (),
regcache_read_pc (regcache), remove_wps,
ecs->event_thread->global_num);
}
immediately, and we're not waiting for this LWP. */
if (!lp->ptid.matches (wait_ptid))
{
- if (breakpoint_inserted_here_p (inf->aspace, pc))
+ if (breakpoint_inserted_here_p (inf->aspace.get (), pc))
leave_stopped = 1;
}
return a pointer to an existing address space, in case inferiors
share an address space on this target system. */
-struct address_space *
-maybe_new_address_space (void)
+address_space_ref_ptr
+maybe_new_address_space ()
{
int shared_aspace
= gdbarch_has_shared_address_space (current_inferior ()->arch ());
return program_spaces[0]->aspace;
}
- return new address_space ();
+ return new_address_space ();
}
/* Start counting over from scratch. */
/* See progspace.h. */
-program_space::program_space (address_space *aspace_)
+program_space::program_space (address_space_ref_ptr aspace_)
: num (++last_program_space_num),
- aspace (aspace_)
+ aspace (std::move (aspace_))
{
program_spaces.push_back (this);
gdb::observers::new_program_space.notify (this);
/* Defer breakpoint re-set because we don't want to create new
locations for this pspace which we're tearing down. */
clear_symtab_users (SYMFILE_DEFER_BP_RESET);
- if (!gdbarch_has_shared_address_space (current_inferior ()->arch ()))
- delete this->aspace;
}
/* See progspace.h. */
if (shared_aspace)
{
- struct address_space *aspace = new address_space ();
+ address_space_ref_ptr aspace = new_address_space ();
- delete current_program_space->aspace;
for (struct program_space *pspace : program_spaces)
pspace->aspace = aspace;
}
else
for (struct program_space *pspace : program_spaces)
- {
- delete pspace->aspace;
- pspace->aspace = new address_space ();
- }
+ pspace->aspace = new_address_space ();
for (inferior *inf : all_inferiors ())
if (gdbarch_has_global_solist (current_inferior ()->arch ()))
modules have done that. Do this before
initialize_current_architecture, because that accesses the ebfd
of current_program_space. */
- current_program_space = new program_space (new address_space ());
+ current_program_space = new program_space (new_address_space ());
}
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/safe-iterator.h"
#include "gdbsupport/intrusive_list.h"
+#include "gdbsupport/refcounted-object.h"
+#include "gdbsupport/gdb_ref_ptr.h"
#include <list>
#include <vector>
typedef std::list<std::unique_ptr<objfile>> objfile_list;
+/* An address space. It is used for comparing if
+ pspaces/inferior/threads see the same address space and for
+ associating caches to each address space. */
+struct address_space : public refcounted_object
+{
+ /* Create a new address space object, and add it to the list. */
+ address_space ();
+ DISABLE_COPY_AND_ASSIGN (address_space);
+
+ /* Returns the integer address space id of this address space. */
+ int num () const
+ {
+ return m_num;
+ }
+
+ /* Per aspace data-pointers required by other GDB modules. */
+ registry<address_space> registry_fields;
+
+private:
+ int m_num;
+};
+
+using address_space_ref_ptr
+ = gdb::ref_ptr<address_space,
+ refcounted_object_delete_ref_policy<address_space>>;
+
+/* Create a new address space. */
+
+static inline address_space_ref_ptr
+new_address_space ()
+{
+ return address_space_ref_ptr::new_reference (new address_space);
+}
+
/* An iterator that wraps an iterator over std::unique_ptr<objfile>,
and dereferences the returned object. This is useful for iterating
over a list of shared pointers and returning raw pointers -- which
{
/* Constructs a new empty program space, binds it to ASPACE, and
adds it to the program space list. */
- explicit program_space (address_space *aspace);
+ explicit program_space (address_space_ref_ptr aspace);
/* Releases a program space, and all its contents (shared libraries,
objfiles, and any other references to the program space in other
are global, then this field is ignored (we don't currently
support inferiors sharing a program space if the target doesn't
make breakpoints global). */
- struct address_space *aspace = NULL;
+ address_space_ref_ptr aspace;
/* True if this program space's section offsets don't yet represent
the final offsets of the "live" address space (that is, the
std::vector<target_section> m_target_sections;
};
-/* An address space. It is used for comparing if
- pspaces/inferior/threads see the same address space and for
- associating caches to each address space. */
-struct address_space
-{
- /* Create a new address space object, and add it to the list. */
- address_space ();
- DISABLE_COPY_AND_ASSIGN (address_space);
-
- /* Returns the integer address space id of this address space. */
- int num () const
- {
- return m_num;
- }
-
- /* Per aspace data-pointers required by other GDB modules. */
- registry<address_space> registry_fields;
-
-private:
- int m_num;
-};
-
/* The list of all program spaces. There's always at least one. */
extern std::vector<struct program_space *>program_spaces;
/* Maybe create a new address space object, and add it to the list, or
return a pointer to an existing address space, in case inferiors
share an address space. */
-extern struct address_space *maybe_new_address_space (void);
+extern address_space_ref_ptr maybe_new_address_space ();
/* Update all program spaces matching to address spaces. The user may
have created several program spaces, and loaded executables into
if (insn == NULL)
return 0;
- return record_check_stopped_by_breakpoint (tp->inf->aspace, insn->pc,
+ return record_check_stopped_by_breakpoint (tp->inf->aspace.get (), insn->pc,
&btinfo->stop_reason);
}
not doing the change at all if the watchpoint
traps. */
if (hardware_watchpoint_inserted_in_range
- (current_inferior ()->aspace,
+ (current_inferior ()->aspace.get (),
entry->u.mem.addr, entry->u.mem.len))
record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
}
ret);
regcache = get_thread_regcache (inferior_thread ());
tmp_pc = regcache_read_pc (regcache);
- const address_space *aspace = current_inferior ()->aspace;
+ const address_space *aspace
+ = current_inferior ()->aspace.get ();
if (target_stopped_by_watchpoint ())
{
record_full_resume_ptid);
regcache *regcache = get_thread_regcache (inferior_thread ());
struct gdbarch *gdbarch = regcache->arch ();
- const address_space *aspace = current_inferior ()->aspace;
+ const address_space *aspace = current_inferior ()->aspace.get ();
int continue_flag = 1;
int first_record_full_end = 1;
Target mock_target;
ptid_t mock_ptid {1, 1};
- program_space mock_pspace {new address_space ()};
+ program_space mock_pspace {new_address_space ()};
inferior mock_inferior {mock_ptid.pid ()};
thread_info mock_thread {&mock_inferior, mock_ptid};
/* Target dcache is initialized or not. */
int
-target_dcache_init_p (address_space *aspace)
+target_dcache_init_p (address_space_ref_ptr aspace)
{
DCACHE *dcache
- = target_dcache_aspace_key.get (aspace);
+ = target_dcache_aspace_key.get (aspace.get ());
return (dcache != NULL);
}
/* Invalidate the target dcache. */
void
-target_dcache_invalidate (address_space *aspace)
+target_dcache_invalidate (address_space_ref_ptr aspace)
{
DCACHE *dcache
- = target_dcache_aspace_key.get (aspace);
+ = target_dcache_aspace_key.get (aspace.get ());
if (dcache != NULL)
dcache_invalidate (dcache);
initialized yet. */
DCACHE *
-target_dcache_get (address_space *aspace)
+target_dcache_get (address_space_ref_ptr aspace)
{
- return target_dcache_aspace_key.get (aspace);
+ return target_dcache_aspace_key.get (aspace.get ());
}
/* Return the target dcache. If it is not initialized yet, initialize
it. */
DCACHE *
-target_dcache_get_or_init (address_space *aspace)
+target_dcache_get_or_init (address_space_ref_ptr aspace)
{
DCACHE *dcache
- = target_dcache_aspace_key.get (aspace);
+ = target_dcache_aspace_key.get (aspace.get ());
if (dcache == NULL)
{
dcache = dcache_init ();
- target_dcache_aspace_key.set (aspace, dcache);
+ target_dcache_aspace_key.set (aspace.get (), dcache);
}
return dcache;
#define TARGET_DCACHE_H
#include "dcache.h"
+#include "progspace.h"
-struct address_space;
+extern void target_dcache_invalidate (address_space_ref_ptr aspace);
-extern void target_dcache_invalidate (address_space *aspace);
+extern DCACHE *target_dcache_get (address_space_ref_ptr aspace);
-extern DCACHE *target_dcache_get (address_space *aspace);
+extern DCACHE *target_dcache_get_or_init (address_space_ref_ptr aspace);
-extern DCACHE *target_dcache_get_or_init (address_space *aspace);
-
-extern int target_dcache_init_p (address_space *aspace);
+extern int target_dcache_init_p (address_space_ref_ptr aspace);
extern int stack_cache_enabled_p (void);
}
};
+/* A policy class to interface gdb::ref_ptr with a refcounted_object, that
+ deletes the object once the refcount reaches 0.. */
+
+template<typename T>
+struct refcounted_object_delete_ref_policy
+{
+ static void incref (T *obj)
+ { obj->incref (); }
+
+ static void decref (T *obj)
+ {
+ obj->decref ();
+ if (obj->refcount () == 0)
+ delete obj;
+ }
+};
+
#endif /* COMMON_REFCOUNTED_OBJECT_H */