X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Ftarget.c;h=18e53aa5d2768638513173243d62ec1ac459a5c8;hb=0d02e70b197c786f26175b9a73f94e01d14abdab;hp=0889da82ea593ad295741e75f6455c1fcd45d055;hpb=dffdd8b51f3fb086faf750592709baa8faa66fd1;p=binutils-gdb.git diff --git a/gdb/target.c b/gdb/target.c index 0889da82ea5..18e53aa5d27 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1,6 +1,6 @@ /* Select target systems and architectures at runtime for GDB. - Copyright (C) 1990-2021 Free Software Foundation, Inc. + Copyright (C) 1990-2022 Free Software Foundation, Inc. Contributed by Cygnus Support. @@ -26,6 +26,7 @@ #include "symtab.h" #include "inferior.h" #include "infrun.h" +#include "observable.h" #include "bfd.h" #include "symfile.h" #include "objfiles.h" @@ -52,6 +53,7 @@ #include #include "target-connection.h" #include "valprint.h" +#include "cli/cli-decode.h" static void generic_tls_error (void) ATTRIBUTE_NORETURN; @@ -66,7 +68,7 @@ static int default_region_ok_for_hw_watchpoint (struct target_ops *, static void default_rcmd (struct target_ops *, const char *, struct ui_file *); static ptid_t default_get_ada_task_ptid (struct target_ops *self, - long lwp, long tid); + long lwp, ULONGEST tid); static void default_mourn_inferior (struct target_ops *self); @@ -110,109 +112,730 @@ static std::unordered_map static struct target_ops *the_debug_target; -/* Top of target stack. */ -/* The target structure we are currently using to talk to a process - or file or whatever "inferior" we have. */ +/* Command list for target. */ + +static struct cmd_list_element *targetlist = NULL; + +/* True if we should trust readonly sections from the + executable when reading memory. */ + +static bool trust_readonly = false; + +/* Nonzero if we should show true memory content including + memory breakpoint inserted by gdb. */ + +static int show_memory_breakpoints = 0; + +/* These globals control whether GDB attempts to perform these + operations; they are useful for targets that need to prevent + inadvertent disruption, such as in non-stop mode. */ + +bool may_write_registers = true; + +bool may_write_memory = true; + +bool may_insert_breakpoints = true; + +bool may_insert_tracepoints = true; + +bool may_insert_fast_tracepoints = true; + +bool may_stop = true; + +/* Non-zero if we want to see trace of target level stuff. */ + +static unsigned int targetdebug = 0; + +static void +set_targetdebug (const char *args, int from_tty, struct cmd_list_element *c) +{ + if (targetdebug) + current_inferior ()->push_target (the_debug_target); + else + current_inferior ()->unpush_target (the_debug_target); +} + +static void +show_targetdebug (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + gdb_printf (file, _("Target debugging is %s.\n"), value); +} + +int +target_has_memory () +{ + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) + if (t->has_memory ()) + return 1; + + return 0; +} + +int +target_has_stack () +{ + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) + if (t->has_stack ()) + return 1; + + return 0; +} + +int +target_has_registers () +{ + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) + if (t->has_registers ()) + return 1; + + return 0; +} + +bool +target_has_execution (inferior *inf) +{ + if (inf == nullptr) + inf = current_inferior (); + + for (target_ops *t = inf->top_target (); + t != nullptr; + t = inf->find_target_beneath (t)) + if (t->has_execution (inf)) + return true; + + return false; +} + +const char * +target_shortname () +{ + return current_inferior ()->top_target ()->shortname (); +} + +/* See target.h. */ + +bool +target_attach_no_wait () +{ + return current_inferior ()->top_target ()->attach_no_wait (); +} + +/* See target.h. */ + +void +target_post_attach (int pid) +{ + return current_inferior ()->top_target ()->post_attach (pid); +} + +/* See target.h. */ + +void +target_prepare_to_store (regcache *regcache) +{ + return current_inferior ()->top_target ()->prepare_to_store (regcache); +} + +/* See target.h. */ + +bool +target_supports_enable_disable_tracepoint () +{ + target_ops *target = current_inferior ()->top_target (); + + return target->supports_enable_disable_tracepoint (); +} + +bool +target_supports_string_tracing () +{ + return current_inferior ()->top_target ()->supports_string_tracing (); +} + +/* See target.h. */ + +bool +target_supports_evaluation_of_breakpoint_conditions () +{ + target_ops *target = current_inferior ()->top_target (); + + return target->supports_evaluation_of_breakpoint_conditions (); +} + +/* See target.h. */ + +bool +target_supports_dumpcore () +{ + return current_inferior ()->top_target ()->supports_dumpcore (); +} + +/* See target.h. */ + +void +target_dumpcore (const char *filename) +{ + return current_inferior ()->top_target ()->dumpcore (filename); +} + +/* See target.h. */ + +bool +target_can_run_breakpoint_commands () +{ + return current_inferior ()->top_target ()->can_run_breakpoint_commands (); +} + +/* See target.h. */ + +void +target_files_info () +{ + return current_inferior ()->top_target ()->files_info (); +} + +/* See target.h. */ + +int +target_insert_fork_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->insert_fork_catchpoint (pid); +} + +/* See target.h. */ + +int +target_remove_fork_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->remove_fork_catchpoint (pid); +} + +/* See target.h. */ + +int +target_insert_vfork_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->insert_vfork_catchpoint (pid); +} + +/* See target.h. */ + +int +target_remove_vfork_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->remove_vfork_catchpoint (pid); +} + +/* See target.h. */ + +int +target_insert_exec_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->insert_exec_catchpoint (pid); +} + +/* See target.h. */ + +int +target_remove_exec_catchpoint (int pid) +{ + return current_inferior ()->top_target ()->remove_exec_catchpoint (pid); +} + +/* See target.h. */ + +int +target_set_syscall_catchpoint (int pid, bool needed, int any_count, + gdb::array_view syscall_counts) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->set_syscall_catchpoint (pid, needed, any_count, + syscall_counts); +} + +/* See target.h. */ + +void +target_rcmd (const char *command, struct ui_file *outbuf) +{ + return current_inferior ()->top_target ()->rcmd (command, outbuf); +} + +/* See target.h. */ + +bool +target_can_lock_scheduler () +{ + target_ops *target = current_inferior ()->top_target (); + + return (target->get_thread_control_capabilities ()& tc_schedlock) != 0; +} + +/* See target.h. */ + +bool +target_can_async_p () +{ + return target_can_async_p (current_inferior ()->top_target ()); +} + +/* See target.h. */ + +bool +target_can_async_p (struct target_ops *target) +{ + if (!target_async_permitted) + return false; + return target->can_async_p (); +} + +/* See target.h. */ + +bool +target_is_async_p () +{ + bool result = current_inferior ()->top_target ()->is_async_p (); + gdb_assert (target_async_permitted || !result); + return result; +} + +exec_direction_kind +target_execution_direction () +{ + return current_inferior ()->top_target ()->execution_direction (); +} + +/* See target.h. */ + +const char * +target_extra_thread_info (thread_info *tp) +{ + return current_inferior ()->top_target ()->extra_thread_info (tp); +} + +/* See target.h. */ + +const char * +target_pid_to_exec_file (int pid) +{ + return current_inferior ()->top_target ()->pid_to_exec_file (pid); +} + +/* See target.h. */ + +gdbarch * +target_thread_architecture (ptid_t ptid) +{ + return current_inferior ()->top_target ()->thread_architecture (ptid); +} + +/* See target.h. */ + +int +target_find_memory_regions (find_memory_region_ftype func, void *data) +{ + return current_inferior ()->top_target ()->find_memory_regions (func, data); +} + +/* See target.h. */ + +gdb::unique_xmalloc_ptr +target_make_corefile_notes (bfd *bfd, int *size_p) +{ + return current_inferior ()->top_target ()->make_corefile_notes (bfd, size_p); +} + +gdb_byte * +target_get_bookmark (const char *args, int from_tty) +{ + return current_inferior ()->top_target ()->get_bookmark (args, from_tty); +} + +void +target_goto_bookmark (const gdb_byte *arg, int from_tty) +{ + return current_inferior ()->top_target ()->goto_bookmark (arg, from_tty); +} + +/* See target.h. */ + +bool +target_stopped_by_watchpoint () +{ + return current_inferior ()->top_target ()->stopped_by_watchpoint (); +} + +/* See target.h. */ + +bool +target_stopped_by_sw_breakpoint () +{ + return current_inferior ()->top_target ()->stopped_by_sw_breakpoint (); +} + +bool +target_supports_stopped_by_sw_breakpoint () +{ + target_ops *target = current_inferior ()->top_target (); + + return target->supports_stopped_by_sw_breakpoint (); +} + +bool +target_stopped_by_hw_breakpoint () +{ + return current_inferior ()->top_target ()->stopped_by_hw_breakpoint (); +} + +bool +target_supports_stopped_by_hw_breakpoint () +{ + target_ops *target = current_inferior ()->top_target (); + + return target->supports_stopped_by_hw_breakpoint (); +} + +/* See target.h. */ + +bool +target_have_steppable_watchpoint () +{ + return current_inferior ()->top_target ()->have_steppable_watchpoint (); +} + +/* See target.h. */ + +int +target_can_use_hardware_watchpoint (bptype type, int cnt, int othertype) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->can_use_hw_breakpoint (type, cnt, othertype); +} + +/* See target.h. */ + +int +target_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->region_ok_for_hw_watchpoint (addr, len); +} + + +int +target_can_do_single_step () +{ + return current_inferior ()->top_target ()->can_do_single_step (); +} + +/* See target.h. */ + +int +target_insert_watchpoint (CORE_ADDR addr, int len, target_hw_bp_type type, + expression *cond) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->insert_watchpoint (addr, len, type, cond); +} + +/* See target.h. */ + +int +target_remove_watchpoint (CORE_ADDR addr, int len, target_hw_bp_type type, + expression *cond) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->remove_watchpoint (addr, len, type, cond); +} + +/* See target.h. */ + +int +target_insert_hw_breakpoint (gdbarch *gdbarch, bp_target_info *bp_tgt) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->insert_hw_breakpoint (gdbarch, bp_tgt); +} + +/* See target.h. */ + +int +target_remove_hw_breakpoint (gdbarch *gdbarch, bp_target_info *bp_tgt) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->remove_hw_breakpoint (gdbarch, bp_tgt); +} + +/* See target.h. */ + +bool +target_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int type, + expression *cond) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->can_accel_watchpoint_condition (addr, len, type, cond); +} + +/* See target.h. */ + +bool +target_can_execute_reverse () +{ + return current_inferior ()->top_target ()->can_execute_reverse (); +} -target_ops * -current_top_target () +ptid_t +target_get_ada_task_ptid (long lwp, ULONGEST tid) { - return current_inferior ()->top_target (); + return current_inferior ()->top_target ()->get_ada_task_ptid (lwp, tid); } -/* Command list for target. */ +bool +target_filesystem_is_local () +{ + return current_inferior ()->top_target ()->filesystem_is_local (); +} -static struct cmd_list_element *targetlist = NULL; +void +target_trace_init () +{ + return current_inferior ()->top_target ()->trace_init (); +} -/* True if we should trust readonly sections from the - executable when reading memory. */ +void +target_download_tracepoint (bp_location *location) +{ + return current_inferior ()->top_target ()->download_tracepoint (location); +} -static bool trust_readonly = false; +bool +target_can_download_tracepoint () +{ + return current_inferior ()->top_target ()->can_download_tracepoint (); +} -/* Nonzero if we should show true memory content including - memory breakpoint inserted by gdb. */ +void +target_download_trace_state_variable (const trace_state_variable &tsv) +{ + target_ops *target = current_inferior ()->top_target (); -static int show_memory_breakpoints = 0; + return target->download_trace_state_variable (tsv); +} -/* These globals control whether GDB attempts to perform these - operations; they are useful for targets that need to prevent - inadvertent disruption, such as in non-stop mode. */ +void +target_enable_tracepoint (bp_location *loc) +{ + return current_inferior ()->top_target ()->enable_tracepoint (loc); +} -bool may_write_registers = true; +void +target_disable_tracepoint (bp_location *loc) +{ + return current_inferior ()->top_target ()->disable_tracepoint (loc); +} -bool may_write_memory = true; +void +target_trace_start () +{ + return current_inferior ()->top_target ()->trace_start (); +} -bool may_insert_breakpoints = true; +void +target_trace_set_readonly_regions () +{ + return current_inferior ()->top_target ()->trace_set_readonly_regions (); +} -bool may_insert_tracepoints = true; +int +target_get_trace_status (trace_status *ts) +{ + return current_inferior ()->top_target ()->get_trace_status (ts); +} -bool may_insert_fast_tracepoints = true; +void +target_get_tracepoint_status (breakpoint *tp, uploaded_tp *utp) +{ + return current_inferior ()->top_target ()->get_tracepoint_status (tp, utp); +} -bool may_stop = true; +void +target_trace_stop () +{ + return current_inferior ()->top_target ()->trace_stop (); +} -/* Non-zero if we want to see trace of target level stuff. */ +int +target_trace_find (trace_find_type type, int num, + CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) +{ + target_ops *target = current_inferior ()->top_target (); -static unsigned int targetdebug = 0; + return target->trace_find (type, num, addr1, addr2, tpp); +} -static void -set_targetdebug (const char *args, int from_tty, struct cmd_list_element *c) +bool +target_get_trace_state_variable_value (int tsv, LONGEST *val) { - if (targetdebug) - push_target (the_debug_target); - else - unpush_target (the_debug_target); + target_ops *target = current_inferior ()->top_target (); + + return target->get_trace_state_variable_value (tsv, val); } -static void -show_targetdebug (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) +int +target_save_trace_data (const char *filename) { - fprintf_filtered (file, _("Target debugging is %s.\n"), value); + return current_inferior ()->top_target ()->save_trace_data (filename); } int -target_has_memory () +target_upload_tracepoints (uploaded_tp **utpp) { - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) - if (t->has_memory ()) - return 1; - - return 0; + return current_inferior ()->top_target ()->upload_tracepoints (utpp); } int -target_has_stack () +target_upload_trace_state_variables (uploaded_tsv **utsvp) { - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) - if (t->has_stack ()) - return 1; + target_ops *target = current_inferior ()->top_target (); - return 0; + return target->upload_trace_state_variables (utsvp); +} + +LONGEST +target_get_raw_trace_data (gdb_byte *buf, ULONGEST offset, LONGEST len) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->get_raw_trace_data (buf, offset, len); } int -target_has_registers () +target_get_min_fast_tracepoint_insn_len () { - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) - if (t->has_registers ()) - return 1; + target_ops *target = current_inferior ()->top_target (); - return 0; + return target->get_min_fast_tracepoint_insn_len (); +} + +void +target_set_disconnected_tracing (int val) +{ + return current_inferior ()->top_target ()->set_disconnected_tracing (val); +} + +void +target_set_circular_trace_buffer (int val) +{ + return current_inferior ()->top_target ()->set_circular_trace_buffer (val); +} + +void +target_set_trace_buffer_size (LONGEST val) +{ + return current_inferior ()->top_target ()->set_trace_buffer_size (val); } bool -target_has_execution (inferior *inf) +target_set_trace_notes (const char *user, const char *notes, + const char *stopnotes) { - if (inf == nullptr) - inf = current_inferior (); + target_ops *target = current_inferior ()->top_target (); - for (target_ops *t = inf->top_target (); - t != nullptr; - t = inf->find_target_beneath (t)) - if (t->has_execution (inf)) - return true; + return target->set_trace_notes (user, notes, stopnotes); +} - return false; +bool +target_get_tib_address (ptid_t ptid, CORE_ADDR *addr) +{ + return current_inferior ()->top_target ()->get_tib_address (ptid, addr); +} + +void +target_set_permissions () +{ + return current_inferior ()->top_target ()->set_permissions (); +} + +bool +target_static_tracepoint_marker_at (CORE_ADDR addr, + static_tracepoint_marker *marker) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->static_tracepoint_marker_at (addr, marker); +} + +std::vector +target_static_tracepoint_markers_by_strid (const char *marker_id) +{ + target_ops *target = current_inferior ()->top_target (); + + return target->static_tracepoint_markers_by_strid (marker_id); +} + +traceframe_info_up +target_traceframe_info () +{ + return current_inferior ()->top_target ()->traceframe_info (); +} + +bool +target_use_agent (bool use) +{ + return current_inferior ()->top_target ()->use_agent (use); +} + +bool +target_can_use_agent () +{ + return current_inferior ()->top_target ()->can_use_agent (); +} + +bool +target_augmented_libraries_svr4_read () +{ + return current_inferior ()->top_target ()->augmented_libraries_svr4_read (); +} + +bool +target_supports_memory_tagging () +{ + return current_inferior ()->top_target ()->supports_memory_tagging (); +} + +bool +target_fetch_memtags (CORE_ADDR address, size_t len, gdb::byte_vector &tags, + int type) +{ + return current_inferior ()->top_target ()->fetch_memtags (address, len, tags, type); +} + +bool +target_store_memtags (CORE_ADDR address, size_t len, + const gdb::byte_vector &tags, int type) +{ + return current_inferior ()->top_target ()->store_memtags (address, len, tags, type); +} + +void +target_log_command (const char *p) +{ + return current_inferior ()->top_target ()->log_command (p); } /* This is used to implement the various target commands. */ @@ -220,18 +843,18 @@ target_has_execution (inferior *inf) static void open_target (const char *args, int from_tty, struct cmd_list_element *command) { - auto *ti = static_cast (get_cmd_context (command)); + auto *ti = static_cast (command->context ()); target_open_ftype *func = target_factories[ti]; if (targetdebug) - fprintf_unfiltered (gdb_stdlog, "-> %s->open (...)\n", - ti->shortname); + gdb_printf (gdb_stdlog, "-> %s->open (...)\n", + ti->shortname); func (args, from_tty); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, "<- %s->open (%s, %d)\n", - ti->shortname, args, from_tty); + gdb_printf (gdb_stdlog, "<- %s->open (%s, %d)\n", + ti->shortname, args, from_tty); } /* See target.h. */ @@ -255,10 +878,10 @@ The first argument is the type or protocol of the target machine.\n\ Remaining arguments are interpreted by the target protocol. For more\n\ information on the arguments for a particular protocol, type\n\ `help target ' followed by the protocol name."), - &targetlist, "target ", 0, &cmdlist); + &targetlist, 0, &cmdlist); c = add_cmd (t.shortname, no_class, t.doc, &targetlist); - set_cmd_context (c, (void *) &t); - set_cmd_sfunc (c, open_target); + c->set_context ((void *) &t); + c->func = open_target; if (completer != NULL) set_cmd_completer (c, completer); } @@ -269,15 +892,15 @@ void add_deprecated_target_alias (const target_info &tinfo, const char *alias) { struct cmd_list_element *c; - char *alt; /* If we use add_alias_cmd, here, we do not get the deprecated warning, see PR cli/15104. */ c = add_cmd (alias, no_class, tinfo.doc, &targetlist); - set_cmd_sfunc (c, open_target); - set_cmd_context (c, (void *) &tinfo); - alt = xstrprintf ("target %s", tinfo.shortname); - deprecate_cmd (c, alt); + c->func = open_target; + c->set_context ((void *) &tinfo); + gdb::unique_xmalloc_ptr alt + = xstrprintf ("target %s", tinfo.shortname); + deprecate_cmd (c, alt.release ()); } /* Stub functions */ @@ -285,14 +908,14 @@ add_deprecated_target_alias (const target_info &tinfo, const char *alias) void target_kill (void) { - current_top_target ()->kill (); + current_inferior ()->top_target ()->kill (); } void target_load (const char *arg, int from_tty) { target_dcache_invalidate (); - current_top_target ()->load (arg, from_tty); + current_inferior ()->top_target ()->load (arg, from_tty); } /* Define it. */ @@ -305,7 +928,7 @@ target_terminal_state target_terminal::m_terminal_state void target_terminal::init (void) { - current_top_target ()->terminal_init (); + current_inferior ()->top_target ()->terminal_init (); m_terminal_state = target_terminal_state::is_ours; } @@ -336,7 +959,7 @@ target_terminal::inferior (void) if (inf->terminal_state != target_terminal_state::is_inferior) { - current_top_target ()->terminal_inferior (); + current_inferior ()->top_target ()->terminal_inferior (); inf->terminal_state = target_terminal_state::is_inferior; } @@ -371,7 +994,7 @@ target_terminal::restore_inferior (void) if (inf->terminal_state == target_terminal_state::is_ours_for_output) { set_current_inferior (inf); - current_top_target ()->terminal_inferior (); + current_inferior ()->top_target ()->terminal_inferior (); inf->terminal_state = target_terminal_state::is_inferior; } } @@ -403,7 +1026,7 @@ target_terminal_is_ours_kind (target_terminal_state desired_state) if (inf->terminal_state == target_terminal_state::is_inferior) { set_current_inferior (inf); - current_top_target ()->terminal_save_inferior (); + current_inferior ()->top_target ()->terminal_save_inferior (); } } @@ -418,9 +1041,9 @@ target_terminal_is_ours_kind (target_terminal_state desired_state) { set_current_inferior (inf); if (desired_state == target_terminal_state::is_ours) - current_top_target ()->terminal_ours (); + current_inferior ()->top_target ()->terminal_ours (); else if (desired_state == target_terminal_state::is_ours_for_output) - current_top_target ()->terminal_ours_for_output (); + current_inferior ()->top_target ()->terminal_ours_for_output (); else gdb_assert_not_reached ("unhandled desired state"); inf->terminal_state = desired_state; @@ -469,7 +1092,7 @@ target_terminal::ours_for_output () void target_terminal::info (const char *arg, int from_tty) { - current_top_target ()->terminal_info (arg, from_tty); + current_inferior ()->top_target ()->terminal_info (arg, from_tty); } /* See target.h. */ @@ -493,7 +1116,7 @@ static void tcomplain (void) { error (_("You can't do that when your target is `%s'"), - current_top_target ()->shortname ()); + current_inferior ()->top_target ()->shortname ()); } void @@ -505,7 +1128,7 @@ noprocess (void) static void default_terminal_info (struct target_ops *self, const char *args, int from_tty) { - printf_unfiltered (_("No saved terminal information.\n")); + gdb_printf (_("No saved terminal information.\n")); } /* A default implementation for the to_get_ada_task_ptid target method. @@ -515,7 +1138,7 @@ default_terminal_info (struct target_ops *self, const char *args, int from_tty) inferior_ptid. */ static ptid_t -default_get_ada_task_ptid (struct target_ops *self, long lwp, long tid) +default_get_ada_task_ptid (struct target_ops *self, long lwp, ULONGEST tid) { return ptid_t (inferior_ptid.pid (), lwp, tid); } @@ -572,31 +1195,6 @@ target_stack::push (target_ops *t) /* See target.h. */ -void -push_target (struct target_ops *t) -{ - current_inferior ()->push_target (t); -} - -/* See target.h. */ - -void -push_target (target_ops_up &&t) -{ - current_inferior ()->push_target (t.get ()); - t.release (); -} - -/* See target.h. */ - -int -unpush_target (struct target_ops *t) -{ - return current_inferior ()->unpush_target (t); -} - -/* See target.h. */ - bool target_stack::unpush (target_ops *t) { @@ -622,7 +1220,7 @@ target_stack::unpush (target_ops *t) m_stack[stratum] = NULL; if (m_top == stratum) - m_top = t->beneath ()->stratum (); + m_top = this->find_beneath (t)->stratum (); /* Finally close the target, if there are no inferiors referencing this target still. Note we do this after unchaining, @@ -640,11 +1238,11 @@ target_stack::unpush (target_ops *t) static void unpush_target_and_assert (struct target_ops *target) { - if (!unpush_target (target)) + if (!current_inferior ()->unpush_target (target)) { - fprintf_unfiltered (gdb_stderr, - "pop_all_targets couldn't find target %s\n", - target->shortname ()); + gdb_printf (gdb_stderr, + "pop_all_targets couldn't find target %s\n", + target->shortname ()); internal_error (__FILE__, __LINE__, _("failed internal consistency check")); } @@ -653,8 +1251,9 @@ unpush_target_and_assert (struct target_ops *target) void pop_all_targets_above (enum strata above_stratum) { - while ((int) (current_top_target ()->stratum ()) > (int) above_stratum) - unpush_target_and_assert (current_top_target ()); + while ((int) (current_inferior ()->top_target ()->stratum ()) + > (int) above_stratum) + unpush_target_and_assert (current_inferior ()->top_target ()); } /* See target.h. */ @@ -662,8 +1261,9 @@ pop_all_targets_above (enum strata above_stratum) void pop_all_targets_at_and_above (enum strata stratum) { - while ((int) (current_top_target ()->stratum ()) >= (int) stratum) - unpush_target_and_assert (current_top_target ()); + while ((int) (current_inferior ()->top_target ()->stratum ()) + >= (int) stratum) + unpush_target_and_assert (current_inferior ()->top_target ()); } void @@ -672,13 +1272,10 @@ pop_all_targets (void) pop_all_targets_above (dummy_stratum); } -/* Return true if T is now pushed in the current inferior's target - stack. Return false otherwise. */ - -bool -target_is_pushed (target_ops *t) +void +target_unpusher::operator() (struct target_ops *ops) const { - return current_inferior ()->target_is_pushed (t); + current_inferior ()->unpush_target (ops); } /* Default implementation of to_get_thread_local_address. */ @@ -696,9 +1293,14 @@ CORE_ADDR target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) { volatile CORE_ADDR addr = 0; - struct target_ops *target = current_top_target (); + struct target_ops *target = current_inferior ()->top_target (); struct gdbarch *gdbarch = target_gdbarch (); + /* If OBJFILE is a separate debug object file, look for the + original object file. */ + if (objfile->separate_debug_objfile_backlink != NULL) + objfile = objfile->separate_debug_objfile_backlink; + if (gdbarch_fetch_tls_load_module_address_p (gdbarch)) { ptid_t ptid = inferior_ptid; @@ -792,26 +1394,6 @@ target_xfer_status_to_string (enum target_xfer_status status) }; -/* See target.h. */ - -gdb::unique_xmalloc_ptr -target_read_string (CORE_ADDR memaddr, int len, int *bytes_read) -{ - gdb::unique_xmalloc_ptr buffer; - - int ignore; - if (bytes_read == nullptr) - bytes_read = &ignore; - - /* Note that the endian-ness does not matter here. */ - int errcode = read_string (memaddr, -1, 1, len, BFD_ENDIAN_LITTLE, - &buffer, bytes_read); - if (errcode != 0) - return {}; - - return gdb::unique_xmalloc_ptr ((char *) buffer.release ()); -} - const target_section_table * target_get_section_table (struct target_ops *target) { @@ -1152,17 +1734,17 @@ target_xfer_partial (struct target_ops *ops, { const unsigned char *myaddr = NULL; - fprintf_unfiltered (gdb_stdlog, - "%s:target_xfer_partial " - "(%d, %s, %s, %s, %s, %s) = %d, %s", - ops->shortname (), - (int) object, - (annex ? annex : "(null)"), - host_address_to_string (readbuf), - host_address_to_string (writebuf), - core_addr_to_string_nz (offset), - pulongest (len), retval, - pulongest (*xfered_len)); + gdb_printf (gdb_stdlog, + "%s:target_xfer_partial " + "(%d, %s, %s, %s, %s, %s) = %d, %s", + ops->shortname (), + (int) object, + (annex ? annex : "(null)"), + host_address_to_string (readbuf), + host_address_to_string (writebuf), + core_addr_to_string_nz (offset), + pulongest (len), retval, + pulongest (*xfered_len)); if (readbuf) myaddr = readbuf; @@ -1172,24 +1754,24 @@ target_xfer_partial (struct target_ops *ops, { int i; - fputs_unfiltered (", bytes =", gdb_stdlog); + gdb_puts (", bytes =", gdb_stdlog); for (i = 0; i < *xfered_len; i++) { if ((((intptr_t) &(myaddr[i])) & 0xf) == 0) { if (targetdebug < 2 && i > 0) { - fprintf_unfiltered (gdb_stdlog, " ..."); + gdb_printf (gdb_stdlog, " ..."); break; } - fprintf_unfiltered (gdb_stdlog, "\n"); + gdb_printf (gdb_stdlog, "\n"); } - fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff); + gdb_printf (gdb_stdlog, " %02x", myaddr[i] & 0xff); } } - fputc_unfiltered ('\n', gdb_stdlog); + gdb_putc ('\n', gdb_stdlog); } /* Check implementations of to_xfer_partial update *XFERED_LEN @@ -1215,7 +1797,8 @@ target_xfer_partial (struct target_ops *ops, int target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) { - if (target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL, + if (target_read (current_inferior ()->top_target (), + TARGET_OBJECT_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1245,7 +1828,8 @@ target_read_uint32 (CORE_ADDR memaddr, uint32_t *result) int target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) { - if (target_read (current_top_target (), TARGET_OBJECT_RAW_MEMORY, NULL, + if (target_read (current_inferior ()->top_target (), + TARGET_OBJECT_RAW_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1258,7 +1842,8 @@ target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) int target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) { - if (target_read (current_top_target (), TARGET_OBJECT_STACK_MEMORY, NULL, + if (target_read (current_inferior ()->top_target (), + TARGET_OBJECT_STACK_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1271,7 +1856,8 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) int target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) { - if (target_read (current_top_target (), TARGET_OBJECT_CODE_MEMORY, NULL, + if (target_read (current_inferior ()->top_target (), + TARGET_OBJECT_CODE_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1287,7 +1873,8 @@ target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len) int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) { - if (target_write (current_top_target (), TARGET_OBJECT_MEMORY, NULL, + if (target_write (current_inferior ()->top_target (), + TARGET_OBJECT_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1303,7 +1890,8 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) int target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) { - if (target_write (current_top_target (), TARGET_OBJECT_RAW_MEMORY, NULL, + if (target_write (current_inferior ()->top_target (), + TARGET_OBJECT_RAW_MEMORY, NULL, myaddr, memaddr, len) == len) return 0; else @@ -1315,7 +1903,8 @@ target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len) std::vector target_memory_map (void) { - std::vector result = current_top_target ()->memory_map (); + target_ops *target = current_inferior ()->top_target (); + std::vector result = target->memory_map (); if (result.empty ()) return result; @@ -1345,22 +1934,22 @@ target_memory_map (void) void target_flash_erase (ULONGEST address, LONGEST length) { - current_top_target ()->flash_erase (address, length); + current_inferior ()->top_target ()->flash_erase (address, length); } void target_flash_done (void) { - current_top_target ()->flash_done (); + current_inferior ()->top_target ()->flash_done (); } static void show_trust_readonly (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Mode for reading from readonly sections is %s.\n"), - value); + gdb_printf (file, + _("Mode for reading from readonly sections is %s.\n"), + value); } /* Target vector read/write partial wrapper functions. */ @@ -1806,7 +2395,9 @@ target_insert_breakpoint (struct gdbarch *gdbarch, return 1; } - return current_top_target ()->insert_breakpoint (gdbarch, bp_tgt); + target_ops *target = current_inferior ()->top_target (); + + return target->insert_breakpoint (gdbarch, bp_tgt); } /* See target.h. */ @@ -1826,7 +2417,9 @@ target_remove_breakpoint (struct gdbarch *gdbarch, return 1; } - return current_top_target ()->remove_breakpoint (gdbarch, bp_tgt, reason); + target_ops *target = current_inferior ()->top_target (); + + return target->remove_breakpoint (gdbarch, bp_tgt, reason); } static void @@ -1837,11 +2430,13 @@ info_target_command (const char *args, int from_tty) if (current_program_space->symfile_object_file != NULL) { objfile *objf = current_program_space->symfile_object_file; - printf_unfiltered (_("Symbols from \"%s\".\n"), - objfile_name (objf)); + gdb_printf (_("Symbols from \"%s\".\n"), + objfile_name (objf)); } - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { if (!t->has_memory ()) continue; @@ -1849,9 +2444,9 @@ info_target_command (const char *args, int from_tty) if ((int) (t->stratum ()) <= (int) dummy_stratum) continue; if (has_all_mem) - printf_unfiltered (_("\tWhile running this, " - "GDB does not access memory from...\n")); - printf_unfiltered ("%s:\n", t->longname ()); + gdb_printf (_("\tWhile running this, " + "GDB does not access memory from...\n")); + gdb_printf ("%s:\n", t->longname ()); t->files_info (); has_all_mem = t->has_all_memory (); } @@ -1961,7 +2556,7 @@ target_detach (inferior *inf, int from_tty) target. */ auto proc_target_ref = target_ops_ref::new_reference (inf->process_target ()); - current_top_target ()->detach (inf, from_tty); + current_inferior ()->top_target ()->detach (inf, from_tty); process_stratum_target *proc_target = as_process_stratum_target (proc_target_ref.get ()); @@ -1983,7 +2578,7 @@ target_disconnect (const char *args, int from_tty) disconnecting. */ remove_breakpoints (); - current_top_target ()->disconnect (args, from_tty); + current_inferior ()->top_target ()->disconnect (args, from_tty); } /* See target/target.h. */ @@ -1992,12 +2587,26 @@ ptid_t target_wait (ptid_t ptid, struct target_waitstatus *status, target_wait_flags options) { - target_ops *target = current_top_target (); + target_ops *target = current_inferior ()->top_target (); + process_stratum_target *proc_target = current_inferior ()->process_target (); - if (!target->can_async_p ()) + gdb_assert (!proc_target->commit_resumed_state); + + if (!target_can_async_p (target)) gdb_assert ((options & TARGET_WNOHANG) == 0); - return target->wait (ptid, status, options); + try + { + gdb::observers::target_pre_wait.notify (ptid); + ptid_t event_ptid = target->wait (ptid, status, options); + gdb::observers::target_post_wait.notify (event_ptid); + return event_ptid; + } + catch (...) + { + gdb::observers::target_post_wait.notify (null_ptid); + throw; + } } /* See target.h. */ @@ -2007,14 +2616,14 @@ default_target_wait (struct target_ops *ops, ptid_t ptid, struct target_waitstatus *status, target_wait_flags options) { - status->kind = TARGET_WAITKIND_IGNORE; + status->set_ignore (); return minus_one_ptid; } std::string target_pid_to_str (ptid_t ptid) { - return current_top_target ()->pid_to_str (ptid); + return current_inferior ()->top_target ()->pid_to_str (ptid); } const char * @@ -2022,7 +2631,7 @@ target_thread_name (struct thread_info *info) { gdb_assert (info->inf == current_inferior ()); - return current_top_target ()->thread_name (info); + return current_inferior ()->top_target ()->thread_name (info); } struct thread_info * @@ -2030,8 +2639,9 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle, int handle_len, struct inferior *inf) { - return current_top_target ()->thread_handle_to_thread_info (thread_handle, - handle_len, inf); + target_ops *target = current_inferior ()->top_target (); + + return target->thread_handle_to_thread_info (thread_handle, handle_len, inf); } /* See target.h. */ @@ -2039,84 +2649,105 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle, gdb::byte_vector target_thread_info_to_thread_handle (struct thread_info *tip) { - return current_top_target ()->thread_info_to_thread_handle (tip); + target_ops *target = current_inferior ()->top_target (); + + return target->thread_info_to_thread_handle (tip); } void -target_resume (ptid_t ptid, int step, enum gdb_signal signal) +target_resume (ptid_t scope_ptid, int step, enum gdb_signal signal) { process_stratum_target *curr_target = current_inferior ()->process_target (); + gdb_assert (!curr_target->commit_resumed_state); + + gdb_assert (inferior_ptid != null_ptid); + gdb_assert (inferior_ptid.matches (scope_ptid)); target_dcache_invalidate (); - current_top_target ()->resume (ptid, step, signal); + current_inferior ()->top_target ()->resume (scope_ptid, step, signal); - registers_changed_ptid (curr_target, ptid); + registers_changed_ptid (curr_target, scope_ptid); /* We only set the internal executing state here. The user/frontend running state is set at a higher level. This also clears the thread's stop_pc as side effect. */ - set_executing (curr_target, ptid, true); - clear_inline_frame_state (curr_target, ptid); -} + set_executing (curr_target, scope_ptid, true); + clear_inline_frame_state (curr_target, scope_ptid); -/* If true, target_commit_resume is a nop. */ -static int defer_target_commit_resume; + if (target_can_async_p ()) + target_async (1); +} /* See target.h. */ void -target_commit_resume (void) +target_commit_resumed () { - if (defer_target_commit_resume) - return; - - current_top_target ()->commit_resume (); + gdb_assert (current_inferior ()->process_target ()->commit_resumed_state); + current_inferior ()->top_target ()->commit_resumed (); } /* See target.h. */ -scoped_restore_tmpl -make_scoped_defer_target_commit_resume () +bool +target_has_pending_events () { - return make_scoped_restore (&defer_target_commit_resume, 1); + return current_inferior ()->top_target ()->has_pending_events (); } void target_pass_signals (gdb::array_view pass_signals) { - current_top_target ()->pass_signals (pass_signals); + current_inferior ()->top_target ()->pass_signals (pass_signals); } void target_program_signals (gdb::array_view program_signals) { - current_top_target ()->program_signals (program_signals); + current_inferior ()->top_target ()->program_signals (program_signals); } -static bool -default_follow_fork (struct target_ops *self, bool follow_child, - bool detach_fork) +static void +default_follow_fork (struct target_ops *self, inferior *child_inf, + ptid_t child_ptid, target_waitkind fork_kind, + bool follow_child, bool detach_fork) { /* Some target returned a fork event, but did not know how to follow it. */ internal_error (__FILE__, __LINE__, _("could not find a target to follow fork")); } -/* Look through the list of possible targets for a target that can - follow forks. */ +/* See target.h. */ -bool -target_follow_fork (bool follow_child, bool detach_fork) +void +target_follow_fork (inferior *child_inf, ptid_t child_ptid, + target_waitkind fork_kind, bool follow_child, + bool detach_fork) { - return current_top_target ()->follow_fork (follow_child, detach_fork); + target_ops *target = current_inferior ()->top_target (); + + /* Check consistency between CHILD_INF, CHILD_PTID, FOLLOW_CHILD and + DETACH_FORK. */ + if (child_inf != nullptr) + { + gdb_assert (follow_child || !detach_fork); + gdb_assert (child_inf->pid == child_ptid.pid ()); + } + else + gdb_assert (!follow_child && detach_fork); + + return target->follow_fork (child_inf, child_ptid, fork_kind, follow_child, + detach_fork); } -/* Target wrapper for follow exec hook. */ +/* See target.h. */ void -target_follow_exec (struct inferior *inf, const char *execd_pathname) +target_follow_exec (inferior *follow_inf, ptid_t ptid, + const char *execd_pathname) { - current_top_target ()->follow_exec (inf, execd_pathname); + current_inferior ()->top_target ()->follow_exec (follow_inf, ptid, + execd_pathname); } static void @@ -2130,7 +2761,7 @@ void target_mourn_inferior (ptid_t ptid) { gdb_assert (ptid.pid () == inferior_ptid.pid ()); - current_top_target ()->mourn_inferior (); + current_inferior ()->top_target ()->mourn_inferior (); /* We no longer need to keep handles on any of the object files. Make sure to release them to avoid unnecessarily locking any @@ -2158,7 +2789,8 @@ default_search_memory (struct target_ops *self, { auto read_memory = [=] (CORE_ADDR addr, gdb_byte *result, size_t len) { - return target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL, + return target_read (current_inferior ()->top_target (), + TARGET_OBJECT_MEMORY, NULL, result, addr, len) == len; }; @@ -2179,8 +2811,10 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp) { - return current_top_target ()->search_memory (start_addr, search_space_len, - pattern, pattern_len, found_addrp); + target_ops *target = current_inferior ()->top_target (); + + return target->search_memory (start_addr, search_space_len, pattern, + pattern_len, found_addrp); } /* Look through the currently pushed targets. If none of them will @@ -2190,7 +2824,9 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len, void target_require_runnable (void) { - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { /* If this target knows how to create a new program, then assume we will still be able to after killing the current @@ -2224,10 +2860,10 @@ static void show_auto_connect_native_target (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Whether GDB may automatically connect to the " - "native target is %s.\n"), - value); + gdb_printf (file, + _("Whether GDB may automatically connect to the " + "native target is %s.\n"), + value); } /* A pointer to the target that can respond to "run" or "attach". @@ -2280,7 +2916,9 @@ struct target_ops * find_attach_target (void) { /* If a target on the current stack can attach, use it. */ - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { if (t->can_attach ()) return t; @@ -2296,7 +2934,9 @@ struct target_ops * find_run_target (void) { /* If a target on the current stack can run, use it. */ - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { if (t->can_create_inferior ()) return t; @@ -2331,8 +2971,8 @@ target_info_proc (const char *args, enum info_proc_what what) if (t->info_proc (args, what)) { if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_info_proc (\"%s\", %d)\n", args, what); + gdb_printf (gdb_stdlog, + "target_info_proc (\"%s\", %d)\n", args, what); return 1; } @@ -2355,7 +2995,7 @@ find_default_supports_disable_randomization (struct target_ops *self) int target_supports_disable_randomization (void) { - return current_top_target ()->supports_disable_randomization (); + return current_inferior ()->top_target ()->supports_disable_randomization (); } /* See target/target.h. */ @@ -2363,7 +3003,7 @@ target_supports_disable_randomization (void) int target_supports_multi_process (void) { - return current_top_target ()->supports_multi_process (); + return current_inferior ()->top_target ()->supports_multi_process (); } /* See target.h. */ @@ -2393,7 +3033,7 @@ target_thread_address_space (ptid_t ptid) { struct address_space *aspace; - aspace = current_top_target ()->thread_address_space (ptid); + aspace = current_inferior ()->top_target ()->thread_address_space (ptid); gdb_assert (aspace != NULL); return aspace; @@ -2446,7 +3086,9 @@ target_ops::can_run () int target_can_run () { - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { if (t->can_run ()) return 1; @@ -2500,13 +3142,9 @@ static std::vector fileio_fhandles; list each time a new file is opened. */ static int lowest_closed_fd; -/* Invalidate the target associated with open handles that were open - on target TARG, since we're about to close (and maybe destroy) the - target. The handles remain open from the client's perspective, but - trying to do anything with them other than closing them will fail - with EIO. */ +/* See target.h. */ -static void +void fileio_handles_invalidate_target (target_ops *targ) { for (fileio_fh_t &fh : fileio_fhandles) @@ -2640,13 +3278,13 @@ target_fileio_open (struct inferior *inf, const char *filename, fd = acquire_fileio_fd (t, fd); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_open (%d,%s,0x%x,0%o,%d)" - " = %d (%d)\n", - inf == NULL ? 0 : inf->num, - filename, flags, mode, - warn_if_slow, fd, - fd != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_open (%d,%s,0x%x,0%o,%d)" + " = %d (%d)\n", + inf == NULL ? 0 : inf->num, + filename, flags, mode, + warn_if_slow, fd, + fd != -1 ? 0 : *target_errno); return fd; } @@ -2672,11 +3310,11 @@ target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len, len, offset, target_errno); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_pwrite (%d,...,%d,%s) " - "= %d (%d)\n", - fd, len, pulongest (offset), - ret, ret != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_pwrite (%d,...,%d,%s) " + "= %d (%d)\n", + fd, len, pulongest (offset), + ret, ret != -1 ? 0 : *target_errno); return ret; } @@ -2698,11 +3336,11 @@ target_fileio_pread (int fd, gdb_byte *read_buf, int len, len, offset, target_errno); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_pread (%d,...,%d,%s) " - "= %d (%d)\n", - fd, len, pulongest (offset), - ret, ret != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_pread (%d,...,%d,%s) " + "= %d (%d)\n", + fd, len, pulongest (offset), + ret, ret != -1 ? 0 : *target_errno); return ret; } @@ -2722,9 +3360,9 @@ target_fileio_fstat (int fd, struct stat *sb, int *target_errno) ret = fh->target->fileio_fstat (fh->target_fd, sb, target_errno); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_fstat (%d) = %d (%d)\n", - fd, ret, ret != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_fstat (%d) = %d (%d)\n", + fd, ret, ret != -1 ? 0 : *target_errno); return ret; } @@ -2749,9 +3387,9 @@ target_fileio_close (int fd, int *target_errno) } if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_close (%d) = %d (%d)\n", - fd, ret, ret != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_close (%d) = %d (%d)\n", + fd, ret, ret != -1 ? 0 : *target_errno); return ret; } @@ -2769,11 +3407,11 @@ target_fileio_unlink (struct inferior *inf, const char *filename, continue; if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_unlink (%d,%s)" - " = %d (%d)\n", - inf == NULL ? 0 : inf->num, filename, - ret, ret != -1 ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_unlink (%d,%s)" + " = %d (%d)\n", + inf == NULL ? 0 : inf->num, filename, + ret, ret != -1 ? 0 : *target_errno); return ret; } @@ -2796,12 +3434,12 @@ target_fileio_readlink (struct inferior *inf, const char *filename, continue; if (targetdebug) - fprintf_unfiltered (gdb_stdlog, - "target_fileio_readlink (%d,%s)" - " = %s (%d)\n", - inf == NULL ? 0 : inf->num, - filename, ret ? ret->c_str () : "(nil)", - ret ? 0 : *target_errno); + gdb_printf (gdb_stdlog, + "target_fileio_readlink (%d,%s)" + " = %s (%d)\n", + inf == NULL ? 0 : inf->num, + filename, ret ? ret->c_str () : "(nil)", + ret ? 0 : *target_errno); return ret; } @@ -2993,13 +3631,32 @@ target_announce_detach (int from_tty) if (!from_tty) return; + pid = inferior_ptid.pid (); exec_file = get_exec_file (0); - if (exec_file == NULL) - exec_file = ""; + if (exec_file == nullptr) + gdb_printf ("Detaching from pid %s\n", + target_pid_to_str (ptid_t (pid)).c_str ()); + else + gdb_printf (_("Detaching from program: %s, %s\n"), exec_file, + target_pid_to_str (ptid_t (pid)).c_str ()); +} - pid = inferior_ptid.pid (); - printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file, - target_pid_to_str (ptid_t (pid)).c_str ()); +/* See target.h */ + +void +target_announce_attach (int from_tty, int pid) +{ + if (!from_tty) + return; + + const char *exec_file = get_exec_file (0); + + if (exec_file != nullptr) + gdb_printf ("Attaching to program: %s, %s\n", exec_file, + target_pid_to_str (ptid_t (pid)).c_str ()); + else + gdb_printf ("Attaching to %s\n", + target_pid_to_str (ptid_t (pid)).c_str ()); } /* The inferior process has died. Long live the inferior! */ @@ -3116,38 +3773,43 @@ debug_target::info () const void target_close (struct target_ops *targ) { - gdb_assert (!target_is_pushed (targ)); + for (inferior *inf : all_inferiors ()) + gdb_assert (!inf->target_is_pushed (targ)); fileio_handles_invalidate_target (targ); targ->close (); if (targetdebug) - fprintf_unfiltered (gdb_stdlog, "target_close ()\n"); + gdb_printf (gdb_stdlog, "target_close ()\n"); } int target_thread_alive (ptid_t ptid) { - return current_top_target ()->thread_alive (ptid); + return current_inferior ()->top_target ()->thread_alive (ptid); } void target_update_thread_list (void) { - current_top_target ()->update_thread_list (); + current_inferior ()->top_target ()->update_thread_list (); } void target_stop (ptid_t ptid) { + process_stratum_target *proc_target = current_inferior ()->process_target (); + + gdb_assert (!proc_target->commit_resumed_state); + if (!may_stop) { warning (_("May not interrupt or stop the target, ignoring attempt")); return; } - current_top_target ()->stop (ptid); + current_inferior ()->top_target ()->stop (ptid); } void @@ -3159,7 +3821,7 @@ target_interrupt () return; } - current_top_target ()->interrupt (); + current_inferior ()->top_target ()->interrupt (); } /* See target.h. */ @@ -3179,7 +3841,7 @@ target_pass_ctrlc (void) { /* A thread can be THREAD_STOPPED and executing, while running an infcall. */ - if (thr->state == THREAD_RUNNING || thr->executing) + if (thr->state == THREAD_RUNNING || thr->executing ()) { /* We can get here quite deep in target layers. Avoid switching thread context or anything that would @@ -3189,7 +3851,7 @@ target_pass_ctrlc (void) through the target_stack. */ scoped_restore_current_inferior restore_inferior; set_current_inferior (inf); - current_top_target ()->pass_ctrlc (); + current_inferior ()->top_target ()->pass_ctrlc (); return; } } @@ -3215,7 +3877,6 @@ target_stop_and_wait (ptid_t ptid) non_stop = true; target_stop (ptid); - memset (&status, 0, sizeof (status)); target_wait (ptid, &status, 0); non_stop = was_non_stop; @@ -3284,7 +3945,7 @@ target_options_to_string (target_wait_flags target_options) void target_fetch_registers (struct regcache *regcache, int regno) { - current_top_target ()->fetch_registers (regcache, regno); + current_inferior ()->top_target ()->fetch_registers (regcache, regno); if (targetdebug) regcache->debug_print_register ("target_fetch_registers", regno); } @@ -3295,7 +3956,7 @@ target_store_registers (struct regcache *regcache, int regno) if (!may_write_registers) error (_("Writing to registers is not allowed (regno %d)"), regno); - current_top_target ()->store_registers (regcache, regno); + current_inferior ()->top_target ()->store_registers (regcache, regno); if (targetdebug) { regcache->debug_print_register ("target_store_registers", regno); @@ -3305,7 +3966,7 @@ target_store_registers (struct regcache *regcache, int regno) int target_core_of_thread (ptid_t ptid) { - return current_top_target ()->core_of_thread (ptid); + return current_inferior ()->top_target ()->core_of_thread (ptid); } int @@ -3343,14 +4004,16 @@ default_verify_memory (struct target_ops *self, const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size) { /* Start over from the top of the target stack. */ - return simple_verify_memory (current_top_target (), + return simple_verify_memory (current_inferior ()->top_target (), data, memaddr, size); } int target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size) { - return current_top_target ()->verify_memory (data, memaddr, size); + target_ops *target = current_inferior ()->top_target (); + + return target->verify_memory (data, memaddr, size); } /* The documentation for this function is in its prototype declaration in @@ -3360,7 +4023,9 @@ int target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, enum target_hw_bp_type rw) { - return current_top_target ()->insert_mask_watchpoint (addr, mask, rw); + target_ops *target = current_inferior ()->top_target (); + + return target->insert_mask_watchpoint (addr, mask, rw); } /* The documentation for this function is in its prototype declaration in @@ -3370,7 +4035,9 @@ int target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, enum target_hw_bp_type rw) { - return current_top_target ()->remove_mask_watchpoint (addr, mask, rw); + target_ops *target = current_inferior ()->top_target (); + + return target->remove_mask_watchpoint (addr, mask, rw); } /* The documentation for this function is in its prototype declaration @@ -3379,7 +4046,9 @@ target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask) { - return current_top_target ()->masked_watch_num_registers (addr, mask); + target_ops *target = current_inferior ()->top_target (); + + return target->masked_watch_num_registers (addr, mask); } /* The documentation for this function is in its prototype declaration @@ -3388,15 +4057,15 @@ target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask) int target_ranged_break_num_registers (void) { - return current_top_target ()->ranged_break_num_registers (); + return current_inferior ()->top_target ()->ranged_break_num_registers (); } /* See target.h. */ struct btrace_target_info * -target_enable_btrace (ptid_t ptid, const struct btrace_config *conf) +target_enable_btrace (thread_info *tp, const struct btrace_config *conf) { - return current_top_target ()->enable_btrace (ptid, conf); + return current_inferior ()->top_target ()->enable_btrace (tp, conf); } /* See target.h. */ @@ -3404,7 +4073,7 @@ target_enable_btrace (ptid_t ptid, const struct btrace_config *conf) void target_disable_btrace (struct btrace_target_info *btinfo) { - current_top_target ()->disable_btrace (btinfo); + current_inferior ()->top_target ()->disable_btrace (btinfo); } /* See target.h. */ @@ -3412,7 +4081,7 @@ target_disable_btrace (struct btrace_target_info *btinfo) void target_teardown_btrace (struct btrace_target_info *btinfo) { - current_top_target ()->teardown_btrace (btinfo); + current_inferior ()->top_target ()->teardown_btrace (btinfo); } /* See target.h. */ @@ -3422,7 +4091,9 @@ target_read_btrace (struct btrace_data *btrace, struct btrace_target_info *btinfo, enum btrace_read_type type) { - return current_top_target ()->read_btrace (btrace, btinfo, type); + target_ops *target = current_inferior ()->top_target (); + + return target->read_btrace (btrace, btinfo, type); } /* See target.h. */ @@ -3430,7 +4101,7 @@ target_read_btrace (struct btrace_data *btrace, const struct btrace_config * target_btrace_conf (const struct btrace_target_info *btinfo) { - return current_top_target ()->btrace_conf (btinfo); + return current_inferior ()->top_target ()->btrace_conf (btinfo); } /* See target.h. */ @@ -3438,7 +4109,7 @@ target_btrace_conf (const struct btrace_target_info *btinfo) void target_stop_recording (void) { - current_top_target ()->stop_recording (); + current_inferior ()->top_target ()->stop_recording (); } /* See target.h. */ @@ -3446,7 +4117,7 @@ target_stop_recording (void) void target_save_record (const char *filename) { - current_top_target ()->save_record (filename); + current_inferior ()->top_target ()->save_record (filename); } /* See target.h. */ @@ -3454,7 +4125,7 @@ target_save_record (const char *filename) int target_supports_delete_record () { - return current_top_target ()->supports_delete_record (); + return current_inferior ()->top_target ()->supports_delete_record (); } /* See target.h. */ @@ -3462,7 +4133,7 @@ target_supports_delete_record () void target_delete_record (void) { - current_top_target ()->delete_record (); + current_inferior ()->top_target ()->delete_record (); } /* See target.h. */ @@ -3470,7 +4141,7 @@ target_delete_record (void) enum record_method target_record_method (ptid_t ptid) { - return current_top_target ()->record_method (ptid); + return current_inferior ()->top_target ()->record_method (ptid); } /* See target.h. */ @@ -3478,7 +4149,7 @@ target_record_method (ptid_t ptid) int target_record_is_replaying (ptid_t ptid) { - return current_top_target ()->record_is_replaying (ptid); + return current_inferior ()->top_target ()->record_is_replaying (ptid); } /* See target.h. */ @@ -3486,7 +4157,7 @@ target_record_is_replaying (ptid_t ptid) int target_record_will_replay (ptid_t ptid, int dir) { - return current_top_target ()->record_will_replay (ptid, dir); + return current_inferior ()->top_target ()->record_will_replay (ptid, dir); } /* See target.h. */ @@ -3494,7 +4165,7 @@ target_record_will_replay (ptid_t ptid, int dir) void target_record_stop_replaying (void) { - current_top_target ()->record_stop_replaying (); + current_inferior ()->top_target ()->record_stop_replaying (); } /* See target.h. */ @@ -3502,7 +4173,7 @@ target_record_stop_replaying (void) void target_goto_record_begin (void) { - current_top_target ()->goto_record_begin (); + current_inferior ()->top_target ()->goto_record_begin (); } /* See target.h. */ @@ -3510,7 +4181,7 @@ target_goto_record_begin (void) void target_goto_record_end (void) { - current_top_target ()->goto_record_end (); + current_inferior ()->top_target ()->goto_record_end (); } /* See target.h. */ @@ -3518,7 +4189,7 @@ target_goto_record_end (void) void target_goto_record (ULONGEST insn) { - current_top_target ()->goto_record (insn); + current_inferior ()->top_target ()->goto_record (insn); } /* See target.h. */ @@ -3526,7 +4197,7 @@ target_goto_record (ULONGEST insn) void target_insn_history (int size, gdb_disassembly_flags flags) { - current_top_target ()->insn_history (size, flags); + current_inferior ()->top_target ()->insn_history (size, flags); } /* See target.h. */ @@ -3535,7 +4206,7 @@ void target_insn_history_from (ULONGEST from, int size, gdb_disassembly_flags flags) { - current_top_target ()->insn_history_from (from, size, flags); + current_inferior ()->top_target ()->insn_history_from (from, size, flags); } /* See target.h. */ @@ -3544,7 +4215,7 @@ void target_insn_history_range (ULONGEST begin, ULONGEST end, gdb_disassembly_flags flags) { - current_top_target ()->insn_history_range (begin, end, flags); + current_inferior ()->top_target ()->insn_history_range (begin, end, flags); } /* See target.h. */ @@ -3552,7 +4223,7 @@ target_insn_history_range (ULONGEST begin, ULONGEST end, void target_call_history (int size, record_print_flags flags) { - current_top_target ()->call_history (size, flags); + current_inferior ()->top_target ()->call_history (size, flags); } /* See target.h. */ @@ -3560,7 +4231,7 @@ target_call_history (int size, record_print_flags flags) void target_call_history_from (ULONGEST begin, int size, record_print_flags flags) { - current_top_target ()->call_history_from (begin, size, flags); + current_inferior ()->top_target ()->call_history_from (begin, size, flags); } /* See target.h. */ @@ -3568,7 +4239,7 @@ target_call_history_from (ULONGEST begin, int size, record_print_flags flags) void target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags) { - current_top_target ()->call_history_range (begin, end, flags); + current_inferior ()->top_target ()->call_history_range (begin, end, flags); } /* See target.h. */ @@ -3576,7 +4247,7 @@ target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flag const struct frame_unwind * target_get_unwinder (void) { - return current_top_target ()->get_unwinder (); + return current_inferior ()->top_target ()->get_unwinder (); } /* See target.h. */ @@ -3584,7 +4255,7 @@ target_get_unwinder (void) const struct frame_unwind * target_get_tailcall_unwinder (void) { - return current_top_target ()->get_tailcall_unwinder (); + return current_inferior ()->top_target ()->get_tailcall_unwinder (); } /* See target.h. */ @@ -3592,7 +4263,7 @@ target_get_tailcall_unwinder (void) void target_prepare_to_generate_core (void) { - current_top_target ()->prepare_to_generate_core (); + current_inferior ()->top_target ()->prepare_to_generate_core (); } /* See target.h. */ @@ -3600,7 +4271,7 @@ target_prepare_to_generate_core (void) void target_done_generating_core (void) { - current_top_target ()->done_generating_core (); + current_inferior ()->top_target ()->done_generating_core (); } @@ -3666,13 +4337,15 @@ flash_erase_command (const char *cmd, int from_tty) static void maintenance_print_target_stack (const char *cmd, int from_tty) { - printf_filtered (_("The current target stack is:\n")); + gdb_printf (_("The current target stack is:\n")); - for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ()) + for (target_ops *t = current_inferior ()->top_target (); + t != NULL; + t = t->beneath ()) { if (t->stratum () == debug_stratum) continue; - printf_filtered (" - %s (%s)\n", t->shortname (), t->longname ()); + gdb_printf (" - %s (%s)\n", t->shortname (), t->longname ()); } } @@ -3681,8 +4354,11 @@ maintenance_print_target_stack (const char *cmd, int from_tty) void target_async (int enable) { + /* If we are trying to enable async mode then it must be the case that + async mode is possible for this target. */ + gdb_assert (!enable || target_can_async_p ()); infrun_async (enable); - current_top_target ()->async (enable); + current_inferior ()->top_target ()->async (enable); } /* See target.h. */ @@ -3690,38 +4366,35 @@ target_async (int enable) void target_thread_events (int enable) { - current_top_target ()->thread_events (enable); + current_inferior ()->top_target ()->thread_events (enable); } /* Controls if targets can report that they can/are async. This is just for maintainers to use when debugging gdb. */ bool target_async_permitted = true; -/* The set command writes to this variable. If the inferior is - executing, target_async_permitted is *not* updated. */ -static bool target_async_permitted_1 = true; - static void -maint_set_target_async_command (const char *args, int from_tty, - struct cmd_list_element *c) +set_maint_target_async (bool permitted) { if (have_live_inferiors ()) - { - target_async_permitted_1 = target_async_permitted; - error (_("Cannot change this setting while the inferior is running.")); - } + error (_("Cannot change this setting while the inferior is running.")); + + target_async_permitted = permitted; +} - target_async_permitted = target_async_permitted_1; +static bool +get_maint_target_async () +{ + return target_async_permitted; } static void -maint_show_target_async_command (struct ui_file *file, int from_tty, - struct cmd_list_element *c, - const char *value) +show_maint_target_async (ui_file *file, int from_tty, + cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Controlling the inferior in " - "asynchronous mode is %s.\n"), value); + gdb_printf (file, + _("Controlling the inferior in " + "asynchronous mode is %s.\n"), value); } /* Return true if the target operates in non-stop mode even with "set @@ -3730,7 +4403,7 @@ maint_show_target_async_command (struct ui_file *file, int from_tty, static int target_always_non_stop_p (void) { - return current_top_target ()->always_non_stop_p (); + return current_inferior ()->top_target ()->always_non_stop_p (); } /* See target.h. */ @@ -3738,10 +4411,11 @@ target_always_non_stop_p (void) bool target_is_non_stop_p () { - return (non_stop - || target_non_stop_enabled == AUTO_BOOLEAN_TRUE - || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO - && target_always_non_stop_p ())); + return ((non_stop + || target_non_stop_enabled == AUTO_BOOLEAN_TRUE + || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO + && target_always_non_stop_p ())) + && target_can_async_p ()); } /* See target.h. */ @@ -3768,41 +4442,38 @@ exists_non_stop_target () mode. This is just for maintainers to use when debugging gdb. */ enum auto_boolean target_non_stop_enabled = AUTO_BOOLEAN_AUTO; -/* The set command writes to this variable. If the inferior is - executing, target_non_stop_enabled is *not* updated. */ -static enum auto_boolean target_non_stop_enabled_1 = AUTO_BOOLEAN_AUTO; - -/* Implementation of "maint set target-non-stop". */ +/* Set callback for maint target-non-stop setting. */ static void -maint_set_target_non_stop_command (const char *args, int from_tty, - struct cmd_list_element *c) +set_maint_target_non_stop (auto_boolean enabled) { if (have_live_inferiors ()) - { - target_non_stop_enabled_1 = target_non_stop_enabled; - error (_("Cannot change this setting while the inferior is running.")); - } + error (_("Cannot change this setting while the inferior is running.")); - target_non_stop_enabled = target_non_stop_enabled_1; + target_non_stop_enabled = enabled; } -/* Implementation of "maint show target-non-stop". */ +/* Get callback for maint target-non-stop setting. */ + +static auto_boolean +get_maint_target_non_stop () +{ + return target_non_stop_enabled; +} static void -maint_show_target_non_stop_command (struct ui_file *file, int from_tty, - struct cmd_list_element *c, - const char *value) +show_maint_target_non_stop (ui_file *file, int from_tty, + cmd_list_element *c, const char *value) { if (target_non_stop_enabled == AUTO_BOOLEAN_AUTO) - fprintf_filtered (file, - _("Whether the target is always in non-stop mode " - "is %s (currently %s).\n"), value, - target_always_non_stop_p () ? "on" : "off"); + gdb_printf (file, + _("Whether the target is always in non-stop mode " + "is %s (currently %s).\n"), value, + target_always_non_stop_p () ? "on" : "off"); else - fprintf_filtered (file, - _("Whether the target is always in non-stop mode " - "is %s.\n"), value); + gdb_printf (file, + _("Whether the target is always in non-stop mode " + "is %s.\n"), value); } /* Temporary copies of permission settings. */ @@ -3898,22 +4569,24 @@ result in significant performance improvement for remote targets."), &maintenanceprintlist); add_setshow_boolean_cmd ("target-async", no_class, - &target_async_permitted_1, _("\ + _("\ Set whether gdb controls the inferior in asynchronous mode."), _("\ Show whether gdb controls the inferior in asynchronous mode."), _("\ Tells gdb whether to control the inferior in asynchronous mode."), - maint_set_target_async_command, - maint_show_target_async_command, + set_maint_target_async, + get_maint_target_async, + show_maint_target_async, &maintenance_set_cmdlist, &maintenance_show_cmdlist); add_setshow_auto_boolean_cmd ("target-non-stop", no_class, - &target_non_stop_enabled_1, _("\ + _("\ Set whether gdb always controls the inferior in non-stop mode."), _("\ Show whether gdb always controls the inferior in non-stop mode."), _("\ Tells gdb whether to control the inferior in non-stop mode."), - maint_set_target_non_stop_command, - maint_show_target_non_stop_command, + set_maint_target_non_stop, + get_maint_target_non_stop, + show_maint_target_non_stop, &maintenance_set_cmdlist, &maintenance_show_cmdlist);