[binutils-gdb] Multi-target support

Pedro Alves palves@sourceware.org
Fri Jan 10 20:09:00 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5b6d1e4fa4fc6827c7b3f0e99ff120dfa14d65d2

commit 5b6d1e4fa4fc6827c7b3f0e99ff120dfa14d65d2
Author: Pedro Alves <palves@redhat.com>
Date:   Fri Jan 10 20:06:08 2020 +0000

    Multi-target support
    
    This commit adds multi-target support to GDB.  What this means is that
    with this commit, GDB can now be connected to different targets at the
    same time.  E.g., you can debug a live native process and a core dump
    at the same time, connect to multiple gdbservers, etc.
    
    Actually, the word "target" is overloaded in gdb.  We already have a
    target stack, with pushes several target_ops instances on top of one
    another.  We also have "info target" already, which means something
    completely different to what this patch does.
    
    So from here on, I'll be using the "target connections" term, to mean
    an open process_stratum target, pushed on a target stack.  This patch
    makes gdb have multiple target stacks, and multiple process_stratum
    targets open simultaneously.  The user-visible changes / commands will
    also use this terminology, but of course it's all open to debate.
    
    User-interface-wise, not that much changes.  The main difference is
    that each inferior may have its own target connection.
    
    A target connection (e.g., a target extended-remote connection) may
    support debugging multiple processes, just as before.
    
    Say you're debugging against gdbserver in extended-remote mode, and
    you do "add-inferior" to prepare to spawn a new process, like:
    
     (gdb) target extended-remote :9999
     ...
     (gdb) start
     ...
     (gdb) add-inferior
     Added inferior 2
     (gdb) inferior 2
     [Switching to inferior 2 [<null>] (<noexec>)]
     (gdb) file a.out
     ...
     (gdb) start
     ...
    
    At this point, you have two inferiors connected to the same gdbserver.
    
    With this commit, GDB will maintain a target stack per inferior,
    instead of a global target stack.
    
    To preserve the behavior above, by default, "add-inferior" makes the
    new inferior inherit a copy of the target stack of the current
    inferior.  Same across a fork - the child inherits a copy of the
    target stack of the parent.  While the target stacks are copied, the
    targets themselves are not.  Instead, target_ops is made a
    refcounted_object, which means that target_ops instances are
    refcounted, which each inferior counting for a reference.
    
    What if you want to create an inferior and connect it to some _other_
    target?  For that, this commit introduces a new "add-inferior
    -no-connection" option that makes the new inferior not share the
    current inferior's target.  So you could do:
    
     (gdb) target extended-remote :9999
     Remote debugging using :9999
     ...
     (gdb) add-inferior -no-connection
     [New inferior 2]
     Added inferior 2
     (gdb) inferior 2
     [Switching to inferior 2 [<null>] (<noexec>)]
     (gdb) info inferiors
       Num  Description       Executable
       1    process 18401     target:/home/pedro/tmp/main
     * 2    <null>
     (gdb) tar extended-remote :10000
     Remote debugging using :10000
     ...
     (gdb) info inferiors
       Num  Description       Executable
       1    process 18401     target:/home/pedro/tmp/main
     * 2    process 18450     target:/home/pedro/tmp/main
     (gdb)
    
    A following patch will extended "info inferiors" to include a column
    indicating which connection an inferior is bound to, along with a
    couple other UI tweaks.
    
    Other than that, debugging is the same as before.  Users interact with
    inferiors and threads as before.  The only difference is that
    inferiors may be bound to processes running in different machines.
    
    That's pretty much all there is to it in terms of noticeable UI
    changes.
    
    On to implementation.
    
    Since we can be connected to different systems at the same time, a
    ptid_t is no longer a unique identifier.  Instead a thread can be
    identified by a pair of ptid_t and 'process_stratum_target *', the
    later being the instance of the process_stratum target that owns the
    process/thread.  Note that process_stratum_target inherits from
    target_ops, and all process_stratum targets inherit from
    process_stratum_target.  In earlier patches, many places in gdb were
    converted to refer to threads by thread_info pointer instead of
    ptid_t, but there are still places in gdb where we start with a
    pid/tid and need to find the corresponding inferior or thread_info
    objects.  So you'll see in the patch many places adding a
    process_stratum_target parameter to functions that used to take only a
    ptid_t.
    
    Since each inferior has its own target stack now, we can always find
    the process_stratum target for an inferior.  That is done via a
    inf->process_target() convenience method.
    
    Since each inferior has its own target stack, we need to handle the
    "beneath" calls when servicing target calls.  The solution I settled
    with is just to make sure to switch the current inferior to the
    inferior you want before making a target call.  Not relying on global
    context is just not feasible in current GDB.  Fortunately, there
    aren't that many places that need to do that, because generally most
    code that calls target methods already has the current context
    pointing to the right inferior/thread.  Note, to emphasize -- there's
    no method to "switch to this target stack".  Instead, you switch the
    current inferior, and that implicitly switches the target stack.
    
    In some spots, we need to iterate over all inferiors so that we reach
    all target stacks.
    
    Native targets are still singletons.  There's always only a single
    instance of such targets.
    
    Remote targets however, we'll have one instance per remote connection.
    
    The exec target is still a singleton.  There's only one instance.  I
    did not see the point of instanciating more than one exec_target
    object.
    
    After vfork, we need to make sure to push the exec target on the new
    inferior.  See exec_on_vfork.
    
    For type safety, functions that need a {target, ptid} pair to identify
    a thread, take a process_stratum_target pointer for target parameter
    instead of target_ops *.  Some shared code in gdb/nat/ also need to
    gain a target pointer parameter.  This poses an issue, since gdbserver
    doesn't have process_stratum_target, only target_ops.  To fix this,
    this commit renames gdbserver's target_ops to process_stratum_target.
    I think this makes sense.  There's no concept of target stack in
    gdbserver, and gdbserver's target_ops really implements a
    process_stratum-like target.
    
    The thread and inferior iterator functions also gain
    process_stratum_target parameters.  These are used to be able to
    iterate over threads and inferiors of a given target.  Following usual
    conventions, if the target pointer is null, then we iterate over
    threads and inferiors of all targets.
    
    I tried converting "add-inferior" to the gdb::option framework, as a
    preparatory patch, but that stumbled on the fact that gdb::option does
    not support file options yet, for "add-inferior -exec".  I have a WIP
    patchset that adds that, but it's not a trivial patch, mainly due to
    need to integrate readline's filename completion, so I deferred that
    to some other time.
    
    In infrun.c/infcmd.c, the main change is that we need to poll events
    out of all targets.  See do_target_wait.  Right after collecting an
    event, we switch the current inferior to an inferior bound to the
    target that reported the event, so that target methods can be used
    while handling the event.  This makes most of the code transparent to
    multi-targets.  See fetch_inferior_event.
    
    infrun.c:stop_all_threads is interesting -- in this function we need
    to stop all threads of all targets.  What the function does is send an
    asynchronous stop request to all threads, and then synchronously waits
    for events, with target_wait, rinse repeat, until all it finds are
    stopped threads.  Now that we have multiple targets, it's not
    efficient to synchronously block in target_wait waiting for events out
    of one target.  Instead, we implement a mini event loop, with
    interruptible_select, select'ing on one file descriptor per target.
    For this to work, we need to be able to ask the target for a waitable
    file descriptor.  Such file descriptors already exist, they are the
    descriptors registered in the main event loop with add_file_handler,
    inside the target_async implementations.  This commit adds a new
    target_async_wait_fd target method that just returns the file
    descriptor in question.  See wait_one / stop_all_threads in infrun.c.
    
    The 'threads_executing' global is made a per-target variable.  Since
    it is only relevant to process_stratum_target targets, this is where
    it is put, instead of in target_ops.
    
    You'll notice that remote.c includes some FIXME notes.  These refer to
    the fact that the global arrays that hold data for the remote packets
    supported are still globals.  For example, if we connect to two
    different servers/stubs, then each might support different remote
    protocol features.  They might even be different architectures, like
    e.g., one ARM baremetal stub, and a x86 gdbserver, to debug a
    host/controller scenario as a single program.  That isn't going to
    work correctly today, because of said globals.  I'm leaving fixing
    that for another pass, since it does not appear to be trivial, and I'd
    rather land the base work first.  It's already useful to be able to
    debug multiple instances of the same server (e.g., a distributed
    cluster, where you have full control over the servers installed), so I
    think as is it's already reasonable incremental progress.
    
    Current limitations:
    
     - You can only resume more that one target at the same time if all
       targets support asynchronous debugging, and support non-stop mode.
       It should be possible to support mixed all-stop + non-stop
       backends, but that is left for another time.  This means that
       currently in order to do multi-target with gdbserver you need to
       issue "maint set target-non-stop on".  I would like to make that
       mode be the default, but we're not there yet.  Note that I'm
       talking about how the target backend works, only.  User-visible
       all-stop mode works just fine.
    
     - As explained above, connecting to different remote servers at the
       same time is likely to produce bad results if they don't support the
       exact set of RSP features.
    
    FreeBSD updates courtesy of John Baldwin.
    
    gdb/ChangeLog:
    2020-01-10  Pedro Alves  <palves@redhat.com>
    	    John Baldwin  <jhb@FreeBSD.org>
    
    	* aarch64-linux-nat.c
    	(aarch64_linux_nat_target::thread_architecture): Adjust.
    	* ada-tasks.c (print_ada_task_info): Adjust find_thread_ptid call.
    	(task_command_1): Likewise.
    	* aix-thread.c (sync_threadlists, aix_thread_target::resume)
    	(aix_thread_target::wait, aix_thread_target::fetch_registers)
    	(aix_thread_target::store_registers)
    	(aix_thread_target::thread_alive): Adjust.
    	* amd64-fbsd-tdep.c: Include "inferior.h".
    	(amd64fbsd_get_thread_local_address): Pass down target.
    	* amd64-linux-nat.c (ps_get_thread_area): Use ps_prochandle
    	thread's gdbarch instead of target_gdbarch.
    	* break-catch-sig.c (signal_catchpoint_print_it): Adjust call to
    	get_last_target_status.
    	* break-catch-syscall.c (print_it_catch_syscall): Likewise.
    	* breakpoint.c (breakpoints_should_be_inserted_now): Consider all
    	inferiors.
    	(update_inserted_breakpoint_locations): Skip if inferiors with no
    	execution.
    	(update_global_location_list): When handling moribund locations,
    	find representative inferior for location's pspace, and use thread
    	count of its process_stratum target.
    	* bsd-kvm.c (bsd_kvm_target_open): Pass target down.
    	* bsd-uthread.c (bsd_uthread_target::wait): Use
    	as_process_stratum_target and adjust thread_change_ptid and
    	add_thread calls.
    	(bsd_uthread_target::update_thread_list): Use
    	as_process_stratum_target and adjust find_thread_ptid,
    	thread_change_ptid and add_thread calls.
    	* btrace.c (maint_btrace_packet_history_cmd): Adjust
    	find_thread_ptid call.
    	* corelow.c (add_to_thread_list): Adjust add_thread call.
    	(core_target_open): Adjust add_thread_silent and thread_count
    	calls.
    	(core_target::pid_to_str): Adjust find_inferior_ptid call.
    	* ctf.c (ctf_target_open): Adjust add_thread_silent call.
    	* event-top.c (async_disconnect): Pop targets from all inferiors.
    	* exec.c (add_target_sections): Push exec target on all inferiors
    	sharing the program space.
    	(remove_target_sections): Remove the exec target from all
    	inferiors sharing the program space.
    	(exec_on_vfork): New.
    	* exec.h (exec_on_vfork): Declare.
    	* fbsd-nat.c (fbsd_add_threads): Add fbsd_nat_target parameter.
    	Pass it down.
    	(fbsd_nat_target::update_thread_list): Adjust.
    	(fbsd_nat_target::resume): Adjust.
    	(fbsd_handle_debug_trap): Add fbsd_nat_target parameter.  Pass it
    	down.
    	(fbsd_nat_target::wait, fbsd_nat_target::post_attach): Adjust.
    	* fbsd-tdep.c (fbsd_corefile_thread): Adjust
    	get_thread_arch_regcache call.
    	* fork-child.c (gdb_startup_inferior): Pass target down to
    	startup_inferior and set_executing.
    	* gdbthread.h (struct process_stratum_target): Forward declare.
    	(add_thread, add_thread_silent, add_thread_with_info)
    	(in_thread_list): Add process_stratum_target parameter.
    	(find_thread_ptid(inferior*, ptid_t)): New overload.
    	(find_thread_ptid, thread_change_ptid): Add process_stratum_target
    	parameter.
    	(all_threads()): Delete overload.
    	(all_threads, all_non_exited_threads): Add process_stratum_target
    	parameter.
    	(all_threads_safe): Use brace initialization.
    	(thread_count): Add process_stratum_target parameter.
    	(set_resumed, set_running, set_stop_requested, set_executing)
    	(threads_are_executing, finish_thread_state): Add
    	process_stratum_target parameter.
    	(switch_to_thread): Use is_current_thread.
    	* i386-fbsd-tdep.c: Include "inferior.h".
    	(i386fbsd_get_thread_local_address): Pass down target.
    	* i386-linux-nat.c (i386_linux_nat_target::low_resume): Adjust.
    	* inf-child.c (inf_child_target::maybe_unpush_target): Remove
    	have_inferiors check.
    	* inf-ptrace.c (inf_ptrace_target::create_inferior)
    	(inf_ptrace_target::attach): Adjust.
    	* infcall.c (run_inferior_call): Adjust.
    	* infcmd.c (run_command_1): Pass target to
    	scoped_finish_thread_state.
    	(proceed_thread_callback): Skip inferiors with no execution.
    	(continue_command): Rename 'all_threads' local to avoid hiding
    	'all_threads' function.  Adjust get_last_target_status call.
    	(prepare_one_step): Adjust set_running call.
    	(signal_command): Use user_visible_resume_target.  Compare thread
    	pointers instead of inferior_ptid.
    	(info_program_command): Adjust to pass down target.
    	(attach_command): Mark target's 'thread_executing' flag.
    	(stop_current_target_threads_ns): New, factored out from ...
    	(interrupt_target_1): ... this.  Switch inferior before making
    	target calls.
    	* inferior-iter.h
    	(struct all_inferiors_iterator, struct all_inferiors_range)
    	(struct all_inferiors_safe_range)
    	(struct all_non_exited_inferiors_range): Filter on
    	process_stratum_target too.  Remove explicit.
    	* inferior.c (inferior::inferior): Push dummy target on target
    	stack.
    	(find_inferior_pid, find_inferior_ptid, number_of_live_inferiors):
    	Add process_stratum_target parameter, and pass it down.
    	(have_live_inferiors): Adjust.
    	(switch_to_inferior_and_push_target): New.
    	(add_inferior_command, clone_inferior_command): Handle
    	"-no-connection" parameter.  Use
    	switch_to_inferior_and_push_target.
    	(_initialize_inferior): Mention "-no-connection" option in
    	the help of "add-inferior" and "clone-inferior" commands.
    	* inferior.h: Include "process-stratum-target.h".
    	(interrupt_target_1): Use bool.
    	(struct inferior) <push_target, unpush_target, target_is_pushed,
    	find_target_beneath, top_target, process_target, target_at,
    	m_stack>: New.
    	(discard_all_inferiors): Delete.
    	(find_inferior_pid, find_inferior_ptid, number_of_live_inferiors)
    	(all_inferiors, all_non_exited_inferiors): Add
    	process_stratum_target parameter.
    	* infrun.c: Include "gdb_select.h" and <unordered_map>.
    	(target_last_proc_target): New global.
    	(follow_fork_inferior): Push target on new inferior.  Pass target
    	to add_thread_silent.  Call exec_on_vfork.  Handle target's
    	reference count.
    	(follow_fork): Adjust get_last_target_status call.  Also consider
    	target.
    	(follow_exec): Push target on new inferior.
    	(struct execution_control_state) <target>: New field.
    	(user_visible_resume_target): New.
    	(do_target_resume): Call target_async.
    	(resume_1): Set target's threads_executing flag.  Consider resume
    	target.
    	(commit_resume_all_targets): New.
    	(proceed): Also consider resume target.  Skip threads of inferiors
    	with no execution.  Commit resumtion in all targets.
    	(start_remote): Pass current inferior to wait_for_inferior.
    	(infrun_thread_stop_requested): Consider target as well.  Pass
    	thread_info pointer to clear_inline_frame_state instead of ptid.
    	(infrun_thread_thread_exit): Consider target as well.
    	(random_pending_event_thread): New inferior parameter.  Use it.
    	(do_target_wait): Rename to ...
    	(do_target_wait_1): ... this.  Add inferior parameter, and pass it
    	down.
    	(threads_are_resumed_pending_p, do_target_wait): New.
    	(prepare_for_detach): Adjust calls.
    	(wait_for_inferior): New inferior parameter.  Handle it.  Use
    	do_target_wait_1 instead of do_target_wait.
    	(fetch_inferior_event): Adjust.  Switch to representative
    	inferior.  Pass target down.
    	(set_last_target_status): Add process_stratum_target parameter.
    	Save target in global.
    	(get_last_target_status): Add process_stratum_target parameter and
    	handle it.
    	(nullify_last_target_wait_ptid): Clear 'target_last_proc_target'.
    	(context_switch): Check inferior_ptid == null_ptid before calling
    	inferior_thread().
    	(get_inferior_stop_soon): Pass down target.
    	(wait_one): Rename to ...
    	(poll_one_curr_target): ... this.
    	(struct wait_one_event): New.
    	(wait_one): New.
    	(stop_all_threads): Adjust.
    	(handle_no_resumed, handle_inferior_event): Adjust to consider the
    	event's target.
    	(switch_back_to_stepped_thread): Also consider target.
    	(print_stop_event): Update.
    	(normal_stop): Update.  Also consider the resume target.
    	* infrun.h (wait_for_inferior): Remove declaration.
    	(user_visible_resume_target): New declaration.
    	(get_last_target_status, set_last_target_status): New
    	process_stratum_target parameter.
    	* inline-frame.c (clear_inline_frame_state(ptid_t)): Add
    	process_stratum_target parameter, and use it.
    	(clear_inline_frame_state (thread_info*)): New.
    	* inline-frame.c (clear_inline_frame_state(ptid_t)): Add
    	process_stratum_target parameter.
    	(clear_inline_frame_state (thread_info*)): Declare.
    	* linux-fork.c (delete_checkpoint_command): Pass target down to
    	find_thread_ptid.
    	(checkpoint_command): Adjust.
    	* linux-nat.c (linux_nat_target::follow_fork): Switch to thread
    	instead of just tweaking inferior_ptid.
    	(linux_nat_switch_fork): Pass target down to thread_change_ptid.
    	(exit_lwp): Pass target down to find_thread_ptid.
    	(attach_proc_task_lwp_callback): Pass target down to
    	add_thread/set_running/set_executing.
    	(linux_nat_target::attach): Pass target down to
    	thread_change_ptid.
    	(get_detach_signal): Pass target down to find_thread_ptid.
    	Consider last target status's target.
    	(linux_resume_one_lwp_throw, resume_lwp)
    	(linux_handle_syscall_trap, linux_handle_extended_wait, wait_lwp)
    	(stop_wait_callback, save_stop_reason, linux_nat_filter_event)
    	(linux_nat_wait_1, resume_stopped_resumed_lwps): Pass target down.
    	(linux_nat_target::async_wait_fd): New.
    	(linux_nat_stop_lwp, linux_nat_target::thread_address_space): Pass
    	target down.
    	* linux-nat.h (linux_nat_target::async_wait_fd): Declare.
    	* linux-tdep.c (get_thread_arch_regcache): Pass target down.
    	* linux-thread-db.c (struct thread_db_info::process_target): New
    	field.
    	(add_thread_db_info): Save target.
    	(get_thread_db_info): New process_stratum_target parameter.  Also
    	match target.
    	(delete_thread_db_info): New process_stratum_target parameter.
    	Also match target.
    	(thread_from_lwp): Adjust to pass down target.
    	(thread_db_notice_clone): Pass down target.
    	(check_thread_db_callback): Pass down target.
    	(try_thread_db_load_1): Always push the thread_db target.
    	(try_thread_db_load, record_thread): Pass target down.
    	(thread_db_target::detach): Pass target down.  Always unpush the
    	thread_db target.
    	(thread_db_target::wait, thread_db_target::mourn_inferior): Pass
    	target down.  Always unpush the thread_db target.
    	(find_new_threads_callback, thread_db_find_new_threads_2)
    	(thread_db_target::update_thread_list): Pass target down.
    	(thread_db_target::pid_to_str): Pass current inferior down.
    	(thread_db_target::get_thread_local_address): Pass target down.
    	(thread_db_target::resume, maintenance_check_libthread_db): Pass
    	target down.
    	* nto-procfs.c (nto_procfs_target::update_thread_list): Adjust.
    	* procfs.c (procfs_target::procfs_init_inferior): Declare.
    	(proc_set_current_signal, do_attach, procfs_target::wait): Adjust.
    	(procfs_init_inferior): Rename to ...
    	(procfs_target::procfs_init_inferior): ... this and adjust.
    	(procfs_target::create_inferior, procfs_notice_thread)
    	(procfs_do_thread_registers): Adjust.
    	* ppc-fbsd-tdep.c: Include "inferior.h".
    	(ppcfbsd_get_thread_local_address): Pass down target.
    	* proc-service.c (ps_xfer_memory): Switch current inferior and
    	program space as well.
    	(get_ps_regcache): Pass target down.
    	* process-stratum-target.c
    	(process_stratum_target::thread_address_space)
    	(process_stratum_target::thread_architecture): Pass target down.
    	* process-stratum-target.h
    	(process_stratum_target::threads_executing): New field.
    	(as_process_stratum_target): New.
    	* ravenscar-thread.c
    	(ravenscar_thread_target::update_inferior_ptid): Pass target down.
    	(ravenscar_thread_target::wait, ravenscar_add_thread): Pass target
    	down.
    	* record-btrace.c (record_btrace_target::info_record): Adjust.
    	(record_btrace_target::record_method)
    	(record_btrace_target::record_is_replaying)
    	(record_btrace_target::fetch_registers)
    	(get_thread_current_frame_id, record_btrace_target::resume)
    	(record_btrace_target::wait, record_btrace_target::stop): Pass
    	target down.
    	* record-full.c (record_full_wait_1): Switch to event thread.
    	Pass target down.
    	* regcache.c (regcache::regcache)
    	(get_thread_arch_aspace_regcache, get_thread_arch_regcache): Add
    	process_stratum_target parameter and handle it.
    	(current_thread_target): New global.
    	(get_thread_regcache): Add process_stratum_target parameter and
    	handle it.  Switch inferior before calling target method.
    	(get_thread_regcache): Pass target down.
    	(get_thread_regcache_for_ptid): Pass target down.
    	(registers_changed_ptid): Add process_stratum_target parameter and
    	handle it.
    	(registers_changed_thread, registers_changed): Pass target down.
    	(test_get_thread_arch_aspace_regcache): New.
    	(current_regcache_test): Define a couple local test_target_ops
    	instances and use them for testing.
    	(readwrite_regcache): Pass process_stratum_target parameter.
    	(cooked_read_test, cooked_write_test): Pass mock_target down.
    	* regcache.h (get_thread_regcache, get_thread_arch_regcache)
    	(get_thread_arch_aspace_regcache): Add process_stratum_target
    	parameter.
    	(regcache::target): New method.
    	(regcache::regcache, regcache::get_thread_arch_aspace_regcache)
    	(regcache::registers_changed_ptid): Add process_stratum_target
    	parameter.
    	(regcache::m_target): New field.
    	(registers_changed_ptid): Add process_stratum_target parameter.
    	* remote.c (remote_state::supports_vCont_probed): New field.
    	(remote_target::async_wait_fd): New method.
    	(remote_unpush_and_throw): Add remote_target parameter.
    	(get_current_remote_target): Adjust.
    	(remote_target::remote_add_inferior): Push target.
    	(remote_target::remote_add_thread)
    	(remote_target::remote_notice_new_inferior)
    	(get_remote_thread_info): Pass target down.
    	(remote_target::update_thread_list): Skip threads of inferiors
    	bound to other targets.  (remote_target::close): Don't discard
    	inferiors.  (remote_target::add_current_inferior_and_thread)
    	(remote_target::process_initial_stop_replies)
    	(remote_target::start_remote)
    	(remote_target::remote_serial_quit_handler): Pass down target.
    	(remote_target::remote_unpush_target): New remote_target
    	parameter.  Unpush the target from all inferiors.
    	(remote_target::remote_unpush_and_throw): New remote_target
    	parameter.  Pass it down.
    	(remote_target::open_1): Check whether the current inferior has
    	execution instead of checking whether any inferior is live.  Pass
    	target down.
    	(remote_target::remote_detach_1): Pass down target.  Use
    	remote_unpush_target.
    	(extended_remote_target::attach): Pass down target.
    	(remote_target::remote_vcont_probe): Set supports_vCont_probed.
    	(remote_target::append_resumption): Pass down target.
    	(remote_target::append_pending_thread_resumptions)
    	(remote_target::remote_resume_with_hc, remote_target::resume)
    	(remote_target::commit_resume): Pass down target.
    	(remote_target::remote_stop_ns): Check supports_vCont_probed.
    	(remote_target::interrupt_query)
    	(remote_target::remove_new_fork_children)
    	(remote_target::check_pending_events_prevent_wildcard_vcont)
    	(remote_target::remote_parse_stop_reply)
    	(remote_target::process_stop_reply): Pass down target.
    	(first_remote_resumed_thread): New remote_target parameter.  Pass
    	it down.
    	(remote_target::wait_as): Pass down target.
    	(unpush_and_perror): New remote_target parameter.  Pass it down.
    	(remote_target::readchar, remote_target::remote_serial_write)
    	(remote_target::getpkt_or_notif_sane_1)
    	(remote_target::kill_new_fork_children, remote_target::kill): Pass
    	down target.
    	(remote_target::mourn_inferior): Pass down target.  Use
    	remote_unpush_target.
    	(remote_target::core_of_thread)
    	(remote_target::remote_btrace_maybe_reopen): Pass down target.
    	(remote_target::pid_to_exec_file)
    	(remote_target::thread_handle_to_thread_info): Pass down target.
    	(remote_target::async_wait_fd): New.
    	* riscv-fbsd-tdep.c: Include "inferior.h".
    	(riscv_fbsd_get_thread_local_address): Pass down target.
    	* sol2-tdep.c (sol2_core_pid_to_str): Pass down target.
    	* sol-thread.c (sol_thread_target::wait, ps_lgetregs, ps_lsetregs)
    	(ps_lgetfpregs, ps_lsetfpregs, sol_update_thread_list_callback):
    	Adjust.
    	* solib-spu.c (spu_skip_standalone_loader): Pass down target.
    	* solib-svr4.c (enable_break): Pass down target.
    	* spu-multiarch.c (parse_spufs_run): Pass down target.
    	* spu-tdep.c (spu2ppu_sniffer): Pass down target.
    	* target-delegates.c: Regenerate.
    	* target.c (g_target_stack): Delete.
    	(current_top_target): Return the current inferior's top target.
    	(target_has_execution_1): Refer to the passed-in inferior's top
    	target.
    	(target_supports_terminal_ours): Check whether the initial
    	inferior was already created.
    	(decref_target): New.
    	(target_stack::push): Incref/decref the target.
    	(push_target, push_target, unpush_target): Adjust.
    	(target_stack::unpush): Defref target.
    	(target_is_pushed): Return bool.  Adjust to refer to the current
    	inferior's target stack.
    	(dispose_inferior): Delete, and inline parts ...
    	(target_preopen): ... here.  Only dispose of the current inferior.
    	(target_detach): Hold strong target reference while detaching.
    	Pass target down.
    	(target_thread_name): Add assertion.
    	(target_resume): Pass down target.
    	(target_ops::beneath, find_target_at): Adjust to refer to the
    	current inferior's target stack.
    	(get_dummy_target): New.
    	(target_pass_ctrlc): Pass the Ctrl-C to the first inferior that
    	has a thread running.
    	(initialize_targets): Rename to ...
    	(_initialize_target): ... this.
    	* target.h: Include "gdbsupport/refcounted-object.h".
    	(struct target_ops): Inherit refcounted_object.
    	(target_ops::shortname, target_ops::longname): Make const.
    	(target_ops::async_wait_fd): New method.
    	(decref_target): Declare.
    	(struct target_ops_ref_policy): New.
    	(target_ops_ref): New typedef.
    	(get_dummy_target): Declare function.
    	(target_is_pushed): Return bool.
    	* thread-iter.c (all_matching_threads_iterator::m_inf_matches)
    	(all_matching_threads_iterator::all_matching_threads_iterator):
    	Handle filter target.
    	* thread-iter.h (struct all_matching_threads_iterator, struct
    	all_matching_threads_range, class all_non_exited_threads_range):
    	Filter by target too.  Remove explicit.
    	* thread.c (threads_executing): Delete.
    	(inferior_thread): Pass down current inferior.
    	(clear_thread_inferior_resources): Pass down thread pointer
    	instead of ptid_t.
    	(add_thread_silent, add_thread_with_info, add_thread): Add
    	process_stratum_target parameter.  Use it for thread and inferior
    	searches.
    	(is_current_thread): New.
    	(thread_info::deletable): Use it.
    	(find_thread_ptid, thread_count, in_thread_list)
    	(thread_change_ptid, set_resumed, set_running): New
    	process_stratum_target parameter.  Pass it down.
    	(set_executing): New process_stratum_target parameter.  Pass it
    	down.  Adjust reference to 'threads_executing'.
    	(threads_are_executing): New process_stratum_target parameter.
    	Adjust reference to 'threads_executing'.
    	(set_stop_requested, finish_thread_state): New
    	process_stratum_target parameter.  Pass it down.
    	(switch_to_thread): Also match inferior.
    	(switch_to_thread): New process_stratum_target parameter.  Pass it
    	down.
    	(update_threads_executing): Reimplement.
    	* top.c (quit_force): Pop targets from all inferior.
    	(gdb_init): Don't call initialize_targets.
    	* windows-nat.c (windows_nat_target) <get_windows_debug_event>:
    	Declare.
    	(windows_add_thread, windows_delete_thread): Adjust.
    	(get_windows_debug_event): Rename to ...
    	(windows_nat_target::get_windows_debug_event): ... this.  Adjust.
    	* tracefile-tfile.c (tfile_target_open): Pass down target.
    	* gdbsupport/common-gdbthread.h (struct process_stratum_target):
    	Forward declare.
    	(switch_to_thread): Add process_stratum_target parameter.
    	* mi/mi-interp.c (mi_on_resume_1): Add process_stratum_target
    	parameter.  Use it.
    	(mi_on_resume): Pass target down.
    	* nat/fork-inferior.c (startup_inferior): Add
    	process_stratum_target parameter.  Pass it down.
    	* nat/fork-inferior.h (startup_inferior): Add
    	process_stratum_target parameter.
    	* python/py-threadevent.c (py_get_event_thread): Pass target down.
    
    gdb/gdbserver/ChangeLog:
    2020-01-10  Pedro Alves  <palves@redhat.com>
    
    	* fork-child.c (post_fork_inferior): Pass target down to
    	startup_inferior.
    	* inferiors.c (switch_to_thread): Add process_stratum_target
    	parameter.
    	* lynx-low.c (lynx_target_ops): Now a process_stratum_target.
    	* nto-low.c (nto_target_ops): Now a process_stratum_target.
    	* linux-low.c (linux_target_ops): Now a process_stratum_target.
    	* remote-utils.c (prepare_resume_reply): Pass the target to
    	switch_to_thread.
    	* target.c (the_target): Now a process_stratum_target.
    	(done_accessing_memory): Pass the target to switch_to_thread.
    	(set_target_ops): Ajust to use process_stratum_target.
    	* target.h (struct target_ops): Rename to ...
    	(struct process_stratum_target): ... this.
    	(the_target, set_target_ops): Adjust.
    	(prepare_to_access_memory): Adjust comment.
    	* win32-low.c (child_xfer_memory): Adjust to use
    	process_stratum_target.
    	(win32_target_ops): Now a process_stratum_target.

