aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog392
-rw-r--r--gdb/gdbserver/Makefile.in17
-rw-r--r--gdb/gdbserver/config.in3
-rwxr-xr-xgdb/gdbserver/configure6
-rw-r--r--gdb/gdbserver/configure.ac5
-rw-r--r--gdb/gdbserver/configure.srv58
-rw-r--r--gdb/gdbserver/inferiors.c48
-rw-r--r--gdb/gdbserver/inferiors.h10
-rw-r--r--gdb/gdbserver/linux-amd64-ipa.c58
-rw-r--r--gdb/gdbserver/linux-i386-ipa.c39
-rw-r--r--gdb/gdbserver/linux-low.c88
-rw-r--r--gdb/gdbserver/linux-low.h25
-rw-r--r--gdb/gdbserver/linux-x86-low.c169
-rw-r--r--gdb/gdbserver/linux-x86-tdesc-selftest.c183
-rw-r--r--gdb/gdbserver/linux-x86-tdesc.c173
-rw-r--r--gdb/gdbserver/linux-x86-tdesc.h78
-rw-r--r--gdb/gdbserver/lynx-i386-low.c9
-rw-r--r--gdb/gdbserver/lynx-low.c14
-rw-r--r--gdb/gdbserver/nto-low.c14
-rw-r--r--gdb/gdbserver/nto-x86-low.c11
-rw-r--r--gdb/gdbserver/regcache.c51
-rw-r--r--gdb/gdbserver/server.c531
-rw-r--r--gdb/gdbserver/target.c36
-rw-r--r--gdb/gdbserver/target.h12
-rw-r--r--gdb/gdbserver/tdesc.c188
-rw-r--r--gdb/gdbserver/tdesc.h97
-rw-r--r--gdb/gdbserver/thread-db.c63
-rw-r--r--gdb/gdbserver/tracepoint.c32
-rw-r--r--gdb/gdbserver/tracepoint.h22
-rw-r--r--gdb/gdbserver/win32-i386-low.c33
-rw-r--r--gdb/gdbserver/win32-low.c8
31 files changed, 1704 insertions, 769 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 4ae5b33..a82dd86 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,395 @@
+2017-09-22 Simon Marchi <simon.marchi@ericsson.com>
+
+ * win32-i386-low.c (i386_arch_setup): Call init_target_desc.
+
+2017-09-21 Kevin Buettner <kevinb@redhat.com>
+
+ * linux-low.h (struct lwp_info): Add new field, thread_handle.
+ (thread_db_thread_handle): Declare.
+ * linux-low.c (linux_target_ops): Initialize thread_handle.
+ * server.c (handle_qxfer_threads_worker): Add support for
+ "handle" attribute.
+ * target.h (struct target_ops): Add new function pointer,
+ thread_handle.
+ (target_thread_handle): Define.
+ * thread-db.c (find_one_thread, attach_thread): Set thread_handle
+ field in lwp.
+ (thread_db_thread_handle): New function.
+
+2017-09-21 Kevin Buettner <kevinb@redhat.com>
+
+ * linux-low.c (handle_extended_wait): Call thread_db_notice_clone().
+ * linux-low.h (thread_db_notice_clone): Declare.
+ * thread-db.c (thread_db_notice_clone): New function.
+
+2017-09-21 Pedro Alves <palves@redhat.com>
+
+ * server.c (gdb_read_memory, handle_status, process_serial_event)
+ (handle_serial_event, handle_target_event): Adjust to
+ set_desired_thread prototype change.
+ * target.c (set_desired_thread): Remove 'use_general' parameter
+ and adjust.
+ * target.h (set_desired_thread): Remove 'use_general' parameter.
+
+2017-09-20 Tom Tromey <tom@tromey.com>
+
+ * target.c (target_terminal::terminal_state): Define.
+ (target_terminal::init): Rename from target_terminal_init.
+ (target_terminal::inferior): Rename from
+ target_terminal_inferior.
+ (target_terminal::ours): Rename from target_terminal_ours.
+ (target_terminal::ours_for_output, target_terminal::info): New.
+
+2017-09-16 Simon Marchi <simon.marchi@ericsson.com>
+
+ * server.c (accumulate_file_name_length): Remove.
+ (emit_dll_description): Adjust to std::string change.
+ (handle_qxfer_libraries): Use std::string to hold document.
+
+2017-09-16 Simon Marchi <simon.marchi@ericsson.com>
+
+ * linux-low.c (linux_qxfer_libraries_svr4): Adjust to change of
+ return type of xml_escape_text.
+ * server.c (emit_dll_description): Likewise.
+
+2017-09-16 Simon Marchi <simon.marchi@ericsson.com>
+
+ * server.c (captured_main): Accept argument for --selftest.
+ Update run_tests call.
+ * linux-x86-tdesc-selftest.c (initialize_low_tdesc): Add names
+ when registering selftests.
+
+2017-09-16 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * regcache.c (get_thread_regcache): Update code to use "std::vector"
+ instead of "VEC" for "target_desc.reg_defs".
+ (regcache_cpy): Likewise.
+ (registers_to_string): Likewise.
+ (registers_from_string): Likewise.
+ (find_regno): Likewise.
+ (supply_regblock): Likewise.
+ (regcache_raw_read_unsigned): Likewise.
+ * tdesc.c (init_target_desc): Likewise.
+ (tdesc_create_reg): Likewise.
+ * tdesc.h: Remove declaration of "tdesc_reg_p". Include <vector>.
+ (struct target_desc) <reg_defs>: Convert to "std::vector".
+ (target_desc): Do not initialize "reg_defs".
+ (~target_desc): Update code to use "std::vector" instead of "VEC"
+ for "target_desc.reg_defs".
+ (operator==): Likewise.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * inferiors.h (thread_to_gdb_id): Remove.
+ * inferiors.c (thread_to_gdb_id): Remove.
+ * server.c (handle_qxfer_threads_worker, handle_query): Adjust.
+ * lynx-low.c (lynx_resume, lynx_wait_1, lynx_fetch_registers,
+ lynx_store_registers, lynx_read_memory, lynx_write_memory):
+ Likewise.
+ * nto-low.c (nto_fetch_registers, nto_store_registers,
+ nto_stopped_by_watchpoint, nto_stopped_data_address): Likewise.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * inferiors.h (gdb_id_to_thread_id): Remove.
+ * inferiors.c (gdb_id_to_thread_id): Remove.
+ * server.c (process_serial_event): Adjust to gdb_id_to_thread_id
+ removal. Move pid declaration closer to where it's used.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * server.c (handle_detach): New function.
+ (process_serial_event): Move code out, call handle_detach.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * server.c (require_running): Rename to ...
+ (require_running_or_return): ... this ...
+ (require_running_or_break): ... and this.
+ (handle_query, process_serial_event): Adjust.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * linux-low.c (linux_set_resume_request): Remove unused
+ variables.
+
+2017-09-15 Simon Marchi <simon.marchi@ericsson.com>
+
+ * server.c (first_thread_of): Remove.
+ (process_serial_event): Replace usage of first_thread_of with
+ find_any_thread_of_pid.
+ * tracepoint.c (same_process_p): Remove.
+ (gdb_agent_about_to_close): Replace usage of same_process_p with
+ find_any_thread_of_pid.
+ * linux-x86-low.c (same_process_callback): Remove.
+ (x86_arch_setup_process_callback): Replace usage of
+ same_process_callback with find_any_thread_of_pid.
+ * thread-db.c (any_thread_of): Remove.
+ (switch_to_process): Replace usage of any_thread_of with
+ find_any_thread_of_pid.
+ * inferiors.c (thread_pid_matches_callback): Remove.
+ (find_thread_process): Adjust to use find_any_thread_of_pid.
+
+2017-09-10 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * regcache.c (get_thread_regcache): Guard calls to "memset"
+ with "!VEC_empty".
+
+2017-09-10 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * linux-low.c (handle_extended_wait): Use
+ "allocate_target_description" instead of "XNEW".
+ * linux-x86-low.c (initialize_low_arch): Likewise.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_i386_regobj): Remove.
+ (srv_amd64_regobj): Remove.
+ (srv_regobj): Set it to "" for x86 non-linux targets.
+ * linux-x86-tdesc.c (i386_linux_read_description):
+ * lynx-i386-low.c: Include x86-xstate.h and arch/i386.h.
+ (init_registers_i386): Remove the declaration.
+ (tdesc_i386): Remove the declaration.
+ (lynx_i386_arch_setup): Call i386_create_target_description.
+ * nto-x86-low.c: Likewise.
+ * win32-i386-low.c [__x86_64__]: include arch/amd64.h.
+ [!__x86_64__]: include arch/i386.h.
+ (i386_arch_setup) [__x86_64__]: Call amd64_create_target_description.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_amd64_linux_xmlfiles): Remove
+ i386/amd64-XXX-linux from it.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv: Empty srv_amd64_linux_regobj if $development is
+ false.
+ (ipa_amd64_linux_regobj): Remove.
+ (ipa_x32_linux_regobj): Remove.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * Makefile.in (arch-amd64.o): New rule.
+ * configure.srv: Append arch-amd64.o.
+ * linux-amd64-ipa.c: Include common/x86-xstate.h.
+ (get_ipa_tdesc): Call amd64_linux_read_description.
+ (initialize_low_tracepoint): Don't call init_registers_x32_XXX
+ and init_registers_amd64_XXX.
+ * linux-x86-low.c (x86_linux_read_description): Call
+ amd64_linux_read_description.
+ (x86_get_ipa_tdesc_idx): Call amd64_get_ipa_tdesc_idx.
+ (initialize_low_arch): Don't call init_registers_x32_XXX and
+ init_registers_amd64_XXX.
+ * linux-x86-tdesc-selftest.c: Declare init_registers_amd64_XXX
+ and tdesc_amd64_XXX.
+ [__x86_64__] (amd64_tdesc_test): New function.
+ (initialize_low_tdesc) [__x86_64__]: Call init_registers_x32_XXX
+ and init_registers_amd64_XXX.
+ * linux-x86-tdesc.c: Include arch/amd64.h.
+ (xcr0_to_tdesc_idx): New function.
+ (i386_linux_read_description): New function.
+ (amd64_get_ipa_tdesc_idx): New function.
+ * linux-x86-tdesc.h (amd64_get_ipa_tdesc_idx): Declare.
+ (amd64_get_ipa_tdesc): Declare.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_i386_linux_xmlfiles): Remove
+ i386/i386-XXX-linux.xml from it.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv: Set srv_i386_linux_regobj empty if $development
+ is false.
+ * linux-i386-ipa.c (initialize_low_tracepoint): Don't call
+ initialize_low_tdesc.
+ * linux-x86-low.c (initialize_low_arch): Wrap initialize_low_tdesc
+ with #if initialize_low_tdesc.
+ * linux-x86-tdesc-selftest.c: New file.
+ * linux-x86-tdesc.c: Move code to linux-x86-tdesc-selftest.c.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * Makefile.in (arch-i386.o): New rule.
+ * configure.srv (i[34567]86-*-linux*): Add arch-i386.o.
+ (x86_64-*-linux*): Likewise.
+ * linux-x86-tdesc.c: Don't include ../features/i386/32bit-XXX.c,
+ include arch/i386.h.
+ (i386_linux_read_description): Remove code and call
+ i386_create_target_description.
+ * tdesc.c (allocate_target_description): New function.
+ * tdesc.h (set_tdesc_architecture): Remove declaration.
+ (set_tdesc_osabi): Likewise.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * linux-x86-tdesc.c: Don't include <inttypes.h>.
+ (i386_linux_read_description) [!IN_PROCESS_AGENT]: Call
+ set_tdesc_architecture and set_tdesc_osabi. Remove code setting
+ .xmltarget.
+ * server.c (get_features_xml): Call tdesc_get_features_xml.
+ * tdesc.c (set_tdesc_architecture): New function.
+ (set_tdesc_osabi): New function.
+ (tdesc_get_features_xml): New function.
+ (tdesc_create_feature): Add an argument.
+ * tdesc.h (struct target_desc) <features>: New field.
+ <arch, osabi>: New field.
+ (~target_desc): xfree features, arch, and osabi.
+ (target_desc::oerator==): Don't compare .xmltarget.
+ [!IN_PROCESS_AGENT] (set_tdesc_architecture): Declare.
+ (set_tdesc_osabi): Likewise.
+ (tdesc_get_features_xml): Likewise.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * linux-x86-tdesc.c: Include selftest.h.
+ (i386_tdesc_test): New function.
+ (initialize_low_tdesc): Call selftests::register_test.
+ * tdesc.h: Include regdef.h.
+ (target_desc): Override operator == and !=.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_tgtobj): Append linux-x86-tdesc.o.
+ (ipa_obj): Likewise.
+ * linux-i386-ipa.c: Include common/x86-xstate.h
+ (get_ipa_tdesc): Call i386_linux_read_description.
+ (initialize_low_tracepoint): Don't call init_registers_XXX
+ functions, call initialize_low_tdesc instead.
+ * linux-x86-low.c (x86_linux_read_description): Call
+ i386_linux_read_description.
+ (initialize_low_arch): Don't call init_registers_i386_XXX
+ functions, call initialize_low_tdesc.
+ * linux-x86-tdesc.c: New file.
+ * linux-x86-tdesc.h (x86_linux_tdesc): New X86_TDESC_LAST.
+ (i386_get_ipa_tdesc_idx): Declare.
+ (i386_get_ipa_tdesc): Declare.
+ (initialize_low_tdesc): Declare.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * linux-x86-low.c (x86_get_ipa_tdesc_idx): Use X86_TDESC_MMX
+ instead of 0.
+
+2017-09-05 Yao Qi <yao.qi@linaro.org>
+
+ * Makefile.in (IPA_OBJS): Add vec-ipa.o
+ * regcache.c (get_thread_regcache): Use VEC_length.
+ (init_register_cache): Likewise.
+ (regcache_cpy): Likewise.
+ (registers_to_string): Iterate reg_defs via VEC_iterate.
+ (find_regno): Likewise.
+ (find_register_by_number): Use VEC_index.
+ (register_size): Call find_register_by_number.
+ (register_data): Call find_register_by_number.
+ (supply_regblock): Use VEC_length.
+ (regcache_raw_read_unsigned): Likewise.
+ * tdesc.c (init_target_desc): Iterate reg_defs via
+ VEC_iterate.
+ (default_description): Update initializer.
+ (copy_target_description): Don't update field num_registers.
+ * tdesc.h (struct target_desc) <reg_defs>: Change it to VEC.
+ <num_registers>: Remove.
+
+2017-09-04 Simon Marchi <simon.marchi@ericsson.com>
+
+ * Makefile.in (.SECONDARY): Define target.
+
+2017-09-03 Simon Marchi <simon.marchi@ericsson.com>
+
+ * linux-low.c (linux_wait_1): Adjust.
+ * server.c (queue_stop_reply_callback): Adjust.
+
+2017-08-31 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * server.c (handle_general_set): Handle QEnvironmentHexEncoded,
+ QEnvironmentUnset and QEnvironmentReset packets.
+ (handle_query): Inform remote that QEnvironmentHexEncoded,
+ QEnvironmentUnset and QEnvironmentReset are supported.
+
+2017-08-25 Simon Marchi <simon.marchi@ericsson.com>
+
+ * inferiors.h (inferior_target_data): Rename to ...
+ (thread_target_data): ... this.
+ (inferior_regcache_data): Rename to ...
+ (thread_regcache_data): ... this.
+ (set_inferior_regcache_data): Rename to ...
+ (set_thread_regcache_data): ... this.
+ * inferiors.c (inferior_target_data): Rename to ...
+ (thread_target_data): ... this.
+ (inferior_regcache_data): Rename to ...
+ (thread_regcache_data): ... this.
+ (set_inferior_regcache_data): Rename to ...
+ (set_thread_regcache_data): ... this.
+ (free_one_thread): Update.
+ * linux-low.h (get_thread_lwp): Update.
+ * regcache.c (get_thread_regcache): Update.
+ (regcache_invalidate_thread): Update.
+ (free_register_cache_thread): Update.
+ * win32-i386-low.c (update_debug_registers_callback): Update.
+ (win32_get_current_dr): Update.
+ * win32-low.c (thread_rec): Update.
+ (delete_thread_info): Update.
+ (continue_one_thread): Update.
+ (suspend_one_thread): Update.
+
+2017-08-24 Simon Marchi <simon.marchi@ericsson.com>
+
+ * inferiors.c (set_inferior_target_data): Remove.
+ * inferiors.h (set_inferior_target_data): Remove.
+
+2017-08-18 Yao Qi <yao.qi@linaro.org>
+
+ * Makefile.in (OBS): Add selftest.o.
+ * configure.ac: AC_DEFINE GDB_SELF_TEST if $development.
+ * configure, config.in: Re-generated.
+ * server.c: Include common/sefltest.h.
+ (captured_main): Handle option --selftest.
+
+2017-08-09 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_i386_regobj): Remove i386-avx.o,
+ i386-avx-avx512.o, i386-avx-mpx-avx512-pku.o, i386-mpx.o,
+ i386-avx-mpx.o and i386-mmx.o.
+ (srv_amd64_regobj): Remove amd64-avx.o, amd64-avx-avx512.o,
+ amd64-avx-mpx-avx512-pku.o, amd64-mpx.o and amd64-avx-mpx.o.
+ (srv_i386_xmlfiles): Remove i386/i386-avx.xml,
+ i386/i386-avx-avx512.xml, i386/i386-avx-mpx-avx512-pku.xml,
+ i386/i386-mpx.xml, i386/i386-avx-mpx.xml and i386/i386-mmx.xml.
+ (srv_amd64_xmlfile):i386/amd64-avx.xml, i386/amd64-avx-avx512.xml,
+ i386/amd64-avx-mpx-avx512-pku.xml, i386/amd64-mpx.xml,
+ i386/amd64-avx-mpx.xml.
+
+2017-08-09 Yao Qi <yao.qi@linaro.org>
+
+ * configure.srv (srv_amd64_regobj): Remove x32.o, x32-avx.o
+ and x32-avx-avx512.o.
+ (srv_amd64_xmlfiles): Remove i386/x32.xml, i386/x32-avx.xml
+ i386/x32-avx-avx512.xml.
+
+2017-07-26 Simon Marchi <simon.marchi@ericsson.com>
+
+ * tracepoint.h (enum class fast_tpoint_collect_result): New
+ enumeration.
+ (fast_tracepoint_collecting): Change return type to
+ fast_tpoint_collect_result.
+ * tracepoint.c (fast_tracepoint_collecting): Likewise.
+ * linux-low.h: Include tracepoint.h.
+ (struct lwp_info) <collecting_fast_tracepoint>: Change type to
+ fast_tpoint_collect_result.
+ * linux-low.c (handle_tracepoints): Adjust.
+ (linux_fast_tracepoint_collecting): Change return type to
+ fast_tpoint_collect_result.
+ (maybe_move_out_of_jump_pad, linux_wait_for_event_filtered,
+ linux_wait_1, stuck_in_jump_pad_callback,
+ lwp_signal_can_be_delivered, linux_resume_one_lwp_throw,
+ proceed_one_lwp): Adjust to type change.
+
+2017-07-10 Yao Qi <yao.qi@linaro.org>
+
+ * linux-x86-low.c (x86_linux_read_description): Re-indent the code.
+
2017-06-29 Yao Qi <yao.qi@linaro.org>
* tdesc.h (struct target_desc) [IN_PROCESS_AGENT] <expedite_regs>:
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 4e0080e..1bbe515 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -258,6 +258,7 @@ OBS = \
regcache.o \
remote-utils.o \
rsp-low.o \
+ selftest.o \
server.o \
signals.o \
signals-state-save-restore.o \
@@ -399,6 +400,7 @@ IPA_OBJS = \
tdesc-ipa.o \
tracepoint-ipa.o \
utils-ipa.o \
+ vec-ipa.o \
${IPA_DEPFILES}
IPA_LIB = libinproctrace.so
@@ -526,6 +528,14 @@ ax.o: ax.c
$(COMPILE) $(WARN_CFLAGS_NO_FORMAT) $<
$(POSTCOMPILE)
+arch-i386.o: ../arch/i386.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
+arch-amd64.o: ../arch/amd64.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
# Rules for objects that go in the in-process agent.
%-ipa.o: %-generated.c
@@ -551,6 +561,10 @@ ax.o: ax.c
$(IPAGENT_COMPILE) $<
$(POSTCOMPILE)
+%-ipa.o: ../arch/%.c
+ $(IPAGENT_COMPILE) $<
+ $(POSTCOMPILE)
+
# Rules for objects that go in the gdbserver binary.
%.o: %-generated.c
@@ -631,4 +645,7 @@ endif
# Disable implicit make rules.
include $(srcdir)/../disable-implicit-rules.mk
+# Do not delete intermediate files (e.g. *-generated.c).
+.SECONDARY:
+
# This is the end of "Makefile.in".
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index 34a7443..5dacbac 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -8,6 +8,9 @@
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
+/* Define if self-testing features should be enabled */
+#undef GDB_SELF_TEST
+
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index 35aeabc..30aa95b 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -5813,6 +5813,12 @@ fi
fi
+if $development; then
+
+$as_echo "#define GDB_SELF_TEST 1" >>confdefs.h
+
+fi
+
case ${build_alias} in
"") build_noncanonical=${build} ;;
*) build_noncanonical=${build_alias} ;;
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 4ea7913..36e21c5 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -56,6 +56,11 @@ else
fi
GDB_AC_LIBMCHECK(${libmcheck_default})
+if $development; then
+ AC_DEFINE(GDB_SELF_TEST, 1,
+ [Define if self-testing features should be enabled])
+fi
+
ACX_NONCANONICAL_TARGET
ACX_NONCANONICAL_HOST
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 43f90c9..2a0c2b2 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -24,21 +24,22 @@
# Default hostio_last_error implementation
srv_hostio_err_objs="hostio-errno.o"
-srv_i386_regobj="i386.o i386-avx.o i386-avx-avx512.o i386-avx-mpx-avx512-pku.o i386-mpx.o i386-avx-mpx.o i386-mmx.o"
-srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx-avx512-linux.o i386-avx-mpx-avx512-pku-linux.o i386-mpx-linux.o i386-avx-mpx-linux.o i386-mmx-linux.o"
-srv_amd64_regobj="amd64.o amd64-avx.o amd64-avx-avx512.o amd64-avx-mpx-avx512-pku.o amd64-mpx.o amd64-avx-mpx.o x32.o x32-avx.o x32-avx-avx512.o"
-srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx-avx512-linux.o amd64-avx-mpx-avx512-pku-linux.o amd64-mpx-linux.o amd64-avx-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx-avx512-linux.o"
+if $development; then
+ srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx-avx512-linux.o i386-avx-mpx-avx512-pku-linux.o i386-mpx-linux.o i386-avx-mpx-linux.o i386-mmx-linux.o linux-x86-tdesc-selftest.o"
+ srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx-avx512-linux.o amd64-avx-mpx-avx512-pku-linux.o amd64-mpx-linux.o amd64-avx-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx-avx512-linux.o"
+else
+ srv_i386_linux_regobj=""
+ srv_amd64_linux_regobj=""
+fi
-ipa_i386_linux_regobj="i386-linux-ipa.o i386-avx-linux-ipa.o i386-avx-mpx-linux-ipa.o i386-avx-avx512-linux-ipa.o i386-avx-mpx-avx512-pku-linux-ipa.o i386-mpx-linux-ipa.o i386-mmx-linux-ipa.o"
-ipa_amd64_linux_regobj="amd64-linux-ipa.o amd64-avx-linux-ipa.o amd64-avx-mpx-linux-ipa.o amd64-avx-avx512-linux-ipa.o amd64-avx-mpx-avx512-pku-linux-ipa.o amd64-mpx-linux-ipa.o"
ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o"
srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml i386/32bit-pkeys.xml"
srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-segments.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml i386/64bit-pkeys.xml"
-srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-avx-avx512.xml i386/i386-avx-mpx-avx512-pku.xml i386/i386-mpx.xml i386/i386-avx-mpx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles"
-srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku.xml i386/x32.xml i386/x32-avx.xml i386/x32-avx-avx512.xml i386/amd64-mpx.xml i386/amd64-avx-mpx.xml $srv_i386_64bit_xmlfiles"
-srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-avx-avx512-linux.xml i386/i386-avx-mpx-avx512-pku-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml i386/i386-mpx-linux.xml i386/i386-avx-mpx-linux.xml $srv_i386_32bit_xmlfiles"
-srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku-linux.xml i386/64bit-linux.xml i386/amd64-mpx-linux.xml i386/amd64-avx-mpx-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml i386/x32-avx-avx512-linux.xml $srv_i386_64bit_xmlfiles"
+srv_i386_xmlfiles="i386/i386.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_xmlfiles="i386/amd64.xml $srv_i386_64bit_xmlfiles"
+srv_i386_linux_xmlfiles="i386/32bit-linux.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_linux_xmlfiles="i386/64bit-linux.xml $srv_i386_64bit_xmlfiles"
# Linux object files. This is so we don't have to repeat
@@ -110,8 +111,9 @@ case "${target}" in
srv_linux_usrregs=yes
srv_linux_thread_db=yes
;;
- i[34567]86-*-cygwin*) srv_regobj="$srv_i386_regobj"
+ i[34567]86-*-cygwin*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
+ srv_tgtobj="${srv_tgtobj} arch-i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
;;
i[34567]86-*-linux*) srv_regobj="$srv_i386_linux_regobj"
@@ -121,25 +123,30 @@ case "${target}" in
srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
srv_tgtobj="amd64-linux-siginfo.o"
fi
+ srv_tgtobj="${srv_tgtobj} arch-i386.o"
srv_tgtobj="${srv_tgtobj} $srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+ srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o"
srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
srv_linux_btrace=yes
- ipa_obj="${ipa_i386_linux_regobj} linux-i386-ipa.o"
+ ipa_obj="linux-i386-ipa.o linux-x86-tdesc-ipa.o"
+ ipa_obj="${ipa_obj} i386-ipa.o"
;;
- i[34567]86-*-lynxos*) srv_regobj="i386.o"
+ i[34567]86-*-lynxos*) srv_regobj=""
srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o fork-inferior.o"
+ srv_tgtobj="${srv_tgtobj} arch-i386.o"
srv_xmlfiles="i386/i386.xml"
srv_xmlfiles="${srv_xmlfiles} i386/32bit-core.xml"
srv_xmlfiles="${srv_xmlfiles} i386/32bit-sse.xml"
srv_lynxos=yes
;;
i[34567]86-*-mingw32ce*)
- srv_regobj="$srv_i386_regobj"
+ srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
+ srv_tgtobj="${srv_tgtobj} arch-i386.o"
srv_tgtobj="${srv_tgtobj} wincecompat.o"
srv_xmlfiles="$srv_i386_xmlfiles"
# hostio_last_error implementation is in win32-low.c
@@ -147,13 +154,14 @@ case "${target}" in
srv_mingw=yes
srv_mingwce=yes
;;
- i[34567]86-*-mingw*) srv_regobj="$srv_i386_regobj"
+ i[34567]86-*-mingw*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
+ srv_tgtobj="${srv_tgtobj} arch-i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
srv_mingw=yes
;;
- i[34567]86-*-nto*) srv_regobj="$srv_i386_regobj"
- srv_tgtobj="nto-low.o nto-x86-low.o"
+ i[34567]86-*-nto*) srv_regobj=""
+ srv_tgtobj="nto-low.o nto-x86-low.o arch-i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
srv_qnx="yes"
;;
@@ -356,6 +364,8 @@ case "${target}" in
;;
x86_64-*-linux*) srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+ srv_tgtobj="${srv_tgtobj} arch-i386.o arch-amd64.o"
+ srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o"
srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
srv_tgtobj="${srv_tgtobj} amd64-linux-siginfo.o"
@@ -364,20 +374,18 @@ case "${target}" in
srv_linux_regsets=yes
srv_linux_thread_db=yes
srv_linux_btrace=yes
- if test "$gdb_cv_x86_is_x32" = yes ; then
- ipa_obj="${ipa_x32_linux_regobj}"
- else
- ipa_obj="${ipa_amd64_linux_regobj}"
- fi
- ipa_obj="${ipa_obj} linux-amd64-ipa.o"
+ ipa_obj="linux-amd64-ipa.o linux-x86-tdesc-ipa.o"
+ ipa_obj="${ipa_obj} amd64-ipa.o"
;;
- x86_64-*-mingw*) srv_regobj="$srv_amd64_regobj"
+ x86_64-*-mingw*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
+ srv_tgtobj="${srv_tgtobj} arch-amd64.o"
srv_xmlfiles="$srv_i386_xmlfiles $srv_amd64_xmlfiles"
srv_mingw=yes
;;
- x86_64-*-cygwin*) srv_regobj="$srv_amd64_regobj"
+ x86_64-*-cygwin*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
+ srv_tgtobj="${srv_tgtobj} arch-amd64.o"
srv_xmlfiles="$srv_i386_xmlfiles"
;;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 5a4a0d1..72f0412 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -121,12 +121,6 @@ add_thread (ptid_t thread_id, void *target_data)
return new_thread;
}
-ptid_t
-thread_to_gdb_id (struct thread_info *thread)
-{
- return thread->entry.id;
-}
-
/* Wrapper around get_first_inferior to return a struct thread_info *. */
struct thread_info *
@@ -141,25 +135,13 @@ find_thread_ptid (ptid_t ptid)
return (struct thread_info *) find_inferior_id (&all_threads, ptid);
}
-/* Predicate function for matching thread entry's pid to the given
- pid value passed by address in ARGS. */
-
-static int
-thread_pid_matches_callback (struct inferior_list_entry *entry, void *args)
-{
- return (ptid_get_pid (entry->id) == *(pid_t *)args);
-}
-
/* Find a thread associated with the given PROCESS, or NULL if no
such thread exists. */
static struct thread_info *
find_thread_process (const struct process_info *const process)
{
- pid_t pid = ptid_get_pid (ptid_of (process));
-
- return (struct thread_info *)
- find_inferior (&all_threads, thread_pid_matches_callback, &pid);
+ return find_any_thread_of_pid (process->entry.id.pid ());
}
/* Helper for find_any_thread_of_pid. Returns true if a thread
@@ -185,19 +167,11 @@ find_any_thread_of_pid (int pid)
return (struct thread_info *) entry;
}
-ptid_t
-gdb_id_to_thread_id (ptid_t gdb_id)
-{
- struct thread_info *thread = find_thread_ptid (gdb_id);
-
- return thread ? thread->entry.id : null_ptid;
-}
-
static void
free_one_thread (struct inferior_list_entry *inf)
{
struct thread_info *thread = get_thread (inf);
- free_register_cache (inferior_regcache_data (thread));
+ free_register_cache (thread_regcache_data (thread));
free (thread);
}
@@ -309,27 +283,21 @@ find_inferior_id (struct inferior_list *list, ptid_t id)
}
void *
-inferior_target_data (struct thread_info *inferior)
-{
- return inferior->target_data;
-}
-
-void
-set_inferior_target_data (struct thread_info *inferior, void *data)
+thread_target_data (struct thread_info *thread)
{
- inferior->target_data = data;
+ return thread->target_data;
}
struct regcache *
-inferior_regcache_data (struct thread_info *inferior)
+thread_regcache_data (struct thread_info *thread)
{
- return inferior->regcache_data;
+ return thread->regcache_data;
}
void
-set_inferior_regcache_data (struct thread_info *inferior, struct regcache *data)
+set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
{
- inferior->regcache_data = data;
+ thread->regcache_data = data;
}
/* Return true if LIST has exactly one entry. */
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index 2290a63..aef8433 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -143,9 +143,6 @@ struct process_info *find_process_pid (int pid);
int have_started_inferiors_p (void);
int have_attached_inferiors_p (void);
-ptid_t thread_to_gdb_id (struct thread_info *);
-ptid_t gdb_id_to_thread_id (ptid_t);
-
void clear_inferiors (void);
struct inferior_list_entry *find_inferior
(struct inferior_list *,
@@ -160,9 +157,8 @@ struct inferior_list_entry *
void *),
void *arg);
-void *inferior_target_data (struct thread_info *);
-void set_inferior_target_data (struct thread_info *, void *);
-struct regcache *inferior_regcache_data (struct thread_info *);
-void set_inferior_regcache_data (struct thread_info *, struct regcache *);
+void *thread_target_data (struct thread_info *);
+struct regcache *thread_regcache_data (struct thread_info *);
+void set_thread_regcache_data (struct thread_info *, struct regcache *);
#endif /* INFERIORS_H */
diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c
index 67f36c2..85d0d45 100644
--- a/gdb/gdbserver/linux-amd64-ipa.c
+++ b/gdb/gdbserver/linux-amd64-ipa.c
@@ -22,6 +22,7 @@
#include <sys/mman.h>
#include "tracepoint.h"
#include "linux-x86-tdesc.h"
+#include "common/x86-xstate.h"
/* Defined in auto-generated file amd64-linux.c. */
void init_registers_amd64_linux (void);
@@ -174,38 +175,37 @@ supply_static_tracepoint_registers (struct regcache *regcache,
const struct target_desc *
get_ipa_tdesc (int idx)
{
-#if defined __ILP32__
- switch (idx)
+ if (idx >= X86_TDESC_LAST)
{
- case X86_TDESC_SSE:
- return tdesc_x32_linux;
- case X86_TDESC_AVX:
- return tdesc_x32_avx_linux;
- case X86_TDESC_AVX512:
- return tdesc_x32_avx512_linux;
- default:
- break;
+ internal_error (__FILE__, __LINE__,
+ "unknown ipa tdesc index: %d", idx);
}
-#else
+
+#if defined __ILP32__
switch (idx)
{
case X86_TDESC_SSE:
- return tdesc_amd64_linux;
+ return amd64_linux_read_description (X86_XSTATE_SSE_MASK, true);
case X86_TDESC_AVX:
- return tdesc_amd64_avx_linux;
- case X86_TDESC_MPX:
- return tdesc_amd64_mpx_linux;
- case X86_TDESC_AVX_MPX:
- return tdesc_amd64_avx_mpx_linux;
- case X86_TDESC_AVX_MPX_AVX512_PKU:
- return tdesc_amd64_avx_mpx_avx512_pku_linux;
+ return amd64_linux_read_description (X86_XSTATE_AVX_MASK, true);
case X86_TDESC_AVX_AVX512:
- return tdesc_amd64_avx_avx512_linux;
+ return amd64_linux_read_description (X86_XSTATE_AVX_AVX512_MASK, true);
default:
- internal_error (__FILE__, __LINE__,
- "unknown ipa tdesc index: %d", idx);
- return tdesc_amd64_linux;
+ break;
}
+#else
+ /* Map the tdesc index to xcr0 mask. */
+ uint64_t idx2mask[X86_TDESC_LAST] = {
+ X86_XSTATE_X87_MASK,
+ X86_XSTATE_SSE_MASK,
+ X86_XSTATE_AVX_MASK,
+ X86_XSTATE_MPX_MASK,
+ X86_XSTATE_AVX_MPX_MASK,
+ X86_XSTATE_AVX_AVX512_MASK,
+ X86_XSTATE_AVX_MPX_AVX512_PKU_MASK,
+ };
+
+ return amd64_linux_read_description (idx2mask[idx], false);
#endif
internal_error (__FILE__, __LINE__,
@@ -276,16 +276,4 @@ alloc_jump_pad_buffer (size_t size)
void
initialize_low_tracepoint (void)
{
-#if defined __ILP32__
- init_registers_x32_linux ();
- init_registers_x32_avx_linux ();
- init_registers_x32_avx512_linux ();
-#else
- init_registers_amd64_linux ();
- init_registers_amd64_avx_linux ();
- init_registers_amd64_mpx_linux ();
- init_registers_amd64_avx_mpx_linux ();
- init_registers_amd64_avx_avx512_linux ();
- init_registers_amd64_avx_mpx_avx512_pku_linux ();
-#endif
}
diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c
index e9ac78b..785a63e 100644
--- a/gdb/gdbserver/linux-i386-ipa.c
+++ b/gdb/gdbserver/linux-i386-ipa.c
@@ -22,6 +22,7 @@
#include <sys/mman.h>
#include "tracepoint.h"
#include "linux-x86-tdesc.h"
+#include "common/x86-xstate.h"
/* GDB register numbers. */
@@ -250,27 +251,24 @@ initialize_fast_tracepoint_trampoline_buffer (void)
const struct target_desc *
get_ipa_tdesc (int idx)
{
- switch (idx)
+ if (idx >= X86_TDESC_LAST)
{
- case X86_TDESC_MMX:
- return tdesc_i386_mmx_linux;
- case X86_TDESC_SSE:
- return tdesc_i386_linux;
- case X86_TDESC_AVX:
- return tdesc_i386_avx_linux;
- case X86_TDESC_MPX:
- return tdesc_i386_mpx_linux;
- case X86_TDESC_AVX_MPX:
- return tdesc_i386_avx_mpx_linux;
- case X86_TDESC_AVX_AVX512:
- return tdesc_i386_avx_avx512_linux;
- case X86_TDESC_AVX_MPX_AVX512_PKU:
- return tdesc_i386_avx_mpx_avx512_pku_linux;
- default:
internal_error (__FILE__, __LINE__,
"unknown ipa tdesc index: %d", idx);
- return tdesc_i386_linux;
}
+
+ /* Map the tdesc index to xcr0 mask. */
+ uint64_t idx2mask[X86_TDESC_LAST] = {
+ X86_XSTATE_X87_MASK,
+ X86_XSTATE_SSE_MASK,
+ X86_XSTATE_AVX_MASK,
+ X86_XSTATE_MPX_MASK,
+ X86_XSTATE_AVX_MPX_MASK,
+ X86_XSTATE_AVX_AVX512_MASK,
+ X86_XSTATE_AVX_MPX_AVX512_PKU_MASK,
+ };
+
+ return i386_linux_read_description (idx2mask[idx]);
}
/* Allocate buffer for the jump pads. On i386, we can reach an arbitrary
@@ -291,12 +289,5 @@ alloc_jump_pad_buffer (size_t size)
void
initialize_low_tracepoint (void)
{
- init_registers_i386_mmx_linux ();
- init_registers_i386_linux ();
- init_registers_i386_avx_linux ();
- init_registers_i386_mpx_linux ();
- init_registers_i386_avx_avx512_linux ();
- init_registers_i386_avx_mpx_avx512_pku_linux ();
-
initialize_fast_tracepoint_trampoline_buffer ();
}
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3d7cfe3..c62dc19 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -570,7 +570,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
clone_all_breakpoints (child_thr, event_thr);
- tdesc = XNEW (struct target_desc);
+ tdesc = allocate_target_description ();
copy_target_description (tdesc, parent_proc->tdesc);
child_proc->tdesc = tdesc;
@@ -656,6 +656,8 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
new_lwp->status_pending = status;
}
+ thread_db_notice_clone (get_thread_process (event_thr), ptid);
+
/* Don't report the event. */
return 1;
}
@@ -2082,7 +2084,9 @@ handle_tracepoints (struct lwp_info *lwp)
lwp_suspended_decr (lwp);
gdb_assert (lwp->suspended == 0);
- gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint);
+ gdb_assert (!stabilizing_threads
+ || (lwp->collecting_fast_tracepoint
+ != fast_tpoint_collect_result::not_collecting));
if (tpoint_related_event)
{
@@ -2094,10 +2098,10 @@ handle_tracepoints (struct lwp_info *lwp)
return 0;
}
-/* Convenience wrapper. Returns true if LWP is presently collecting a
- fast tracepoint. */
+/* Convenience wrapper. Returns information about LWP's fast tracepoint
+ collection status. */
-static int
+static fast_tpoint_collect_result
linux_fast_tracepoint_collecting (struct lwp_info *lwp,
struct fast_tpoint_collect_status *status)
{
@@ -2105,14 +2109,14 @@ linux_fast_tracepoint_collecting (struct lwp_info *lwp,
struct thread_info *thread = get_lwp_thread (lwp);
if (the_low_target.get_thread_area == NULL)
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
/* Get the thread area address. This is used to recognize which
thread is which when tracing with the in-process agent library.
We don't read anything from the address, and treat it as opaque;
it's the address itself that we assume is unique per-thread. */
if ((*the_low_target.get_thread_area) (lwpid_of (thread), &thread_area) == -1)
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status);
}
@@ -2136,14 +2140,14 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
&& agent_loaded_p ())
{
struct fast_tpoint_collect_status status;
- int r;
if (debug_threads)
debug_printf ("Checking whether LWP %ld needs to move out of the "
"jump pad.\n",
lwpid_of (current_thread));
- r = linux_fast_tracepoint_collecting (lwp, &status);
+ fast_tpoint_collect_result r
+ = linux_fast_tracepoint_collecting (lwp, &status);
if (wstat == NULL
|| (WSTOPSIG (*wstat) != SIGILL
@@ -2153,9 +2157,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
{
lwp->collecting_fast_tracepoint = r;
- if (r != 0)
+ if (r != fast_tpoint_collect_result::not_collecting)
{
- if (r == 1 && lwp->exit_jump_pad_bkpt == NULL)
+ if (r == fast_tpoint_collect_result::before_insn
+ && lwp->exit_jump_pad_bkpt == NULL)
{
/* Haven't executed the original instruction yet.
Set breakpoint there, and wait till it's hit,
@@ -2181,9 +2186,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
reporting to GDB. Otherwise, it's an IPA lib bug: just
report the signal to GDB, and pray for the best. */
- lwp->collecting_fast_tracepoint = 0;
+ lwp->collecting_fast_tracepoint
+ = fast_tpoint_collect_result::not_collecting;
- if (r != 0
+ if (r != fast_tpoint_collect_result::not_collecting
&& (status.adjusted_insn_addr <= lwp->stop_pc
&& lwp->stop_pc < status.adjusted_insn_addr_end))
{
@@ -2715,7 +2721,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
if (stopping_threads == NOT_STOPPING_THREADS
&& requested_child->status_pending_p
- && requested_child->collecting_fast_tracepoint)
+ && (requested_child->collecting_fast_tracepoint
+ != fast_tpoint_collect_result::not_collecting))
{
enqueue_one_deferred_signal (requested_child,
&requested_child->status_pending);
@@ -3467,20 +3474,22 @@ linux_wait_1 (ptid_t ptid,
}
}
- if (event_child->collecting_fast_tracepoint)
+ if (event_child->collecting_fast_tracepoint
+ != fast_tpoint_collect_result::not_collecting)
{
if (debug_threads)
debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
"Check if we're already there.\n",
lwpid_of (current_thread),
- event_child->collecting_fast_tracepoint);
+ (int) event_child->collecting_fast_tracepoint);
trace_event = 1;
event_child->collecting_fast_tracepoint
= linux_fast_tracepoint_collecting (event_child, NULL);
- if (event_child->collecting_fast_tracepoint != 1)
+ if (event_child->collecting_fast_tracepoint
+ != fast_tpoint_collect_result::before_insn)
{
/* No longer need this breakpoint. */
if (event_child->exit_jump_pad_bkpt != NULL)
@@ -3507,7 +3516,8 @@ linux_wait_1 (ptid_t ptid,
}
}
- if (event_child->collecting_fast_tracepoint == 0)
+ if (event_child->collecting_fast_tracepoint
+ == fast_tpoint_collect_result::not_collecting)
{
if (debug_threads)
debug_printf ("fast tracepoint finished "
@@ -3725,12 +3735,11 @@ linux_wait_1 (ptid_t ptid,
{
if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
{
- char *str;
+ std::string str
+ = target_waitstatus_to_string (&event_child->waitstatus);
- str = target_waitstatus_to_string (&event_child->waitstatus);
debug_printf ("LWP %ld: extended event with waitstatus %s\n",
- lwpid_of (get_lwp_thread (event_child)), str);
- xfree (str);
+ lwpid_of (get_lwp_thread (event_child)), str.c_str ());
}
if (current_thread->last_resume_kind == resume_step)
{
@@ -4192,7 +4201,8 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
&& (gdb_breakpoint_here (lwp->stop_pc)
|| lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT
|| thread->last_resume_kind == resume_step)
- && linux_fast_tracepoint_collecting (lwp, NULL));
+ && (linux_fast_tracepoint_collecting (lwp, NULL)
+ != fast_tpoint_collect_result::not_collecting));
}
static void
@@ -4369,7 +4379,8 @@ single_step (struct lwp_info* lwp)
static int
lwp_signal_can_be_delivered (struct lwp_info *lwp)
{
- return !lwp->collecting_fast_tracepoint;
+ return (lwp->collecting_fast_tracepoint
+ == fast_tpoint_collect_result::not_collecting);
}
/* Resume execution of LWP. If STEP is nonzero, single-step it. If
@@ -4381,7 +4392,6 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
{
struct thread_info *thread = get_lwp_thread (lwp);
struct thread_info *saved_thread;
- int fast_tp_collecting;
int ptrace_request;
struct process_info *proc = get_thread_process (thread);
@@ -4397,9 +4407,12 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
- fast_tp_collecting = lwp->collecting_fast_tracepoint;
+ fast_tpoint_collect_result fast_tp_collecting
+ = lwp->collecting_fast_tracepoint;
- gdb_assert (!stabilizing_threads || fast_tp_collecting);
+ gdb_assert (!stabilizing_threads
+ || (fast_tp_collecting
+ != fast_tpoint_collect_result::not_collecting));
/* Cancel actions that rely on GDB not changing the PC (e.g., the
user used the "jump" command, or "set $pc = foo"). */
@@ -4455,7 +4468,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
if (can_hardware_single_step ())
{
- if (fast_tp_collecting == 0)
+ if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting)
{
if (step == 0)
warning ("BAD - reinserting but not stepping.");
@@ -4468,14 +4481,14 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
step = maybe_hw_step (thread);
}
- if (fast_tp_collecting == 1)
+ if (fast_tp_collecting == fast_tpoint_collect_result::before_insn)
{
if (debug_threads)
debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
" (exit-jump-pad-bkpt)\n",
lwpid_of (thread));
}
- else if (fast_tp_collecting == 2)
+ else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn)
{
if (debug_threads)
debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
@@ -4700,7 +4713,6 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
does not yet know are new fork children. */
if (lwp->fork_relative != NULL)
{
- struct inferior_list_entry *inf, *tmp;
struct lwp_info *rel = lwp->fork_relative;
if (rel->status_pending_p
@@ -5294,7 +5306,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
if (thread->last_resume_kind == resume_stop
&& lwp->pending_signals_to_report == NULL
- && lwp->collecting_fast_tracepoint == 0)
+ && (lwp->collecting_fast_tracepoint
+ == fast_tpoint_collect_result::not_collecting))
{
/* We haven't reported this LWP as stopped yet (otherwise, the
last_status.kind check above would catch it, and we wouldn't
@@ -7277,7 +7290,6 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
{
/* 6x the size for xml_escape_text below. */
size_t len = 6 * strlen ((char *) libname);
- char *name;
if (!header_done)
{
@@ -7296,12 +7308,11 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
p = document + document_len;
}
- name = xml_escape_text ((char *) libname);
+ std::string name = xml_escape_text ((char *) libname);
p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
"l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
- name, (unsigned long) lm_addr,
+ name.c_str (), (unsigned long) lm_addr,
(unsigned long) l_addr, (unsigned long) l_ld);
- free (name);
}
}
@@ -7694,6 +7705,11 @@ static struct target_ops linux_target_ops = {
linux_supports_software_single_step,
linux_supports_catch_syscall,
linux_get_ipa_tdesc_idx,
+#if USE_THREAD_DB
+ thread_db_thread_handle,
+#else
+ NULL,
+#endif
};
#ifdef HAVE_LINUX_REGSETS
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 6328da0..85bb8ca 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -26,6 +26,7 @@
/* Included for ptrace type definitions. */
#include "nat/linux-ptrace.h"
#include "target/waitstatus.h" /* For enum target_stop_reason. */
+#include "tracepoint.h"
#define PTRACE_XFER_TYPE long
@@ -251,7 +252,7 @@ struct linux_target_ops
extern struct linux_target_ops the_low_target;
-#define get_thread_lwp(thr) ((struct lwp_info *) (inferior_target_data (thr)))
+#define get_thread_lwp(thr) ((struct lwp_info *) (thread_target_data (thr)))
#define get_lwp_thread(lwp) ((lwp)->thread)
/* This struct is recorded in the target_data field of struct thread_info.
@@ -353,12 +354,11 @@ struct lwp_info
and then processed and cleared in linux_resume_one_lwp. */
struct thread_resume *resume;
- /* True if it is known that this lwp is presently collecting a fast
- tracepoint (it is in the jump pad or in some code that will
- return to the jump pad. Normally, we won't care about this, but
- we will if a signal arrives to this lwp while it is
- collecting. */
- int collecting_fast_tracepoint;
+ /* Information bout this lwp's fast tracepoint collection status (is it
+ currently stopped in the jump pad, and if so, before or at/after the
+ relocated instruction). Normally, we won't care about this, but we will
+ if a signal arrives to this lwp while it is collecting. */
+ fast_tpoint_collect_result collecting_fast_tracepoint;
/* If this is non-zero, it points to a chain of signals which need
to be reported to GDB. These were deferred because the thread
@@ -374,6 +374,9 @@ struct lwp_info
/* The thread handle, used for e.g. TLS access. Only valid if
THREAD_KNOWN is set. */
td_thrhandle_t th;
+
+ /* The pthread_t handle. */
+ thread_t thread_handle;
#endif
/* Arch-specific additions. */
@@ -410,4 +413,12 @@ int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
CORE_ADDR load_module, CORE_ADDR *address);
int thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp);
+/* Called from linux-low.c when a clone event is detected. Upon entry,
+ both the clone and the parent should be stopped. This function does
+ whatever is required have the clone under thread_db's control. */
+
+void thread_db_notice_clone (struct process_info *proc, ptid_t lwp);
+
+bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len);
+
extern int have_ptrace_getregset;
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index b39026c..49f6b2d 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -757,7 +757,7 @@ x86_linux_read_description (void)
{
have_ptrace_getfpxregs = 0;
have_ptrace_getregset = 0;
- return tdesc_i386_mmx_linux;
+ return i386_linux_read_description (X86_XSTATE_X87);
}
else
have_ptrace_getfpxregs = 1;
@@ -809,7 +809,7 @@ x86_linux_read_description (void)
/* Check the native XCR0 only if PTRACE_GETREGSET is available. */
xcr0_features = (have_ptrace_getregset
- && (xcr0 & X86_XSTATE_ALL_MASK));
+ && (xcr0 & X86_XSTATE_ALL_MASK));
if (xcr0_features)
x86_xcr0 = xcr0;
@@ -817,103 +817,35 @@ x86_linux_read_description (void)
if (machine == EM_X86_64)
{
#ifdef __x86_64__
- if (is_elf64)
- {
- if (xcr0_features)
- {
- switch (xcr0 & X86_XSTATE_ALL_MASK)
- {
- case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
- return tdesc_amd64_avx_mpx_avx512_pku_linux;
-
- case X86_XSTATE_AVX_AVX512_MASK:
- return tdesc_amd64_avx_avx512_linux;
-
- case X86_XSTATE_AVX_MPX_MASK:
- return tdesc_amd64_avx_mpx_linux;
-
- case X86_XSTATE_MPX_MASK:
- return tdesc_amd64_mpx_linux;
+ const target_desc *tdesc = NULL;
- case X86_XSTATE_AVX_MASK:
- return tdesc_amd64_avx_linux;
-
- default:
- return tdesc_amd64_linux;
- }
- }
- else
- return tdesc_amd64_linux;
- }
- else
+ if (xcr0_features)
{
- if (xcr0_features)
- {
- switch (xcr0 & X86_XSTATE_ALL_MASK)
- {
- case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
- /* No x32 MPX and PKU, fall back to avx_avx512. */
- return tdesc_x32_avx_avx512_linux;
-
- case X86_XSTATE_AVX_AVX512_MASK:
- return tdesc_x32_avx_avx512_linux;
-
- case X86_XSTATE_MPX_MASK: /* No MPX on x32. */
- case X86_XSTATE_AVX_MASK:
- return tdesc_x32_avx_linux;
-
- default:
- return tdesc_x32_linux;
- }
- }
- else
- return tdesc_x32_linux;
+ tdesc = amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK,
+ !is_elf64);
}
+
+ if (tdesc == NULL)
+ tdesc = amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64);
+ return tdesc;
#endif
}
else
{
- if (xcr0_features)
- {
- switch (xcr0 & X86_XSTATE_ALL_MASK)
- {
- case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
- return tdesc_i386_avx_mpx_avx512_pku_linux;
-
- case (X86_XSTATE_AVX_AVX512_MASK):
- return tdesc_i386_avx_avx512_linux;
+ const target_desc *tdesc = NULL;
- case (X86_XSTATE_MPX_MASK):
- return tdesc_i386_mpx_linux;
-
- case (X86_XSTATE_AVX_MPX_MASK):
- return tdesc_i386_avx_mpx_linux;
+ if (xcr0_features)
+ tdesc = i386_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK);
- case (X86_XSTATE_AVX_MASK):
- return tdesc_i386_avx_linux;
+ if (tdesc == NULL)
+ tdesc = i386_linux_read_description (X86_XSTATE_SSE);
- default:
- return tdesc_i386_linux;
- }
- }
- else
- return tdesc_i386_linux;
+ return tdesc;
}
gdb_assert_not_reached ("failed to return tdesc");
}
-/* Callback for find_inferior. Stops iteration when a thread with a
- given PID is found. */
-
-static int
-same_process_callback (struct inferior_list_entry *entry, void *data)
-{
- int pid = *(int *) data;
-
- return (ptid_get_pid (entry->id) == pid);
-}
-
/* Callback for for_each_inferior. Calls the arch_setup routine for
each process. */
@@ -923,9 +855,7 @@ x86_arch_setup_process_callback (struct inferior_list_entry *entry)
int pid = ptid_get_pid (entry->id);
/* Look up any thread of this processes. */
- current_thread
- = (struct thread_info *) find_inferior (&all_threads,
- same_process_callback, &pid);
+ current_thread = find_any_thread_of_pid (pid);
the_low_target.arch_setup ();
}
@@ -2897,37 +2827,13 @@ x86_get_ipa_tdesc_idx (void)
const struct target_desc *tdesc = regcache->tdesc;
#ifdef __x86_64__
- if (tdesc == tdesc_amd64_linux || tdesc == tdesc_amd64_linux_no_xml
- || tdesc == tdesc_x32_linux)
- return X86_TDESC_SSE;
- if (tdesc == tdesc_amd64_avx_linux || tdesc == tdesc_x32_avx_linux)
- return X86_TDESC_AVX;
- if (tdesc == tdesc_amd64_mpx_linux)
- return X86_TDESC_MPX;
- if (tdesc == tdesc_amd64_avx_mpx_linux)
- return X86_TDESC_AVX_MPX;
- if (tdesc == tdesc_amd64_avx_mpx_avx512_pku_linux || tdesc == tdesc_x32_avx_avx512_linux)
- return X86_TDESC_AVX_MPX_AVX512_PKU;
- if (tdesc == tdesc_amd64_avx_avx512_linux)
- return X86_TDESC_AVX_AVX512;
+ return amd64_get_ipa_tdesc_idx (tdesc);
#endif
- if (tdesc == tdesc_i386_mmx_linux)
- return X86_TDESC_MMX;
- if (tdesc == tdesc_i386_linux || tdesc == tdesc_i386_linux_no_xml)
+ if (tdesc == tdesc_i386_linux_no_xml)
return X86_TDESC_SSE;
- if (tdesc == tdesc_i386_avx_linux)
- return X86_TDESC_AVX;
- if (tdesc == tdesc_i386_mpx_linux)
- return X86_TDESC_MPX;
- if (tdesc == tdesc_i386_avx_mpx_linux)
- return X86_TDESC_AVX_MPX;
- if (tdesc == tdesc_i386_avx_mpx_avx512_pku_linux)
- return X86_TDESC_AVX_MPX_AVX512_PKU;
- if (tdesc == tdesc_i386_avx_avx512_linux)
- return X86_TDESC_AVX_AVX512;
- return 0;
+ return i386_get_ipa_tdesc_idx (tdesc);
}
/* This is initialized assuming an amd64 target.
@@ -2981,31 +2887,20 @@ initialize_low_arch (void)
{
/* Initialize the Linux target descriptions. */
#ifdef __x86_64__
- init_registers_amd64_linux ();
- init_registers_amd64_avx_linux ();
- init_registers_amd64_mpx_linux ();
- init_registers_amd64_avx_mpx_linux ();
- init_registers_amd64_avx_avx512_linux ();
- init_registers_amd64_avx_mpx_avx512_pku_linux ();
-
- init_registers_x32_linux ();
- init_registers_x32_avx_linux ();
- init_registers_x32_avx_avx512_linux ();
-
- tdesc_amd64_linux_no_xml = XNEW (struct target_desc);
- copy_target_description (tdesc_amd64_linux_no_xml, tdesc_amd64_linux);
+ tdesc_amd64_linux_no_xml = allocate_target_description ();
+ copy_target_description (tdesc_amd64_linux_no_xml,
+ amd64_linux_read_description (X86_XSTATE_SSE_MASK,
+ false));
tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml;
#endif
- init_registers_i386_linux ();
- init_registers_i386_mmx_linux ();
- init_registers_i386_avx_linux ();
- init_registers_i386_mpx_linux ();
- init_registers_i386_avx_mpx_linux ();
- init_registers_i386_avx_avx512_linux ();
- init_registers_i386_avx_mpx_avx512_pku_linux ();
-
- tdesc_i386_linux_no_xml = XNEW (struct target_desc);
- copy_target_description (tdesc_i386_linux_no_xml, tdesc_i386_linux);
+
+#if GDB_SELF_TEST
+ initialize_low_tdesc ();
+#endif
+
+ tdesc_i386_linux_no_xml = allocate_target_description ();
+ copy_target_description (tdesc_i386_linux_no_xml,
+ i386_linux_read_description (X86_XSTATE_SSE_MASK));
tdesc_i386_linux_no_xml->xmltarget = xmltarget_i386_linux_no_xml;
initialize_regsets_info (&x86_regsets_info);
diff --git a/gdb/gdbserver/linux-x86-tdesc-selftest.c b/gdb/gdbserver/linux-x86-tdesc-selftest.c
new file mode 100644
index 0000000..c5ab2ab
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-tdesc-selftest.c
@@ -0,0 +1,183 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "server.h"
+#include "linux-x86-tdesc.h"
+#include "tdesc.h"
+#include "common/selftest.h"
+#include "x86-xstate.h"
+
+/* Defined in auto-generated file i386-linux.c. */
+void init_registers_i386_linux (void);
+extern const struct target_desc *tdesc_i386_linux;
+
+/* Defined in auto-generated file i386-mmx-linux.c. */
+void init_registers_i386_mmx_linux (void);
+extern const struct target_desc *tdesc_i386_mmx_linux;
+
+/* Defined in auto-generated file i386-avx-linux.c. */
+void init_registers_i386_avx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_linux;
+
+/* Defined in auto-generated file i386-avx-mpx-linux.c. */
+void init_registers_i386_avx_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_mpx_linux;
+
+/* Defined in auto-generated file i386-avx-avx512-linux.c. */
+void init_registers_i386_avx_avx512_linux (void);
+extern const struct target_desc *tdesc_i386_avx_avx512_linux;
+
+/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */
+void init_registers_i386_avx_mpx_avx512_pku_linux (void);
+extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
+
+/* Defined in auto-generated file i386-mpx-linux.c. */
+void init_registers_i386_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_mpx_linux;
+
+#ifdef __x86_64__
+
+/* Defined in auto-generated file amd64-linux.c. */
+void init_registers_amd64_linux (void);
+extern const struct target_desc *tdesc_amd64_linux;
+
+/* Defined in auto-generated file amd64-avx-linux.c. */
+void init_registers_amd64_avx_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_linux;
+
+/* Defined in auto-generated file amd64-avx-avx512-linux.c. */
+void init_registers_amd64_avx_avx512_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_avx512_linux;
+
+/* Defined in auto-generated file amd64-avx-mpx-avx512-pku-linux.c. */
+void init_registers_amd64_avx_mpx_avx512_pku_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux;
+
+/* Defined in auto-generated file amd64-avx-mpx-linux.c. */
+void init_registers_amd64_avx_mpx_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_mpx_linux;
+
+/* Defined in auto-generated file amd64-mpx-linux.c. */
+void init_registers_amd64_mpx_linux (void);
+extern const struct target_desc *tdesc_amd64_mpx_linux;
+
+/* Defined in auto-generated file x32-linux.c. */
+void init_registers_x32_linux (void);
+extern const struct target_desc *tdesc_x32_linux;
+
+/* Defined in auto-generated file x32-avx-linux.c. */
+void init_registers_x32_avx_linux (void);
+extern const struct target_desc *tdesc_x32_avx_linux;
+
+/* Defined in auto-generated file x32-avx-avx512-linux.c. */
+void init_registers_x32_avx_avx512_linux (void);
+extern const struct target_desc *tdesc_x32_avx_avx512_linux;
+
+#endif
+
+namespace selftests {
+namespace tdesc {
+static void
+i386_tdesc_test ()
+{
+ struct
+ {
+ unsigned int mask;
+ const target_desc *tdesc;
+ } tdesc_tests[] = {
+ { X86_XSTATE_X87, tdesc_i386_mmx_linux },
+ { X86_XSTATE_SSE_MASK, tdesc_i386_linux },
+ { X86_XSTATE_AVX_MASK, tdesc_i386_avx_linux },
+ { X86_XSTATE_MPX_MASK, tdesc_i386_mpx_linux },
+ { X86_XSTATE_AVX_MPX_MASK, tdesc_i386_avx_mpx_linux },
+ { X86_XSTATE_AVX_AVX512_MASK, tdesc_i386_avx_avx512_linux },
+ { X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, tdesc_i386_avx_mpx_avx512_pku_linux }
+ };
+
+ for (auto &elem : tdesc_tests)
+ {
+ const target_desc *tdesc = i386_linux_read_description (elem.mask);
+
+ SELF_CHECK (*tdesc == *elem.tdesc);
+ }
+}
+
+#ifdef __x86_64__
+
+static void
+amd64_tdesc_test ()
+{
+ struct
+ {
+ unsigned int mask;
+ const target_desc *tdesc[2];
+ } tdesc_tests[] = {
+ { X86_XSTATE_SSE_MASK, { tdesc_amd64_linux, tdesc_x32_linux } },
+ { X86_XSTATE_AVX_MASK, { tdesc_amd64_avx_linux, tdesc_x32_avx_linux } },
+ { X86_XSTATE_MPX_MASK, { tdesc_amd64_mpx_linux, tdesc_x32_avx_linux } },
+ { X86_XSTATE_AVX_MPX_MASK, { tdesc_amd64_avx_mpx_linux,
+ tdesc_x32_avx_linux } },
+ { X86_XSTATE_AVX_AVX512_MASK, { tdesc_amd64_avx_avx512_linux,
+ tdesc_x32_avx_avx512_linux } },
+ { X86_XSTATE_AVX_MPX_AVX512_PKU_MASK,
+ { tdesc_amd64_avx_mpx_avx512_pku_linux, tdesc_x32_avx_avx512_linux } },
+ };
+
+ for (auto &elem : tdesc_tests)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ const target_desc *tdesc = amd64_linux_read_description (elem.mask,
+ i);
+
+ SELF_CHECK (*tdesc == *elem.tdesc[i]);
+ }
+ }
+}
+
+#endif
+}
+} // namespace selftests
+
+void
+initialize_low_tdesc ()
+{
+ init_registers_i386_linux ();
+ init_registers_i386_mmx_linux ();
+ init_registers_i386_avx_linux ();
+ init_registers_i386_mpx_linux ();
+ init_registers_i386_avx_mpx_linux ();
+ init_registers_i386_avx_avx512_linux ();
+ init_registers_i386_avx_mpx_avx512_pku_linux ();
+
+ selftests::register_test ("i386-tdesc", selftests::tdesc::i386_tdesc_test);
+
+#ifdef __x86_64__
+ init_registers_x32_linux ();
+ init_registers_x32_avx_linux ();
+ init_registers_x32_avx_avx512_linux ();
+
+ init_registers_amd64_linux ();
+ init_registers_amd64_avx_linux ();
+ init_registers_amd64_mpx_linux ();
+ init_registers_amd64_avx_mpx_linux ();
+ init_registers_amd64_avx_avx512_linux ();
+ init_registers_amd64_avx_mpx_avx512_pku_linux ();
+
+ selftests::register_test ("amd64-tdesc", selftests::tdesc::amd64_tdesc_test);
+#endif
+}
diff --git a/gdb/gdbserver/linux-x86-tdesc.c b/gdb/gdbserver/linux-x86-tdesc.c
new file mode 100644
index 0000000..d27068c
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-tdesc.c
@@ -0,0 +1,173 @@
+/* GNU/Linux/x86-64 specific target description, for the remote server
+ for GDB.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "server.h"
+#include "tdesc.h"
+#include "linux-x86-tdesc.h"
+#include "arch/i386.h"
+#include "common/x86-xstate.h"
+#ifdef __x86_64__
+#include "arch/amd64.h"
+#endif
+
+/* Return the right x86_linux_tdesc index for a given XCR0. Return
+ X86_TDESC_LAST if can't find a match. */
+
+static enum x86_linux_tdesc
+xcr0_to_tdesc_idx (uint64_t xcr0, bool is_x32)
+{
+ if (xcr0 & X86_XSTATE_PKRU)
+ {
+ if (is_x32)
+ {
+ /* No x32 MPX and PKU, fall back to avx_avx512. */
+ return X86_TDESC_AVX_AVX512;
+ }
+ else
+ return X86_TDESC_AVX_MPX_AVX512_PKU;
+ }
+ else if (xcr0 & X86_XSTATE_AVX512)
+ return X86_TDESC_AVX_AVX512;
+ else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
+ {
+ if (is_x32) /* No MPX on x32. */
+ return X86_TDESC_AVX;
+ else
+ return X86_TDESC_AVX_MPX;
+ }
+ else if (xcr0 & X86_XSTATE_MPX)
+ {
+ if (is_x32) /* No MPX on x32. */
+ return X86_TDESC_AVX;
+ else
+ return X86_TDESC_MPX;
+ }
+ else if (xcr0 & X86_XSTATE_AVX)
+ return X86_TDESC_AVX;
+ else if (xcr0 & X86_XSTATE_SSE)
+ return X86_TDESC_SSE;
+ else if (xcr0 & X86_XSTATE_X87)
+ return X86_TDESC_MMX;
+ else
+ return X86_TDESC_LAST;
+}
+
+static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
+
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+
+/* Return the target description according to XCR0. */
+
+const struct target_desc *
+i386_linux_read_description (uint64_t xcr0)
+{
+ enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, false);
+
+ if (idx == X86_TDESC_LAST)
+ return NULL;
+
+ struct target_desc **tdesc = &i386_tdescs[idx];
+
+ if (*tdesc == NULL)
+ {
+ *tdesc = i386_create_target_description (xcr0, true);
+
+ init_target_desc (*tdesc);
+
+#ifndef IN_PROCESS_AGENT
+ static const char *expedite_regs_i386[] = { "ebp", "esp", "eip", NULL };
+ (*tdesc)->expedite_regs = expedite_regs_i386;
+#endif
+ }
+
+ return *tdesc;;
+}
+#endif
+
+#ifdef __x86_64__
+
+static target_desc *amd64_tdescs[X86_TDESC_LAST] = { };
+static target_desc *x32_tdescs[X86_TDESC_LAST] = { };
+
+const struct target_desc *
+amd64_linux_read_description (uint64_t xcr0, bool is_x32)
+{
+ enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, is_x32);
+
+ if (idx == X86_TDESC_LAST)
+ return NULL;
+
+ struct target_desc **tdesc = NULL;
+
+ if (is_x32)
+ tdesc = &x32_tdescs[idx];
+ else
+ tdesc = &amd64_tdescs[idx];
+
+ if (*tdesc == NULL)
+ {
+ *tdesc = amd64_create_target_description (xcr0, is_x32, true);
+
+ init_target_desc (*tdesc);
+
+#ifndef IN_PROCESS_AGENT
+ static const char *expedite_regs_amd64[] = { "rbp", "rsp", "rip", NULL };
+ (*tdesc)->expedite_regs = expedite_regs_amd64;
+#endif
+ }
+ return *tdesc;
+}
+
+#endif
+
+#ifndef IN_PROCESS_AGENT
+
+int
+i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
+{
+ for (int i = 0; i < X86_TDESC_LAST; i++)
+ {
+ if (tdesc == i386_tdescs[i])
+ return i;
+ }
+
+ /* If none tdesc is found, return the one with minimum features. */
+ return X86_TDESC_MMX;
+}
+
+#if defined __x86_64__
+int
+amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc)
+{
+ for (int i = 0; i < X86_TDESC_LAST; i++)
+ {
+ if (tdesc == amd64_tdescs[i])
+ return i;
+ }
+ for (int i = 0; i < X86_TDESC_LAST; i++)
+ {
+ if (tdesc == x32_tdescs[i])
+ return i;
+ }
+
+ return X86_TDESC_SSE;
+}
+
+#endif
+#endif
diff --git a/gdb/gdbserver/linux-x86-tdesc.h b/gdb/gdbserver/linux-x86-tdesc.h
index bbe4078..a6dc330 100644
--- a/gdb/gdbserver/linux-x86-tdesc.h
+++ b/gdb/gdbserver/linux-x86-tdesc.h
@@ -30,78 +30,24 @@ enum x86_linux_tdesc {
X86_TDESC_AVX_MPX = 4,
X86_TDESC_AVX_AVX512 = 5,
X86_TDESC_AVX_MPX_AVX512_PKU = 6,
+ X86_TDESC_LAST = 7,
};
-#ifdef __x86_64__
-
-#if defined __LP64__ || !defined IN_PROCESS_AGENT
-/* Defined in auto-generated file amd64-linux.c. */
-void init_registers_amd64_linux (void);
-extern const struct target_desc *tdesc_amd64_linux;
-
-/* Defined in auto-generated file amd64-avx-linux.c. */
-void init_registers_amd64_avx_linux (void);
-extern const struct target_desc *tdesc_amd64_avx_linux;
-
-/* Defined in auto-generated file amd64-avx-avx512-linux.c. */
-void init_registers_amd64_avx_avx512_linux (void);
-extern const struct target_desc *tdesc_amd64_avx_avx512_linux;
-
-/* Defined in auto-generated file amd64-avx-mpx-avx512-pku-linux.c. */
-void init_registers_amd64_avx_mpx_avx512_pku_linux (void);
-extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux;
-
-/* Defined in auto-generated file amd64-avx-mpx-linux.c. */
-void init_registers_amd64_avx_mpx_linux (void);
-extern const struct target_desc *tdesc_amd64_avx_mpx_linux;
-
-/* Defined in auto-generated file amd64-mpx-linux.c. */
-void init_registers_amd64_mpx_linux (void);
-extern const struct target_desc *tdesc_amd64_mpx_linux;
-#endif
-
-#if defined __ILP32__ || !defined IN_PROCESS_AGENT
-/* Defined in auto-generated file x32-linux.c. */
-void init_registers_x32_linux (void);
-extern const struct target_desc *tdesc_x32_linux;
-
-/* Defined in auto-generated file x32-avx-linux.c. */
-void init_registers_x32_avx_linux (void);
-extern const struct target_desc *tdesc_x32_avx_linux;
-
-/* Defined in auto-generated file x32-avx-avx512-linux.c. */
-void init_registers_x32_avx_avx512_linux (void);
-extern const struct target_desc *tdesc_x32_avx_avx512_linux;
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc);
#endif
+#if defined __x86_64__ && !defined IN_PROCESS_AGENT
+int amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc);
#endif
-#if defined __i386__ || !defined IN_PROCESS_AGENT
-/* Defined in auto-generated file i386-linux.c. */
-void init_registers_i386_linux (void);
-extern const struct target_desc *tdesc_i386_linux;
-
-/* Defined in auto-generated file i386-mmx-linux.c. */
-void init_registers_i386_mmx_linux (void);
-extern const struct target_desc *tdesc_i386_mmx_linux;
-
-/* Defined in auto-generated file i386-avx-linux.c. */
-void init_registers_i386_avx_linux (void);
-extern const struct target_desc *tdesc_i386_avx_linux;
+const struct target_desc *i386_get_ipa_tdesc (int idx);
-/* Defined in auto-generated file i386-avx-mpx-linux.c. */
-void init_registers_i386_avx_mpx_linux (void);
-extern const struct target_desc *tdesc_i386_avx_mpx_linux;
-
-/* Defined in auto-generated file i386-avx-avx512-linux.c. */
-void init_registers_i386_avx_avx512_linux (void);
-extern const struct target_desc *tdesc_i386_avx_avx512_linux;
+#ifdef __x86_64__
+const struct target_desc *amd64_linux_read_description (uint64_t xcr0,
+ bool is_x32);
+#endif
-/* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */
-void init_registers_i386_avx_mpx_avx512_pku_linux (void);
-extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux;
+const struct target_desc *i386_linux_read_description (uint64_t xcr0);
-/* Defined in auto-generated file i386-mpx-linux.c. */
-void init_registers_i386_mpx_linux (void);
-extern const struct target_desc *tdesc_i386_mpx_linux;
-#endif
+void initialize_low_tdesc ();
diff --git a/gdb/gdbserver/lynx-i386-low.c b/gdb/gdbserver/lynx-i386-low.c
index 64e6c0f..57181d6 100644
--- a/gdb/gdbserver/lynx-i386-low.c
+++ b/gdb/gdbserver/lynx-i386-low.c
@@ -19,6 +19,8 @@
#include "lynx-low.h"
#include <limits.h>
#include <sys/ptrace.h>
+#include "x86-xstate.h"
+#include "arch/i386.h"
/* The following two typedefs are defined in a .h file which is not
in the standard include path (/sys/include/family/x86/ucontext.h),
@@ -118,10 +120,6 @@ enum lynx_i386_gdb_regnum
I386_SENTINEL_REGUM
};
-/* Defined in auto-generated file i386.c. */
-extern void init_registers_i386 (void);
-extern const struct target_desc *tdesc_i386;
-
/* The fill_function for the general-purpose register set. */
static void
@@ -295,8 +293,7 @@ lynx_i386_store_fpregset (struct regcache *regcache, const char *buf)
static void
lynx_i386_arch_setup (void)
{
- init_registers_i386 ();
- lynx_tdesc = tdesc_i386;
+ lynx_tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
}
/* Description of all the x86-lynx register sets. */
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index 77f570e..f074dd5 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -350,7 +350,7 @@ lynx_resume (struct thread_resume *resume_info, size_t n)
the moment we resume its execution for the first time. It is
fine to use the current_thread's ptid in those cases. */
if (ptid_equal (ptid, minus_one_ptid))
- ptid = thread_to_gdb_id (current_thread);
+ ptid = ptid_of (current_thread);
regcache_invalidate_pid (ptid_get_pid (ptid));
@@ -423,7 +423,7 @@ lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
ptid_t new_ptid;
if (ptid_equal (ptid, minus_one_ptid))
- pid = lynx_ptid_get_pid (thread_to_gdb_id (current_thread));
+ pid = lynx_ptid_get_pid (ptid_of (current_thread));
else
pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
@@ -612,7 +612,7 @@ static void
lynx_fetch_registers (struct regcache *regcache, int regno)
{
struct lynx_regset_info *regset = lynx_target_regsets;
- ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
+ ptid_t inferior_ptid = ptid_of (current_thread);
lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
@@ -637,7 +637,7 @@ static void
lynx_store_registers (struct regcache *regcache, int regno)
{
struct lynx_regset_info *regset = lynx_target_regsets;
- ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
+ ptid_t inferior_ptid = ptid_of (current_thread);
lynx_debug ("lynx_store_registers (regno = %d)", regno);
@@ -673,7 +673,7 @@ lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
int buf;
const int xfer_size = sizeof (buf);
CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
- ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
+ ptid_t inferior_ptid = ptid_of (current_thread);
while (addr < memaddr + len)
{
@@ -706,7 +706,7 @@ lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
int buf;
const int xfer_size = sizeof (buf);
CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
- ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
+ ptid_t inferior_ptid = ptid_of (current_thread);
while (addr < memaddr + len)
{
@@ -742,7 +742,7 @@ lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
static void
lynx_request_interrupt (void)
{
- ptid_t inferior_ptid = thread_to_gdb_id (get_first_thread ());
+ ptid_t inferior_ptid = ptid_of (get_first_thread ());
kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
}
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index a5f1543..a8c981a 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -620,7 +620,6 @@ nto_fetch_registers (struct regcache *regcache, int regno)
{
int regsize;
procfs_greg greg;
- ptid_t ptid;
TRACE ("%s (regno=%d)\n", __func__, regno);
if (regno >= the_low_target.num_regs)
@@ -631,7 +630,7 @@ nto_fetch_registers (struct regcache *regcache, int regno)
TRACE ("current_thread is NULL\n");
return;
}
- ptid = thread_to_gdb_id (current_thread);
+ ptid_t ptid = ptid_of (current_thread);
if (!nto_set_thread (ptid))
return;
@@ -669,7 +668,6 @@ nto_store_registers (struct regcache *regcache, int regno)
{
procfs_greg greg;
int err;
- ptid_t ptid;
TRACE ("%s (regno:%d)\n", __func__, regno);
@@ -678,7 +676,7 @@ nto_store_registers (struct regcache *regcache, int regno)
TRACE ("current_thread is NULL\n");
return;
}
- ptid = thread_to_gdb_id (current_thread);
+ ptid_t ptid = ptid_of (current_thread);
if (!nto_set_thread (ptid))
return;
@@ -867,9 +865,7 @@ nto_stopped_by_watchpoint (void)
TRACE ("%s\n", __func__);
if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
{
- ptid_t ptid;
-
- ptid = thread_to_gdb_id (current_thread);
+ ptid_t ptid = ptid_of (current_thread);
if (nto_set_thread (ptid))
{
const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
@@ -899,9 +895,7 @@ nto_stopped_data_address (void)
TRACE ("%s\n", __func__);
if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
{
- ptid_t ptid;
-
- ptid = thread_to_gdb_id (current_thread);
+ ptid_t ptid = ptid_of (current_thread);
if (nto_set_thread (ptid))
{
diff --git a/gdb/gdbserver/nto-x86-low.c b/gdb/gdbserver/nto-x86-low.c
index 901ac7b..cfa5993 100644
--- a/gdb/gdbserver/nto-x86-low.c
+++ b/gdb/gdbserver/nto-x86-low.c
@@ -23,12 +23,8 @@
#include "regcache.h"
#include <x86/context.h>
-
-
-/* Defined in auto-generated build-time file gdb/gdbserver/i386.c. */
-extern void init_registers_i386 ();
-extern struct reg *regs_i386;
-extern const struct target_desc *tdesc_i386;
+#include "x86-xstate.h"
+#include "arch/i386.h"
const unsigned char x86_breakpoint[] = { 0xCC };
#define x86_breakpoint_len 1
@@ -90,9 +86,8 @@ nto_x86_register_offset (int gdbregno)
static void
nto_x86_arch_setup (void)
{
- init_registers_i386 ();
the_low_target.num_regs = 16;
- nto_tdesc = tdesc_i386;
+ nto_tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
}
struct nto_target_ops the_low_target =
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 0f16f60..7548091 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -28,7 +28,7 @@ get_thread_regcache (struct thread_info *thread, int fetch)
{
struct regcache *regcache;
- regcache = inferior_regcache_data (thread);
+ regcache = thread_regcache_data (thread);
/* Threads' regcaches are created lazily, because biarch targets add
the main thread/lwp before seeing it stop for the first time, and
@@ -44,7 +44,7 @@ get_thread_regcache (struct thread_info *thread, int fetch)
gdb_assert (proc->tdesc != NULL);
regcache = new_register_cache (proc->tdesc);
- set_inferior_regcache_data (thread, regcache);
+ set_thread_regcache_data (thread, regcache);
}
if (fetch && regcache->registers_valid == 0)
@@ -54,7 +54,7 @@ get_thread_regcache (struct thread_info *thread, int fetch)
current_thread = thread;
/* Invalidate all registers, to prevent stale left-overs. */
memset (regcache->register_status, REG_UNAVAILABLE,
- regcache->tdesc->num_registers);
+ regcache->tdesc->reg_defs.size ());
fetch_inferior_registers (regcache, -1);
current_thread = saved_thread;
regcache->registers_valid = 1;
@@ -76,7 +76,7 @@ regcache_invalidate_thread (struct thread_info *thread)
{
struct regcache *regcache;
- regcache = inferior_regcache_data (thread);
+ regcache = thread_regcache_data (thread);
if (regcache == NULL)
return;
@@ -145,9 +145,9 @@ init_register_cache (struct regcache *regcache,
= (unsigned char *) xcalloc (1, tdesc->registers_size);
regcache->registers_owned = 1;
regcache->register_status
- = (unsigned char *) xmalloc (tdesc->num_registers);
+ = (unsigned char *) xmalloc (tdesc->reg_defs.size ());
memset ((void *) regcache->register_status, REG_UNAVAILABLE,
- tdesc->num_registers);
+ tdesc->reg_defs.size ());
#else
gdb_assert_not_reached ("can't allocate memory from the heap");
#endif
@@ -204,7 +204,7 @@ regcache_cpy (struct regcache *dst, struct regcache *src)
#ifndef IN_PROCESS_AGENT
if (dst->register_status != NULL && src->register_status != NULL)
memcpy (dst->register_status, src->register_status,
- src->tdesc->num_registers);
+ src->tdesc->reg_defs.size ());
#endif
dst->registers_valid = src->registers_valid;
}
@@ -217,10 +217,11 @@ registers_to_string (struct regcache *regcache, char *buf)
{
unsigned char *registers = regcache->registers;
const struct target_desc *tdesc = regcache->tdesc;
- int i;
- for (i = 0; i < tdesc->num_registers; i++)
+ for (int i = 0; i < tdesc->reg_defs.size (); ++i)
{
+ struct reg *reg = tdesc->reg_defs[i];
+
if (regcache->register_status[i] == REG_VALID)
{
bin2hex (registers, buf, register_size (tdesc, i));
@@ -256,34 +257,36 @@ registers_from_string (struct regcache *regcache, char *buf)
int
find_regno (const struct target_desc *tdesc, const char *name)
{
- int i;
+ for (int i = 0; i < tdesc->reg_defs.size (); ++i)
+ {
+ struct reg *reg = tdesc->reg_defs[i];
- for (i = 0; i < tdesc->num_registers; i++)
- if (strcmp (name, tdesc->reg_defs[i].name) == 0)
- return i;
+ if (strcmp (name, reg->name) == 0)
+ return i;
+ }
internal_error (__FILE__, __LINE__, "Unknown register %s requested",
name);
}
+#endif
+
struct reg *
find_register_by_number (const struct target_desc *tdesc, int n)
{
- return &tdesc->reg_defs[n];
+ return tdesc->reg_defs[n];
}
-#endif
-
#ifndef IN_PROCESS_AGENT
static void
free_register_cache_thread (struct thread_info *thread)
{
- struct regcache *regcache = inferior_regcache_data (thread);
+ struct regcache *regcache = thread_regcache_data (thread);
if (regcache != NULL)
{
regcache_invalidate_thread (thread);
free_register_cache (regcache);
- set_inferior_regcache_data (thread, NULL);
+ set_thread_regcache_data (thread, NULL);
}
}
@@ -312,7 +315,7 @@ register_cache_size (const struct target_desc *tdesc)
int
register_size (const struct target_desc *tdesc, int n)
{
- return tdesc->reg_defs[n].size / 8;
+ return find_register_by_number (tdesc, n)->size / 8;
}
/* See common/common-regcache.h. */
@@ -326,7 +329,8 @@ regcache_register_size (const struct regcache *regcache, int n)
static unsigned char *
register_data (struct regcache *regcache, int n, int fetch)
{
- return regcache->registers + regcache->tdesc->reg_defs[n].offset / 8;
+ return (regcache->registers
+ + find_register_by_number (regcache->tdesc, n)->offset / 8);
}
/* Supply register N, whose contents are stored in BUF, to REGCACHE.
@@ -385,7 +389,7 @@ supply_regblock (struct regcache *regcache, const void *buf)
{
int i;
- for (i = 0; i < tdesc->num_registers; i++)
+ for (i = 0; i < tdesc->reg_defs.size (); i++)
regcache->register_status[i] = REG_VALID;
}
#endif
@@ -399,7 +403,7 @@ supply_regblock (struct regcache *regcache, const void *buf)
{
int i;
- for (i = 0; i < tdesc->num_registers; i++)
+ for (i = 0; i < tdesc->reg_defs.size (); i++)
regcache->register_status[i] = REG_UNAVAILABLE;
}
#endif
@@ -431,7 +435,8 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
int size;
gdb_assert (regcache != NULL);
- gdb_assert (regnum >= 0 && regnum < regcache->tdesc->num_registers);
+ gdb_assert (regnum >= 0
+ && regnum < regcache->tdesc->reg_defs.size ());
size = register_size (regcache->tdesc, regnum);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 3838351..f3eee31 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -40,6 +40,22 @@
#include "job-control.h"
#include "environ.h"
+#include "common/selftest.h"
+
+#define require_running_or_return(BUF) \
+ if (!target_running ()) \
+ { \
+ write_enn (BUF); \
+ return; \
+ }
+
+#define require_running_or_break(BUF) \
+ if (!target_running ()) \
+ { \
+ write_enn (BUF); \
+ break; \
+ }
+
/* The environment to pass to the inferior when creating it. */
static gdb_environ our_environ;
@@ -631,6 +647,67 @@ handle_general_set (char *own_buf)
return;
}
+ if (strcmp (own_buf, "QEnvironmentReset") == 0)
+ {
+ our_environ = gdb_environ::from_host_environ ();
+
+ write_ok (own_buf);
+ return;
+ }
+
+ if (startswith (own_buf, "QEnvironmentHexEncoded:"))
+ {
+ const char *p = own_buf + sizeof ("QEnvironmentHexEncoded:") - 1;
+ /* The final form of the environment variable. FINAL_VAR will
+ hold the 'VAR=VALUE' format. */
+ std::string final_var = hex2str (p);
+ std::string var_name, var_value;
+
+ if (remote_debug)
+ {
+ debug_printf (_("[QEnvironmentHexEncoded received '%s']\n"), p);
+ debug_printf (_("[Environment variable to be set: '%s']\n"),
+ final_var.c_str ());
+ debug_flush ();
+ }
+
+ size_t pos = final_var.find ('=');
+ if (pos == std::string::npos)
+ {
+ warning (_("Unexpected format for environment variable: '%s'"),
+ final_var.c_str ());
+ write_enn (own_buf);
+ return;
+ }
+
+ var_name = final_var.substr (0, pos);
+ var_value = final_var.substr (pos + 1, std::string::npos);
+
+ our_environ.set (var_name.c_str (), var_value.c_str ());
+
+ write_ok (own_buf);
+ return;
+ }
+
+ if (startswith (own_buf, "QEnvironmentUnset:"))
+ {
+ const char *p = own_buf + sizeof ("QEnvironmentUnset:") - 1;
+ std::string varname = hex2str (p);
+
+ if (remote_debug)
+ {
+ debug_printf (_("[QEnvironmentUnset received '%s']\n"), p);
+ debug_printf (_("[Environment variable to be unset: '%s']\n"),
+ varname.c_str ());
+ debug_flush ();
+ }
+
+ our_environ.unset (varname.c_str ());
+
+ write_ok (own_buf);
+ return;
+ }
+
if (strcmp (own_buf, "QStartNoAckMode") == 0)
{
if (remote_debug)
@@ -810,12 +887,14 @@ get_features_xml (const char *annex)
This variable is set up from the auto-generated
init_registers_... routine for the current target. */
- if (desc->xmltarget != NULL && strcmp (annex, "target.xml") == 0)
+ if (strcmp (annex, "target.xml") == 0)
{
- if (*desc->xmltarget == '@')
- return desc->xmltarget + 1;
+ const char *ret = tdesc_get_features_xml ((target_desc*) desc);
+
+ if (*ret == '@')
+ return ret + 1;
else
- annex = desc->xmltarget;
+ annex = ret;
}
#ifdef USE_XML
@@ -890,7 +969,7 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
res = prepare_to_access_memory ();
if (res == 0)
{
- if (set_desired_thread (1))
+ if (set_desired_thread ())
res = read_inferior_memory (memaddr, myaddr, len);
else
res = 1;
@@ -917,7 +996,7 @@ gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
ret = prepare_to_access_memory ();
if (ret == 0)
{
- if (set_desired_thread (1))
+ if (set_desired_thread ())
ret = write_inferior_memory (memaddr, myaddr, len);
else
ret = EIO;
@@ -1078,12 +1157,99 @@ handle_search_memory (char *own_buf, int packet_len)
free (pattern);
}
-#define require_running(BUF) \
- if (!target_running ()) \
- { \
- write_enn (BUF); \
- return; \
+/* Handle the "D" packet. */
+
+static void
+handle_detach (char *own_buf)
+{
+ require_running_or_return (own_buf);
+
+ int pid;
+
+ if (multi_process)
+ {
+ /* skip 'D;' */
+ pid = strtol (&own_buf[2], NULL, 16);
}
+ else
+ pid = ptid_get_pid (current_ptid);
+
+ if ((tracing && disconnected_tracing) || any_persistent_commands ())
+ {
+ struct process_info *process = find_process_pid (pid);
+
+ if (process == NULL)
+ {
+ write_enn (own_buf);
+ return;
+ }
+
+ if (tracing && disconnected_tracing)
+ fprintf (stderr,
+ "Disconnected tracing in effect, "
+ "leaving gdbserver attached to the process\n");
+
+ if (any_persistent_commands ())
+ fprintf (stderr,
+ "Persistent commands are present, "
+ "leaving gdbserver attached to the process\n");
+
+ /* Make sure we're in non-stop/async mode, so we we can both
+ wait for an async socket accept, and handle async target
+ events simultaneously. There's also no point either in
+ having the target stop all threads, when we're going to
+ pass signals down without informing GDB. */
+ if (!non_stop)
+ {
+ if (debug_threads)
+ debug_printf ("Forcing non-stop mode\n");
+
+ non_stop = 1;
+ start_non_stop (1);
+ }
+
+ process->gdb_detached = 1;
+
+ /* Detaching implicitly resumes all threads. */
+ target_continue_no_signal (minus_one_ptid);
+
+ write_ok (own_buf);
+ return;
+ }
+
+ fprintf (stderr, "Detaching from process %d\n", pid);
+ stop_tracing ();
+ if (detach_inferior (pid) != 0)
+ write_enn (own_buf);
+ else
+ {
+ discard_queued_stop_replies (pid_to_ptid (pid));
+ write_ok (own_buf);
+
+ if (extended_protocol || target_running ())
+ {
+ /* There is still at least one inferior remaining or
+ we are in extended mode, so don't terminate gdbserver,
+ and instead treat this like a normal program exit. */
+ last_status.kind = TARGET_WAITKIND_EXITED;
+ last_status.value.integer = 0;
+ last_ptid = pid_to_ptid (pid);
+
+ current_thread = NULL;
+ }
+ else
+ {
+ putpkt (own_buf);
+ remote_close ();
+
+ /* If we are attached, then we can exit. Otherwise, we
+ need to hang around doing nothing, until the child is
+ gone. */
+ join_inferior (pid);
+ exit (0);
+ }
+ }
+}
/* Parse options to --debug-format= and "monitor set debug-format".
ARG is the text after "--debug-format=" or "monitor set debug-format".
@@ -1343,45 +1509,18 @@ handle_qxfer_features (const char *annex,
}
/* Worker routine for handle_qxfer_libraries.
- Add to the length pointed to by ARG a conservative estimate of the
- length needed to transmit the file name of INF. */
-
-static void
-accumulate_file_name_length (struct inferior_list_entry *inf, void *arg)
-{
- struct dll_info *dll = (struct dll_info *) inf;
- unsigned int *total_len = (unsigned int *) arg;
-
- /* Over-estimate the necessary memory. Assume that every character
- in the library name must be escaped. */
- *total_len += 128 + 6 * strlen (dll->name);
-}
-
-/* Worker routine for handle_qxfer_libraries.
Emit the XML to describe the library in INF. */
static void
emit_dll_description (struct inferior_list_entry *inf, void *arg)
{
struct dll_info *dll = (struct dll_info *) inf;
- char **p_ptr = (char **) arg;
- char *p = *p_ptr;
- char *name;
-
- strcpy (p, " <library name=\"");
- p = p + strlen (p);
- name = xml_escape_text (dll->name);
- strcpy (p, name);
- free (name);
- p = p + strlen (p);
- strcpy (p, "\"><segment address=\"");
- p = p + strlen (p);
- sprintf (p, "0x%lx", (long) dll->base_addr);
- p = p + strlen (p);
- strcpy (p, "\"/></library>\n");
- p = p + strlen (p);
-
- *p_ptr = p;
+ std::string *document = (std::string *) arg;
+ std::string name = xml_escape_text (dll->name);
+
+ *document += string_printf
+ (" <library name=\"%s\"><segment address=\"0x%lx\"/></library>\n",
+ name.c_str (), (long) dll->base_addr);
}
/* Handle qXfer:libraries:read. */
@@ -1391,43 +1530,26 @@ handle_qxfer_libraries (const char *annex,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
- unsigned int total_len;
- char *document, *p;
-
if (writebuf != NULL)
return -2;
if (annex[0] != '\0' || current_thread == NULL)
return -1;
- total_len = 64;
- for_each_inferior_with_data (&all_dlls, accumulate_file_name_length,
- &total_len);
+ std::string document = "<library-list version=\"1.0\">\n";
- document = (char *) malloc (total_len);
- if (document == NULL)
- return -1;
+ for_each_inferior_with_data (&all_dlls, emit_dll_description, &document);
- strcpy (document, "<library-list version=\"1.0\">\n");
- p = document + strlen (document);
+ document += "</library-list>\n";
- for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
-
- strcpy (p, "</library-list>\n");
-
- total_len = strlen (document);
+ if (offset > document.length ())
+ return -1;
- if (offset > total_len)
- {
- free (document);
- return -1;
- }
+ if (offset + len > document.length ())
+ len = document.length () - offset;
- if (offset + len > total_len)
- len = total_len - offset;
+ memcpy (readbuf, &document[offset], len);
- memcpy (readbuf, document + offset, len);
- free (document);
return len;
}
@@ -1521,11 +1643,14 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
{
struct thread_info *thread = (struct thread_info *) inf;
struct buffer *buffer = (struct buffer *) arg;
- ptid_t ptid = thread_to_gdb_id (thread);
+ ptid_t ptid = ptid_of (thread);
char ptid_s[100];
int core = target_core_of_thread (ptid);
char core_s[21];
const char *name = target_thread_name (ptid);
+ int handle_len;
+ gdb_byte *handle;
+ bool handle_status = target_thread_handle (ptid, &handle, &handle_len);
write_ptid (ptid_s, ptid);
@@ -1540,6 +1665,13 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
if (name != NULL)
buffer_xml_printf (buffer, " name=\"%s\"", name);
+ if (handle_status)
+ {
+ char *handle_s = (char *) alloca (handle_len * 2 + 1);
+ bin2hex (handle, handle_s, handle_len);
+ buffer_xml_printf (buffer, " handle=\"%s\"", handle_s);
+ }
+
buffer_xml_printf (buffer, "/>\n");
}
@@ -2005,21 +2137,20 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
/* Reply the current thread id. */
if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
{
- ptid_t gdb_id;
- require_running (own_buf);
+ ptid_t ptid;
+ require_running_or_return (own_buf);
- if (!ptid_equal (general_thread, null_ptid)
- && !ptid_equal (general_thread, minus_one_ptid))
- gdb_id = general_thread;
+ if (general_thread != null_ptid && general_thread != minus_one_ptid)
+ ptid = general_thread;
else
{
thread_ptr = get_first_inferior (&all_threads);
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
+ ptid = thread_ptr->id;
}
sprintf (own_buf, "QC");
own_buf += 2;
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, ptid);
return;
}
@@ -2075,28 +2206,22 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
if (strcmp ("qfThreadInfo", own_buf) == 0)
{
- ptid_t gdb_id;
-
- require_running (own_buf);
+ require_running_or_return (own_buf);
thread_ptr = get_first_inferior (&all_threads);
*own_buf++ = 'm';
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
if (strcmp ("qsThreadInfo", own_buf) == 0)
{
- ptid_t gdb_id;
-
- require_running (own_buf);
+ require_running_or_return (own_buf);
if (thread_ptr != NULL)
{
*own_buf++ = 'm';
- gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
- write_ptid (own_buf, gdb_id);
+ write_ptid (own_buf, thread_ptr->id);
thread_ptr = thread_ptr->next;
return;
}
@@ -2113,7 +2238,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
CORE_ADDR text, data;
- require_running (own_buf);
+ require_running_or_return (own_buf);
if (the_target->read_offsets (&text, &data))
sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
(long)text, (long)data, (long)data);
@@ -2228,7 +2353,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
}
sprintf (own_buf,
- "PacketSize=%x;QPassSignals+;QProgramSignals+;QStartupWithShell+",
+ "PacketSize=%x;QPassSignals+;QProgramSignals+;"
+ "QStartupWithShell+;QEnvironmentHexEncoded+;"
+ "QEnvironmentReset+;QEnvironmentUnset+",
PBUFSIZ - 1);
if (target_supports_catch_syscall ())
@@ -2348,7 +2475,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
int i, err;
ptid_t ptid = null_ptid;
- require_running (own_buf);
+ require_running_or_return (own_buf);
for (i = 0; i < 3; i++)
{
@@ -2461,7 +2588,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (startswith (own_buf, "qSearch:memory:"))
{
- require_running (own_buf);
+ require_running_or_return (own_buf);
handle_search_memory (own_buf, packet_len);
return;
}
@@ -2479,7 +2606,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
}
else
{
- require_running (own_buf);
+ require_running_or_return (own_buf);
process = current_process ();
}
@@ -2501,7 +2628,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
int len;
unsigned long long crc;
- require_running (own_buf);
+ require_running_or_return (own_buf);
comma = unpack_varlen_hex (own_buf + 5, &base);
if (*comma++ != ',')
{
@@ -3116,14 +3243,12 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
{
if (debug_threads)
{
- char *status_string
+ std::string status_string
= target_waitstatus_to_string (&thread->last_status);
debug_printf ("Reporting thread %s as already stopped with %s\n",
target_pid_to_str (entry->id),
- status_string);
-
- xfree (status_string);
+ status_string.c_str ());
}
gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
@@ -3283,7 +3408,7 @@ handle_status (char *own_buf)
/* GDB assumes the current thread is the thread we're
reporting the status for. */
general_thread = thread->id;
- set_desired_thread (1);
+ set_desired_thread ();
gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
@@ -3376,26 +3501,6 @@ gdbserver_show_disableable (FILE *stream)
" threads \tAll of the above\n");
}
-
-#undef require_running
-#define require_running(BUF) \
- if (!target_running ()) \
- { \
- write_enn (BUF); \
- break; \
- }
-
-static int
-first_thread_of (struct inferior_list_entry *entry, void *args)
-{
- int pid = * (int *) args;
-
- if (ptid_get_pid (entry->id) == pid)
- return 1;
-
- return 0;
-}
-
static void
kill_inferior_callback (struct inferior_list_entry *entry)
{
@@ -3521,6 +3626,8 @@ captured_main (int argc, char *argv[])
volatile int multi_mode = 0;
volatile int attach = 0;
int was_running;
+ bool selftest = false;
+ const char *selftest_filter = NULL;
while (*next_arg != NULL && **next_arg == '-')
{
@@ -3639,6 +3746,13 @@ captured_main (int argc, char *argv[])
startup_with_shell = false;
else if (strcmp (*next_arg, "--once") == 0)
run_once = 1;
+ else if (strcmp (*next_arg, "--selftest") == 0)
+ selftest = true;
+ else if (startswith (*next_arg, "--selftest="))
+ {
+ selftest = true;
+ selftest_filter = *next_arg + strlen ("--selftest=");
+ }
else
{
fprintf (stderr, "Unknown argument: %s\n", *next_arg);
@@ -3654,7 +3768,8 @@ captured_main (int argc, char *argv[])
port = *next_arg;
next_arg++;
}
- if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+ if ((port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+ && !selftest)
{
gdbserver_usage (stderr);
exit (1);
@@ -3670,7 +3785,8 @@ captured_main (int argc, char *argv[])
starting the inferior. Inferiors created in this scenario have
stdin,stdout redirected. So do this here before we call
start_inferior. */
- remote_prepare (port);
+ if (port != NULL)
+ remote_prepare (port);
bad_attach = 0;
pid = 0;
@@ -3711,6 +3827,12 @@ captured_main (int argc, char *argv[])
own_buf = (char *) xmalloc (PBUFSIZ + 1);
mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
+ if (selftest)
+ {
+ selftests::run_tests (selftest_filter);
+ throw_quit ("Quit");
+ }
+
if (pid == 0 && *next_arg != NULL)
{
int i, n;
@@ -3940,13 +4062,10 @@ process_point_options (struct gdb_breakpoint *bp, char **packet)
static int
process_serial_event (void)
{
- char ch;
- int i = 0;
int signal;
unsigned int len;
int res;
CORE_ADDR mem_addr;
- int pid;
unsigned char sig;
int packet_len;
int new_packet_len = -1;
@@ -3963,8 +4082,7 @@ process_serial_event (void)
}
response_needed = 1;
- i = 0;
- ch = own_buf[i++];
+ char ch = own_buf[0];
switch (ch)
{
case 'q':
@@ -3974,91 +4092,7 @@ process_serial_event (void)
handle_general_set (own_buf);
break;
case 'D':
- require_running (own_buf);
-
- if (multi_process)
- {
- i++; /* skip ';' */
- pid = strtol (&own_buf[i], NULL, 16);
- }
- else
- pid = ptid_get_pid (current_ptid);
-
- if ((tracing && disconnected_tracing) || any_persistent_commands ())
- {
- struct process_info *process = find_process_pid (pid);
-
- if (process == NULL)
- {
- write_enn (own_buf);
- break;
- }
-
- if (tracing && disconnected_tracing)
- fprintf (stderr,
- "Disconnected tracing in effect, "
- "leaving gdbserver attached to the process\n");
-
- if (any_persistent_commands ())
- fprintf (stderr,
- "Persistent commands are present, "
- "leaving gdbserver attached to the process\n");
-
- /* Make sure we're in non-stop/async mode, so we we can both
- wait for an async socket accept, and handle async target
- events simultaneously. There's also no point either in
- having the target stop all threads, when we're going to
- pass signals down without informing GDB. */
- if (!non_stop)
- {
- if (debug_threads)
- debug_printf ("Forcing non-stop mode\n");
-
- non_stop = 1;
- start_non_stop (1);
- }
-
- process->gdb_detached = 1;
-
- /* Detaching implicitly resumes all threads. */
- target_continue_no_signal (minus_one_ptid);
-
- write_ok (own_buf);
- break; /* from switch/case */
- }
-
- fprintf (stderr, "Detaching from process %d\n", pid);
- stop_tracing ();
- if (detach_inferior (pid) != 0)
- write_enn (own_buf);
- else
- {
- discard_queued_stop_replies (pid_to_ptid (pid));
- write_ok (own_buf);
-
- if (extended_protocol || target_running ())
- {
- /* There is still at least one inferior remaining or
- we are in extended mode, so don't terminate gdbserver,
- and instead treat this like a normal program exit. */
- last_status.kind = TARGET_WAITKIND_EXITED;
- last_status.value.integer = 0;
- last_ptid = pid_to_ptid (pid);
-
- current_thread = NULL;
- }
- else
- {
- putpkt (own_buf);
- remote_close ();
-
- /* If we are attached, then we can exit. Otherwise, we
- need to hang around doing nothing, until the child is
- gone. */
- join_inferior (pid);
- exit (0);
- }
- }
+ handle_detach (own_buf);
break;
case '!':
extended_protocol = 1;
@@ -4070,27 +4104,18 @@ process_serial_event (void)
case 'H':
if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
{
- ptid_t gdb_id, thread_id;
- int pid;
-
- require_running (own_buf);
+ require_running_or_break (own_buf);
- gdb_id = read_ptid (&own_buf[2], NULL);
+ ptid_t thread_id = read_ptid (&own_buf[2], NULL);
- pid = ptid_get_pid (gdb_id);
-
- if (ptid_equal (gdb_id, null_ptid)
- || ptid_equal (gdb_id, minus_one_ptid))
+ if (thread_id == null_ptid || thread_id == minus_one_ptid)
thread_id = null_ptid;
- else if (pid != 0
- && ptid_equal (pid_to_ptid (pid),
- gdb_id))
+ else if (thread_id.is_pid ())
{
- struct thread_info *thread =
- (struct thread_info *) find_inferior (&all_threads,
- first_thread_of,
- &pid);
- if (!thread)
+ /* The ptid represents a pid. */
+ thread_info *thread = find_any_thread_of_pid (thread_id.pid ());
+
+ if (thread == NULL)
{
write_enn (own_buf);
break;
@@ -4100,8 +4125,8 @@ process_serial_event (void)
}
else
{
- thread_id = gdb_id_to_thread_id (gdb_id);
- if (ptid_equal (thread_id, null_ptid))
+ /* The ptid represents a lwp/tid. */
+ if (find_thread_ptid (thread_id) == NULL)
{
write_enn (own_buf);
break;
@@ -4124,7 +4149,7 @@ process_serial_event (void)
}
general_thread = thread_id;
- set_desired_thread (1);
+ set_desired_thread ();
gdb_assert (current_thread != NULL);
}
else if (own_buf[1] == 'c')
@@ -4140,7 +4165,7 @@ process_serial_event (void)
}
break;
case 'g':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (current_traceframe >= 0)
{
struct regcache *regcache
@@ -4157,7 +4182,7 @@ process_serial_event (void)
{
struct regcache *regcache;
- if (!set_desired_thread (1))
+ if (!set_desired_thread ())
write_enn (own_buf);
else
{
@@ -4167,14 +4192,14 @@ process_serial_event (void)
}
break;
case 'G':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (current_traceframe >= 0)
write_enn (own_buf);
else
{
struct regcache *regcache;
- if (!set_desired_thread (1))
+ if (!set_desired_thread ())
write_enn (own_buf);
else
{
@@ -4185,7 +4210,7 @@ process_serial_event (void)
}
break;
case 'm':
- require_running (own_buf);
+ require_running_or_break (own_buf);
decode_m_packet (&own_buf[1], &mem_addr, &len);
res = gdb_read_memory (mem_addr, mem_buf, len);
if (res < 0)
@@ -4194,7 +4219,7 @@ process_serial_event (void)
bin2hex (mem_buf, own_buf, res);
break;
case 'M':
- require_running (own_buf);
+ require_running_or_break (own_buf);
decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
write_ok (own_buf);
@@ -4202,7 +4227,7 @@ process_serial_event (void)
write_enn (own_buf);
break;
case 'X':
- require_running (own_buf);
+ require_running_or_break (own_buf);
if (decode_X_packet (&own_buf[1], packet_len - 1,
&mem_addr, &len, &mem_buf) < 0
|| gdb_write_memory (mem_addr, mem_buf, len) != 0)
@@ -4211,7 +4236,7 @@ process_serial_event (void)
write_ok (own_buf);
break;
case 'C':
- require_running (own_buf);
+ require_running_or_break (own_buf);
hex2bin (own_buf + 1, &sig, 1);
if (gdb_signal_to_host_p ((enum gdb_signal) sig))
signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4220,7 +4245,7 @@ process_serial_event (void)
myresume (own_buf, 0, signal);
break;
case 'S':
- require_running (own_buf);
+ require_running_or_break (own_buf);
hex2bin (own_buf + 1, &sig, 1);
if (gdb_signal_to_host_p ((enum gdb_signal) sig))
signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4229,12 +4254,12 @@ process_serial_event (void)
myresume (own_buf, 1, signal);
break;
case 'c':
- require_running (own_buf);
+ require_running_or_break (own_buf);
signal = 0;
myresume (own_buf, 0, signal);
break;
case 's':
- require_running (own_buf);
+ require_running_or_break (own_buf);
signal = 0;
myresume (own_buf, 1, signal);
break;
@@ -4306,13 +4331,10 @@ process_serial_event (void)
case 'T':
{
- ptid_t gdb_id, thread_id;
+ require_running_or_break (own_buf);
- require_running (own_buf);
-
- gdb_id = read_ptid (&own_buf[1], NULL);
- thread_id = gdb_id_to_thread_id (gdb_id);
- if (ptid_equal (thread_id, null_ptid))
+ ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+ if (find_thread_ptid (thread_id) == NULL)
{
write_enn (own_buf);
break;
@@ -4408,7 +4430,7 @@ handle_serial_event (int err, gdb_client_data client_data)
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
- set_desired_thread (1);
+ set_desired_thread ();
return 0;
}
@@ -4503,7 +4525,18 @@ handle_target_event (int err, gdb_client_data client_data)
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
- set_desired_thread (1);
+ set_desired_thread ();
return 0;
}
+
+#if GDB_SELF_TEST
+namespace selftests
+{
+
+void
+reset ()
+{}
+
+} // namespace selftests
+#endif /* GDB_SELF_TEST */
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 7526463..7f5bed7 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -24,14 +24,9 @@
struct target_ops *the_target;
int
-set_desired_thread (int use_general)
+set_desired_thread ()
{
- struct thread_info *found;
-
- if (use_general == 1)
- found = find_thread_ptid (general_thread);
- else
- found = find_thread_ptid (cont_thread);
+ thread_info *found = find_thread_ptid (general_thread);
current_thread = found;
return (current_thread != NULL);
@@ -388,10 +383,15 @@ default_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
return size;
}
+/* Define it. */
+
+enum target_terminal::terminal_state target_terminal::terminal_state
+ = target_terminal::terminal_is_ours;
+
/* See target/target.h. */
void
-target_terminal_init ()
+target_terminal::init ()
{
/* Placeholder needed because of fork_inferior. Not necessary on
GDBserver. */
@@ -400,7 +400,7 @@ target_terminal_init ()
/* See target/target.h. */
void
-target_terminal_inferior ()
+target_terminal::inferior ()
{
/* Placeholder needed because of fork_inferior. Not necessary on
GDBserver. */
@@ -409,8 +409,24 @@ target_terminal_inferior ()
/* See target/target.h. */
void
-target_terminal_ours ()
+target_terminal::ours ()
{
/* Placeholder needed because of fork_inferior. Not necessary on
GDBserver. */
}
+
+/* See target/target.h. */
+
+void
+target_terminal::ours_for_output (void)
+{
+ /* Placeholder. */
+}
+
+/* See target/target.h. */
+
+void
+target_terminal::info (const char *arg, int from_tty)
+{
+ /* Placeholder. */
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index be89258..0a3d1db 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -475,6 +475,11 @@ struct target_ops
/* Return tdesc index for IPA. */
int (*get_ipa_tdesc_idx) (void);
+
+ /* Thread ID to (numeric) thread handle: Return true on success and
+ false for failure. Return pointer to thread handle via HANDLE
+ and the handle's length via HANDLE_LEN. */
+ bool (*thread_handle) (ptid_t ptid, gdb_byte **handle, int *handle_len);
};
extern struct target_ops *the_target;
@@ -693,12 +698,17 @@ void done_accessing_memory (void);
(the_target->thread_name ? (*the_target->thread_name) (ptid) \
: NULL)
+#define target_thread_handle(ptid, handle, handle_len) \
+ (the_target->thread_handle ? (*the_target->thread_handle) \
+ (ptid, handle, handle_len) \
+ : false)
+
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
int len);
-int set_desired_thread (int id);
+int set_desired_thread ();
const char *target_pid_to_str (ptid_t);
diff --git a/gdb/gdbserver/tdesc.c b/gdb/gdbserver/tdesc.c
index fdd35197..63d6467 100644
--- a/gdb/gdbserver/tdesc.c
+++ b/gdb/gdbserver/tdesc.c
@@ -22,13 +22,12 @@
void
init_target_desc (struct target_desc *tdesc)
{
- int offset, i;
+ int offset = 0;
- offset = 0;
- for (i = 0; i < tdesc->num_registers; i++)
+ for (reg *reg : tdesc->reg_defs)
{
- tdesc->reg_defs[i].offset = offset;
- offset += tdesc->reg_defs[i].size;
+ reg->offset = offset;
+ offset += reg->size;
}
tdesc->registers_size = offset / 8;
@@ -38,16 +37,21 @@ init_target_desc (struct target_desc *tdesc)
gdb_assert (2 * tdesc->registers_size + 32 <= PBUFSIZ);
}
+struct target_desc *
+allocate_target_description (void)
+{
+ return new target_desc ();
+}
+
#ifndef IN_PROCESS_AGENT
-static const struct target_desc default_description = { 0 };
+static const struct target_desc default_description {};
void
copy_target_description (struct target_desc *dest,
const struct target_desc *src)
{
dest->reg_defs = src->reg_defs;
- dest->num_registers = src->num_registers;
dest->expedite_regs = src->expedite_regs;
dest->registers_size = src->registers_size;
dest->xmltarget = src->xmltarget;
@@ -62,4 +66,174 @@ current_target_desc (void)
return current_process ()->tdesc;
}
+/* See arch/tdesc.h. */
+
+void
+set_tdesc_architecture (struct target_desc *target_desc,
+ const char *name)
+{
+ target_desc->arch = xstrdup (name);
+}
+
+/* See arch/tdesc.h. */
+
+void
+set_tdesc_osabi (struct target_desc *target_desc, const char *name)
+{
+ target_desc->osabi = xstrdup (name);
+}
+
+/* Return a string which is of XML format, including XML target
+ description to be sent to GDB. */
+
+const char *
+tdesc_get_features_xml (target_desc *tdesc)
+{
+ /* Either .xmltarget or .features is not NULL. */
+ gdb_assert (tdesc->xmltarget != NULL
+ || (tdesc->features != NULL
+ && tdesc->arch != NULL
+ && tdesc->osabi != NULL));
+
+ if (tdesc->xmltarget == NULL)
+ {
+ std::string buffer ("@<?xml version=\"1.0\"?>");
+
+ buffer += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">";
+ buffer += "<target>";
+ buffer += "<architecture>";
+ buffer += tdesc->arch;
+ buffer += "</architecture>";
+
+ buffer += "<osabi>";
+ buffer += tdesc->osabi;
+ buffer += "</osabi>";
+
+ char *xml;
+
+ for (int i = 0; VEC_iterate (char_ptr, tdesc->features, i, xml); i++)
+ {
+ buffer += "<xi:include href=\"";
+ buffer += xml;
+ buffer += "\"/>";
+ }
+
+ buffer += "</target>";
+
+ tdesc->xmltarget = xstrdup (buffer.c_str ());
+ }
+
+ return tdesc->xmltarget;
+}
#endif
+
+struct tdesc_type
+{};
+
+/* See arch/tdesc.h. */
+
+struct tdesc_feature *
+tdesc_create_feature (struct target_desc *tdesc, const char *name,
+ const char *xml)
+{
+#ifndef IN_PROCESS_AGENT
+ VEC_safe_push (char_ptr, tdesc->features, xstrdup (xml));
+#endif
+ return tdesc;
+}
+
+/* See arch/tdesc.h. */
+
+struct tdesc_type *
+tdesc_create_flags (struct tdesc_feature *feature, const char *name,
+ int size)
+{
+ return NULL;
+}
+
+/* See arch/tdesc.h. */
+
+void
+tdesc_add_flag (struct tdesc_type *type, int start,
+ const char *flag_name)
+{}
+
+/* See arch/tdesc.h. */
+
+struct tdesc_type *
+tdesc_named_type (const struct tdesc_feature *feature, const char *id)
+{
+ return NULL;
+}
+
+/* See arch/tdesc.h. */
+
+struct tdesc_type *
+tdesc_create_union (struct tdesc_feature *feature, const char *id)
+{
+ return NULL;
+}
+
+/* See arch/tdesc.h. */
+
+struct tdesc_type *
+tdesc_create_struct (struct tdesc_feature *feature, const char *id)
+{
+ return NULL;
+}
+
+/* See arch/tdesc.h. */
+
+void
+tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+ int regnum, int save_restore, const char *group,
+ int bitsize, const char *type)
+{
+ struct target_desc *tdesc = (struct target_desc *) feature;
+
+ while (tdesc->reg_defs.size () < regnum)
+ {
+ struct reg *reg = XCNEW (struct reg);
+
+ reg->name = "";
+ reg->size = 0;
+ tdesc->reg_defs.push_back (reg);
+ }
+
+ gdb_assert (regnum == 0
+ || regnum == tdesc->reg_defs.size ());
+
+ struct reg *reg = XCNEW (struct reg);
+
+ reg->name = name;
+ reg->size = bitsize;
+ tdesc->reg_defs.push_back (reg);
+}
+
+/* See arch/tdesc.h. */
+
+struct tdesc_type *
+tdesc_create_vector (struct tdesc_feature *feature, const char *name,
+ struct tdesc_type *field_type, int count)
+{
+ return NULL;
+}
+
+void
+tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+ int start, int end)
+{}
+
+/* See arch/tdesc.h. */
+
+void
+tdesc_add_field (struct tdesc_type *type, const char *field_name,
+ struct tdesc_type *field_type)
+{}
+
+/* See arch/tdesc.h. */
+
+void
+tdesc_set_struct_size (struct tdesc_type *type, int size)
+{
+}
diff --git a/gdb/gdbserver/tdesc.h b/gdb/gdbserver/tdesc.h
index 0341278..24efcd1 100644
--- a/gdb/gdbserver/tdesc.h
+++ b/gdb/gdbserver/tdesc.h
@@ -19,19 +19,22 @@
#ifndef TDESC_H
#define TDESC_H
-struct reg;
+#include "arch/tdesc.h"
-/* A target description. */
+#include "regdef.h"
+#include <vector>
-struct target_desc
+struct tdesc_feature
+{};
+
+/* A target description. Inherit from tdesc_feature so that target_desc
+ can be used as tdesc_feature. */
+
+struct target_desc : tdesc_feature
{
- /* An array of NUM_REGISTERS elements of register definitions that
+ /* A vector of elements of register definitions that
describe the inferior's register set. */
- struct reg *reg_defs;
-
- /* The number of registers in inferior's register set (and thus in
- the regcache). */
- int num_registers;
+ std::vector<struct reg *> reg_defs;
/* The register cache size, in bytes. */
int registers_size;
@@ -39,13 +42,79 @@ struct target_desc
#ifndef IN_PROCESS_AGENT
/* An array of register names. These are the "expedite" registers:
registers whose values are sent along with stop replies. */
- const char **expedite_regs;
+ const char **expedite_regs = NULL;
/* Defines what to return when looking for the "target.xml" file in
response to qXfer:features:read. Its contents can either be
verbatim XML code (prefixed with a '@') or else the name of the
- actual XML file to be used in place of "target.xml". */
- const char *xmltarget;
+ actual XML file to be used in place of "target.xml".
+
+ It can be NULL, then, its content is got from the following three
+ fields features, arch, and osabi in tdesc_get_features_xml. */
+ const char *xmltarget = NULL;
+
+ /* XML features in this target description. */
+ VEC (char_ptr) *features = NULL;
+
+ /* The value of <architecture> element in the XML, replying GDB. */
+ const char *arch = NULL;
+
+ /* The value of <osabi> element in the XML, replying GDB. */
+ const char *osabi = NULL;
+
+public:
+ target_desc ()
+ : registers_size (0)
+ {}
+
+ ~target_desc ()
+ {
+ int i;
+
+ for (reg *reg : reg_defs)
+ xfree (reg);
+
+ xfree ((char *) arch);
+ xfree ((char *) osabi);
+
+ char *f;
+
+ for (i = 0; VEC_iterate (char_ptr, features, i, f); i++)
+ xfree (f);
+ VEC_free (char_ptr, features);
+ }
+
+ bool operator== (const target_desc &other) const
+ {
+ if (reg_defs.size () != other.reg_defs.size ())
+ return false;
+
+ for (int i = 0; i < reg_defs.size (); ++i)
+ {
+ struct reg *reg = reg_defs[i];
+ struct reg *reg2 = other.reg_defs[i];
+
+ if (reg != reg2 && *reg != *reg2)
+ return false;
+ }
+
+ /* Compare expedite_regs. */
+ int i = 0;
+ for (; expedite_regs[i] != NULL; i++)
+ {
+ if (strcmp (expedite_regs[i], other.expedite_regs[i]) != 0)
+ return false;
+ }
+ if (other.expedite_regs[i] != NULL)
+ return false;
+
+ return true;
+ }
+
+ bool operator!= (const target_desc &other) const
+ {
+ return !(*this == other);
+ }
#endif
};
@@ -63,4 +132,8 @@ void init_target_desc (struct target_desc *tdesc);
const struct target_desc *current_target_desc (void);
+#ifndef IN_PROCESS_AGENT
+const char *tdesc_get_features_xml (struct target_desc *tdesc);
+#endif
+
#endif /* TDESC_H */
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 1ffb79d..9156d89 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -200,6 +200,7 @@ find_one_thread (ptid_t ptid)
lwp->thread_known = 1;
lwp->th = th;
+ lwp->thread_handle = ti.ti_tid;
return 1;
}
@@ -231,6 +232,7 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
gdb_assert (lwp != NULL);
lwp->thread_known = 1;
lwp->th = *th_p;
+ lwp->thread_handle = ti_p->ti_tid;
return 1;
}
@@ -439,6 +441,36 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
return err;
}
+/* See linux-low.h. */
+
+bool
+thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len)
+{
+ struct thread_db *thread_db;
+ struct lwp_info *lwp;
+ struct thread_info *thread
+ = (struct thread_info *) find_inferior_id (&all_threads, ptid);
+
+ if (thread == NULL)
+ return false;
+
+ thread_db = get_thread_process (thread)->priv->thread_db;
+
+ if (thread_db == NULL)
+ return false;
+
+ lwp = get_thread_lwp (thread);
+
+ if (!lwp->thread_known && !find_one_thread (thread->entry.id))
+ return false;
+
+ gdb_assert (lwp->thread_known);
+
+ *handle = (gdb_byte *) &lwp->thread_handle;
+ *handle_len = sizeof (lwp->thread_handle);
+ return true;
+}
+
#ifdef USE_LIBTHREAD_DB_DIRECTLY
static int
@@ -733,25 +765,12 @@ thread_db_init (void)
return 0;
}
-static int
-any_thread_of (struct inferior_list_entry *entry, void *args)
-{
- int *pid_p = (int *) args;
-
- if (ptid_get_pid (entry->id) == *pid_p)
- return 1;
-
- return 0;
-}
-
static void
switch_to_process (struct process_info *proc)
{
int pid = pid_of (proc);
- current_thread =
- (struct thread_info *) find_inferior (&all_threads,
- any_thread_of, &pid);
+ current_thread = find_any_thread_of_pid (pid);
}
/* Disconnect from libthread_db and free resources. */
@@ -864,3 +883,19 @@ thread_db_handle_monitor_command (char *mon)
/* Tell server.c to perform default processing. */
return 0;
}
+
+/* See linux-low.h. */
+
+void
+thread_db_notice_clone (struct process_info *proc, ptid_t ptid)
+{
+ struct thread_db *thread_db = proc->priv->thread_db;
+
+ /* If the thread layer isn't initialized, return. It may just
+ be that the program uses clone, but does not use libthread_db. */
+ if (thread_db == NULL || !thread_db->all_symbols_looked_up)
+ return;
+
+ if (!find_one_thread (ptid))
+ warning ("Cannot find thread after clone.\n");
+}
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index d4fe76a..0f41ff4 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -3956,17 +3956,6 @@ cmd_qtstmat (char *packet)
run_inferior_command (packet, strlen (packet) + 1);
}
-/* Helper for gdb_agent_about_to_close.
- Return non-zero if thread ENTRY is in the same process in DATA. */
-
-static int
-same_process_p (struct inferior_list_entry *entry, void *data)
-{
- int *pid = (int *) data;
-
- return ptid_get_pid (entry->id) == *pid;
-}
-
/* Sent the agent a command to close it. */
void
@@ -3981,8 +3970,7 @@ gdb_agent_about_to_close (int pid)
saved_thread = current_thread;
/* Find any thread which belongs to process PID. */
- current_thread = (struct thread_info *)
- find_inferior (&all_threads, same_process_p, &pid);
+ current_thread = find_any_thread_of_pid (pid);
strcpy (buf, "close");
@@ -5581,7 +5569,7 @@ force_unlock_trace_buffer (void)
case, if we want to move the thread out of the jump pad, we need to
single-step it until this function returns 0. */
-int
+fast_tpoint_collect_result
fast_tracepoint_collecting (CORE_ADDR thread_area,
CORE_ADDR stop_pc,
struct fast_tpoint_collect_status *status)
@@ -5656,7 +5644,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
if (tpoint == NULL)
{
warning ("in jump pad, but no matching tpoint?");
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
else
{
@@ -5684,7 +5672,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
if (tpoint == NULL)
{
warning ("in trampoline, but no matching tpoint?");
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
else
{
@@ -5712,14 +5700,14 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
{
trace_debug ("fast_tracepoint_collecting:"
" failed reading 'collecting' in the inferior");
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
if (!ipa_collecting)
{
trace_debug ("fast_tracepoint_collecting: not collecting"
" (and nobody is).");
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
/* Some thread is collecting. Check which. */
@@ -5732,7 +5720,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
{
trace_debug ("fast_tracepoint_collecting: not collecting "
"(another thread is)");
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
tpoint
@@ -5742,7 +5730,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
warning ("fast_tracepoint_collecting: collecting, "
"but tpoint %s not found?",
paddress ((CORE_ADDR) ipa_collecting_obj.tpoint));
- return 0;
+ return fast_tpoint_collect_result::not_collecting;
}
/* The thread is within `gdb_collect', skip over the rest of
@@ -5769,7 +5757,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area,
fast_tracepoint_collecting, returning continue-until-break at %s",
paddress (tpoint->adjusted_insn_addr));
- return 1; /* continue */
+ return fast_tpoint_collect_result::before_insn; /* continue */
}
else
{
@@ -5780,7 +5768,7 @@ fast_tracepoint_collecting, returning continue-until-break at %s",
paddress (tpoint->adjusted_insn_addr),
paddress (tpoint->adjusted_insn_addr_end));
- return 2; /* single-step */
+ return fast_tpoint_collect_result::at_insn; /* single-step */
}
}
diff --git a/gdb/gdbserver/tracepoint.h b/gdb/gdbserver/tracepoint.h
index 799a16c..31103a3 100644
--- a/gdb/gdbserver/tracepoint.h
+++ b/gdb/gdbserver/tracepoint.h
@@ -115,9 +115,25 @@ struct fast_tpoint_collect_status
CORE_ADDR adjusted_insn_addr_end;
};
-int fast_tracepoint_collecting (CORE_ADDR thread_area,
- CORE_ADDR stop_pc,
- struct fast_tpoint_collect_status *status);
+/* The possible states a thread can be in, related to the collection of fast
+ tracepoint. */
+
+enum class fast_tpoint_collect_result
+{
+ /* Not collecting a fast tracepoint. */
+ not_collecting,
+
+ /* In the jump pad, but before the relocated instruction. */
+ before_insn,
+
+ /* In the jump pad, but at (or after) the relocated instruction. */
+ at_insn,
+};
+
+fast_tpoint_collect_result fast_tracepoint_collecting
+ (CORE_ADDR thread_area, CORE_ADDR stop_pc,
+ struct fast_tpoint_collect_status *status);
+
void force_unlock_trace_buffer (void);
int handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc);
diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c
index c505190..03d6e17 100644
--- a/gdb/gdbserver/win32-i386-low.c
+++ b/gdb/gdbserver/win32-i386-low.c
@@ -18,6 +18,12 @@
#include "server.h"
#include "win32-low.h"
#include "x86-low.h"
+#include "x86-xstate.h"
+#ifdef __x86_64__
+#include "arch/amd64.h"
+#endif
+#include "arch/i386.h"
+#include "tdesc.h"
#ifndef CONTEXT_EXTENDED_REGISTERS
#define CONTEXT_EXTENDED_REGISTERS 0
@@ -28,16 +34,6 @@
#define FLAG_TRACE_BIT 0x100
-#ifdef __x86_64__
-/* Defined in auto-generated build-time file gdb/gdbserver/amd64.c. */
-void init_registers_amd64 (void);
-extern const struct target_desc *tdesc_amd64;
-#else
-/* Defined in auto-generated build-time file gdb/gdbserver/i386.c. */
-void init_registers_i386 (void);
-extern const struct target_desc *tdesc_i386;
-#endif
-
static struct x86_debug_reg_state debug_reg_state;
static int
@@ -45,7 +41,7 @@ update_debug_registers_callback (struct inferior_list_entry *entry,
void *pid_p)
{
struct thread_info *thr = (struct thread_info *) entry;
- win32_thread_info *th = (win32_thread_info *) inferior_target_data (thr);
+ win32_thread_info *th = (win32_thread_info *) thread_target_data (thr);
int pid = *(int *) pid_p;
/* Only update the threads of this process. */
@@ -90,7 +86,7 @@ static DWORD64
win32_get_current_dr (int dr)
{
win32_thread_info *th
- = (win32_thread_info *) inferior_target_data (current_thread);
+ = (win32_thread_info *) thread_target_data (current_thread);
win32_require_context (th);
@@ -448,13 +444,18 @@ static const unsigned char i386_win32_breakpoint = 0xcc;
static void
i386_arch_setup (void)
{
+ struct target_desc *tdesc;
+
#ifdef __x86_64__
- init_registers_amd64 ();
- win32_tdesc = tdesc_amd64;
+ tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
+ false);
#else
- init_registers_i386 ();
- win32_tdesc = tdesc_i386;
+ tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
#endif
+
+ init_target_desc (tdesc);
+
+ win32_tdesc = tdesc;
}
struct win32_target_ops the_low_target = {
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 88f6911..cc84d15 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -198,7 +198,7 @@ thread_rec (ptid_t ptid, int get_context)
if (thread == NULL)
return NULL;
- th = (win32_thread_info *) inferior_target_data (thread);
+ th = (win32_thread_info *) thread_target_data (thread);
if (get_context)
win32_require_context (th);
return th;
@@ -232,7 +232,7 @@ static void
delete_thread_info (struct inferior_list_entry *entry)
{
struct thread_info *thread = (struct thread_info *) entry;
- win32_thread_info *th = (win32_thread_info *) inferior_target_data (thread);
+ win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
remove_thread (thread);
CloseHandle (th->h);
@@ -433,7 +433,7 @@ continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
{
struct thread_info *thread = (struct thread_info *) this_thread;
int thread_id = * (int *) id_ptr;
- win32_thread_info *th = (win32_thread_info *) inferior_target_data (thread);
+ win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
if (thread_id == -1 || thread_id == th->tid)
{
@@ -1333,7 +1333,7 @@ static void
suspend_one_thread (struct inferior_list_entry *entry)
{
struct thread_info *thread = (struct thread_info *) entry;
- win32_thread_info *th = (win32_thread_info *) inferior_target_data (thread);
+ win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
if (!th->suspended)
{