[PATCH v2] Enable tracing of pseudo-registers on ARM

Antoine Tremblay
2016-02-15T14:46:08Z

In this v2:
Use user_reg_map_name_to_regnum.
Add testcase. Note that this testcase needs the tracepoint patch applyed to work
we can however keep the series order, the test will be untested until the tracepoint
patch is present.

-

This patch implements the ax_pseudo_register_push_stack and
ax_pseudo_register_collect gdbarch functions so that a pseudo-register can
be traced.

No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }

gdb/ChangeLog:

* arm-tdep.c (arm_pseudo_register_to_register): New function.
(arm_ax_pseudo_register_collect): New function.
(arm_ax_pseudo_register_push_stack): New function.
(arm_gdbarch_init): Set
gdbarch_ax_pseudo_register_{collect,push_stack} functions.

gdb/testsuite/ChangeLog:

* gdb.trace/tfile-avx.c: Move to...
* gdb.trace/tracefile-pseudo-reg.c: Here.
* gdb.trace/tfile-avx.exp: Move to...
* gdb.trace/tracefile-pseudo-reg.exp: Here.
---
gdb/arm-tdep.c | 68 +++++++++++++++++
gdb/testsuite/gdb.trace/tfile-avx.c | 51 -------------
gdb/testsuite/gdb.trace/tfile-avx.exp | 73 ------------------
gdb/testsuite/gdb.trace/tracefile-pseudo-reg.c | 63 ++++++++++++++++
gdb/testsuite/gdb.trace/tracefile-pseudo-reg.exp | 94 ++++++++++++++++++++++++
5 files changed, 225 insertions(+), 124 deletions(-)
delete mode 100644 gdb/testsuite/gdb.trace/tfile-avx.c
delete mode 100644 gdb/testsuite/gdb.trace/tfile-avx.exp
create mode 100644 gdb/testsuite/gdb.trace/tracefile-pseudo-reg.c
create mode 100644 gdb/testsuite/gdb.trace/tracefile-pseudo-reg.exp

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index ccfefa8..0f6d88c 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8718,6 +8718,70 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
}
}

+/* Map the pseudo register number REG to the proper register number. */
+
+static int
+arm_pseudo_register_to_register (struct gdbarch *gdbarch, int reg)
+{
+ int double_regnum = 0;
+ int num_regs = gdbarch_num_regs (gdbarch);
+ char name_buf[4];
+
+ /* Single precision pseudo registers. s0-s31. */
+ if (reg >= num_regs && reg < num_regs + 32)
+ {
+ xsnprintf (name_buf, sizeof (name_buf), "d%d", (reg - num_regs) / 2);
+ double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
+ strlen (name_buf));
+ }
+ /* Quadruple precision pseudo regisers. q0-q15. */
+ else if (reg >= num_regs + 32 && reg < num_regs + 32 + 16)
+ {
+ xsnprintf (name_buf, sizeof (name_buf), "d%d", (reg - num_regs - 32) * 2);
+ double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
+ strlen (name_buf));
+ }
+ /* Error bad register number. */
+ else
+ return -1;
+
+ return double_regnum;
+}
+
+/* Implementation of the ax_pseudo_register_collect gdbarch function. */
+
+static int
+arm_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = arm_pseudo_register_to_register (gdbarch, reg);
+
+ /* Error. */
+ if (rawnum < 0)
+ return 1;
+
+ ax_reg_mask (ax, rawnum);
+
+ return 0;
+}
+
+/* Implementation of the ax_pseudo_register_push_stack gdbarch function. */
+
+static int
+arm_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = arm_pseudo_register_to_register (gdbarch, reg);
+
+ /* Error. */
+ if (rawnum < 0)
+ return 1;
+
+ ax_reg (ax, rawnum);
+
+ return 0;
+}
+
static struct value *
value_of_arm_user_reg (struct frame_info *frame, const void *baton)
{
@@ -9379,6 +9443,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
+ set_gdbarch_ax_pseudo_register_push_stack
+ (gdbarch, arm_ax_pseudo_register_push_stack);
+ set_gdbarch_ax_pseudo_register_collect
+ (gdbarch, arm_ax_pseudo_register_collect);
}