Diff:
---
 gdb/ChangeLog                     | 419 ++++++++++++++++++++++++++
 gdb/aarch64-linux-nat.c           |   2 +-
 gdb/ada-tasks.c                   |   4 +-
 gdb/aix-thread.c                  |  24 +-
 gdb/amd64-fbsd-tdep.c             |   4 +-
 gdb/amd64-linux-nat.c             |   2 +-
 gdb/break-catch-sig.c             |   2 +-
 gdb/break-catch-syscall.c         |   2 +-
 gdb/breakpoint.c                  |  25 +-
 gdb/bsd-kvm.c                     |   2 +-
 gdb/bsd-uthread.c                 |  20 +-
 gdb/btrace.c                      |   2 +-
 gdb/corelow.c                     |   8 +-
 gdb/event-top.c                   |  14 +-
 gdb/exec.c                        |  51 +++-
 gdb/exec.h                        |   7 +
 gdb/fbsd-nat.c                    |  33 ++-
 gdb/fbsd-tdep.c                   |   3 +-
 gdb/fork-child.c                  |   7 +-
 gdb/gdbserver/ChangeLog           |  22 ++
 gdb/gdbserver/fork-child.c        |   3 +-
 gdb/gdbserver/inferiors.c         |   2 +-
 gdb/gdbserver/linux-low.c         |   2 +-
 gdb/gdbserver/lynx-low.c          |   2 +-
 gdb/gdbserver/nto-low.c           |   2 +-
 gdb/gdbserver/remote-utils.c      |   2 +-
 gdb/gdbserver/target.c            |   8 +-
 gdb/gdbserver/target.h            |  11 +-
 gdb/gdbserver/win32-low.c         |   4 +-
 gdb/gdbsupport/common-gdbthread.h |   5 +-
 gdb/gdbthread.h                   | 127 ++++----
 gdb/i386-fbsd-tdep.c              |   4 +-
 gdb/i386-linux-nat.c              |   2 +-
 gdb/inf-child.c                   |   2 +-
 gdb/inf-ptrace.c                  |   6 +-
 gdb/infcall.c                     |   3 +-
 gdb/infcmd.c                      | 112 ++++---
 gdb/inferior-iter.h               |  80 ++++-
 gdb/inferior.c                    |  78 +++--
 gdb/inferior.h                    |  64 +++-
 gdb/infrun.c                      | 597 +++++++++++++++++++++++++++++---------
 gdb/infrun.h                      |  18 +-
 gdb/inline-frame.c                |  51 ++--
 gdb/inline-frame.h                |  12 +-
 gdb/linux-fork.c                  |   4 +-
 gdb/linux-nat.c                   |  75 +++--
 gdb/linux-nat.h                   |   1 +
 gdb/linux-tdep.c                  |   3 +-
 gdb/linux-thread-db.c             | 110 +++----
 gdb/mi/mi-interp.c                |  10 +-
 gdb/nat/fork-inferior.c           |   8 +-
 gdb/nat/fork-inferior.h           |   5 +-
 gdb/nto-procfs.c                  |   2 +-
 gdb/ppc-fbsd-tdep.c               |   4 +-
 gdb/proc-service.c                |  17 +-
 gdb/process-stratum-target.c      |   4 +-
 gdb/process-stratum-target.h      |  16 +
 gdb/procfs.c                      |  49 ++--
 gdb/python/py-threadevent.c       |   4 +-
 gdb/ravenscar-thread.c            |  15 +-
 gdb/record-btrace.c               |  41 ++-
 gdb/record-full.c                 |  11 +-
 gdb/regcache.c                    | 162 +++++++----
 gdb/regcache.h                    |  30 +-
 gdb/remote.c                      | 221 ++++++++------
 gdb/riscv-fbsd-tdep.c             |   4 +-
 gdb/sol-thread.c                  |  28 +-
 gdb/sol2-tdep.c                   |   2 +-
 gdb/solib-svr4.c                  |   3 +-
 gdb/target-delegates.c            |  27 ++
 gdb/target.c                      | 170 ++++++-----
 gdb/target.h                      |  34 ++-
 gdb/thread-iter.c                 |  14 +-
 gdb/thread-iter.h                 |  25 +-
 gdb/thread.c                      | 139 +++++----
 gdb/top.c                         |  17 +-
 gdb/tracectf.c                    |   2 +-
 gdb/tracefile-tfile.c             |   2 +-
 gdb/windows-nat.c                 |  20 +-
 79 files changed, 2263 insertions(+), 866 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a6fd8b1..5218bbd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,423 @@
 2020-01-10  Pedro Alves  <palves@redhat.com>
