X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftarget.c;h=e3e30afd7a5450b65101ac2c90d8be7190bd65dd;hb=3318ac0e53a673f9989f5e9bbaa9d1c5d536f4e5;hp=ad7eba3fa3c9cf613ade335d16ca37bb1ab0e867;hpb=be6d4f74c77c6f521afc873d226480e001cb99c2;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/target.c b/gdb/target.c index ad7eba3fa3..e3e30afd7a 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-2019 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Contributed by Cygnus Support. @@ -40,13 +40,13 @@ #include "inline-frame.h" #include "tracepoint.h" #include "gdb/fileio.h" -#include "agent.h" +#include "gdbsupport/agent.h" #include "auxv.h" #include "target-debug.h" #include "top.h" #include "event-top.h" #include -#include "byte-vector.h" +#include "gdbsupport/byte-vector.h" #include "terminal.h" #include @@ -92,7 +92,7 @@ static int dummy_find_memory_regions (struct target_ops *self, static char *dummy_make_corefile_notes (struct target_ops *self, bfd *ignore1, int *ignore2); -static const char *default_pid_to_str (struct target_ops *ops, ptid_t ptid); +static std::string default_pid_to_str (struct target_ops *ops, ptid_t ptid); static enum exec_direction_kind default_execution_direction (struct target_ops *self); @@ -106,10 +106,8 @@ static enum exec_direction_kind default_execution_direction static std::unordered_map target_factories; -/* The initial current target, so that there is always a semi-valid - current target. */ +/* The singleton debug target. */ -static struct target_ops *the_dummy_target; static struct target_ops *the_debug_target; /* The target stack. */ @@ -130,10 +128,10 @@ current_top_target () static struct cmd_list_element *targetlist = NULL; -/* Nonzero if we should trust readonly sections from the +/* True if we should trust readonly sections from the executable when reading memory. */ -static int trust_readonly = 0; +static bool trust_readonly = false; /* Nonzero if we should show true memory content including memory breakpoint inserted by gdb. */ @@ -142,19 +140,19 @@ 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 - inadvertant disruption, such as in non-stop mode. */ + inadvertent disruption, such as in non-stop mode. */ -int may_write_registers = 1; +bool may_write_registers = true; -int may_write_memory = 1; +bool may_write_memory = true; -int may_insert_breakpoints = 1; +bool may_insert_breakpoints = true; -int may_insert_tracepoints = 1; +bool may_insert_tracepoints = true; -int may_insert_fast_tracepoints = 1; +bool may_insert_fast_tracepoints = true; -int may_stop = 1; +bool may_stop = true; /* Non-zero if we want to see trace of target level stuff. */ @@ -564,11 +562,7 @@ target_stack::push (target_ops *t) strata stratum = t->stratum (); if (m_stack[stratum] != NULL) - { - target_ops *prev = m_stack[stratum]; - m_stack[stratum] = NULL; - target_close (prev); - } + unpush (m_stack[stratum]); /* Now add the new one. */ m_stack[stratum] = t; @@ -585,6 +579,15 @@ push_target (struct target_ops *t) g_target_stack.push (t); } +/* See target.h */ + +void +push_target (target_ops_up &&t) +{ + g_target_stack.push (t.get ()); + t.release (); +} + /* See target.h. */ int @@ -598,14 +601,14 @@ unpush_target (struct target_ops *t) bool target_stack::unpush (target_ops *t) { + gdb_assert (t != NULL); + strata stratum = t->stratum (); if (stratum == dummy_stratum) internal_error (__FILE__, __LINE__, _("Attempt to unpush the dummy target")); - gdb_assert (t != NULL); - /* Look for the specified target. Note that a target can only occur once in the target stack. */ @@ -691,24 +694,29 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) { volatile CORE_ADDR addr = 0; struct target_ops *target = current_top_target (); + struct gdbarch *gdbarch = target_gdbarch (); - if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ())) + if (gdbarch_fetch_tls_load_module_address_p (gdbarch)) { ptid_t ptid = inferior_ptid; - TRY + try { CORE_ADDR lm_addr; /* Fetch the load module address for this objfile. */ - lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (), + lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch, objfile); - addr = target->get_thread_local_address (ptid, lm_addr, offset); + if (gdbarch_get_thread_local_address_p (gdbarch)) + addr = gdbarch_get_thread_local_address (gdbarch, ptid, lm_addr, + offset); + else + addr = target->get_thread_local_address (ptid, lm_addr, offset); } /* If an error occurred, print TLS related messages here. Otherwise, throw the error to some higher catcher. */ - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { int objfile_is_library = (objfile->flags & OBJF_SHARED); @@ -732,35 +740,34 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) " thread-local variables in\n" "the shared library `%s'\n" "for %s"), - objfile_name (objfile), target_pid_to_str (ptid)); + objfile_name (objfile), + target_pid_to_str (ptid).c_str ()); else error (_("The inferior has not yet allocated storage for" " thread-local variables in\n" "the executable `%s'\n" "for %s"), - objfile_name (objfile), target_pid_to_str (ptid)); + objfile_name (objfile), + target_pid_to_str (ptid).c_str ()); break; case TLS_GENERIC_ERROR: if (objfile_is_library) error (_("Cannot find thread-local storage for %s, " "shared library %s:\n%s"), - target_pid_to_str (ptid), - objfile_name (objfile), ex.message); + target_pid_to_str (ptid).c_str (), + objfile_name (objfile), ex.what ()); else error (_("Cannot find thread-local storage for %s, " "executable file %s:\n%s"), - target_pid_to_str (ptid), - objfile_name (objfile), ex.message); + target_pid_to_str (ptid).c_str (), + objfile_name (objfile), ex.what ()); break; default: - throw_exception (ex); + throw; break; } } - END_CATCH } - /* It wouldn't be wrong here to try a gdbarch method, too; finding - TLS is an ABI-specific thing. But we don't do that yet. */ else error (_("Cannot find thread-local variables on this target")); @@ -1031,9 +1038,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, secp = target_section_by_addr (ops, memaddr); if (secp != NULL - && (bfd_get_section_flags (secp->the_bfd_section->owner, - secp->the_bfd_section) - & SEC_READONLY)) + && (bfd_section_flags (secp->the_bfd_section) & SEC_READONLY)) { table = target_get_section_table (ops); return section_table_xfer_memory_partial (readbuf, writebuf, @@ -2001,6 +2006,11 @@ target_preopen (int from_tty) void target_detach (inferior *inf, int from_tty) { + /* After we have detached, we will clear the register cache for this inferior + by calling registers_changed_ptid. We must save the pid_ptid before + detaching, as the target detach method will clear inf->pid. */ + ptid_t save_pid_ptid = ptid_t (inf->pid); + /* As long as some to_detach implementations rely on the current_inferior (either directly, or indirectly, like through target_gdbarch or by reading memory), INF needs to be the current inferior. When that @@ -2020,6 +2030,14 @@ target_detach (inferior *inf, int from_tty) prepare_for_detach (); current_top_target ()->detach (inf, from_tty); + + registers_changed_ptid (save_pid_ptid); + + /* We have to ensure we have no frame cache left. Normally, + registers_changed_ptid (save_pid_ptid) calls reinit_frame_cache when + inferior_ptid matches save_pid_ptid, but in our case, it does not + call it, as inferior_ptid has been reset. */ + reinit_frame_cache (); } void @@ -2052,7 +2070,7 @@ default_target_wait (struct target_ops *ops, return minus_one_ptid; } -const char * +std::string target_pid_to_str (ptid_t ptid) { return current_top_target ()->pid_to_str (ptid); @@ -2073,6 +2091,14 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle, handle_len, inf); } +/* See target.h. */ + +gdb::byte_vector +target_thread_info_to_thread_handle (struct thread_info *tip) +{ + return current_top_target ()->thread_info_to_thread_handle (tip); +} + void target_resume (ptid_t ptid, int step, enum gdb_signal signal) { @@ -2111,15 +2137,15 @@ make_scoped_defer_target_commit_resume () } void -target_pass_signals (int numsigs, const unsigned char *pass_signals) +target_pass_signals (gdb::array_view pass_signals) { - current_top_target ()->pass_signals (numsigs, pass_signals); + current_top_target ()->pass_signals (pass_signals); } void -target_program_signals (int numsigs, const unsigned char *program_signals) +target_program_signals (gdb::array_view program_signals) { - current_top_target ()->program_signals (numsigs, program_signals); + current_top_target ()->program_signals (program_signals); } static int @@ -2143,7 +2169,7 @@ target_follow_fork (int follow_child, int detach_fork) /* Target wrapper for follow exec hook. */ void -target_follow_exec (struct inferior *inf, char *execd_pathname) +target_follow_exec (struct inferior *inf, const char *execd_pathname) { current_top_target ()->follow_exec (inf, execd_pathname); } @@ -2342,7 +2368,7 @@ target_require_runnable (void) /* Whether GDB is allowed to fall back to the default run target for "run", "attach", etc. when no target is connected yet. */ -static int auto_connect_native_target = 1; +static bool auto_connect_native_target = true; static void show_auto_connect_native_target (struct ui_file *file, int from_tty, @@ -3074,7 +3100,7 @@ target_fileio_read_stralloc (struct inferior *inf, const char *filename) return gdb::unique_xmalloc_ptr (nullptr); if (transferred == 0) - return gdb::unique_xmalloc_ptr (xstrdup ("")); + return make_unique_xstrdup (""); bufstr[transferred] = 0; @@ -3147,8 +3173,7 @@ target_announce_detach (int from_tty) pid = inferior_ptid.pid (); printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file, - target_pid_to_str (ptid_t (pid))); - gdb_flush (gdb_stdout); + target_pid_to_str (ptid_t (pid)).c_str ()); } /* The inferior process has died. Long live the inferior! */ @@ -3185,16 +3210,13 @@ generic_mourn_inferior (void) /* Convert a normal process ID to a string. Returns the string in a static buffer. */ -const char * +std::string normal_pid_to_str (ptid_t ptid) { - static char buf[32]; - - xsnprintf (buf, sizeof buf, "process %d", ptid.pid ()); - return buf; + return string_printf ("process %d", ptid.pid ()); } -static const char * +static std::string default_pid_to_str (struct target_ops *ops, ptid_t ptid) { return normal_pid_to_str (ptid); @@ -3220,6 +3242,10 @@ dummy_make_corefile_notes (struct target_ops *self, #include "target-delegates.c" +/* The initial current target, so that there is always a semi-valid + current target. */ + +static dummy_target the_dummy_target; static const target_info dummy_target_info = { "None", @@ -3324,9 +3350,9 @@ void target_stop_and_wait (ptid_t ptid) { struct target_waitstatus status; - int was_non_stop = non_stop; + bool was_non_stop = non_stop; - non_stop = 1; + non_stop = true; target_stop (ptid); memset (&status, 0, sizeof (status)); @@ -3761,9 +3787,9 @@ flash_erase_command (const char *cmd, int from_tty) ui_out_emit_tuple tuple_emitter (current_uiout, "erased-regions"); current_uiout->message (_("Erasing flash memory region at address ")); - current_uiout->field_fmt ("address", "%s", paddress (gdbarch, m.lo)); + current_uiout->field_core_addr ("address", gdbarch, m.lo); current_uiout->message (", size = "); - current_uiout->field_fmt ("size", "%s", hex_string (m.hi - m.lo)); + current_uiout->field_string ("size", hex_string (m.hi - m.lo)); current_uiout->message ("\n"); } } @@ -3809,11 +3835,11 @@ target_thread_events (int enable) /* Controls if targets can report that they can/are async. This is just for maintainers to use when debugging gdb. */ -int target_async_permitted = 1; +bool target_async_permitted = true; /* The set command writes to this variable. If the inferior is executing, target_async_permitted is *not* updated. */ -static int target_async_permitted_1 = 1; +static bool target_async_permitted_1 = true; static void maint_set_target_async_command (const char *args, int from_tty, @@ -3901,12 +3927,12 @@ maint_show_target_non_stop_command (struct ui_file *file, int from_tty, /* Temporary copies of permission settings. */ -static int may_write_registers_1 = 1; -static int may_write_memory_1 = 1; -static int may_insert_breakpoints_1 = 1; -static int may_insert_tracepoints_1 = 1; -static int may_insert_fast_tracepoints_1 = 1; -static int may_stop_1 = 1; +static bool may_write_registers_1 = true; +static bool may_write_memory_1 = true; +static bool may_insert_breakpoints_1 = true; +static bool may_insert_tracepoints_1 = true; +static bool may_insert_fast_tracepoints_1 = true; +static bool may_stop_1 = true; /* Make the user-set values match the real values again. */ @@ -3957,8 +3983,7 @@ set_write_memory_permission (const char *args, int from_tty, void initialize_targets (void) { - the_dummy_target = new dummy_target (); - push_target (the_dummy_target); + push_target (&the_dummy_target); the_debug_target = new debug_target ();