mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-09 04:21:49 +08:00
Change iterate_over_lwps to take a gdb::function_view
This changes iterate_over_lwps to use a gdb::function_view. This was needed in order to make null_ptid and minus_one_ptid 'const'. gdb/ChangeLog 2019-03-12 Tom Tromey <tromey@adacore.com> * linux-nat.c (iterate_over_lwps): Update. (stop_callback): Remove parameter. (stop_wait_callback, detach_callback, resume_set_callback) (select_singlestep_lwp_callback, set_ignore_sigint) (status_callback, resumed_callback, resume_clear_callback) (kill_callback, kill_wait_callback, linux_nat_stop_lwp): Remove data parameter. (linux_nat_target::detach, linux_nat_target::resume) (linux_stop_and_wait_all_lwps, select_event_lwp) (linux_nat_filter_event, linux_nat_wait_1) (linux_nat_target::kill, linux_nat_target::stop) (linux_nat_target::stop): Update. (linux_nat_resume_callback): Change type. (resume_stopped_resumed_lwps, count_events_callback) (select_event_lwp_callback): Likewise. (linux_stop_lwp, linux_nat_stop_lwp): Update. * arm-linux-nat.c (struct update_registers_data): Remove. (update_registers_callback): Change type. (arm_linux_insert_hw_breakpoint1): Update. * nat/x86-linux-dregs.c (update_debug_registers_callback): Remove parameter. (x86_linux_dr_set_addr): Update. (x86_linux_dr_set_control): Update. * nat/linux-nat.h (iterate_over_lwps_ftype): Remove parameter. (iterate_over_lwps): Use gdb::function_view. * nat/aarch64-linux-hw-point.c (struct aarch64_dr_update_callback_param): Remove. (debug_reg_change_callback): Change type. (aarch64_notify_debug_reg_change): Update. * s390-linux-nat.c (s390_refresh_per_info): Update. gdb/gdbserver/ChangeLog 2019-03-12 Tom Tromey <tromey@adacore.com> * linux-low.c (iterate_over_lwps): Update.
This commit is contained in:
parent
7a6e0d89bb
commit
d3a70e03cf
@ -1,3 +1,36 @@
|
|||||||
|
2019-03-12 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
* linux-nat.c (iterate_over_lwps): Update.
|
||||||
|
(stop_callback): Remove parameter.
|
||||||
|
(stop_wait_callback, detach_callback, resume_set_callback)
|
||||||
|
(select_singlestep_lwp_callback, set_ignore_sigint)
|
||||||
|
(status_callback, resumed_callback, resume_clear_callback)
|
||||||
|
(kill_callback, kill_wait_callback, linux_nat_stop_lwp): Remove
|
||||||
|
data parameter.
|
||||||
|
(linux_nat_target::detach, linux_nat_target::resume)
|
||||||
|
(linux_stop_and_wait_all_lwps, select_event_lwp)
|
||||||
|
(linux_nat_filter_event, linux_nat_wait_1)
|
||||||
|
(linux_nat_target::kill, linux_nat_target::stop)
|
||||||
|
(linux_nat_target::stop): Update.
|
||||||
|
(linux_nat_resume_callback): Change type.
|
||||||
|
(resume_stopped_resumed_lwps, count_events_callback)
|
||||||
|
(select_event_lwp_callback): Likewise.
|
||||||
|
(linux_stop_lwp, linux_nat_stop_lwp): Update.
|
||||||
|
* arm-linux-nat.c (struct update_registers_data): Remove.
|
||||||
|
(update_registers_callback): Change type.
|
||||||
|
(arm_linux_insert_hw_breakpoint1): Update.
|
||||||
|
* nat/x86-linux-dregs.c (update_debug_registers_callback): Remove
|
||||||
|
parameter.
|
||||||
|
(x86_linux_dr_set_addr): Update.
|
||||||
|
(x86_linux_dr_set_control): Update.
|
||||||
|
* nat/linux-nat.h (iterate_over_lwps_ftype): Remove parameter.
|
||||||
|
(iterate_over_lwps): Use gdb::function_view.
|
||||||
|
* nat/aarch64-linux-hw-point.c (struct
|
||||||
|
aarch64_dr_update_callback_param): Remove.
|
||||||
|
(debug_reg_change_callback): Change type.
|
||||||
|
(aarch64_notify_debug_reg_change): Update.
|
||||||
|
* s390-linux-nat.c (s390_refresh_per_info): Update.
|
||||||
|
|
||||||
2019-03-11 Tom Tromey <tromey@adacore.com>
|
2019-03-11 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
* dwarf2read.c (dwarf2_find_containing_comp_unit): Remove
|
* dwarf2read.c (dwarf2_find_containing_comp_unit): Remove
|
||||||
|
@ -952,26 +952,18 @@ arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1,
|
|||||||
/* Callback to mark a watch-/breakpoint to be updated in all threads of
|
/* Callback to mark a watch-/breakpoint to be updated in all threads of
|
||||||
the current process. */
|
the current process. */
|
||||||
|
|
||||||
struct update_registers_data
|
|
||||||
{
|
|
||||||
int watch;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_registers_callback (struct lwp_info *lwp, void *arg)
|
update_registers_callback (struct lwp_info *lwp, int watch, int index)
|
||||||
{
|
{
|
||||||
struct update_registers_data *data = (struct update_registers_data *) arg;
|
|
||||||
|
|
||||||
if (lwp->arch_private == NULL)
|
if (lwp->arch_private == NULL)
|
||||||
lwp->arch_private = XCNEW (struct arch_lwp_info);
|
lwp->arch_private = XCNEW (struct arch_lwp_info);
|
||||||
|
|
||||||
/* The actual update is done later just before resuming the lwp,
|
/* The actual update is done later just before resuming the lwp,
|
||||||
we just mark that the registers need updating. */
|
we just mark that the registers need updating. */
|
||||||
if (data->watch)
|
if (watch)
|
||||||
lwp->arch_private->wpts_changed[data->index] = 1;
|
lwp->arch_private->wpts_changed[index] = 1;
|
||||||
else
|
else
|
||||||
lwp->arch_private->bpts_changed[data->index] = 1;
|
lwp->arch_private->bpts_changed[index] = 1;
|
||||||
|
|
||||||
/* If the lwp isn't stopped, force it to momentarily pause, so
|
/* If the lwp isn't stopped, force it to momentarily pause, so
|
||||||
we can update its breakpoint registers. */
|
we can update its breakpoint registers. */
|
||||||
@ -991,7 +983,6 @@ arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt,
|
|||||||
ptid_t pid_ptid;
|
ptid_t pid_ptid;
|
||||||
gdb_byte count, i;
|
gdb_byte count, i;
|
||||||
struct arm_linux_hw_breakpoint* bpts;
|
struct arm_linux_hw_breakpoint* bpts;
|
||||||
struct update_registers_data data;
|
|
||||||
|
|
||||||
pid = inferior_ptid.pid ();
|
pid = inferior_ptid.pid ();
|
||||||
pid_ptid = ptid_t (pid);
|
pid_ptid = ptid_t (pid);
|
||||||
@ -1010,10 +1001,13 @@ arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt,
|
|||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
if (!arm_hwbp_control_is_enabled (bpts[i].control))
|
if (!arm_hwbp_control_is_enabled (bpts[i].control))
|
||||||
{
|
{
|
||||||
data.watch = watchpoint;
|
|
||||||
data.index = i;
|
|
||||||
bpts[i] = *bpt;
|
bpts[i] = *bpt;
|
||||||
iterate_over_lwps (pid_ptid, update_registers_callback, &data);
|
iterate_over_lwps (pid_ptid,
|
||||||
|
[=] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return update_registers_callback (info, watch,
|
||||||
|
index);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2019-03-12 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
* linux-low.c (iterate_over_lwps): Update.
|
||||||
|
|
||||||
2019-03-06 Tom Tromey <tom@tromey.com>
|
2019-03-06 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* server.c (detach_or_kill_for_exit_cleanup): Remove parameter.
|
* server.c (detach_or_kill_for_exit_cleanup): Remove parameter.
|
||||||
|
@ -1843,14 +1843,13 @@ num_lwps (int pid)
|
|||||||
|
|
||||||
struct lwp_info *
|
struct lwp_info *
|
||||||
iterate_over_lwps (ptid_t filter,
|
iterate_over_lwps (ptid_t filter,
|
||||||
iterate_over_lwps_ftype callback,
|
gdb::function_view<iterate_over_lwps_ftype> callback)
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
|
thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
|
||||||
{
|
{
|
||||||
lwp_info *lwp = get_thread_lwp (thr_arg);
|
lwp_info *lwp = get_thread_lwp (thr_arg);
|
||||||
|
|
||||||
return callback (lwp, data);
|
return callback (lwp);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (thread == NULL)
|
if (thread == NULL)
|
||||||
|
138
gdb/linux-nat.c
138
gdb/linux-nat.c
@ -262,8 +262,7 @@ async_file_mark (void)
|
|||||||
|
|
||||||
static int kill_lwp (int lwpid, int signo);
|
static int kill_lwp (int lwpid, int signo);
|
||||||
|
|
||||||
static int stop_callback (struct lwp_info *lp, void *data);
|
static int stop_callback (struct lwp_info *lp);
|
||||||
static int resume_stopped_resumed_lwps (struct lwp_info *lp, void *data);
|
|
||||||
|
|
||||||
static void block_child_signals (sigset_t *prev_mask);
|
static void block_child_signals (sigset_t *prev_mask);
|
||||||
static void restore_child_signals_mask (sigset_t *prev_mask);
|
static void restore_child_signals_mask (sigset_t *prev_mask);
|
||||||
@ -807,8 +806,8 @@ linux_nat_target::pass_signals
|
|||||||
|
|
||||||
|
|
||||||
/* Prototypes for local functions. */
|
/* Prototypes for local functions. */
|
||||||
static int stop_wait_callback (struct lwp_info *lp, void *data);
|
static int stop_wait_callback (struct lwp_info *lp);
|
||||||
static int resume_stopped_resumed_lwps (struct lwp_info *lp, void *data);
|
static int resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid);
|
||||||
static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
|
static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
|
||||||
|
|
||||||
|
|
||||||
@ -960,8 +959,7 @@ find_lwp_pid (ptid_t ptid)
|
|||||||
|
|
||||||
struct lwp_info *
|
struct lwp_info *
|
||||||
iterate_over_lwps (ptid_t filter,
|
iterate_over_lwps (ptid_t filter,
|
||||||
iterate_over_lwps_ftype callback,
|
gdb::function_view<iterate_over_lwps_ftype> callback)
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
struct lwp_info *lp, *lpnext;
|
struct lwp_info *lp, *lpnext;
|
||||||
|
|
||||||
@ -971,7 +969,7 @@ iterate_over_lwps (ptid_t filter,
|
|||||||
|
|
||||||
if (lp->ptid.matches (filter))
|
if (lp->ptid.matches (filter))
|
||||||
{
|
{
|
||||||
if ((*callback) (lp, data) != 0)
|
if (callback (lp) != 0)
|
||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1456,7 +1454,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
detach_callback (struct lwp_info *lp, void *data)
|
detach_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
/* We don't actually detach from the thread group leader just yet.
|
/* We don't actually detach from the thread group leader just yet.
|
||||||
If the thread group exits, we must reap the zombie clone lwps
|
If the thread group exits, we must reap the zombie clone lwps
|
||||||
@ -1477,12 +1475,12 @@ linux_nat_target::detach (inferior *inf, int from_tty)
|
|||||||
|
|
||||||
/* Stop all threads before detaching. ptrace requires that the
|
/* Stop all threads before detaching. ptrace requires that the
|
||||||
thread is stopped to sucessfully detach. */
|
thread is stopped to sucessfully detach. */
|
||||||
iterate_over_lwps (ptid_t (pid), stop_callback, NULL);
|
iterate_over_lwps (ptid_t (pid), stop_callback);
|
||||||
/* ... and wait until all of them have reported back that
|
/* ... and wait until all of them have reported back that
|
||||||
they're no longer running. */
|
they're no longer running. */
|
||||||
iterate_over_lwps (ptid_t (pid), stop_wait_callback, NULL);
|
iterate_over_lwps (ptid_t (pid), stop_wait_callback);
|
||||||
|
|
||||||
iterate_over_lwps (ptid_t (pid), detach_callback, NULL);
|
iterate_over_lwps (ptid_t (pid), detach_callback);
|
||||||
|
|
||||||
/* Only the initial process should be left right now. */
|
/* Only the initial process should be left right now. */
|
||||||
gdb_assert (num_lwps (pid) == 1);
|
gdb_assert (num_lwps (pid) == 1);
|
||||||
@ -1646,7 +1644,7 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
|
|||||||
Resume LWP with the last stop signal, if it is in pass state. */
|
Resume LWP with the last stop signal, if it is in pass state. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linux_nat_resume_callback (struct lwp_info *lp, void *except)
|
linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
|
||||||
{
|
{
|
||||||
enum gdb_signal signo = GDB_SIGNAL_0;
|
enum gdb_signal signo = GDB_SIGNAL_0;
|
||||||
|
|
||||||
@ -1670,7 +1668,7 @@ linux_nat_resume_callback (struct lwp_info *lp, void *except)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resume_clear_callback (struct lwp_info *lp, void *data)
|
resume_clear_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
lp->resumed = 0;
|
lp->resumed = 0;
|
||||||
lp->last_resume_kind = resume_stop;
|
lp->last_resume_kind = resume_stop;
|
||||||
@ -1678,7 +1676,7 @@ resume_clear_callback (struct lwp_info *lp, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resume_set_callback (struct lwp_info *lp, void *data)
|
resume_set_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
lp->resumed = 1;
|
lp->resumed = 1;
|
||||||
lp->last_resume_kind = resume_continue;
|
lp->last_resume_kind = resume_continue;
|
||||||
@ -1705,7 +1703,7 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
|
|||||||
|| ptid.is_pid ());
|
|| ptid.is_pid ());
|
||||||
|
|
||||||
/* Mark the lwps we're resuming as resumed. */
|
/* Mark the lwps we're resuming as resumed. */
|
||||||
iterate_over_lwps (ptid, resume_set_callback, NULL);
|
iterate_over_lwps (ptid, resume_set_callback);
|
||||||
|
|
||||||
/* See if it's the current inferior that should be handled
|
/* See if it's the current inferior that should be handled
|
||||||
specially. */
|
specially. */
|
||||||
@ -1766,7 +1764,10 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resume_many)
|
if (resume_many)
|
||||||
iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
|
iterate_over_lwps (ptid, [=] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return linux_nat_resume_callback (info, lp);
|
||||||
|
});
|
||||||
|
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
@ -2305,7 +2306,7 @@ wait_lwp (struct lwp_info *lp)
|
|||||||
/* Send a SIGSTOP to LP. */
|
/* Send a SIGSTOP to LP. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
stop_callback (struct lwp_info *lp, void *data)
|
stop_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
if (!lp->stopped && !lp->signalled)
|
if (!lp->stopped && !lp->signalled)
|
||||||
{
|
{
|
||||||
@ -2339,7 +2340,7 @@ stop_callback (struct lwp_info *lp, void *data)
|
|||||||
void
|
void
|
||||||
linux_stop_lwp (struct lwp_info *lwp)
|
linux_stop_lwp (struct lwp_info *lwp)
|
||||||
{
|
{
|
||||||
stop_callback (lwp, NULL);
|
stop_callback (lwp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See linux-nat.h */
|
/* See linux-nat.h */
|
||||||
@ -2348,11 +2349,11 @@ void
|
|||||||
linux_stop_and_wait_all_lwps (void)
|
linux_stop_and_wait_all_lwps (void)
|
||||||
{
|
{
|
||||||
/* Stop all LWP's ... */
|
/* Stop all LWP's ... */
|
||||||
iterate_over_lwps (minus_one_ptid, stop_callback, NULL);
|
iterate_over_lwps (minus_one_ptid, stop_callback);
|
||||||
|
|
||||||
/* ... and wait until all of them have reported back that
|
/* ... and wait until all of them have reported back that
|
||||||
they're no longer running. */
|
they're no longer running. */
|
||||||
iterate_over_lwps (minus_one_ptid, stop_wait_callback, NULL);
|
iterate_over_lwps (minus_one_ptid, stop_wait_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See linux-nat.h */
|
/* See linux-nat.h */
|
||||||
@ -2361,7 +2362,10 @@ void
|
|||||||
linux_unstop_all_lwps (void)
|
linux_unstop_all_lwps (void)
|
||||||
{
|
{
|
||||||
iterate_over_lwps (minus_one_ptid,
|
iterate_over_lwps (minus_one_ptid,
|
||||||
resume_stopped_resumed_lwps, &minus_one_ptid);
|
[] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return resume_stopped_resumed_lwps (info, minus_one_ptid);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if LWP PID has a pending SIGINT. */
|
/* Return non-zero if LWP PID has a pending SIGINT. */
|
||||||
@ -2383,7 +2387,7 @@ linux_nat_has_pending_sigint (int pid)
|
|||||||
/* Set a flag in LP indicating that we should ignore its next SIGINT. */
|
/* Set a flag in LP indicating that we should ignore its next SIGINT. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_ignore_sigint (struct lwp_info *lp, void *data)
|
set_ignore_sigint (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
/* If a thread has a pending SIGINT, consume it; otherwise, set a
|
/* If a thread has a pending SIGINT, consume it; otherwise, set a
|
||||||
flag to consume the next one. */
|
flag to consume the next one. */
|
||||||
@ -2484,7 +2488,7 @@ linux_nat_target::low_status_is_event (int status)
|
|||||||
/* Wait until LP is stopped. */
|
/* Wait until LP is stopped. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
stop_wait_callback (struct lwp_info *lp, void *data)
|
stop_wait_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
struct inferior *inf = find_inferior_ptid (lp->ptid);
|
struct inferior *inf = find_inferior_ptid (lp->ptid);
|
||||||
|
|
||||||
@ -2516,7 +2520,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
|||||||
target_pid_to_str (lp->ptid),
|
target_pid_to_str (lp->ptid),
|
||||||
errno ? safe_strerror (errno) : "OK");
|
errno ? safe_strerror (errno) : "OK");
|
||||||
|
|
||||||
return stop_wait_callback (lp, NULL);
|
return stop_wait_callback (lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_clear_ignore_sigint (lp);
|
maybe_clear_ignore_sigint (lp);
|
||||||
@ -2566,7 +2570,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
|||||||
caused the stop became uninteresting. */
|
caused the stop became uninteresting. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
status_callback (struct lwp_info *lp, void *data)
|
status_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
/* Only report a pending wait status if we pretend that this has
|
/* Only report a pending wait status if we pretend that this has
|
||||||
indeed been resumed. */
|
indeed been resumed. */
|
||||||
@ -2628,10 +2632,8 @@ status_callback (struct lwp_info *lp, void *data)
|
|||||||
/* Count the LWP's that have had events. */
|
/* Count the LWP's that have had events. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
count_events_callback (struct lwp_info *lp, void *data)
|
count_events_callback (struct lwp_info *lp, int *count)
|
||||||
{
|
{
|
||||||
int *count = (int *) data;
|
|
||||||
|
|
||||||
gdb_assert (count != NULL);
|
gdb_assert (count != NULL);
|
||||||
|
|
||||||
/* Select only resumed LWPs that have an event pending. */
|
/* Select only resumed LWPs that have an event pending. */
|
||||||
@ -2644,7 +2646,7 @@ count_events_callback (struct lwp_info *lp, void *data)
|
|||||||
/* Select the LWP (if any) that is currently being single-stepped. */
|
/* Select the LWP (if any) that is currently being single-stepped. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
select_singlestep_lwp_callback (struct lwp_info *lp, void *data)
|
select_singlestep_lwp_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
if (lp->last_resume_kind == resume_step
|
if (lp->last_resume_kind == resume_step
|
||||||
&& lp->status != 0)
|
&& lp->status != 0)
|
||||||
@ -2667,10 +2669,8 @@ lwp_status_pending_p (struct lwp_info *lp)
|
|||||||
/* Select the Nth LWP that has had an event. */
|
/* Select the Nth LWP that has had an event. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
select_event_lwp_callback (struct lwp_info *lp, void *data)
|
select_event_lwp_callback (struct lwp_info *lp, int *selector)
|
||||||
{
|
{
|
||||||
int *selector = (int *) data;
|
|
||||||
|
|
||||||
gdb_assert (selector != NULL);
|
gdb_assert (selector != NULL);
|
||||||
|
|
||||||
/* Select only resumed LWPs that have an event pending. */
|
/* Select only resumed LWPs that have an event pending. */
|
||||||
@ -2869,8 +2869,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
|
|||||||
signal. */
|
signal. */
|
||||||
if (!target_is_non_stop_p ())
|
if (!target_is_non_stop_p ())
|
||||||
{
|
{
|
||||||
event_lp = iterate_over_lwps (filter,
|
event_lp = iterate_over_lwps (filter, select_singlestep_lwp_callback);
|
||||||
select_singlestep_lwp_callback, NULL);
|
|
||||||
if (event_lp != NULL)
|
if (event_lp != NULL)
|
||||||
{
|
{
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
@ -2885,7 +2884,11 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
|
|||||||
/* Pick one at random, out of those which have had events. */
|
/* Pick one at random, out of those which have had events. */
|
||||||
|
|
||||||
/* First see how many events we have. */
|
/* First see how many events we have. */
|
||||||
iterate_over_lwps (filter, count_events_callback, &num_events);
|
iterate_over_lwps (filter,
|
||||||
|
[&] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return count_events_callback (info, &num_events);
|
||||||
|
});
|
||||||
gdb_assert (num_events > 0);
|
gdb_assert (num_events > 0);
|
||||||
|
|
||||||
/* Now randomly pick a LWP out of those that have had
|
/* Now randomly pick a LWP out of those that have had
|
||||||
@ -2898,9 +2901,14 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
|
|||||||
"SEL: Found %d events, selecting #%d\n",
|
"SEL: Found %d events, selecting #%d\n",
|
||||||
num_events, random_selector);
|
num_events, random_selector);
|
||||||
|
|
||||||
event_lp = iterate_over_lwps (filter,
|
event_lp
|
||||||
select_event_lwp_callback,
|
= (iterate_over_lwps
|
||||||
&random_selector);
|
(filter,
|
||||||
|
[&] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return select_event_lwp_callback (info,
|
||||||
|
&random_selector);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_lp != NULL)
|
if (event_lp != NULL)
|
||||||
@ -2917,7 +2925,7 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
|
|||||||
/* Return non-zero if LP has been resumed. */
|
/* Return non-zero if LP has been resumed. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resumed_callback (struct lwp_info *lp, void *data)
|
resumed_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
return lp->resumed;
|
return lp->resumed;
|
||||||
}
|
}
|
||||||
@ -3136,8 +3144,7 @@ linux_nat_filter_event (int lwpid, int status)
|
|||||||
will receive it - unless they're using CLONE_THREAD to
|
will receive it - unless they're using CLONE_THREAD to
|
||||||
share signals. Since we only want to report it once, we
|
share signals. Since we only want to report it once, we
|
||||||
mark it as ignored for all LWPs except this one. */
|
mark it as ignored for all LWPs except this one. */
|
||||||
iterate_over_lwps (ptid_t (lp->ptid.pid ()),
|
iterate_over_lwps (ptid_t (lp->ptid.pid ()), set_ignore_sigint);
|
||||||
set_ignore_sigint, NULL);
|
|
||||||
lp->ignore_sigint = 0;
|
lp->ignore_sigint = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3279,7 +3286,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
block_child_signals (&prev_mask);
|
block_child_signals (&prev_mask);
|
||||||
|
|
||||||
/* First check if there is a LWP with a wait status pending. */
|
/* First check if there is a LWP with a wait status pending. */
|
||||||
lp = iterate_over_lwps (ptid, status_callback, NULL);
|
lp = iterate_over_lwps (ptid, status_callback);
|
||||||
if (lp != NULL)
|
if (lp != NULL)
|
||||||
{
|
{
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
@ -3336,11 +3343,14 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
/* Now that we've pulled all events out of the kernel, resume
|
/* Now that we've pulled all events out of the kernel, resume
|
||||||
LWPs that don't have an interesting event to report. */
|
LWPs that don't have an interesting event to report. */
|
||||||
iterate_over_lwps (minus_one_ptid,
|
iterate_over_lwps (minus_one_ptid,
|
||||||
resume_stopped_resumed_lwps, &minus_one_ptid);
|
[] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return resume_stopped_resumed_lwps (info, minus_one_ptid);
|
||||||
|
});
|
||||||
|
|
||||||
/* ... and find an LWP with a status to report to the core, if
|
/* ... and find an LWP with a status to report to the core, if
|
||||||
any. */
|
any. */
|
||||||
lp = iterate_over_lwps (ptid, status_callback, NULL);
|
lp = iterate_over_lwps (ptid, status_callback);
|
||||||
if (lp != NULL)
|
if (lp != NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3350,7 +3360,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
|
|
||||||
/* If there are no resumed children left, bail. We'd be stuck
|
/* If there are no resumed children left, bail. We'd be stuck
|
||||||
forever in the sigsuspend call below otherwise. */
|
forever in the sigsuspend call below otherwise. */
|
||||||
if (iterate_over_lwps (ptid, resumed_callback, NULL) == NULL)
|
if (iterate_over_lwps (ptid, resumed_callback) == NULL)
|
||||||
{
|
{
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
|
fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
|
||||||
@ -3388,11 +3398,11 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
if (!target_is_non_stop_p ())
|
if (!target_is_non_stop_p ())
|
||||||
{
|
{
|
||||||
/* Now stop all other LWP's ... */
|
/* Now stop all other LWP's ... */
|
||||||
iterate_over_lwps (minus_one_ptid, stop_callback, NULL);
|
iterate_over_lwps (minus_one_ptid, stop_callback);
|
||||||
|
|
||||||
/* ... and wait until all of them have reported back that
|
/* ... and wait until all of them have reported back that
|
||||||
they're no longer running. */
|
they're no longer running. */
|
||||||
iterate_over_lwps (minus_one_ptid, stop_wait_callback, NULL);
|
iterate_over_lwps (minus_one_ptid, stop_wait_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not waiting for a specific LWP, choose an event LWP from
|
/* If we're not waiting for a specific LWP, choose an event LWP from
|
||||||
@ -3431,11 +3441,11 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
{
|
{
|
||||||
/* In all-stop, from the core's perspective, all LWPs are now
|
/* In all-stop, from the core's perspective, all LWPs are now
|
||||||
stopped until a new resume action is sent over. */
|
stopped until a new resume action is sent over. */
|
||||||
iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
|
iterate_over_lwps (minus_one_ptid, resume_clear_callback);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resume_clear_callback (lp, NULL);
|
resume_clear_callback (lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linux_target->low_status_is_event (status))
|
if (linux_target->low_status_is_event (status))
|
||||||
@ -3485,10 +3495,8 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
to report, but are resumed from the core's perspective. */
|
to report, but are resumed from the core's perspective. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
|
resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
|
||||||
{
|
{
|
||||||
ptid_t *wait_ptid_p = (ptid_t *) data;
|
|
||||||
|
|
||||||
if (!lp->stopped)
|
if (!lp->stopped)
|
||||||
{
|
{
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
@ -3522,7 +3530,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
|
|||||||
|
|
||||||
/* Don't bother if there's a breakpoint at PC that we'd hit
|
/* Don't bother if there's a breakpoint at PC that we'd hit
|
||||||
immediately, and we're not waiting for this LWP. */
|
immediately, and we're not waiting for this LWP. */
|
||||||
if (!lp->ptid.matches (*wait_ptid_p))
|
if (!lp->ptid.matches (wait_ptid))
|
||||||
{
|
{
|
||||||
if (breakpoint_inserted_here_p (regcache->aspace (), pc))
|
if (breakpoint_inserted_here_p (regcache->aspace (), pc))
|
||||||
leave_stopped = 1;
|
leave_stopped = 1;
|
||||||
@ -3579,7 +3587,11 @@ linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
|
|||||||
meanwhile the event became uninteresting. Don't bother resuming
|
meanwhile the event became uninteresting. Don't bother resuming
|
||||||
LWPs we're not going to wait for if they'd stop immediately. */
|
LWPs we're not going to wait for if they'd stop immediately. */
|
||||||
if (target_is_non_stop_p ())
|
if (target_is_non_stop_p ())
|
||||||
iterate_over_lwps (minus_one_ptid, resume_stopped_resumed_lwps, &ptid);
|
iterate_over_lwps (minus_one_ptid,
|
||||||
|
[=] (struct lwp_info *info)
|
||||||
|
{
|
||||||
|
return resume_stopped_resumed_lwps (info, ptid);
|
||||||
|
});
|
||||||
|
|
||||||
event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options);
|
event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options);
|
||||||
|
|
||||||
@ -3662,7 +3674,7 @@ kill_wait_one_lwp (pid_t pid)
|
|||||||
/* Callback for iterate_over_lwps. */
|
/* Callback for iterate_over_lwps. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
kill_callback (struct lwp_info *lp, void *data)
|
kill_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
kill_one_lwp (lp->ptid.lwp ());
|
kill_one_lwp (lp->ptid.lwp ());
|
||||||
return 0;
|
return 0;
|
||||||
@ -3671,7 +3683,7 @@ kill_callback (struct lwp_info *lp, void *data)
|
|||||||
/* Callback for iterate_over_lwps. */
|
/* Callback for iterate_over_lwps. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
kill_wait_callback (struct lwp_info *lp, void *data)
|
kill_wait_callback (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
kill_wait_one_lwp (lp->ptid.lwp ());
|
kill_wait_one_lwp (lp->ptid.lwp ());
|
||||||
return 0;
|
return 0;
|
||||||
@ -3720,16 +3732,16 @@ linux_nat_target::kill ()
|
|||||||
|
|
||||||
/* Stop all threads before killing them, since ptrace requires
|
/* Stop all threads before killing them, since ptrace requires
|
||||||
that the thread is stopped to sucessfully PTRACE_KILL. */
|
that the thread is stopped to sucessfully PTRACE_KILL. */
|
||||||
iterate_over_lwps (ptid, stop_callback, NULL);
|
iterate_over_lwps (ptid, stop_callback);
|
||||||
/* ... and wait until all of them have reported back that
|
/* ... and wait until all of them have reported back that
|
||||||
they're no longer running. */
|
they're no longer running. */
|
||||||
iterate_over_lwps (ptid, stop_wait_callback, NULL);
|
iterate_over_lwps (ptid, stop_wait_callback);
|
||||||
|
|
||||||
/* Kill all LWP's ... */
|
/* Kill all LWP's ... */
|
||||||
iterate_over_lwps (ptid, kill_callback, NULL);
|
iterate_over_lwps (ptid, kill_callback);
|
||||||
|
|
||||||
/* ... and wait until we've flushed all events. */
|
/* ... and wait until we've flushed all events. */
|
||||||
iterate_over_lwps (ptid, kill_wait_callback, NULL);
|
iterate_over_lwps (ptid, kill_wait_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_mourn_inferior (inferior_ptid);
|
target_mourn_inferior (inferior_ptid);
|
||||||
@ -4415,7 +4427,7 @@ linux_nat_target::async (int enable)
|
|||||||
event came out. */
|
event came out. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
|
linux_nat_stop_lwp (struct lwp_info *lwp)
|
||||||
{
|
{
|
||||||
if (!lwp->stopped)
|
if (!lwp->stopped)
|
||||||
{
|
{
|
||||||
@ -4435,7 +4447,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_callback (lwp, NULL);
|
stop_callback (lwp);
|
||||||
lwp->last_resume_kind = resume_stop;
|
lwp->last_resume_kind = resume_stop;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4461,7 +4473,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
|
|||||||
void
|
void
|
||||||
linux_nat_target::stop (ptid_t ptid)
|
linux_nat_target::stop (ptid_t ptid)
|
||||||
{
|
{
|
||||||
iterate_over_lwps (ptid, linux_nat_stop_lwp, NULL);
|
iterate_over_lwps (ptid, linux_nat_stop_lwp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -278,27 +278,17 @@ aarch64_align_watchpoint (CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p,
|
|||||||
*next_addr_orig_p = align_down (*next_addr_orig_p + alignment, alignment);
|
*next_addr_orig_p = align_down (*next_addr_orig_p + alignment, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct aarch64_dr_update_callback_param
|
/* Helper for aarch64_notify_debug_reg_change. Records the
|
||||||
{
|
|
||||||
int is_watchpoint;
|
|
||||||
unsigned int idx;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Callback for iterate_over_lwps. Records the
|
|
||||||
information about the change of one hardware breakpoint/watchpoint
|
information about the change of one hardware breakpoint/watchpoint
|
||||||
setting for the thread LWP.
|
setting for the thread LWP.
|
||||||
The information is passed in via PTR.
|
|
||||||
N.B. The actual updating of hardware debug registers is not
|
N.B. The actual updating of hardware debug registers is not
|
||||||
carried out until the moment the thread is resumed. */
|
carried out until the moment the thread is resumed. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
debug_reg_change_callback (struct lwp_info *lwp, void *ptr)
|
debug_reg_change_callback (struct lwp_info *lwp, int is_watchpoint,
|
||||||
|
unsigned int idx)
|
||||||
{
|
{
|
||||||
struct aarch64_dr_update_callback_param *param_p
|
|
||||||
= (struct aarch64_dr_update_callback_param *) ptr;
|
|
||||||
int tid = ptid_of_lwp (lwp).lwp ();
|
int tid = ptid_of_lwp (lwp).lwp ();
|
||||||
int idx = param_p->idx;
|
|
||||||
int is_watchpoint = param_p->is_watchpoint;
|
|
||||||
struct arch_lwp_info *info = lwp_arch_private_info (lwp);
|
struct arch_lwp_info *info = lwp_arch_private_info (lwp);
|
||||||
dr_changed_t *dr_changed_ptr;
|
dr_changed_t *dr_changed_ptr;
|
||||||
dr_changed_t dr_changed;
|
dr_changed_t dr_changed;
|
||||||
@ -356,13 +346,14 @@ static void
|
|||||||
aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
|
aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
|
||||||
int is_watchpoint, unsigned int idx)
|
int is_watchpoint, unsigned int idx)
|
||||||
{
|
{
|
||||||
struct aarch64_dr_update_callback_param param;
|
|
||||||
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
||||||
|
|
||||||
param.is_watchpoint = is_watchpoint;
|
iterate_over_lwps (pid_ptid, [=] (struct lwp_info *info)
|
||||||
param.idx = idx;
|
{
|
||||||
|
return debug_reg_change_callback (info,
|
||||||
iterate_over_lwps (pid_ptid, debug_reg_change_callback, (void *) ¶m);
|
is_watchpoint,
|
||||||
|
idx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reconfigure STATE to be compatible with Linux kernels with the PR
|
/* Reconfigure STATE to be compatible with Linux kernels with the PR
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef NAT_LINUX_NAT_H
|
#ifndef NAT_LINUX_NAT_H
|
||||||
#define NAT_LINUX_NAT_H
|
#define NAT_LINUX_NAT_H
|
||||||
|
|
||||||
|
#include "common/function-view.h"
|
||||||
#include "target/waitstatus.h"
|
#include "target/waitstatus.h"
|
||||||
|
|
||||||
struct lwp_info;
|
struct lwp_info;
|
||||||
@ -43,7 +44,7 @@ struct arch_lwp_info;
|
|||||||
extern ptid_t current_lwp_ptid (void);
|
extern ptid_t current_lwp_ptid (void);
|
||||||
|
|
||||||
/* Function type for the CALLBACK argument of iterate_over_lwps. */
|
/* Function type for the CALLBACK argument of iterate_over_lwps. */
|
||||||
typedef int (iterate_over_lwps_ftype) (struct lwp_info *lwp, void *arg);
|
typedef int (iterate_over_lwps_ftype) (struct lwp_info *lwp);
|
||||||
|
|
||||||
/* Iterate over all LWPs. Calls CALLBACK with its second argument set
|
/* Iterate over all LWPs. Calls CALLBACK with its second argument set
|
||||||
to DATA for every LWP in the list. If CALLBACK returns nonzero for
|
to DATA for every LWP in the list. If CALLBACK returns nonzero for
|
||||||
@ -51,9 +52,9 @@ typedef int (iterate_over_lwps_ftype) (struct lwp_info *lwp, void *arg);
|
|||||||
LWP immediately. Otherwise return NULL. This function must be
|
LWP immediately. Otherwise return NULL. This function must be
|
||||||
provided by the client. */
|
provided by the client. */
|
||||||
|
|
||||||
extern struct lwp_info *iterate_over_lwps (ptid_t filter,
|
extern struct lwp_info *iterate_over_lwps
|
||||||
iterate_over_lwps_ftype callback,
|
(ptid_t filter,
|
||||||
void *data);
|
gdb::function_view<iterate_over_lwps_ftype> callback);
|
||||||
|
|
||||||
/* Return the ptid of LWP. */
|
/* Return the ptid of LWP. */
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
|
|||||||
the actual debug registers immediately prior to LWP resuming. */
|
the actual debug registers immediately prior to LWP resuming. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_debug_registers_callback (struct lwp_info *lwp, void *arg)
|
update_debug_registers_callback (struct lwp_info *lwp)
|
||||||
{
|
{
|
||||||
lwp_set_debug_registers_changed (lwp, 1);
|
lwp_set_debug_registers_changed (lwp, 1);
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ x86_linux_dr_set_addr (int regnum, CORE_ADDR addr)
|
|||||||
|
|
||||||
gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
|
gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
|
||||||
|
|
||||||
iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
|
iterate_over_lwps (pid_ptid, update_debug_registers_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See nat/x86-linux-dregs.h. */
|
/* See nat/x86-linux-dregs.h. */
|
||||||
@ -124,7 +124,7 @@ x86_linux_dr_set_control (unsigned long control)
|
|||||||
{
|
{
|
||||||
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
||||||
|
|
||||||
iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
|
iterate_over_lwps (pid_ptid, update_debug_registers_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See nat/x86-linux-dregs.h. */
|
/* See nat/x86-linux-dregs.h. */
|
||||||
|
@ -833,7 +833,7 @@ s390_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
|
|||||||
/* Iterator callback for s390_refresh_per_info. */
|
/* Iterator callback for s390_refresh_per_info. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
s390_refresh_per_info_cb (struct lwp_info *lp, void *arg)
|
s390_refresh_per_info_cb (struct lwp_info *lp)
|
||||||
{
|
{
|
||||||
s390_mark_per_info_changed (lp);
|
s390_mark_per_info_changed (lp);
|
||||||
|
|
||||||
@ -849,7 +849,7 @@ s390_refresh_per_info (void)
|
|||||||
{
|
{
|
||||||
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
|
||||||
|
|
||||||
iterate_over_lwps (pid_ptid, s390_refresh_per_info_cb, NULL);
|
iterate_over_lwps (pid_ptid, s390_refresh_per_info_cb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user