+	    John Baldwin  <jhb@FreeBSD.org>
+
+	* aarch64-linux-nat.c
+	(aarch64_linux_nat_target::thread_architecture): Adjust.
+	* ada-tasks.c (print_ada_task_info): Adjust find_thread_ptid call.
+	(task_command_1): Likewise.
+	* aix-thread.c (sync_threadlists, aix_thread_target::resume)
+	(aix_thread_target::wait, aix_thread_target::fetch_registers)
+	(aix_thread_target::store_registers)
+	(aix_thread_target::thread_alive): Adjust.
+	* amd64-fbsd-tdep.c: Include "inferior.h".
+	(amd64fbsd_get_thread_local_address): Pass down target.
+	* amd64-linux-nat.c (ps_get_thread_area): Use ps_prochandle
+	thread's gdbarch instead of target_gdbarch.
+	* break-catch-sig.c (signal_catchpoint_print_it): Adjust call to
+	get_last_target_status.
+	* break-catch-syscall.c (print_it_catch_syscall): Likewise.
+	* breakpoint.c (breakpoints_should_be_inserted_now): Consider all
+	inferiors.
+	(update_inserted_breakpoint_locations): Skip if inferiors with no
+	execution.
+	(update_global_location_list): When handling moribund locations,
+	find representative inferior for location's pspace, and use thread
+	count of its process_stratum target.
+	* bsd-kvm.c (bsd_kvm_target_open): Pass target down.
+	* bsd-uthread.c (bsd_uthread_target::wait): Use
+	as_process_stratum_target and adjust thread_change_ptid and
+	add_thread calls.
+	(bsd_uthread_target::update_thread_list): Use
+	as_process_stratum_target and adjust find_thread_ptid,
+	thread_change_ptid and add_thread calls.
+	* btrace.c (maint_btrace_packet_history_cmd): Adjust
+	find_thread_ptid call.
+	* corelow.c (add_to_thread_list): Adjust add_thread call.
+	(core_target_open): Adjust add_thread_silent and thread_count
+	calls.
+	(core_target::pid_to_str): Adjust find_inferior_ptid call.
+	* ctf.c (ctf_target_open): Adjust add_thread_silent call.
+	* event-top.c (async_disconnect): Pop targets from all inferiors.
+	* exec.c (add_target_sections): Push exec target on all inferiors
+	sharing the program space.
+	(remove_target_sections): Remove the exec target from all
+	inferiors sharing the program space.
+	(exec_on_vfork): New.
+	* exec.h (exec_on_vfork): Declare.
+	* fbsd-nat.c (fbsd_add_threads): Add fbsd_nat_target parameter.
+	Pass it down.
+	(fbsd_nat_target::update_thread_list): Adjust.
+	(fbsd_nat_target::resume): Adjust.
+	(fbsd_handle_debug_trap): Add fbsd_nat_target parameter.  Pass it
+	down.
+	(fbsd_nat_target::wait, fbsd_nat_target::post_attach): Adjust.
+	* fbsd-tdep.c (fbsd_corefile_thread): Adjust
+	get_thread_arch_regcache call.
+	* fork-child.c (gdb_startup_inferior): Pass target down to
+	startup_inferior and set_executing.
+	* gdbthread.h (struct process_stratum_target): Forward declare.
+	(add_thread, add_thread_silent, add_thread_with_info)
+	(in_thread_list): Add process_stratum_target parameter.
+	(find_thread_ptid(inferior*, ptid_t)): New overload.
+	(find_thread_ptid, thread_change_ptid): Add process_stratum_target
+	parameter.
+	(all_threads()): Delete overload.
+	(all_threads, all_non_exited_threads): Add process_stratum_target
+	parameter.
+	(all_threads_safe): Use brace initialization.
+	(thread_count): Add process_stratum_target parameter.
+	(set_resumed, set_running, set_stop_requested, set_executing)
+	(threads_are_executing, finish_thread_state): Add
+	process_stratum_target parameter.
+	(switch_to_thread): Use is_current_thread.
+	* i386-fbsd-tdep.c: Include "inferior.h".
+	(i386fbsd_get_thread_local_address): Pass down target.
+	* i386-linux-nat.c (i386_linux_nat_target::low_resume): Adjust.
+	* inf-child.c (inf_child_target::maybe_unpush_target): Remove
+	have_inferiors check.
+	* inf-ptrace.c (inf_ptrace_target::create_inferior)
+	(inf_ptrace_target::attach): Adjust.
+	* infcall.c (run_inferior_call): Adjust.
+	* infcmd.c (run_command_1): Pass target to
+	scoped_finish_thread_state.
+	(proceed_thread_callback): Skip inferiors with no execution.
+	(continue_command): Rename 'all_threads' local to avoid hiding
+	'all_threads' function.  Adjust get_last_target_status call.
+	(prepare_one_step): Adjust set_running call.
+	(signal_command): Use user_visible_resume_target.  Compare thread
+	pointers instead of inferior_ptid.
+	(info_program_command): Adjust to pass down target.
+	(attach_command): Mark target's 'thread_executing' flag.
+	(stop_current_target_threads_ns): New, factored out from ...
+	(interrupt_target_1): ... this.  Switch inferior before making
+	target calls.
+	* inferior-iter.h
+	(struct all_inferiors_iterator, struct all_inferiors_range)
+	(struct all_inferiors_safe_range)
+	(struct all_non_exited_inferiors_range): Filter on
+	process_stratum_target too.  Remove explicit.
+	* inferior.c (inferior::inferior): Push dummy target on target
+	stack.
+	(find_inferior_pid, find_inferior_ptid, number_of_live_inferiors):
+	Add process_stratum_target parameter, and pass it down.
+	(have_live_inferiors): Adjust.
+	(switch_to_inferior_and_push_target): New.
+	(add_inferior_command, clone_inferior_command): Handle
+	"-no-connection" parameter.  Use
+	switch_to_inferior_and_push_target.
+	(_initialize_inferior): Mention "-no-connection" option in
+	the help of "add-inferior" and "clone-inferior" commands.
+	* inferior.h: Include "process-stratum-target.h".
+	(interrupt_target_1): Use bool.
+	(struct inferior) <push_target, unpush_target, target_is_pushed,
+	find_target_beneath, top_target, process_target, target_at,
+	m_stack>: New.
+	(discard_all_inferiors): Delete.
+	(find_inferior_pid, find_inferior_ptid, number_of_live_inferiors)
+	(all_inferiors, all_non_exited_inferiors): Add
+	process_stratum_target parameter.
+	* infrun.c: Include "gdb_select.h" and <unordered_map>.
+	(target_last_proc_target): New global.
+	(follow_fork_inferior): Push target on new inferior.  Pass target
+	to add_thread_silent.  Call exec_on_vfork.  Handle target's
+	reference count.
+	(follow_fork): Adjust get_last_target_status call.  Also consider
+	target.
+	(follow_exec): Push target on new inferior.
+	(struct execution_control_state) <target>: New field.
+	(user_visible_resume_target): New.
+	(do_target_resume): Call target_async.
+	(resume_1): Set target's threads_executing flag.  Consider resume
+	target.
+	(commit_resume_all_targets): New.
+	(proceed): Also consider resume target.  Skip threads of inferiors
+	with no execution.  Commit resumtion in all targets.
+	(start_remote): Pass current inferior to wait_for_inferior.
+	(infrun_thread_stop_requested): Consider target as well.  Pass
+	thread_info pointer to clear_inline_frame_state instead of ptid.
+	(infrun_thread_thread_exit): Consider target as well.
+	(random_pending_event_thread): New inferior parameter.  Use it.
+	(do_target_wait): Rename to ...
+	(do_target_wait_1): ... this.  Add inferior parameter, and pass it
+	down.
+	(threads_are_resumed_pending_p, do_target_wait): New.
+	(prepare_for_detach): Adjust calls.
+	(wait_for_inferior): New inferior parameter.  Handle it.  Use
+	do_target_wait_1 instead of do_target_wait.
+	(fetch_inferior_event): Adjust.  Switch to representative
+	inferior.  Pass target down.
+	(set_last_target_status): Add process_stratum_target parameter.
+	Save target in global.
+	(get_last_target_status): Add process_stratum_target parameter and
+	handle it.
+	(nullify_last_target_wait_ptid): Clear 'target_last_proc_target'.
+	(context_switch): Check inferior_ptid == null_ptid before calling
+	inferior_thread().
+	(get_inferior_stop_soon): Pass down target.
+	(wait_one): Rename to ...
+	(poll_one_curr_target): ... this.
+	(struct wait_one_event): New.
+	(wait_one): New.
+	(stop_all_threads): Adjust.
+	(handle_no_resumed, handle_inferior_event): Adjust to consider the
+	event's target.
+	(switch_back_to_stepped_thread): Also consider target.
+	(print_stop_event): Update.
+	(normal_stop): Update.  Also consider the resume target.
+	* infrun.h (wait_for_inferior): Remove declaration.
+	(user_visible_resume_target): New declaration.
+	(get_last_target_status, set_last_target_status): New
+	process_stratum_target parameter.
+	* inline-frame.c (clear_inline_frame_state(ptid_t)): Add
+	process_stratum_target parameter, and use it.
+	(clear_inline_frame_state (thread_info*)): New.
+	* inline-frame.c (clear_inline_frame_state(ptid_t)): Add
+	process_stratum_target parameter.
+	(clear_inline_frame_state (thread_info*)): Declare.
+	* linux-fork.c (delete_checkpoint_command): Pass target down to
+	find_thread_ptid.
+	(checkpoint_command): Adjust.
+	* linux-nat.c (linux_nat_target::follow_fork): Switch to thread
+	instead of just tweaking inferior_ptid.
+	(linux_nat_switch_fork): Pass target down to thread_change_ptid.
+	(exit_lwp): Pass target down to find_thread_ptid.
+	(attach_proc_task_lwp_callback): Pass target down to
+	add_thread/set_running/set_executing.
+	(linux_nat_target::attach): Pass target down to
+	thread_change_ptid.
+	(get_detach_signal): Pass target down to find_thread_ptid.
+	Consider last target status's target.
+	(linux_resume_one_lwp_throw, resume_lwp)
+	(linux_handle_syscall_trap, linux_handle_extended_wait, wait_lwp)
+	(stop_wait_callback, save_stop_reason, linux_nat_filter_event)
+	(linux_nat_wait_1, resume_stopped_resumed_lwps): Pass target down.
+	(linux_nat_target::async_wait_fd): New.
+	(linux_nat_stop_lwp, linux_nat_target::thread_address_space): Pass
+	target down.
+	* linux-nat.h (linux_nat_target::async_wait_fd): Declare.
+	* linux-tdep.c (get_thread_arch_regcache): Pass target down.
+	* linux-thread-db.c (struct thread_db_info::process_target): New
+	field.
+	(add_thread_db_info): Save target.
+	(get_thread_db_info): New process_stratum_target parameter.  Also
+	match target.
+	(delete_thread_db_info): New process_stratum_target parameter.
+	Also match target.
+	(thread_from_lwp): Adjust to pass down target.
+	(thread_db_notice_clone): Pass down target.
+	(check_thread_db_callback): Pass down target.
+	(try_thread_db_load_1): Always push the thread_db target.
+	(try_thread_db_load, record_thread): Pass target down.
+	(thread_db_target::detach): Pass target down.  Always unpush the
+	thread_db target.
+	(thread_db_target::wait, thread_db_target::mourn_inferior): Pass
+	target down.  Always unpush the thread_db target.
+	(find_new_threads_callback, thread_db_find_new_threads_2)
+	(thread_db_target::update_thread_list): Pass target down.
+	(thread_db_target::pid_to_str): Pass current inferior down.
+	(thread_db_target::get_thread_local_address): Pass target down.
+	(thread_db_target::resume, maintenance_check_libthread_db): Pass
+	target down.
+	* nto-procfs.c (nto_procfs_target::update_thread_list): Adjust.
+	* procfs.c (procfs_target::procfs_init_inferior): Declare.
+	(proc_set_current_signal, do_attach, procfs_target::wait): Adjust.
+	(procfs_init_inferior): Rename to ...
+	(procfs_target::procfs_init_inferior): ... this and adjust.
+	(procfs_target::create_inferior, procfs_notice_thread)
+	(procfs_do_thread_registers): Adjust.
+	* ppc-fbsd-tdep.c: Include "inferior.h".
+	(ppcfbsd_get_thread_local_address): Pass down target.
+	* proc-service.c (ps_xfer_memory): Switch current inferior and
+	program space as well.
+	(get_ps_regcache): Pass target down.
+	* process-stratum-target.c
+	(process_stratum_target::thread_address_space)
+	(process_stratum_target::thread_architecture): Pass target down.
+	* process-stratum-target.h
+	(process_stratum_target::threads_executing): New field.
+	(as_process_stratum_target): New.
+	* ravenscar-thread.c
+	(ravenscar_thread_target::update_inferior_ptid): Pass target down.
+	(ravenscar_thread_target::wait, ravenscar_add_thread): Pass target
+	down.
+	* record-btrace.c (record_btrace_target::info_record): Adjust.
+	(record_btrace_target::record_method)
+	(record_btrace_target::record_is_replaying)
+	(record_btrace_target::fetch_registers)
+	(get_thread_current_frame_id, record_btrace_target::resume)
+	(record_btrace_target::wait, record_btrace_target::stop): Pass
+	target down.
+	* record-full.c (record_full_wait_1): Switch to event thread.
+	Pass target down.
+	* regcache.c (regcache::regcache)
+	(get_thread_arch_aspace_regcache, get_thread_arch_regcache): Add
+	process_stratum_target parameter and handle it.
+	(current_thread_target): New global.
+	(get_thread_regcache): Add process_stratum_target parameter and
+	handle it.  Switch inferior before calling target method.
+	(get_thread_regcache): Pass target down.
+	(get_thread_regcache_for_ptid): Pass target down.
+	(registers_changed_ptid): Add process_stratum_target parameter and
+	handle it.
+	(registers_changed_thread, registers_changed): Pass target down.
+	(test_get_thread_arch_aspace_regcache): New.
+	(current_regcache_test): Define a couple local test_target_ops
+	instances and use them for testing.
+	(readwrite_regcache): Pass process_stratum_target parameter.
+	(cooked_read_test, cooked_write_test): Pass mock_target down.
+	* regcache.h (get_thread_regcache, get_thread_arch_regcache)
+	(get_thread_arch_aspace_regcache): Add process_stratum_target
+	parameter.
+	(regcache::target): New method.
+	(regcache::regcache, regcache::get_thread_arch_aspace_regcache)
+	(regcache::registers_changed_ptid): Add process_stratum_target
+	parameter.
+	(regcache::m_target): New field.
+	(registers_changed_ptid): Add process_stratum_target parameter.
+	* remote.c (remote_state::supports_vCont_probed): New field.
+	(remote_target::async_wait_fd): New method.
+	(remote_unpush_and_throw): Add remote_target parameter.
+	(get_current_remote_target): Adjust.
+	(remote_target::remote_add_inferior): Push target.
+	(remote_target::remote_add_thread)
+	(remote_target::remote_notice_new_inferior)
+	(get_remote_thread_info): Pass target down.
+	(remote_target::update_thread_list): Skip threads of inferiors
+	bound to other targets.  (remote_target::close): Don't discard
+	inferiors.  (remote_target::add_current_inferior_and_thread)
+	(remote_target::process_initial_stop_replies)
+	(remote_target::start_remote)
+	(remote_target::remote_serial_quit_handler): Pass down target.
+	(remote_target::remote_unpush_target): New remote_target
+	parameter.  Unpush the target from all inferiors.
+	(remote_target::remote_unpush_and_throw): New remote_target
+	parameter.  Pass it down.
+	(remote_target::open_1): Check whether the current inferior has
+	execution instead of checking whether any inferior is live.  Pass
+	target down.
+	(remote_target::remote_detach_1): Pass down target.  Use
+	remote_unpush_target.
+	(extended_remote_target::attach): Pass down target.
+	(remote_target::remote_vcont_probe): Set supports_vCont_probed.
+	(remote_target::append_resumption): Pass down target.
+	(remote_target::append_pending_thread_resumptions)
+	(remote_target::remote_resume_with_hc, remote_target::resume)
+	(remote_target::commit_resume): Pass down target.
+	(remote_target::remote_stop_ns): Check supports_vCont_probed.
+	(remote_target::interrupt_query)
+	(remote_target::remove_new_fork_children)
+	(remote_target::check_pending_events_prevent_wildcard_vcont)
+	(remote_target::remote_parse_stop_reply)
+	(remote_target::process_stop_reply): Pass down target.
+	(first_remote_resumed_thread): New remote_target parameter.  Pass
+	it down.
+	(remote_target::wait_as): Pass down target.
+	(unpush_and_perror): New remote_target parameter.  Pass it down.
+	(remote_target::readchar, remote_target::remote_serial_write)
+	(remote_target::getpkt_or_notif_sane_1)
+	(remote_target::kill_new_fork_children, remote_target::kill): Pass
+	down target.
+	(remote_target::mourn_inferior): Pass down target.  Use
+	remote_unpush_target.
+	(remote_target::core_of_thread)
+	(remote_target::remote_btrace_maybe_reopen): Pass down target.
+	(remote_target::pid_to_exec_file)
+	(remote_target::thread_handle_to_thread_info): Pass down target.
+	(remote_target::async_wait_fd): New.
+	* riscv-fbsd-tdep.c: Include "inferior.h".
+	(riscv_fbsd_get_thread_local_address): Pass down target.
+	* sol2-tdep.c (sol2_core_pid_to_str): Pass down target.
+	* sol-thread.c (sol_thread_target::wait, ps_lgetregs, ps_lsetregs)
+	(ps_lgetfpregs, ps_lsetfpregs, sol_update_thread_list_callback):
+	Adjust.
+	* solib-spu.c (spu_skip_standalone_loader): Pass down target.
+	* solib-svr4.c (enable_break): Pass down target.
+	* spu-multiarch.c (parse_spufs_run): Pass down target.
+	* spu-tdep.c (spu2ppu_sniffer): Pass down target.
+	* target-delegates.c: Regenerate.
+	* target.c (g_target_stack): Delete.
+	(current_top_target): Return the current inferior's top target.
+	(target_has_execution_1): Refer to the passed-in inferior's top
+	target.
+	(target_supports_terminal_ours): Check whether the initial
+	inferior was already created.
+	(decref_target): New.
+	(target_stack::push): Incref/decref the target.
+	(push_target, push_target, unpush_target): Adjust.
+	(target_stack::unpush): Defref target.
+	(target_is_pushed): Return bool.  Adjust to refer to the current
+	inferior's target stack.
+	(dispose_inferior): Delete, and inline parts ...
+	(target_preopen): ... here.  Only dispose of the current inferior.
+	(target_detach): Hold strong target reference while detaching.
+	Pass target down.
+	(target_thread_name): Add assertion.
+	(target_resume): Pass down target.
+	(target_ops::beneath, find_target_at): Adjust to refer to the
+	current inferior's target stack.
+	(get_dummy_target): New.
+	(target_pass_ctrlc): Pass the Ctrl-C to the first inferior that
+	has a thread running.
+	(initialize_targets): Rename to ...
+	(_initialize_target): ... this.
+	* target.h: Include "gdbsupport/refcounted-object.h".
+	(struct target_ops): Inherit refcounted_object.
+	(target_ops::shortname, target_ops::longname): Make const.
+	(target_ops::async_wait_fd): New method.
+	(decref_target): Declare.
+	(struct target_ops_ref_policy): New.
+	(target_ops_ref): New typedef.
+	(get_dummy_target): Declare function.
+	(target_is_pushed): Return bool.
+	* thread-iter.c (all_matching_threads_iterator::m_inf_matches)
+	(all_matching_threads_iterator::all_matching_threads_iterator):
+	Handle filter target.
+	* thread-iter.h (struct all_matching_threads_iterator, struct
+	all_matching_threads_range, class all_non_exited_threads_range):
+	Filter by target too.  Remove explicit.
+	* thread.c (threads_executing): Delete.
+	(inferior_thread): Pass down current inferior.
+	(clear_thread_inferior_resources): Pass down thread pointer
+	instead of ptid_t.
+	(add_thread_silent, add_thread_with_info, add_thread): Add
+	process_stratum_target parameter.  Use it for thread and inferior
+	searches.
+	(is_current_thread): New.
+	(thread_info::deletable): Use it.
+	(find_thread_ptid, thread_count, in_thread_list)
+	(thread_change_ptid, set_resumed, set_running): New
+	process_stratum_target parameter.  Pass it down.
+	(set_executing): New process_stratum_target parameter.  Pass it
+	down.  Adjust reference to 'threads_executing'.
+	(threads_are_executing): New process_stratum_target parameter.
+	Adjust reference to 'threads_executing'.
+	(set_stop_requested, finish_thread_state): New
+	process_stratum_target parameter.  Pass it down.
+	(switch_to_thread): Also match inferior.
+	(switch_to_thread): New process_stratum_target parameter.  Pass it
+	down.
+	(update_threads_executing): Reimplement.
+	* top.c (quit_force): Pop targets from all inferior.
+	(gdb_init): Don't call initialize_targets.
+	* windows-nat.c (windows_nat_target) <get_windows_debug_event>:
+	Declare.
+	(windows_add_thread, windows_delete_thread): Adjust.
+	(get_windows_debug_event): Rename to ...
+	(windows_nat_target::get_windows_debug_event): ... this.  Adjust.
+	* tracefile-tfile.c (tfile_target_open): Pass down target.
+	* gdbsupport/common-gdbthread.h (struct process_stratum_target):
+	Forward declare.
+	(switch_to_thread): Add process_stratum_target parameter.
+	* mi/mi-interp.c (mi_on_resume_1): Add process_stratum_target
+	parameter.  Use it.
+	(mi_on_resume): Pass target down.
+	* nat/fork-inferior.c (startup_inferior): Add
+	process_stratum_target parameter.  Pass it down.
+	* nat/fork-inferior.h (startup_inferior): Add
+	process_stratum_target parameter.
+	* python/py-threadevent.c (py_get_event_thread): Pass target down.
+
+2020-01-10  Pedro Alves  <palves@redhat.com>
 
 	* remote.c (remote_target::start_remote): Don't set inferior_ptid
 	directly.  Instead find the first thread in the thread list and
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 4e712eb..b385b58 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -959,7 +959,7 @@ aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
 
   /* Find the current gdbarch the same way as process_stratum_target.  Only
      return it if the current vector length matches the one in the tdep.  */