if (tdesc_data)
diff --git a/gdb/testsuite/gdb.trace/tfile-avx.c b/gdb/testsuite/gdb.trace/tfile-avx.c
deleted file mode 100644
index 212c556..0000000
--- a/gdb/testsuite/gdb.trace/tfile-avx.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2016 Free Software Foundation, Inc.
-
- 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/>. */
-
-/*
- * Test program for reading target description from tfile: collects AVX
- * registers on x86_64.
- */
-
-#include <immintrin.h>
-
-void
-dummy (void)
-{
-}
-
-static void
-end (void)
-{
-}
-
-int
-main (void)
-{
- register __v8si a asm("ymm15") = {
- 0x12340001,
- 0x12340002,
- 0x12340003,
- 0x12340004,
- 0x12340005,
- 0x12340006,
- 0x12340007,
- 0x12340008,
- };
- asm volatile ("traceme: call dummy" : : "x" (a));
- end ();
- return 0;
-}
diff --git a/gdb/testsuite/gdb.trace/tfile-avx.exp b/gdb/testsuite/gdb.trace/tfile-avx.exp
deleted file mode 100644
index 4c52c64..0000000
--- a/gdb/testsuite/gdb.trace/tfile-avx.exp
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright 2016 Free Software Foundation, Inc.
-# 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/>.
-
-if { ! [is_amd64_regs_target] } {
- verbose "Skipping tfile AVX test (target is not x86_64)."
- return
-}
-
-load_lib "trace-support.exp"
-
-standard_testfile
-
-if {[prepare_for_testing $testfile.exp $testfile $srcfile \
- [list debug additional_flags=-mavx]]} {
- return -1
-}
-
-if ![runto_main] {
- fail "Can't run to main to check for trace support"
- return -1
-}
-
-if ![gdb_target_supports_trace] {
- unsupported "target does not support trace"
- return -1
-}
-
-gdb_test_multiple "print \$ymm15" "check for AVX support" {
- -re " = void.*$gdb_prompt $" {
- verbose "Skipping tfile AVX test (target doesn't support AVX)."
- return
- }
- -re " = \\{.*}.*$gdb_prompt $" {
- # All is well.
- }
-}
-
-gdb_test "trace traceme" ".*"
-
-gdb_trace_setactions "set actions for tracepoint" "" \
- "collect \$ymm15" "^$"
-
-gdb_breakpoint "end"
-
-gdb_test_no_output "tstart"
-
-gdb_test "continue" ".*Breakpoint $decimal, end .*"
-
-set tracefile [standard_output_file ${testfile}]
-
-# Save trace frames to tfile.
-gdb_test "tsave ${tracefile}.tf" \
- "Trace data saved to file '${tracefile}.tf'.*" \
- "save tfile trace file"
-
-# Change target to tfile.
-gdb_test "target tfile ${tracefile}.tf" "" "change to tfile target" \
- "A program is being debugged already. Kill it. .y or n. $" "y"
-
-gdb_test "tfind 0" "Found trace frame 0, tracepoint .*"
-
-gdb_test "print/x \$ymm15.v8_int32" " = \\{0x12340001, .*, 0x12340008}"
diff --git a/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.c b/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.c
new file mode 100644
index 0000000..e8f66f7
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.c
@@ -0,0 +1,63 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2016 Free Software Foundation, Inc.
+
+ 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/>. */
+
+/*
+ * Test program for reading target description from tfile: collects AVX
+ * registers on x86_64.
+ */
+
+#if (defined __x86_64__)
+#include <immintrin.h>
+#elif (defined __arm__ || defined __thumb2__ || defined __thumb__)
+#include <arm_neon.h>
+#endif
+
+void
+dummy (void)
+{
+}
+
+static void
+end (void)
+{
+}
+
+int
+main (void)
+{
+#if (defined __x86_64__)
+ register __v8si a asm("xmm15") = {
+ 0x12340001,
+ 0x12340002,
+ 0x12340003,
+ 0x12340004,
+ 0x12340005,
+ 0x12340006,
+ 0x12340007,
+ 0x12340008,
+ };
+ asm volatile ("traceme: call dummy" : : "x" (a));
+#elif (defined __arm__ || defined __thumb2__ || defined __thumb__)
+ register uint32_t a asm("s5") = {
+ 0x2
+ };
+ asm volatile ("traceme: bl dummy" : : "x" (a));
+#endif
+
+ end ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.exp b/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.exp
new file mode 100644
index 0000000..12a2740
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/tracefile-pseudo-reg.exp
@@ -0,0 +1,94 @@
+# Copyright 2016 Free Software Foundation, Inc.
+# 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/>.
+
+if { ! [is_amd64_regs_target] && ! [istarget "arm*-*-*"] } {
+ verbose "Skipping tracefile pseudo register tests, target is not supported."
+ return
+}
+
+load_lib "trace-support.exp"
+
+standard_testfile
+
+if { [is_amd64_regs_target] } {
+ set add_flags "-mavx"
+} elseif { [istarget "arm*-*-*"] } {
+ set add_flags "-mfpu=neon"
+}
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+ [list debug additional_flags=$add_flags]]} {
+ return -1
+}
+
+if ![runto_main] {
+ fail "Can't run to main to check for trace support"
+ return -1
+}
+
+if ![gdb_target_supports_trace] {
+ unsupported "target does not support trace"
+ return -1
+}
+
+if { [is_amd64_regs_target] } {
+ set reg "\$ymm15"
+ set reg_message "check for AVX support"
+} elseif { [istarget "arm*-*-*"] } {
+ set reg "\$s5"
+ set reg_message "check for Neon support"
+}
+
+gdb_test_multiple "print $reg" $reg_message {
+ -re " = void.*$gdb_prompt $" {
+ verbose "Skipping tracefile pseudo register tests, target is not supported."
+ return
+ }
+ -re " = \\{.*}.*$gdb_prompt $" {
+ # All is well.
+ }
+ -re " = 0.*$gdb_prompt $" {
+ # All is well.
+ }
+}
+
+gdb_test "trace traceme" ".*"
+
+gdb_trace_setactions "set actions for tracepoint" "" \
+ "collect $reg" "^$"
+
+gdb_breakpoint "end"
+
+gdb_test_no_output "tstart"
+
+gdb_test "continue" ".*Breakpoint $decimal, end .*"
+
+set tracefile [standard_output_file ${testfile}]
+
+# Save trace frames to tfile.
+gdb_test "tsave ${tracefile}.tf" \
+ "Trace data saved to file '${tracefile}.tf'.*" \
+ "save tfile trace file"
+
+# Change target to tfile.
+gdb_test "target tfile ${tracefile}.tf" "" "change to tfile target" \
+ "A program is being debugged already. Kill it. .y or n. $" "y"
+
+gdb_test "tfind 0" "Found trace frame 0, tracepoint .*"
+
+if { [is_amd64_regs_target] } {
+ gdb_test "print/x \$ymm15.v8_int32" " = \\{0x12340001, .*, 0x12340008}"
+} elseif { [istarget "arm*-*-*"] } {
+ gdb_test "print \$s5" "2.80259693e-45"
+}
--
2.6.4