-  inferior *inf = find_inferior_ptid (ptid);
+  inferior *inf = find_inferior_ptid (this, ptid);
   gdb_assert (inf != NULL);
   if (vq == gdbarch_tdep (inf->gdbarch)->vq)
     return inf->gdbarch;
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 4f83084..0b7a8eb 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -1128,7 +1128,7 @@ print_ada_task_info (struct ui_out *uiout,
       if (uiout->is_mi_like_p ())
         {
 	  thread_info *thread = (ada_task_is_alive (task_info)
-				 ? find_thread_ptid (task_info->ptid)
+				 ? find_thread_ptid (inf, task_info->ptid)
 				 : nullptr);
 
 	  if (thread != NULL)
@@ -1343,7 +1343,7 @@ task_command_1 (const char *taskno_str, int from_tty, struct inferior *inf)
      computed if target_get_ada_task_ptid has not been implemented for
      our target (yet).  Rather than cause an assertion error in that case,
      it's nicer for the user to just refuse to perform the task switch.  */
-  thread_info *tp = find_thread_ptid (task_info->ptid);
+  thread_info *tp = find_thread_ptid (inf, task_info->ptid);
   if (tp == NULL)
     error (_("Unable to compute thread ID for task %s.\n"
              "Cannot switch to this task."),
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index efecf41..b9b25d5 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -805,7 +805,11 @@ sync_threadlists (void)
 	  priv->pdtid = pbuf[pi].pdtid;
 	  priv->tid = pbuf[pi].tid;
 
-	  thread = add_thread_with_info (ptid_t (infpid, 0, pbuf[pi].pthid), priv);
+	  process_stratum_target *proc_target
+	    = current_inferior ()->process_target ();
+	  thread = add_thread_with_info (proc_target,
+					 ptid_t (infpid, 0, pbuf[pi].pthid),
+					 priv);
 
 	  pi++;
 	}
@@ -837,7 +841,9 @@ sync_threadlists (void)
 	    }
 	  else
 	    {
-	      thread = add_thread (pptid);
+	      process_stratum_target *proc_target
+		= current_inferior ()->process_target ();
+	      thread = add_thread (proc_target, pptid);
 
 	      aix_thread_info *priv = new aix_thread_info;
 	      thread->priv.reset (priv);
@@ -1043,7 +1049,7 @@ aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
     }
   else
     {
-      thread = find_thread_ptid (ptid);
+      thread = find_thread_ptid (current_inferior (), ptid);
       if (!thread)
 	error (_("aix-thread resume: unknown pthread %ld"),
 	       ptid.lwp ());
@@ -1089,7 +1095,9 @@ aix_thread_target::wait (ptid_t ptid, struct target_waitstatus *status,
   if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED
       && status->value.sig == GDB_SIGNAL_TRAP)
     {
-      struct regcache *regcache = get_thread_regcache (ptid);
+      process_stratum_target *proc_target
+	= current_inferior ()->process_target ();
+      struct regcache *regcache = get_thread_regcache (proc_target, ptid);
       struct gdbarch *gdbarch = regcache->arch ();
 
       if (regcache_read_pc (regcache)
@@ -1354,7 +1362,7 @@ aix_thread_target::fetch_registers (struct regcache *regcache, int regno)
     beneath ()->fetch_registers (regcache, regno);
   else
     {
-      thread = find_thread_ptid (regcache->ptid ());
+      thread = find_thread_ptid (current_inferior (), regcache->ptid ());
       aix_thread_info *priv = get_aix_thread_info (thread);
       tid = priv->tid;
 
@@ -1692,7 +1700,7 @@ aix_thread_target::store_registers (struct regcache *regcache, int regno)
     beneath ()->store_registers (regcache, regno);
   else
     {
-      thread = find_thread_ptid (regcache->ptid ());
+      thread = find_thread_ptid (current_inferior (), regcache->ptid ());
       aix_thread_info *priv = get_aix_thread_info (thread);
       tid = priv->tid;
 
@@ -1740,7 +1748,9 @@ aix_thread_target::thread_alive (ptid_t ptid)
 
   /* We update the thread list every time the child stops, so all
      valid threads should be in the thread list.  */
-  return in_thread_list (ptid);
+  process_stratum_target *proc_target
+    = current_inferior ()->process_target ();
+  return in_thread_list (proc_target, ptid);
 }
 
 /* Return a printable representation of composite PID for use in
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c
index f71bddf..b0639ed 100644
--- a/gdb/amd64-fbsd-tdep.c
+++ b/gdb/amd64-fbsd-tdep.c
@@ -30,6 +30,7 @@
 #include "amd64-tdep.h"
 #include "fbsd-tdep.h"
 #include "solib-svr4.h"
+#include "inferior.h"
 
 /* Support for signal handlers.  */
 
@@ -212,7 +213,8 @@ amd64fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
 {
   struct regcache *regcache;
 
-  regcache = get_thread_arch_regcache (ptid, gdbarch);
+  regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+				       ptid, gdbarch);
 
   target_fetch_registers (regcache, AMD64_FSBASE_REGNUM);
 
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index f98d992..27748ff 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -383,7 +383,7 @@ ps_err_e
 ps_get_thread_area (struct ps_prochandle *ph,
                     lwpid_t lwpid, int idx, void **base)
 {
-  if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
+  if (gdbarch_bfd_arch_info (ph->thread->inf->gdbarch)->bits_per_word == 32)
     {
       unsigned int base_addr;
       ps_err_e result;
diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c
index 9970efa..c645746 100644
--- a/gdb/break-catch-sig.c
+++ b/gdb/break-catch-sig.c
@@ -185,7 +185,7 @@ signal_catchpoint_print_it (bpstat bs)
   const char *signal_name;
   struct ui_out *uiout = current_uiout;
 
-  get_last_target_status (nullptr, &last);
+  get_last_target_status (nullptr, nullptr, &last);
 
   signal_name = signal_to_name_or_int (last.value.sig);
 
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
index e51777c..553c01c 100644
--- a/gdb/break-catch-syscall.c
+++ b/gdb/break-catch-syscall.c
@@ -186,7 +186,7 @@ print_it_catch_syscall (bpstat bs)
   struct syscall s;
   struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
 
-  get_last_target_status (nullptr, &last);
+  get_last_target_status (nullptr, nullptr, &last);
 
   get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
 
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 055a8c9..5b734ab 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -389,7 +389,7 @@ breakpoints_should_be_inserted_now (void)
 	 no threads under GDB's control yet.  */
       return 1;
     }
-  else if (target_has_execution)
+  else
     {
       if (always_inserted_mode)
 	{
@@ -398,8 +398,10 @@ breakpoints_should_be_inserted_now (void)
 	  return 1;
 	}
 
-      if (threads_are_executing ())
-	return 1;
+      for (inferior *inf : all_inferiors ())
+	if (inf->has_execution ()
+	    && threads_are_executing (inf->process_target ()))
+	  return 1;
 
       /* Don't remove breakpoints yet if, even though all threads are
 	 stopped, we still have events to process.  */
@@ -2887,7 +2889,7 @@ update_inserted_breakpoint_locations (void)
 	 if we aren't attached to any process yet, we should still
 	 insert breakpoints.  */
       if (!gdbarch_has_global_breakpoints (target_gdbarch ())
-	  && inferior_ptid == null_ptid)
+	  && (inferior_ptid == null_ptid || !target_has_execution))
 	continue;
 
       val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
@@ -2943,7 +2945,7 @@ insert_breakpoint_locations (void)
 	 if we aren't attached to any process yet, we should still
 	 insert breakpoints.  */
       if (!gdbarch_has_global_breakpoints (target_gdbarch ())
-	  && inferior_ptid == null_ptid)
+	  && (inferior_ptid == null_ptid || !target_has_execution))
 	continue;
 
       val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
@@ -11903,7 +11905,18 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 		 around.  We simply always ignore hardware watchpoint
 		 traps we can no longer explain.  */
 
-	      old_loc->events_till_retirement = 3 * (thread_count () + 1);
+	      process_stratum_target *proc_target = nullptr;
+	      for (inferior *inf : all_inferiors ())
+		if (inf->pspace == old_loc->pspace)
+		  {
+		    proc_target = inf->process_target ();
+		    break;
+		  }
+	      if (proc_target != nullptr)
+		old_loc->events_till_retirement
+		  = 3 * (thread_count (proc_target) + 1);
+	      else
+		old_loc->events_till_retirement = 1;
 	      old_loc->owner = NULL;
 
 	      moribund_locations.push_back (old_loc);
diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
index 28e6fcf..f864ba8 100644
--- a/gdb/bsd-kvm.c
+++ b/gdb/bsd-kvm.c
@@ -136,7 +136,7 @@ bsd_kvm_target_open (const char *arg, int from_tty)
   core_kd = temp_kd;
   push_target (&bsd_kvm_ops);
 
-  add_thread_silent (bsd_kvm_ptid);
+  add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
   inferior_ptid = bsd_kvm_ptid;
 
   target_fetch_registers (get_current_regcache (), -1);
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index eb9dcb6..a8622a8 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -381,9 +381,11 @@ bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR addr;
+  process_stratum_target *beneath
+    = as_process_stratum_target (this->beneath ());
 
   /* Pass the request to the layer beneath.  */
-  ptid = beneath ()->wait (ptid, status, options);
+  ptid = beneath->wait (ptid, status, options);
 
   /* If the process is no longer alive, there's no point in figuring
      out the thread ID.  It will fail anyway.  */
@@ -414,13 +416,13 @@ bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
      ptid with tid set, then ptid is still the initial thread of
      the process.  Notify GDB core about it.  */
   if (inferior_ptid.tid () == 0
-      && ptid.tid () != 0 && !in_thread_list (ptid))
-    thread_change_ptid (inferior_ptid, ptid);
+      && ptid.tid () != 0 && !in_thread_list (beneath, ptid))
+    thread_change_ptid (beneath, inferior_ptid, ptid);
 
   /* Don't let the core see a ptid without a corresponding thread.  */
-  thread_info *thread = find_thread_ptid (ptid);
+  thread_info *thread = find_thread_ptid (beneath, ptid);
   if (thread == NULL || thread->state == THREAD_EXITED)
-    add_thread (ptid);
+    add_thread (beneath, ptid);
 
   return ptid;
 }
@@ -467,16 +469,18 @@ bsd_uthread_target::update_thread_list ()
     {
       ptid_t ptid = ptid_t (pid, 0, addr);
 
-      thread_info *thread = find_thread_ptid (ptid);
+      process_stratum_target *proc_target
+	= as_process_stratum_target (this->beneath ());
+      thread_info *thread = find_thread_ptid (proc_target, ptid);
       if (thread == nullptr || thread->state == THREAD_EXITED)
 	{
 	  /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
 	     is still the initial thread of the process.  Notify GDB
 	     core about it.  */
 	  if (inferior_ptid.tid () == 0)
-	    thread_change_ptid (inferior_ptid, ptid);
+	    thread_change_ptid (proc_target, inferior_ptid, ptid);
 	  else
-	    add_thread (ptid);
+	    add_thread (proc_target, ptid);
 	}
 
       addr = bsd_uthread_read_memory_address (addr + offset);
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 407f01a..a91a676 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -3228,7 +3228,7 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
   struct btrace_thread_info *btinfo;
   unsigned int size, begin, end, from, to;
 
-  thread_info *tp = find_thread_ptid (inferior_ptid);
+  thread_info *tp = find_thread_ptid (current_inferior (), inferior_ptid);
   if (tp == NULL)
     error (_("No thread."));
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 74f6608..c53bf1d 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -314,7 +314,7 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
 
   ptid = ptid_t (pid, lwpid, 0);
 
-  add_thread (ptid);
+  add_thread (inf->process_target (), ptid);
 
 /* Warning, Will Robinson, looking at BFD private data! */
 
@@ -472,7 +472,7 @@ core_target_open (const char *arg, int from_tty)
 	{
 	  inferior_appeared (current_inferior (), CORELOW_PID);
 	  inferior_ptid = ptid_t (CORELOW_PID);
-	  add_thread_silent (inferior_ptid);
+	  add_thread_silent (target, inferior_ptid);
 	}
       else
 	switch_to_thread (thread);
@@ -540,7 +540,7 @@ core_target_open (const char *arg, int from_tty)
   /* Current thread should be NUM 1 but the user does not know that.
      If a program is single threaded gdb in general does not mention
      anything about threads.  That is why the test is >= 2.  */
-  if (thread_count () >= 2)
+  if (thread_count (target) >= 2)
     {
       try
 	{
@@ -944,7 +944,7 @@ core_target::pid_to_str (ptid_t ptid)
 
   /* Otherwise, this isn't a "threaded" core -- use the PID field, but
      only if it isn't a fake PID.  */
-  inf = find_inferior_ptid (ptid);
+  inf = find_inferior_ptid (this, ptid);
   if (inf != NULL && !inf->fake_pid_p)
     return normal_pid_to_str (ptid);
 
diff --git a/gdb/event-top.c b/gdb/event-top.c
index a5f8c68..3f10b21 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -1137,12 +1137,16 @@ async_disconnect (gdb_client_data arg)
       exception_print (gdb_stderr, exception);
     }
 
-  try
-    {
-      pop_all_targets ();
-    }
-  catch (const gdb_exception &exception)
+  for (inferior *inf : all_inferiors ())
     {
+      switch_to_inferior_no_thread (inf);
+      try
+	{
+	  pop_all_targets ();
+	}
+      catch (const gdb_exception &exception)
+	{
+	}
     }
 
   signal (SIGHUP, SIG_DFL);	/*FIXME: ???????????  */
diff --git a/gdb/exec.c b/gdb/exec.c
index 906ae61..468f9f5 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -547,10 +547,23 @@ add_target_sections (void *owner,
 	  table->sections[space + i].owner = owner;
 	}
 
+      scoped_restore_current_thread restore_thread;
+      program_space *curr_pspace = current_program_space;
+
       /* If these are the first file sections we can provide memory
-	 from, push the file_stratum target.  */
-      if (!target_is_pushed (&exec_ops))
-	push_target (&exec_ops);
+	 from, push the file_stratum target.  Must do this in all
+	 inferiors sharing the program space.  */
+      for (inferior *inf : all_inferiors ())
+	{
+	  if (inf->pspace != curr_pspace)
+	    continue;
+
+	  if (inf->target_is_pushed (&exec_ops))
+	    continue;
+
+	  switch_to_inferior_no_thread (inf);
+	  push_target (&exec_ops);
+	}
     }
 }
 
@@ -628,21 +641,39 @@ remove_target_sections (void *owner)
       old_count = resize_section_table (table, dest - src);
 
       /* If we don't have any more sections to read memory from,
-	 remove the file_stratum target from the stack.  */
+	 remove the file_stratum target from the stack of each
+	 inferior sharing the program space.  */
       if (old_count + (dest - src) == 0)
 	{
-	  struct program_space *pspace;
+	  scoped_restore_current_thread restore_thread;
+	  program_space *curr_pspace = current_program_space;
+
+	  for (inferior *inf : all_inferiors ())
+	    {
+	      if (inf->pspace != curr_pspace)
+		continue;
 
-	  ALL_PSPACES (pspace)
-	    if (pspace->target_sections.sections
-		!= pspace->target_sections.sections_end)
-	      return;
+	      if (inf->pspace->target_sections.sections
+		  != inf->pspace->target_sections.sections_end)
+		continue;
 
-	  unpush_target (&exec_ops);
+	      switch_to_inferior_no_thread (inf);
+	      unpush_target (&exec_ops);
+	    }
 	}
     }
 }
 
+/* See exec.h.  */
+
+void
+exec_on_vfork ()
+{
+  if (current_program_space->target_sections.sections
+      != current_program_space->target_sections.sections_end)
+    push_target (&exec_ops);
+}
+
 
 
 enum target_xfer_status
diff --git a/gdb/exec.h b/gdb/exec.h
index e50a3a0..54e6ff4 100644
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -44,6 +44,13 @@ extern int build_section_table (struct bfd *, struct target_section **,
 
 extern void clear_section_table (struct target_section_table *table);
 
+/* The current inferior is a child vforked and its program space is
+   shared with its parent.  This pushes the exec target on the
+   current/child inferior's target stack if there are sections in the
+   program space's section table.  */
+
+extern void exec_on_vfork ();
+
 /* Read from mappable read-only sections of BFD executable files.
    Return TARGET_XFER_OK, if read is successful.  Return
    TARGET_XFER_EOF if read is done.  Return TARGET_XFER_E_IO
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index f0f1e79..698d1f0 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -991,11 +991,11 @@ fbsd_enable_proc_events (pid_t pid)
    called to discover new threads each time the thread list is updated.  */
 
 static void
-fbsd_add_threads (pid_t pid)
+fbsd_add_threads (fbsd_nat_target *target, pid_t pid)
 {
   int i, nlwps;
 
-  gdb_assert (!in_thread_list (ptid_t (pid)));
+  gdb_assert (!in_thread_list (target, ptid_t (pid)));
   nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0);
   if (nlwps == -1)
     perror_with_name (("ptrace"));
@@ -1010,7 +1010,7 @@ fbsd_add_threads (pid_t pid)
     {
       ptid_t ptid = ptid_t (pid, lwps[i], 0);
 
-      if (!in_thread_list (ptid))
+      if (!in_thread_list (target, ptid))
 	{
 #ifdef PT_LWP_EVENTS
 	  struct ptrace_lwpinfo pl;
@@ -1026,7 +1026,7 @@ fbsd_add_threads (pid_t pid)
 	    fprintf_unfiltered (gdb_stdlog,
 				"FLWP: adding thread for LWP %u\n",
 				lwps[i]);
-	  add_thread (ptid);
+	  add_thread (target, ptid);
 	}
     }
 }
@@ -1043,7 +1043,7 @@ fbsd_nat_target::update_thread_list ()
 #else
   prune_threads ();
 
-  fbsd_add_threads (inferior_ptid.pid ());
+  fbsd_add_threads (this, inferior_ptid.pid ());
 #endif
 }
 
@@ -1174,7 +1174,7 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
   if (ptid.lwp_p ())
     {
       /* If ptid is a specific LWP, suspend all other LWPs in the process.  */
-      inferior *inf = find_inferior_ptid (ptid);
+      inferior *inf = find_inferior_ptid (this, ptid);
 
       for (thread_info *tp : inf->non_exited_threads ())
         {
@@ -1193,7 +1193,7 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
     {
       /* If ptid is a wildcard, resume all matching threads (they won't run
 	 until the process is continued however).  */
-      for (thread_info *tp : all_non_exited_threads (ptid))
+      for (thread_info *tp : all_non_exited_threads (this, ptid))
 	if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1)
 	  perror_with_name (("ptrace"));
       ptid = inferior_ptid;
@@ -1239,7 +1239,8 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
    core, return true.  */
 
 static bool
-fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl)
+fbsd_handle_debug_trap (fbsd_nat_target *target, ptid_t ptid,
+			const struct ptrace_lwpinfo &pl)
 {
 
   /* Ignore traps without valid siginfo or for signals other than
@@ -1266,7 +1267,7 @@ fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl)
   if (pl.pl_siginfo.si_code == TRAP_BRKPT)
     {
       /* Fixup PC for the software breakpoint.  */
-      struct regcache *regcache = get_thread_regcache (ptid);
+      struct regcache *regcache = get_thread_regcache (target, ptid);
       struct gdbarch *gdbarch = regcache->arch ();
       int decr_pc = gdbarch_decr_pc_after_break (gdbarch);
 
@@ -1340,7 +1341,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 		 threads might be skipped during post_attach that
 		 have not yet reported their PL_FLAG_EXITED event.
 		 Ignore EXITED events for an unknown LWP.  */
-	      thread_info *thr = find_thread_ptid (wptid);
+	      thread_info *thr = find_thread_ptid (this, wptid);
 	      if (thr != nullptr)
 		{
 		  if (debug_fbsd_lwp)
@@ -1364,13 +1365,13 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 	     PL_FLAG_BORN in case the first stop reported after
 	     attaching to an existing process is a PL_FLAG_BORN
 	     event.  */
-	  if (in_thread_list (ptid_t (pid)))
+	  if (in_thread_list (this, ptid_t (pid)))
 	    {
 	      if (debug_fbsd_lwp)
 		fprintf_unfiltered (gdb_stdlog,
 				    "FLWP: using LWP %u for first thread\n",
 				    pl.pl_lwpid);
-	      thread_change_ptid (ptid_t (pid), wptid);
+	      thread_change_ptid (this, ptid_t (pid), wptid);
 	    }
 
 #ifdef PT_LWP_EVENTS
@@ -1380,13 +1381,13 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 		 threads might be added by fbsd_add_threads that have
 		 not yet reported their PL_FLAG_BORN event.  Ignore
 		 BORN events for an already-known LWP.  */
-	      if (!in_thread_list (wptid))
+	      if (!in_thread_list (this, wptid))
 		{
 		  if (debug_fbsd_lwp)
 		    fprintf_unfiltered (gdb_stdlog,
 					"FLWP: adding thread for LWP %u\n",
 					pl.pl_lwpid);
-		  add_thread (wptid);
+		  add_thread (this, wptid);
 		}
 	      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
 	      return wptid;
@@ -1474,7 +1475,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 #endif
 
 #ifdef USE_SIGTRAP_SIGINFO
-	  if (fbsd_handle_debug_trap (wptid, pl))
+	  if (fbsd_handle_debug_trap (this, wptid, pl))
 	    return wptid;
 #endif
 
@@ -1633,7 +1634,7 @@ void
 fbsd_nat_target::post_attach (int pid)
 {
   fbsd_enable_proc_events (pid);
-  fbsd_add_threads (pid);
+  fbsd_add_threads (this, pid);
 }
 
 #ifdef PL_FLAG_EXEC
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index ff642d5..9e5d23a 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -673,7 +673,8 @@ fbsd_corefile_thread (struct thread_info *info,
 {
   struct regcache *regcache;
 
-  regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
+  regcache = get_thread_arch_regcache (info->inf->process_target (),
+				       info->ptid, args->gdbarch);
 
   target_fetch_registers (regcache, -1);
 
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 3e9e7f9..65a189e 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -128,10 +128,13 @@ postfork_child_hook ()
 ptid_t
 gdb_startup_inferior (pid_t pid, int num_traps)
 {
-  ptid_t ptid = startup_inferior (pid, num_traps, NULL, NULL);
+  inferior *inf = current_inferior ();
+  process_stratum_target *proc_target = inf->process_target ();
+
+  ptid_t ptid = startup_inferior (proc_target, pid, num_traps, NULL, NULL);
 
   /* Mark all threads non-executing.  */
-  set_executing (ptid, 0);
+  set_executing (proc_target, ptid, 0);
 
   return ptid;
 }
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 63778e2..b62ed4c 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,25 @@
+2020-01-10  Pedro Alves  <palves@redhat.com>
+
+	* fork-child.c (post_fork_inferior): Pass target down to
+	startup_inferior.
+	* inferiors.c (switch_to_thread): Add process_stratum_target
+	parameter.
+	* lynx-low.c (lynx_target_ops): Now a process_stratum_target.
+	* nto-low.c (nto_target_ops): Now a process_stratum_target.
+	* linux-low.c (linux_target_ops): Now a process_stratum_target.
+	* remote-utils.c (prepare_resume_reply): Pass the target to
+	switch_to_thread.
+	* target.c (the_target): Now a process_stratum_target.
+	(done_accessing_memory): Pass the target to switch_to_thread.
+	(set_target_ops): Ajust to use process_stratum_target.
+	* target.h (struct target_ops): Rename to ...
+	(struct process_stratum_target): ... this.
+	(the_target, set_target_ops): Adjust.
+	(prepare_to_access_memory): Adjust comment.
+	* win32-low.c (child_xfer_memory): Adjust to use
+	process_stratum_target.
+	(win32_target_ops): Now a process_stratum_target.
+
 2020-01-06  Eli Zaretskii  <eliz@gnu.org>
 	    Pedro Alves  <palves@redhat.com>
 
diff --git a/gdb/gdbserver/fork-child.c b/gdb/gdbserver/fork-child.c
index 0a53a25..7a71ec0 100644
--- a/gdb/gdbserver/fork-child.c
+++ b/gdb/gdbserver/fork-child.c
@@ -107,7 +107,8 @@ post_fork_inferior (int pid, const char *program)
   atexit (restore_old_foreground_pgrp);
 #endif
 
-  startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED,
+  startup_inferior (the_target, pid,
+		    START_INFERIOR_TRAPS_EXPECTED,
 		    &cs.last_status, &cs.last_ptid);
   current_thread->last_resume_kind = resume_stop;
   current_thread->last_status = cs.last_status;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index fe7161c..cf6e914 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -216,7 +216,7 @@ current_process (void)
 /* See gdbsupport/common-gdbthread.h.  */
 
 void
-switch_to_thread (ptid_t ptid)
+switch_to_thread (process_stratum_target *ops, ptid_t ptid)
 {
   gdb_assert (ptid != minus_one_ptid);
   current_thread = find_thread_ptid (ptid);
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 4255795..676dea2 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -7354,7 +7354,7 @@ linux_get_hwcap2 (int wordsize)
   return hwcap2;
 }
 
-static struct target_ops linux_target_ops = {
+static process_stratum_target linux_target_ops = {
   linux_create_inferior,
   linux_post_create_inferior,
   linux_attach,
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index decbe49..a5b0193 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -721,7 +721,7 @@ lynx_request_interrupt (void)
 
 /* The LynxOS target_ops vector.  */
 
-static struct target_ops lynx_target_ops = {
+static process_stratum_target lynx_target_ops = {
   lynx_create_inferior,
   NULL,  /* post_create_inferior */
   lynx_attach,
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index 8af5cf6..b4dea47 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -931,7 +931,7 @@ nto_sw_breakpoint_from_kind (int kind, int *size)
 }
 
 
-static struct target_ops nto_target_ops = {
+static process_stratum_target nto_target_ops = {
   nto_create_inferior,
   NULL,  /* post_create_inferior */
   nto_attach,
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index b757740..b8a8c65 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1208,7 +1208,7 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 
 	saved_thread = current_thread;
 
-	switch_to_thread (ptid);
+	switch_to_thread (the_target, ptid);
 
 	regp = current_target_desc ()->expedite_regs;
 
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index f3887b3..a4593cf 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -22,7 +22,7 @@
 #include "tracepoint.h"
 #include "gdbsupport/byte-vector.h"
 
-struct target_ops *the_target;
+process_stratum_target *the_target;
 
 int
 set_desired_thread ()
@@ -119,7 +119,7 @@ done_accessing_memory (void)
 
   /* Restore the previous selected thread.  */
   cs.general_thread = prev_general_thread;
-  switch_to_thread (cs.general_thread);
+  switch_to_thread (the_target, cs.general_thread);
 }
 
 int
@@ -284,9 +284,9 @@ start_non_stop (int nonstop)
 }
 
 void
-set_target_ops (struct target_ops *target)
+set_target_ops (process_stratum_target *target)
 {
-  the_target = XNEW (struct target_ops);
+  the_target = XNEW (process_stratum_target);
   memcpy (the_target, target, sizeof (*the_target));
 }
 
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 2681078..1b0810b 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -63,7 +63,10 @@ struct thread_resume
   CORE_ADDR step_range_end;	/* Exclusive */
 };
 
-struct target_ops
+/* GDBserver doesn't have a concept of strata like GDB, but we call
+   its target vector "process_stratum" anyway for the benefit of
+   shared code.  */
+struct process_stratum_target
 {
   /* Start a new process.
 
@@ -476,9 +479,9 @@ struct target_ops
   bool (*thread_handle) (ptid_t ptid, gdb_byte **handle, int *handle_len);
 };
 
-extern struct target_ops *the_target;
+extern process_stratum_target *the_target;
 
-void set_target_ops (struct target_ops *);
+void set_target_ops (process_stratum_target *);
 
 #define create_inferior(program, program_args)	\
   (*the_target->create_inferior) (program, program_args)
@@ -702,7 +705,7 @@ ptid_t mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
 	       int connected_wait);
 
 /* Prepare to read or write memory from the inferior process.  See the
-   corresponding target_ops methods for more details.  */
+   corresponding process_stratum_target methods for more details.  */
 
 int prepare_to_access_memory (void);
 void done_accessing_memory (void);
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 340f65b..2c4a9b1 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -307,7 +307,7 @@ win32_stopped_data_address (void)
 /* Transfer memory from/to the debugged process.  */
 static int
 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
-		   int write, struct target_ops *target)
+		   int write, process_stratum_target *target)
 {
   BOOL success;
   SIZE_T done = 0;
@@ -1795,7 +1795,7 @@ win32_sw_breakpoint_from_kind (int kind, int *size)
   return the_low_target.breakpoint;
 }
 
-static struct target_ops win32_target_ops = {
+static process_stratum_target win32_target_ops = {
   win32_create_inferior,
   NULL,  /* post_create_inferior */
   win32_attach,
diff --git a/gdb/gdbsupport/common-gdbthread.h b/gdb/gdbsupport/common-gdbthread.h
index 57d0870..050ad80 100644
--- a/gdb/gdbsupport/common-gdbthread.h
+++ b/gdb/gdbsupport/common-gdbthread.h
@@ -19,7 +19,10 @@
 #ifndef COMMON_COMMON_GDBTHREAD_H
 #define COMMON_COMMON_GDBTHREAD_H
 
+struct process_stratum_target;
+
 /* Switch from one thread to another.  */
-extern void switch_to_thread (ptid_t ptid);
+extern void switch_to_thread (process_stratum_target *proc_target,
+			      ptid_t ptid);
 
 #endif /* COMMON_COMMON_GDBTHREAD_H */
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 5f1e3bb..f205e29 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -34,6 +34,7 @@ struct symtab;
 #include "gdbsupport/forward-scope-exit.h"
 
 struct inferior;
+struct process_stratum_target;
 
 /* Frontend view of the thread state.  Possible extensions: stepping,
    finishing, until(ling),...
@@ -304,7 +305,7 @@ public:
      from saying that there is an active target and we are stopped at
      a breakpoint, for instance.  This is a real indicator whether the
      thread is off and running.  */
-  int executing = 0;
+  bool executing = false;
 
   /* Non-zero if this thread is resumed from infrun's perspective.
      Note that a thread can be marked both as not-executing and
@@ -419,15 +420,18 @@ extern void init_thread_list (void);
    that a new thread is found, and return the pointer to
    the new thread.  Caller my use this pointer to 
    initialize the private thread data.  */
-extern struct thread_info *add_thread (ptid_t ptid);
+extern struct thread_info *add_thread (process_stratum_target *targ,
+				       ptid_t ptid);
 
-/* Same as add_thread, but does not print a message
-   about new thread.  */
-extern struct thread_info *add_thread_silent (ptid_t ptid);
+/* Same as add_thread, but does not print a message about new
+   thread.  */
+extern struct thread_info *add_thread_silent (process_stratum_target *targ,
+					      ptid_t ptid);
 
 /* Same as add_thread, and sets the private info.  */
-extern struct thread_info *add_thread_with_info (ptid_t ptid,
-						 struct private_thread_info *);
+extern struct thread_info *add_thread_with_info (process_stratum_target *targ,
+						 ptid_t ptid,
+						 private_thread_info *);
 
 /* Delete an existing thread list entry.  */
 extern void delete_thread (struct thread_info *thread);
@@ -468,14 +472,18 @@ extern int show_inferior_qualified_tids (void);
 const char *print_thread_id (struct thread_info *thr);
 
 /* Boolean test for an already-known ptid.  */
-extern int in_thread_list (ptid_t ptid);
+extern bool in_thread_list (process_stratum_target *targ, ptid_t ptid);
 
 /* Boolean test for an already-known global thread id (GDB's homegrown
    global id, not the system's).  */
 extern int valid_global_thread_id (int global_id);
 
+/* Find thread PTID of inferior INF.  */
+extern thread_info *find_thread_ptid (inferior *inf, ptid_t ptid);
+
 /* Search function to lookup a thread by 'pid'.  */
-extern struct thread_info *find_thread_ptid (ptid_t ptid);
+extern struct thread_info *find_thread_ptid (process_stratum_target *targ,
+					     ptid_t ptid);
 
 /* Search function to lookup a thread by 'ptid'.  Only searches in
    threads of INF.  */
@@ -500,7 +508,8 @@ extern struct thread_info *any_thread_of_inferior (inferior *inf);
 extern struct thread_info *any_live_thread_of_inferior (inferior *inf);
 
 /* Change the ptid of thread OLD_PTID to NEW_PTID.  */
-void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid);
+void thread_change_ptid (process_stratum_target *targ,
+			 ptid_t old_ptid, ptid_t new_ptid);
 
 /* Iterator function to call a user-provided callback function
    once for each known thread.  */
@@ -511,34 +520,44 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
    iterators.  Must be done after struct thread_info is defined.  */
 #include "thread-iter.h"
 
-/* Return a range that can be used to walk over all threads of all
-   inferiors, with range-for.  Used like this:
+/* Return a range that can be used to walk over threads, with
+   range-for.
+
+   Used like this, it walks over all threads of all inferiors of all
+   targets:
 
        for (thread_info *thr : all_threads ())
 	 { .... }
-*/
-inline all_threads_range
-all_threads ()
-{
-  return {};
-}
 
-/* Likewise, but accept a filter PTID.  */
+   FILTER_PTID can be used to filter out threads that don't match.
+   FILTER_PTID can be:
+
+   - minus_one_ptid, meaning walk all threads of all inferiors of
+     PROC_TARGET.  If PROC_TARGET is NULL, then of all targets.
+
+   - A process ptid, in which case walk all threads of the specified
+     process.  PROC_TARGET must be non-NULL in this case.
+
+   - A thread ptid, in which case walk that thread only.  PROC_TARGET
+     must be non-NULL in this case.
+*/
 
 inline all_matching_threads_range
-all_threads (ptid_t filter_ptid)
+all_threads (process_stratum_target *proc_target = nullptr,
+	     ptid_t filter_ptid = minus_one_ptid)
 {
-  return all_matching_threads_range (filter_ptid);
+  return all_matching_threads_range (proc_target, filter_ptid);
 }
 
 /* Return a range that can be used to walk over all non-exited threads
-   of all inferiors, with range-for.  FILTER_PTID can be used to
-   filter out thread that don't match.  */
+   of all inferiors, with range-for.  Arguments are like all_threads
+   above.  */
 
 inline all_non_exited_threads_range
-all_non_exited_threads (ptid_t filter_ptid = minus_one_ptid)
+all_non_exited_threads (process_stratum_target *proc_target = nullptr,
+			ptid_t filter_ptid = minus_one_ptid)
 {
-  return all_non_exited_threads_range (filter_ptid);
+  return all_non_exited_threads_range (proc_target, filter_ptid);
 }
 
 /* Return a range that can be used to walk over all threads of all
@@ -554,10 +573,10 @@ all_non_exited_threads (ptid_t filter_ptid = minus_one_ptid)
 inline all_threads_safe_range
 all_threads_safe ()
 {
-  return all_threads_safe_range ();
+  return {};
 }
 
-extern int thread_count (void);
+extern int thread_count (process_stratum_target *proc_target);
 
 /* Return true if we have any thread in any inferior.  */
 extern bool any_thread_p ();
@@ -571,44 +590,50 @@ extern void switch_to_no_thread ();
 /* Switch from one thread to another.  Does not read registers.  */
 extern void switch_to_thread_no_regs (struct thread_info *thread);
 
-/* Marks or clears thread(s) PTID as resumed.  If PTID is
-   MINUS_ONE_PTID, applies to all threads.  If ptid_is_pid(PTID) is
-   true, applies to all threads of the process pointed at by PTID.  */
-extern void set_resumed (ptid_t ptid, int resumed);
-
-/* Marks thread PTID is running, or stopped. 
-   If PTID is minus_one_ptid, marks all threads.  */
-extern void set_running (ptid_t ptid, int running);
-
-/* Marks or clears thread(s) PTID as having been requested to stop.
-   If PTID is MINUS_ONE_PTID, applies to all threads.  If
+/* Marks or clears thread(s) PTID of TARG as resumed.  If PTID is
+   MINUS_ONE_PTID, applies to all threads of TARG.  If
    ptid_is_pid(PTID) is true, applies to all threads of the process
-   pointed at by PTID.  If STOP, then the THREAD_STOP_REQUESTED
-   observer is called with PTID as argument.  */
-extern void set_stop_requested (ptid_t ptid, int stop);
-
-/* Marks thread PTID as executing, or not.  If PTID is minus_one_ptid,
-   marks all threads.
+   pointed at by {TARG,PTID}.  */
+extern void set_resumed (process_stratum_target *targ,
+			 ptid_t ptid, bool resumed);
+
+/* Marks thread PTID of TARG as running, or as stopped.  If PTID is
+   minus_one_ptid, marks all threads of TARG.  */
+extern void set_running (process_stratum_target *targ,
+			 ptid_t ptid, bool running);
+
+/* Marks or clears thread(s) PTID of TARG as having been requested to
+   stop.  If PTID is MINUS_ONE_PTID, applies to all threads of TARG.
+   If ptid_is_pid(PTID) is true, applies to all threads of the process
+   pointed at by {TARG, PTID}.  If STOP, then the
+   THREAD_STOP_REQUESTED observer is called with PTID as argument.  */
+extern void set_stop_requested (process_stratum_target *targ,
+				ptid_t ptid, bool stop);
+
+/* Marks thread PTID of TARG as executing, or not.  If PTID is
+   minus_one_ptid, marks all threads of TARG.
 
    Note that this is different from the running state.  See the
    description of state and executing fields of struct
    thread_info.  */
-extern void set_executing (ptid_t ptid, int executing);
+extern void set_executing (process_stratum_target *targ,
+			   ptid_t ptid, bool executing);
 
-/* True if any (known or unknown) thread is or may be executing.  */
-extern int threads_are_executing (void);
+/* True if any (known or unknown) thread of TARG is or may be
+   executing.  */
+extern bool threads_are_executing (process_stratum_target *targ);
 
-/* Merge the executing property of thread PTID over to its thread
-   state property (frontend running/stopped view).
+/* Merge the executing property of thread PTID of TARG over to its
+   thread state property (frontend running/stopped view).
 
    "not executing" -> "stopped"
    "executing"     -> "running"
    "exited"        -> "exited"
 
-   If PTID is minus_one_ptid, go over all threads.
+   If PTID is minus_one_ptid, go over all threads of TARG.
 
    Notifications are only emitted if the thread state did change.  */
-extern void finish_thread_state (ptid_t ptid);
+extern void finish_thread_state (process_stratum_target *targ, ptid_t ptid);
 
 /* Calls finish_thread_state on scope exit, unless release() is called
    to disengage.  */
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index cb66bbf..d072709 100644
--- a/gdb/i386-fbsd-tdep.c
+++ b/gdb/i386-fbsd-tdep.c
@@ -30,6 +30,7 @@
 #include "i387-tdep.h"
 #include "fbsd-tdep.h"
 #include "solib-svr4.h"
+#include "inferior.h"
 
 /* Support for signal handlers.  */
 
@@ -332,7 +333,8 @@ i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
   if (tdep->fsbase_regnum == -1)
     error (_("Unable to fetch %%gsbase"));
 
-  regcache = get_thread_arch_regcache (ptid, gdbarch);
+  regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+				       ptid, gdbarch);
 
   target_fetch_registers (regcache, tdep->fsbase_regnum + 1);
 
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 9ed4c9c..32cd879 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -657,7 +657,7 @@ i386_linux_nat_target::low_resume (ptid_t ptid, int step, enum gdb_signal signal
 
   if (step)
     {
-      struct regcache *regcache = get_thread_regcache (ptid);
+      struct regcache *regcache = get_thread_regcache (this, ptid);
       struct gdbarch *gdbarch = regcache->arch ();
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       ULONGEST pc;
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index a9bb8d2..4833094 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -206,7 +206,7 @@ inf_child_target::mourn_inferior ()
 void
 inf_child_target::maybe_unpush_target ()
 {
-  if (!inf_child_explicitly_opened && !have_inferiors ())
+  if (!inf_child_explicitly_opened)
     unpush_target (this);
 }
 
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 4ad1cd0..ecd82ad 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -136,7 +136,7 @@ inf_ptrace_target::create_inferior (const char *exec_file,
   /* We have something that executes now.  We'll be running through
      the shell at this point (if startup-with-shell is true), but the
      pid shouldn't change.  */
-  add_thread_silent (ptid);
+  add_thread_silent (this, ptid);
 
   unpusher.release ();
 
@@ -235,10 +235,10 @@ inf_ptrace_target::attach (const char *args, int from_tty)
 
   /* Always add a main thread.  If some target extends the ptrace
      target, it should decorate the ptid later with more info.  */
-  thread_info *thr = add_thread_silent (inferior_ptid);
+  thread_info *thr = add_thread_silent (this, inferior_ptid);
   /* Don't consider the thread stopped until we've processed its
      initial SIGSTOP stop.  */
-  set_executing (thr->ptid, true);
+  set_executing (this, thr->ptid, true);
 
   unpusher.release ();
 }
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 2611137..240644a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -649,7 +649,8 @@ run_inferior_call (struct call_thread_fsm *sm,
   if (!was_running
       && call_thread_ptid == inferior_ptid
       && stop_stack_dummy == STOP_STACK_DUMMY)
-    finish_thread_state (user_visible_resume_ptid (0));
+    finish_thread_state (call_thread->inf->process_target (),
+			 user_visible_resume_ptid (0));
 
   enable_watchpoints_after_interactive_call_stop ();
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 99823a8..2bf21e2 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -645,10 +645,19 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
      events --- the frontend shouldn't see them as stopped.  In
      all-stop, always finish the state of all threads, as we may be
      resuming more than just the new process.  */
-  ptid_t finish_ptid = (non_stop
-			? ptid_t (current_inferior ()->pid)
-			: minus_one_ptid);
-  scoped_finish_thread_state finish_state (finish_ptid);
+  process_stratum_target *finish_target;
+  ptid_t finish_ptid;
+  if (non_stop)
+    {
+      finish_target = current_inferior ()->process_target ();
+      finish_ptid = ptid_t (current_inferior ()->pid);
+    }
+  else
+    {
+      finish_target = nullptr;
+      finish_ptid = minus_one_ptid;
+    }
+  scoped_finish_thread_state finish_state (finish_target, finish_ptid);
 
   /* Pass zero for FROM_TTY, because at this point the "run" command
      has done its thing; now we are setting up the running program.  */
@@ -718,6 +727,9 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
   if (thread->state != THREAD_STOPPED)
     return 0;
 
+  if (!thread->inf->has_execution ())
+    return 0;
+
   switch_to_thread (thread);
   clear_proceed_status (0);
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
@@ -811,7 +823,7 @@ static void
 continue_command (const char *args, int from_tty)
 {
   int async_exec;
-  int all_threads = 0;
+  bool all_threads_p = false;
 
   ERROR_NO_INFERIOR;
 
@@ -823,17 +835,17 @@ continue_command (const char *args, int from_tty)
     {
       if (startswith (args, "-a"))
 	{
-	  all_threads = 1;
+	  all_threads_p = true;
 	  args += sizeof ("-a") - 1;
 	  if (*args == '\0')
 	    args = NULL;
 	}
     }
 
-  if (!non_stop && all_threads)
+  if (!non_stop && all_threads_p)
     error (_("`-a' is meaningless in all-stop mode."));
 
-  if (args != NULL && all_threads)
+  if (args != NULL && all_threads_p)
     error (_("Can't resume all threads and specify "
 	     "proceed count simultaneously."));
 
@@ -850,10 +862,11 @@ continue_command (const char *args, int from_tty)
 	tp = inferior_thread ();
       else
 	{
+	  process_stratum_target *last_target;
 	  ptid_t last_ptid;
 
-	  get_last_target_status (&last_ptid, nullptr);
-	  tp = find_thread_ptid (last_ptid);
+	  get_last_target_status (&last_target, &last_ptid, nullptr);
+	  tp = find_thread_ptid (last_target, last_ptid);
 	}
       if (tp != NULL)
 	bs = tp->control.stop_bpstat;
@@ -881,7 +894,7 @@ continue_command (const char *args, int from_tty)
   ERROR_NO_INFERIOR;
   ensure_not_tfind_mode ();
 
-  if (!non_stop || !all_threads)
+  if (!non_stop || !all_threads_p)
     {
       ensure_valid_thread ();
       ensure_not_running ();
@@ -892,7 +905,7 @@ continue_command (const char *args, int from_tty)
   if (from_tty)
     printf_filtered (_("Continuing.\n"));
 
-  continue_1 (all_threads);
+  continue_1 (all_threads_p);
 }
 
 /* Record the starting point of a "step" or "next" command.  */
@@ -1112,7 +1125,7 @@ prepare_one_step (struct step_command_fsm *sm)
 
 	      /* Pretend that we've ran.  */
 	      resume_ptid = user_visible_resume_ptid (1);
-	      set_running (resume_ptid, 1);
+	      set_running (tp->inf->process_target (), resume_ptid, true);
 
 	      step_into_inline_frame (tp);
 
@@ -1316,10 +1329,14 @@ signal_command (const char *signum_exp, int from_tty)
       /* This indicates what will be resumed.  Either a single thread,
 	 a whole process, or all threads of all processes.  */
       ptid_t resume_ptid = user_visible_resume_ptid (0);
+      process_stratum_target *resume_target
+	= user_visible_resume_target (resume_ptid);
 
-      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+      thread_info *current = inferior_thread ();
+
+      for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid))
 	{
-	  if (tp->ptid == inferior_ptid)
+	  if (tp == current)
 	    continue;
 
 	  if (tp->suspend.stop_signal != GDB_SIGNAL_0
@@ -1982,6 +1999,7 @@ info_program_command (const char *args, int from_tty)
   bpstat bs;
   int num, stat;
   ptid_t ptid;
+  process_stratum_target *proc_target;
 
   if (!target_has_execution)
     {
@@ -1990,14 +2008,17 @@ info_program_command (const char *args, int from_tty)
     }
 
   if (non_stop)
-    ptid = inferior_ptid;
+    {
+      ptid = inferior_ptid;
+      proc_target = current_inferior ()->process_target ();
+    }
   else
-    get_last_target_status (&ptid, nullptr);
+    get_last_target_status (&proc_target, &ptid, nullptr);
 
   if (ptid == null_ptid || ptid == minus_one_ptid)
     error (_("No selected thread."));
 
-  thread_info *tp = find_thread_ptid (ptid);
+  thread_info *tp = find_thread_ptid (proc_target, ptid);
 
   if (tp->state == THREAD_EXITED)
     error (_("Invalid selected thread."));
@@ -2786,12 +2807,16 @@ attach_command (const char *args, int from_tty)
       add_inferior_continuation (attach_command_continuation, a,
 				 attach_command_continuation_free_args);
 
+      /* Let infrun consider waiting for events out of this
+	 target.  */
+      inferior->process_target ()->threads_executing = true;
+
       if (!target_is_async_p ())
 	mark_infrun_async_event_handler ();
       return;
     }
-
-  attach_post_wait (args, from_tty, mode);
+  else
+    attach_post_wait (args, from_tty, mode);
 }
 
 /* We had just found out that the target was already attached to an
@@ -2908,20 +2933,15 @@ disconnect_command (const char *args, int from_tty)
     deprecated_detach_hook ();
 }
 
-void 
-interrupt_target_1 (int all_threads)
-{
-  ptid_t ptid;
-
-  if (all_threads)
-    ptid = minus_one_ptid;
-  else
-    ptid = inferior_ptid;
+/* Stop PTID in the current target, and tag the PTID threads as having
+   been explicitly requested to stop.  PTID can be a thread, a
+   process, or minus_one_ptid, meaning all threads of all inferiors of
+   the current target.  */
 
-  if (non_stop)
-    target_stop (ptid);
-  else
-    target_interrupt ();
+static void
+stop_current_target_threads_ns (ptid_t ptid)
+{
+  target_stop (ptid);
 
   /* Tag the thread as having been explicitly requested to stop, so
      other parts of gdb know not to resume this thread automatically,
@@ -2929,8 +2949,32 @@ interrupt_target_1 (int all_threads)
      non-stop mode, as when debugging a multi-threaded application in
      all-stop mode, we will only get one stop event --- it's undefined
      which thread will report the event.  */
+  set_stop_requested (current_inferior ()->process_target (),
+		      ptid, 1);
+}
+
+/* See inferior.h.  */
+
+void
+interrupt_target_1 (bool all_threads)
+{
   if (non_stop)
-    set_stop_requested (ptid, 1);
+    {
+      if (all_threads)
+	{
+	  scoped_restore_current_thread restore_thread;
+
+	  for (inferior *inf : all_inferiors ())
+	    {
+	      switch_to_inferior_no_thread (inf);
+	      stop_current_target_threads_ns (minus_one_ptid);
+	    }
+	}
+      else
+	stop_current_target_threads_ns (inferior_ptid);
+    }
+  else
+    target_interrupt ();
 }
 
 /* interrupt [-a]
diff --git a/gdb/inferior-iter.h b/gdb/inferior-iter.h
index fb6da8a..8061dcc 100644
--- a/gdb/inferior-iter.h
+++ b/gdb/inferior-iter.h
@@ -36,18 +36,23 @@ public:
   typedef int difference_type;
 
   /* Create an iterator pointing at HEAD.  */
-  explicit all_inferiors_iterator (inferior *head)
-    : m_inf (head)
-  {}
+  all_inferiors_iterator (process_stratum_target *proc_target, inferior *head)
+    : m_proc_target (proc_target)
+  {
+    /* Advance M_INF to the first inferior's position.  */
+    for (m_inf = head; m_inf != NULL; m_inf = m_inf->next)
+      if (m_inf_matches ())
+	return;
+  }
 
   /* Create a one-past-end iterator.  */
   all_inferiors_iterator ()
-    : m_inf (nullptr)
+    : m_proc_target (nullptr), m_inf (nullptr)
   {}
 
   all_inferiors_iterator &operator++ ()
   {
-    m_inf = m_inf->next;
+    advance ();
     return *this;
   }
 
@@ -58,6 +63,30 @@ public:
   { return m_inf != other.m_inf; }
 
 private:
+  /* Advance to next inferior, skipping filtered inferiors.  */
+  void advance ()
+  {
+    /* The loop below is written in the natural way as-if we'd always
+       start at the beginning of the inferior list.  This
+       fast-forwards the algorithm to the actual current position.  */
+    goto start;
+
+    while (m_inf != NULL)
+      {
+	if (m_inf_matches ())
+	  return;
+      start:
+	m_inf = m_inf->next;
+      }
+  }
+
+  bool m_inf_matches ()
+  {
+    return (m_proc_target == nullptr
+	    || m_proc_target == m_inf->process_target ());
+  }
+
+  process_stratum_target *m_proc_target;
   inferior *m_inf;
 };
 
@@ -80,10 +109,17 @@ using all_non_exited_inferiors_iterator
    inferiors with range-for.  */
 struct all_inferiors_range
 {
+  all_inferiors_range (process_stratum_target *proc_target = nullptr)
+    : m_filter_target (proc_target)
+  {}
+
   all_inferiors_iterator begin () const
-  { return all_inferiors_iterator (inferior_list); }
+  { return all_inferiors_iterator (m_filter_target, inferior_list); }
   all_inferiors_iterator end () const
   { return all_inferiors_iterator (); }
+
+private:
+  process_stratum_target *m_filter_target;
 };
 
 /* Iterate over all inferiors, safely.  */
@@ -97,10 +133,26 @@ using all_inferiors_safe_iterator
 
 struct all_inferiors_safe_range
 {
+  explicit all_inferiors_safe_range (process_stratum_target *filter_target)
+    : m_filter_target (filter_target)
+  {}
+
+  all_inferiors_safe_range ()
+    : m_filter_target (nullptr)
+  {}
+
   all_inferiors_safe_iterator begin () const
-  { return all_inferiors_safe_iterator (inferior_list); }
+  {
+    return (all_inferiors_safe_iterator
+	    (all_inferiors_iterator (m_filter_target, inferior_list)));
+  }
+
   all_inferiors_safe_iterator end () const
   { return all_inferiors_safe_iterator (); }
+
+private:
+  /* The filter.  */
+  process_stratum_target *m_filter_target;
 };
 
 /* A range adapter that makes it possible to iterate over all
@@ -108,10 +160,22 @@ struct all_inferiors_safe_range
 
 struct all_non_exited_inferiors_range
 {
+  explicit all_non_exited_inferiors_range (process_stratum_target *filter_target)
+    : m_filter_target (filter_target)
+  {}
+
+  all_non_exited_inferiors_range ()
+    : m_filter_target (nullptr)
+  {}
+
   all_non_exited_inferiors_iterator begin () const
-  { return all_non_exited_inferiors_iterator (inferior_list); }
+  { return all_non_exited_inferiors_iterator (m_filter_target, inferior_list); }
   all_non_exited_inferiors_iterator end () const
   { return all_non_exited_inferiors_iterator (); }
+
+private:
+  /* The filter.  */
+  process_stratum_target *m_filter_target;
 };
 
 #endif /* !defined (INFERIOR_ITER_H) */
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 0c5e2c7..d732690 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -90,6 +90,8 @@ inferior::inferior (int pid_)
     registry_data ()
 {
   inferior_alloc_data (this);
+
+  m_target_stack.push (get_dummy_target ());
 }
 
 struct inferior *
@@ -276,14 +278,14 @@ find_inferior_id (int num)
 }
 
 struct inferior *
-find_inferior_pid (int pid)
+find_inferior_pid (process_stratum_target *targ, int pid)
 {
   /* Looking for inferior pid == 0 is always wrong, and indicative of
      a bug somewhere else.  There may be more than one with pid == 0,
      for instance.  */
   gdb_assert (pid != 0);
 
-  for (inferior *inf : all_inferiors ())
+  for (inferior *inf : all_inferiors (targ))
     if (inf->pid == pid)
       return inf;
 
@@ -293,9 +295,9 @@ find_inferior_pid (int pid)
 /* See inferior.h */
 
 struct inferior *
-find_inferior_ptid (ptid_t ptid)
+find_inferior_ptid (process_stratum_target *targ, ptid_t ptid)
 {
-  return find_inferior_pid (ptid.pid ());
+  return find_inferior_pid (targ, ptid.pid ());
 }
 
 /* See inferior.h.  */
@@ -340,11 +342,11 @@ have_inferiors (void)
    in the middle of a 'mourn' operation.  */
 
 int
-number_of_live_inferiors (void)
+number_of_live_inferiors (process_stratum_target *proc_target)
 {
   int num_inf = 0;
 
-  for (inferior *inf : all_non_exited_inferiors ())
+  for (inferior *inf : all_non_exited_inferiors (proc_target))
     if (inf->has_execution ())
       for (thread_info *tp ATTRIBUTE_UNUSED : inf->non_exited_threads ())
 	{
@@ -362,7 +364,7 @@ number_of_live_inferiors (void)
 int
 have_live_inferiors (void)
 {
-  return number_of_live_inferiors () > 0;
+  return number_of_live_inferiors (NULL) > 0;
 }
 
 /* Prune away any unused inferiors, and then prune away no longer used
@@ -694,7 +696,28 @@ add_inferior_with_spaces (void)
   return inf;
 }
 
-/* add-inferior [-copies N] [-exec FILENAME]  */
+/* Switch to inferior NEW_INF, a new inferior, and unless
+   NO_CONNECTION is true, push the process_stratum_target of ORG_INF
+   to NEW_INF.  */
+
+static void
+switch_to_inferior_and_push_target (inferior *new_inf,
+				    bool no_connection, inferior *org_inf)
+{
+  process_stratum_target *proc_target = org_inf->process_target ();
+
+  /* Switch over temporarily, while reading executable and
+     symbols.  */
+  switch_to_inferior_no_thread (new_inf);
+
+  /* Reuse the target for new inferior.  */
+  if (!no_connection && proc_target != NULL)
+    push_target (proc_target);
+
+  printf_filtered (_("Added inferior %d\n"), new_inf->num);
+}
+
+/* add-inferior [-copies N] [-exec FILENAME] [-no-connection] */
 
 static void
 add_inferior_command (const char *args, int from_tty)
@@ -702,6 +725,7 @@ add_inferior_command (const char *args, int from_tty)
   int i, copies = 1;
   gdb::unique_xmalloc_ptr<char> exec;
   symfile_add_flags add_flags = 0;
+  bool no_connection = false;
 
   if (from_tty)
     add_flags |= SYMFILE_VERBOSE;
@@ -721,6 +745,8 @@ add_inferior_command (const char *args, int from_tty)
 		    error (_("No argument to -copies"));
 		  copies = parse_and_eval_long (*argv);
 		}
+	      else if (strcmp (*argv, "-no-connection") == 0)
+		no_connection = true;
 	      else if (strcmp (*argv, "-exec") == 0)
 		{
 		  ++argv;
@@ -734,32 +760,32 @@ add_inferior_command (const char *args, int from_tty)
 	}
     }
 
+  inferior *orginf = current_inferior ();
+
   scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   for (i = 0; i < copies; ++i)
     {
-      struct inferior *inf = add_inferior_with_spaces ();
+      inferior *inf = add_inferior_with_spaces ();
 
-      printf_filtered (_("Added inferior %d\n"), inf->num);
+      switch_to_inferior_and_push_target (inf, no_connection, orginf);
 
       if (exec != NULL)
 	{
-	  /* Switch over temporarily, while reading executable and
-	     symbols.  */
-	  switch_to_inferior_no_thread (inf);
 	  exec_file_attach (exec.get (), from_tty);
 	  symbol_file_add_main (exec.get (), add_flags);
 	}
     }
 }
 
-/* clone-inferior [-copies N] [ID] */
+/* clone-inferior [-copies N] [ID] [-no-connection] */
 
 static void
 clone_inferior_command (const char *args, int from_tty)
 {
   int i, copies = 1;
   struct inferior *orginf = NULL;
+  bool no_connection = false;
 
   if (args)
     {
@@ -780,6 +806,8 @@ clone_inferior_command (const char *args, int from_tty)
 		  if (copies < 0)
 		    error (_("Invalid copies number"));
 		}
+	      else if (strcmp (*argv, "-no-connection") == 0)
+		no_connection = true;
 	    }
 	  else
 	    {
@@ -825,15 +853,13 @@ clone_inferior_command (const char *args, int from_tty)
       inf->aspace = pspace->aspace;
       inf->gdbarch = orginf->gdbarch;
 
+      switch_to_inferior_and_push_target (inf, no_connection, orginf);
+
       /* If the original inferior had a user specified target
 	 description, make the clone use it too.  */
       if (target_desc_info_from_user_p (inf->tdesc_info))
 	copy_inferior_target_desc_info (inf, orginf);
 
-      printf_filtered (_("Added inferior %d.\n"), inf->num);
-
-      set_current_inferior (inf);
-      switch_to_no_thread ();
       clone_program_space (pspace, orginf->pspace);
     }
 }
@@ -894,10 +920,13 @@ By default all inferiors are displayed."));
 
   c = add_com ("add-inferior", no_class, add_inferior_command, _("\
 Add a new inferior.\n\
-Usage: add-inferior [-copies N] [-exec FILENAME]\n\
+Usage: add-inferior [-copies N] [-exec FILENAME] [-no-connection]\n\
 N is the optional number of inferiors to add, default is 1.\n\
 FILENAME is the file name of the executable to use\n\
-as main program."));
+as main program.\n\
+By default, the new inferior inherits the current inferior's connection.\n\
+If -no-connection is specified, the new inferior begins with\n\
+no target connection yet."));
   set_cmd_completer (c, filename_completer);
 
   add_com ("remove-inferiors", no_class, remove_inferior_command, _("\
@@ -906,11 +935,14 @@ Usage: remove-inferiors ID..."));
 
   add_com ("clone-inferior", no_class, clone_inferior_command, _("\
 Clone inferior ID.\n\
-Usage: clone-inferior [-copies N] [ID]\n\
-Add N copies of inferior ID.  The new inferior has the same\n\
+Usage: clone-inferior [-copies N] [-no-connection] [ID]\n\
+Add N copies of inferior ID.  The new inferiors have the same\n\
 executable loaded as the copied inferior.  If -copies is not specified,\n\
 adds 1 copy.  If ID is not specified, it is the current inferior\n\
-that is cloned."));
+that is cloned.\n\
+By default, the new inferiors inherit the copied inferior's connection.\n\
+If -no-connection is specified, the new inferiors begin with\n\
+no target connection yet."));
 
   add_cmd ("inferiors", class_run, detach_inferior_command, _("\
 Detach from inferior ID (or list of IDS).\n\
diff --git a/gdb/inferior.h b/gdb/inferior.h
index a9baa52..4229c60 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -56,6 +56,8 @@ struct thread_info;
 #include "gdbsupport/common-inferior.h"
 #include "gdbthread.h"
 
+#include "process-stratum-target.h"
+
 struct infcall_suspend_state;
 struct infcall_control_state;
 
@@ -206,7 +208,7 @@ extern void registers_info (const char *, int);
 
 extern void continue_1 (int all_threads);
 
-extern void interrupt_target_1 (int all_threads);
+extern void interrupt_target_1 (bool all_threads);
 
 using delete_longjmp_breakpoint_cleanup
   = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint);
@@ -343,6 +345,35 @@ public:
   /* Returns true if we can delete this inferior.  */
   bool deletable () const { return refcount () == 0; }
 
+  /* Push T in this inferior's target stack.  */
+  void push_target (struct target_ops *t)
+  { m_target_stack.push (t); }
+
+  /* Unpush T from this inferior's target stack.  */
+  int unpush_target (struct target_ops *t)
+  { return m_target_stack.unpush (t); }
+
+  /* Returns true if T is pushed in this inferior's target stack.  */
+  bool target_is_pushed (target_ops *t)
+  { return m_target_stack.is_pushed (t); }
+
+  /* Find the target beneath T in this inferior's target stack.  */
+  target_ops *find_target_beneath (const target_ops *t)
+  { return m_target_stack.find_beneath (t); }
+
+  /* Return the target at the top of this inferior's target stack.  */
+  target_ops *top_target ()
+  { return m_target_stack.top (); }
+
+  /* Return the target at process_stratum level in this inferior's
+     target stack.  */
+  struct process_stratum_target *process_target ()
+  { return (process_stratum_target *) m_target_stack.at (process_stratum); }
+
+  /* Return the target at STRATUM in this inferior's target stack.  */
+  target_ops *target_at (enum strata stratum)
+  { return m_target_stack.at (stratum); }
+
   bool has_execution ()
   { return target_has_execution_1 (this); }
 
@@ -507,6 +538,10 @@ public:
 
   /* Per inferior data-pointers required by other GDB modules.  */
   REGISTRY_FIELDS;
+
+private:
+  /* The inferior's target stack.  */
+  target_stack m_target_stack;
 };
 
 /* Keep a registry of per-inferior data-pointers required by other GDB
@@ -537,14 +572,14 @@ extern void exit_inferior_num_silent (int num);
 
 extern void inferior_appeared (struct inferior *inf, int pid);
 
-/* Get rid of all inferiors.  */
-extern void discard_all_inferiors (void);
+/* Search function to lookup an inferior of TARG by target 'pid'.  */
+extern struct inferior *find_inferior_pid (process_stratum_target *targ,
+					   int pid);
 
-/* Search function to lookup an inferior by target 'pid'.  */
-extern struct inferior *find_inferior_pid (int pid);
-
-/* Search function to lookup an inferior whose pid is equal to 'ptid.pid'. */
-extern struct inferior *find_inferior_ptid (ptid_t ptid);
+/* Search function to lookup an inferior of TARG whose pid is equal to
+   'ptid.pid'. */
+extern struct inferior *find_inferior_ptid (process_stratum_target *targ,
+					    ptid_t ptid);
 
 /* Search function to lookup an inferior by GDB 'num'.  */
 extern struct inferior *find_inferior_id (int num);
@@ -571,8 +606,9 @@ extern struct inferior *iterate_over_inferiors (int (*) (struct inferior *,
 /* Returns true if the inferior list is not empty.  */
 extern int have_inferiors (void);
 
-/* Returns the number of live inferiors (real live processes).  */
-extern int number_of_live_inferiors (void);
+/* Returns the number of live inferiors running on PROC_TARGET (real
+   live processes with execution).  */
+extern int number_of_live_inferiors (process_stratum_target *proc_target);
 
 /* Returns true if there are any live inferiors in the inferior list
    (not cores, not executables, real live processes).  */
@@ -629,18 +665,18 @@ all_inferiors_safe ()
 */
 
 inline all_inferiors_range
-all_inferiors ()
+all_inferiors (process_stratum_target *proc_target = nullptr)
 {
-  return {};
+  return all_inferiors_range (proc_target);
 }
 
 /* Return a range that can be used to walk over all inferiors with PID
    not zero, with range-for.  */
 
 inline all_non_exited_inferiors_range
-all_non_exited_inferiors ()
+all_non_exited_inferiors (process_stratum_target *proc_target = nullptr)
 {
-  return {};
+  return all_non_exited_inferiors_range (proc_target);
 }
 
 /* Prune away automatically added inferiors that aren't required
diff --git a/gdb/infrun.c b/gdb/infrun.c
index bc8a3da..707c053 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -63,6 +63,8 @@
 #include "arch-utils.h"
 #include "gdbsupport/scope-exit.h"
 #include "gdbsupport/forward-scope-exit.h"
+#include "gdb_select.h"
+#include <unordered_map>
 
 /* Prototypes for local functions */
 
@@ -88,6 +90,8 @@ static int maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc);
 
 static void resume (gdb_signal sig);
 
+static void wait_for_inferior (inferior *inf);
+
 /* Asynchronous signal handler registered as event loop source for
    when we have pending events ready to be passed to the core.  */
 static struct async_event_handler *infrun_async_inferior_event_token;
@@ -370,9 +374,10 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty,
 
 static int stop_print_frame;
 
-/* This is a cached copy of the pid/waitstatus of the last event
-   returned by target_wait()/deprecated_target_wait_hook().  This
-   information is returned by get_last_target_status().  */
+/* This is a cached copy of the target/ptid/waitstatus of the last
+   event returned by target_wait()/deprecated_target_wait_hook().
+   This information is returned by get_last_target_status().  */
+static process_stratum_target *target_last_proc_target;
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
@@ -478,10 +483,12 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
 	  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
-	  inferior_ptid = child_ptid;
-	  add_thread_silent (inferior_ptid);
 	  set_current_inferior (child_inf);
+	  switch_to_no_thread ();
 	  child_inf->symfile_flags = SYMFILE_NO_READ;
+	  push_target (parent_inf->process_target ());
+	  add_thread_silent (child_inf->process_target (), child_ptid);
+	  inferior_ptid = child_ptid;
 
 	  /* If this is a vfork child, then the address-space is
 	     shared with the parent.  */
@@ -490,6 +497,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 	      child_inf->pspace = parent_inf->pspace;
 	      child_inf->aspace = parent_inf->aspace;
 
+	      exec_on_vfork ();
+
 	      /* The parent will be frozen until the child is done
 		 with the shared region.  Keep track of the
 		 parent.  */
@@ -565,52 +574,64 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
       parent_pspace = parent_inf->pspace;
 
-      /* If we're vforking, we want to hold on to the parent until the
-	 child exits or execs.  At child exec or exit time we can
-	 remove the old breakpoints from the parent and detach or
-	 resume debugging it.  Otherwise, detach the parent now; we'll
-	 want to reuse it's program/address spaces, but we can't set
-	 them to the child before removing breakpoints from the
-	 parent, otherwise, the breakpoints module could decide to
-	 remove breakpoints from the wrong process (since they'd be
-	 assigned to the same address space).  */
+      process_stratum_target *target = parent_inf->process_target ();
 
-      if (has_vforked)
-	{
-	  gdb_assert (child_inf->vfork_parent == NULL);
-	  gdb_assert (parent_inf->vfork_child == NULL);
-	  child_inf->vfork_parent = parent_inf;
-	  child_inf->pending_detach = 0;
-	  parent_inf->vfork_child = child_inf;
-	  parent_inf->pending_detach = detach_fork;
-	  parent_inf->waiting_for_vfork_done = 0;
-	}
-      else if (detach_fork)
-	{
-	  if (print_inferior_events)
-	    {
-	      /* Ensure that we have a process ptid.  */
-	      ptid_t process_ptid = ptid_t (parent_ptid.pid ());
+      {
+	/* Hold a strong reference to the target while (maybe)
+	   detaching the parent.  Otherwise detaching could close the
+	   target.  */
+	auto target_ref = target_ops_ref::new_reference (target);
+
+	/* If we're vforking, we want to hold on to the parent until
+	   the child exits or execs.  At child exec or exit time we
+	   can remove the old breakpoints from the parent and detach
+	   or resume debugging it.  Otherwise, detach the parent now;
+	   we'll want to reuse it's program/address spaces, but we
+	   can't set them to the child before removing breakpoints
+	   from the parent, otherwise, the breakpoints module could
+	   decide to remove breakpoints from the wrong process (since
+	   they'd be assigned to the same address space).  */
+
+	if (has_vforked)
+	  {
+	    gdb_assert (child_inf->vfork_parent == NULL);
+	    gdb_assert (parent_inf->vfork_child == NULL);
+	    child_inf->vfork_parent = parent_inf;
+	    child_inf->pending_detach = 0;
+	    parent_inf->vfork_child = child_inf;
+	    parent_inf->pending_detach = detach_fork;
+	    parent_inf->waiting_for_vfork_done = 0;
+	  }
+	else if (detach_fork)
+	  {
+	    if (print_inferior_events)
+	      {
+		/* Ensure that we have a process ptid.  */
+		ptid_t process_ptid = ptid_t (parent_ptid.pid ());
+
+		target_terminal::ours_for_output ();
+		fprintf_filtered (gdb_stdlog,
+				  _("[Detaching after fork from "
+				    "parent %s]\n"),
+				  target_pid_to_str (process_ptid).c_str ());
+	      }
 
-	      target_terminal::ours_for_output ();
-	      fprintf_filtered (gdb_stdlog,
-				_("[Detaching after fork from "
-				  "parent %s]\n"),
-				target_pid_to_str (process_ptid).c_str ());
-	    }
+	    target_detach (parent_inf, 0);
+	    parent_inf = NULL;
+	  }
 
-	  target_detach (parent_inf, 0);
-	}
+	/* Note that the detach above makes PARENT_INF dangling.  */
 
-      /* Note that the detach above makes PARENT_INF dangling.  */
+	/* Add the child thread to the appropriate lists, and switch
+	   to this new thread, before cloning the program space, and
+	   informing the solib layer about this new process.  */
 
-      /* Add the child thread to the appropriate lists, and switch to
-	 this new thread, before cloning the program space, and
-	 informing the solib layer about this new process.  */
+	set_current_inferior (child_inf);
+	push_target (target);
+      }
 
+      add_thread_silent (target, child_ptid);
       inferior_ptid = child_ptid;
-      add_thread_silent (inferior_ptid);
-      set_current_inferior (child_inf);
 
       /* If this is a vfork child, then the address-space is shared
 	 with the parent.  If we detached from the parent, then we can
@@ -619,6 +640,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 	{
 	  child_inf->pspace = parent_pspace;
 	  child_inf->aspace = child_inf->pspace->aspace;
+
+	  exec_on_vfork ();
 	}
       else
 	{
@@ -665,11 +688,12 @@ follow_fork (void)
 
   if (!non_stop)
     {
+      process_stratum_target *wait_target;
       ptid_t wait_ptid;
       struct target_waitstatus wait_status;
 
       /* Get the last target status returned by target_wait().  */
-      get_last_target_status (&wait_ptid, &wait_status);
+      get_last_target_status (&wait_target, &wait_ptid, &wait_status);
 
       /* If not stopped at a fork event, then there's nothing else to
 	 do.  */
@@ -680,14 +704,14 @@ follow_fork (void)
       /* Check if we switched over from WAIT_PTID, since the event was
 	 reported.  */
       if (wait_ptid != minus_one_ptid
-	  && inferior_ptid != wait_ptid)
+	  && (current_inferior ()->process_target () != wait_target
+	      || inferior_ptid != wait_ptid))
 	{
 	  /* We did.  Switch back to WAIT_PTID thread, to tell the
 	     target to follow it (in either direction).  We'll
 	     afterwards refuse to resume, and inform the user what
 	     happened.  */
-	  thread_info *wait_thread
-	    = find_thread_ptid (wait_ptid);
+	  thread_info *wait_thread = find_thread_ptid (wait_target, wait_ptid);
 	  switch_to_thread (wait_thread);
 	  should_resume = 0;
 	}
@@ -733,6 +757,7 @@ follow_fork (void)
 	parent = inferior_ptid;
 	child = tp->pending_follow.value.related_pid;
 
+	process_stratum_target *parent_targ = tp->inf->process_target ();
 	/* Set up inferior(s) as specified by the caller, and tell the
 	   target to do whatever is necessary to follow either parent
 	   or child.  */
@@ -748,7 +773,7 @@ follow_fork (void)
 	       or another.  The previous selected thread may be gone
 	       from the lists by now, but if it is still around, need
 	       to clear the pending follow request.  */
-	    tp = find_thread_ptid (parent);
+	    tp = find_thread_ptid (parent_targ, parent);
 	    if (tp)
 	      tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
 
@@ -759,7 +784,7 @@ follow_fork (void)
 	    /* If we followed the child, switch to it...  */
 	    if (follow_child)
 	      {
-		thread_info *child_thr = find_thread_ptid (child);
+		thread_info *child_thr = find_thread_ptid (parent_targ, child);
 		switch_to_thread (child_thr);
 
 		/* ... and preserve the stepping state, in case the
@@ -1188,9 +1213,11 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
       inf->pid = pid;
       target_follow_exec (inf, exec_file_target);
 
-      set_current_inferior (inf);
-      set_current_program_space (inf->pspace);
-      add_thread (ptid);
+      inferior *org_inferior = current_inferior ();
+      switch_to_inferior_no_thread (inf);
+      push_target (org_inferior->process_target ());
+      thread_info *thr = add_thread (inf->process_target (), ptid);
+      switch_to_thread (thr);
     }
   else
     {
@@ -1884,6 +1911,7 @@ displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
    discarded between events.  */
 struct execution_control_state
 {
+  process_stratum_target *target;
   ptid_t ptid;
   /* The thread that got the event, if this was a thread event; NULL
      otherwise.  */
@@ -2140,6 +2168,16 @@ user_visible_resume_ptid (int step)
   return resume_ptid;
 }
 
+/* See infrun.h.  */
+
+process_stratum_target *
+user_visible_resume_target (ptid_t resume_ptid)
+{
+  return (resume_ptid == minus_one_ptid && sched_multi
+	  ? NULL
+	  : current_inferior ()->process_target ());
+}
+
 /* Return a ptid representing the set of threads that we will resume,
    in the perspective of the target, assuming run control handling
    does not require leaving some threads stopped (e.g., stepping past
@@ -2204,6 +2242,9 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
   target_resume (resume_ptid, step, sig);
 
   target_commit_resume ();
+
+  if (target_can_async_p ())
+    target_async (1);
 }
 
 /* Resume the inferior.  SIG is the signal to give the inferior
@@ -2247,6 +2288,7 @@ resume_1 (enum gdb_signal sig)
 			      currently_stepping (tp));
 	}
 
+      tp->inf->process_target ()->threads_executing = true;
       tp->resumed = 1;
 
       /* FIXME: What should we do if we are supposed to resume this
@@ -2732,10 +2774,12 @@ clear_proceed_status (int step)
   if (!non_stop && inferior_ptid != null_ptid)
     {
       ptid_t resume_ptid = user_visible_resume_ptid (step);
+      process_stratum_target *resume_target
+	= user_visible_resume_target (resume_ptid);
 
       /* In all-stop mode, delete the per-thread status of all threads
 	 we're about to resume, implicitly and explicitly.  */
-      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+      for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid))
 	clear_proceed_status_thread (tp);
     }
 
@@ -2812,6 +2856,31 @@ schedlock_applies (struct thread_info *tp)
 					    execution_direction)));
 }
 
+/* Calls target_commit_resume on all targets.  */
+
+static void
+commit_resume_all_targets ()
+{
+  scoped_restore_current_thread restore_thread;
+
+  /* Map between process_target and a representative inferior.  This
+     is to avoid committing a resume in the same target more [...]

[diff truncated at 100000 bytes]



More information about the Gdb-cvs mailing list