qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH  v2 0/9] gdbstub/next (cleanups, softmmu, SVE)
@ 2020-12-18 11:26 Alex Bennée
  2020-12-18 11:26 ` [PATCH v2 1/9] test/guest-debug: echo QEMU command as well Alex Bennée
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée

Hi,

This is the next iteration of gdbstub/next. Apart from adding review
tags there are a few new patches:

 - now the 8.3.1 gating is there we can revert the disable of gdbstub-sha1
 - addition of some softmmu tests (which exercise watchpoints)
 - moving the SVE target representation to org.gnu.gdb.aarch64.sve

The final patch allows GDB to do SVE aware handling of pseudo registers
rather than treating the set as a custom target description. The
following still need review:

 - target/arm: use official org.gnu.gdb.aarch64.sve layout for registers
 - gdbstub: implement a softmmu based test
 - Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1 test"
 - configure: gate our use of GDB to 8.3.1 or above

Alex Bennée (8):
  test/guest-debug: echo QEMU command as well
  configure: gate our use of GDB to 8.3.1 or above
  Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1
    test"
  gdbstub: implement a softmmu based test
  gdbstub: drop CPUEnv from gdb_exit()
  gdbstub: drop gdbserver_cleanup in favour of gdb_exit
  gdbstub: ensure we clean-up when terminated
  target/arm: use official org.gnu.gdb.aarch64.sve layout for registers

Lirong Yuan (1):
  gdbstub: add support to Xfer:auxv:read: packet

 configure                                     |   7 +-
 include/exec/gdbstub.h                        |  14 +-
 bsd-user/syscall.c                            |   6 +-
 gdbstub.c                                     |  65 +++++++--
 linux-user/exit.c                             |   2 +-
 softmmu/runstate.c                            |   2 +-
 target/arm/arm-semi.c                         |   2 +-
 target/arm/gdbstub.c                          |  75 ++++------
 target/arm/helper.c                           |   2 +-
 target/m68k/m68k-semi.c                       |   2 +-
 target/nios2/nios2-semi.c                     |   2 +-
 MAINTAINERS                                   |   1 +
 tests/guest-debug/run-test.py                 |  35 +++--
 tests/tcg/aarch64/Makefile.softmmu-target     |   1 +
 tests/tcg/aarch64/gdbstub/test-sve-ioctl.py   |  11 ++
 tests/tcg/aarch64/system/boot.S               |   1 +
 tests/tcg/i386/Makefile.softmmu-target        |   1 +
 tests/tcg/i386/system/boot.S                  |   2 +-
 tests/tcg/multiarch/Makefile.target           |  13 +-
 tests/tcg/multiarch/gdbstub/memory.py         | 130 ++++++++++++++++++
 .../multiarch/gdbstub/test-qxfer-auxv-read.py |  57 ++++++++
 .../multiarch/system/Makefile.softmmu-target  |  19 ++-
 tests/tcg/x86_64/Makefile.softmmu-target      |   1 +
 tests/tcg/x86_64/system/boot.S                |   2 +-
 24 files changed, 371 insertions(+), 82 deletions(-)
 create mode 100644 tests/tcg/multiarch/gdbstub/memory.py
 create mode 100644 tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py

-- 
2.20.1



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH  v2 1/9] test/guest-debug: echo QEMU command as well
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
@ 2020-12-18 11:26 ` Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 2/9] configure: gate our use of GDB to 8.3.1 or above Alex Bennée
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée

This helps with debugging.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20201214153012.12723-2-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/guest-debug/run-test.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
index 71c5569054..0c4f5c3808 100755
--- a/tests/guest-debug/run-test.py
+++ b/tests/guest-debug/run-test.py
@@ -53,6 +53,7 @@ if __name__ == '__main__':
         cmd = "%s %s -g %s %s" % (args.qemu, args.qargs, socket_name,
                                   args.binary)
 
+    print("QEMU CMD: %s" % (cmd))
     inferior = subprocess.Popen(shlex.split(cmd))
 
     # Now launch gdb with our test and collect the result
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH  v2 2/9] configure: gate our use of GDB to 8.3.1 or above
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
  2020-12-18 11:26 ` [PATCH v2 1/9] test/guest-debug: echo QEMU command as well Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 3/9] Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1 test" Alex Bennée
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée

The support of socket based debugging which we need for linux-user
testing is only really stable as of 8.3.1 so lets gate our use of GDB
on having a relatively modern version.

For direct testing you can just point to a locally compiled version of
gdb via configure, e.g.:

  ../../configure --gdb=$HOME/src/binutils-gdb.git/builds/all/install/bin/gdb

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20201214153012.12723-3-alex.bennee@linaro.org>

---
v2
  - reword intention
---
 configure | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 0e542b4c46..07df350e06 100755
--- a/configure
+++ b/configure
@@ -6676,8 +6676,11 @@ if test "$plugins" = "yes" ; then
     fi
 fi
 
-if test -n "$gdb_bin" ; then
-    echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
+if test -n "$gdb_bin"; then
+    gdb_version=$($gdb_bin --version | head -n 1)
+    if version_ge ${gdb_version##* } 8.3.1; then
+        echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
+    fi
 fi
 
 if test "$secret_keyring" = "yes" ; then
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/9] Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1 test"
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
  2020-12-18 11:26 ` [PATCH v2 1/9] test/guest-debug: echo QEMU command as well Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 2/9] configure: gate our use of GDB to 8.3.1 or above Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 4/9] gdbstub: implement a softmmu based test Alex Bennée
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée

We won't attempt to run the test now it's gated on a newer version of
gdb.

This reverts commit a930cadd83b4681a98ce72abf530a791ee2e42a6.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/tcg/multiarch/Makefile.target | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 230eb9a95e..cb49cc9ccb 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -54,9 +54,7 @@ run-gdbstub-sha1: sha1
 		--bin $< --test $(MULTIARCH_SRC)/gdbstub/sha1.py, \
 	"basic gdbstub support")
 
-# Disable this for now -- it provokes a gdb internal-error on
-# Ubuntu gdb 8.1.1-0ubuntu1.
-# EXTRA_RUNS += run-gdbstub-sha1
+EXTRA_RUNS += run-gdbstub-sha1
 endif
 
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH  v2 4/9] gdbstub: implement a softmmu based test
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (2 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 3/9] Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1 test" Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 14:45   ` Philippe Mathieu-Daudé
  2020-12-18 11:27 ` [PATCH v2 5/9] gdbstub: add support to Xfer:auxv:read: packet Alex Bennée
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Alex Bennée,
	Richard Henderson, open list:ARM TCG CPUs, Paolo Bonzini,
	Philippe Mathieu-Daudé

This adds a new tests that allows us to test softmmu only features
including watchpoints. To do achieve this we need to:

  - add _exit: labels to the boot codes
  - write a memory.py test case
  - plumb the test case into the build system
  - tweak the run_test script to:
    - re-direct output when asked
    - use socket based connection for all tests
    - add a small pause before connection

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/guest-debug/run-test.py                 |  36 +++--
 tests/tcg/aarch64/Makefile.softmmu-target     |   1 +
 tests/tcg/aarch64/system/boot.S               |   1 +
 tests/tcg/i386/Makefile.softmmu-target        |   1 +
 tests/tcg/i386/system/boot.S                  |   2 +-
 tests/tcg/multiarch/gdbstub/memory.py         | 130 ++++++++++++++++++
 .../multiarch/system/Makefile.softmmu-target  |  19 ++-
 tests/tcg/x86_64/Makefile.softmmu-target      |   1 +
 tests/tcg/x86_64/system/boot.S                |   2 +-
 9 files changed, 181 insertions(+), 12 deletions(-)
 create mode 100644 tests/tcg/multiarch/gdbstub/memory.py

diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
index 0c4f5c3808..8b91ff95af 100755
--- a/tests/guest-debug/run-test.py
+++ b/tests/guest-debug/run-test.py
@@ -16,6 +16,7 @@ import subprocess
 import shutil
 import shlex
 import os
+from time import sleep
 from tempfile import TemporaryDirectory
 
 def get_args():
@@ -27,10 +28,21 @@ def get_args():
                         required=True)
     parser.add_argument("--test", help="GDB test script",
                         required=True)
-    parser.add_argument("--gdb", help="The gdb binary to use", default=None)
+    parser.add_argument("--gdb", help="The gdb binary to use",
+                        default=None)
+    parser.add_argument("--output", help="A file to redirect output to")
 
     return parser.parse_args()
 
+
+def log(output, msg):
+    if output:
+        output.write(msg + "\n")
+        output.flush()
+    else:
+        print(msg)
+
+
 if __name__ == '__main__':
     args = get_args()
 
@@ -42,18 +54,25 @@ if __name__ == '__main__':
     if not args.gdb:
         print("We need gdb to run the test")
         exit(-1)
+    if args.output:
+        output = open(args.output, "w")
+    else:
+        output = None
 
     socket_dir = TemporaryDirectory("qemu-gdbstub")
     socket_name = os.path.join(socket_dir.name, "gdbstub.socket")
 
     # Launch QEMU with binary
     if "system" in args.qemu:
-        cmd = "%s %s %s -s -S" % (args.qemu, args.qargs, args.binary)
+        cmd = "%s %s %s -gdb unix:path=%s,server" % (args.qemu,
+                                                     args.qargs,
+                                                     args.binary,
+                                                     socket_name)
     else:
         cmd = "%s %s -g %s %s" % (args.qemu, args.qargs, socket_name,
                                   args.binary)
 
-    print("QEMU CMD: %s" % (cmd))
+    log(output, "QEMU CMD: %s" % (cmd))
     inferior = subprocess.Popen(shlex.split(cmd))
 
     # Now launch gdb with our test and collect the result
@@ -63,16 +82,15 @@ if __name__ == '__main__':
     # disable prompts in case of crash
     gdb_cmd += " -ex 'set confirm off'"
     # connect to remote
-    if "system" in args.qemu:
-        gdb_cmd += " -ex 'target remote localhost:1234'"
-    else:
-        gdb_cmd += " -ex 'target remote %s'" % (socket_name)
+    gdb_cmd += " -ex 'target remote %s'" % (socket_name)
     # finally the test script itself
     gdb_cmd += " -x %s" % (args.test)
 
-    print("GDB CMD: %s" % (gdb_cmd))
 
-    result = subprocess.call(gdb_cmd, shell=True);
+    sleep(1)
+    log(output, "GDB CMD: %s" % (gdb_cmd))
+
+    result = subprocess.call(gdb_cmd, shell=True, stdout=output)
 
     # A negative result is the result of an internal gdb failure like
     # a crash. We force a return of 0 so we don't fail the test on
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index 1057a8ac49..a7286ac295 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -15,6 +15,7 @@ CRT_PATH=$(AARCH64_SYSTEM_SRC)
 LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
 LDFLAGS=-Wl,-T$(LINK_SCRIPT)
 TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
+EXTRA_RUNS+=$(MULTIARCH_RUNS)
 CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
 LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
 
diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
index b14e94f332..e190b1efa6 100644
--- a/tests/tcg/aarch64/system/boot.S
+++ b/tests/tcg/aarch64/system/boot.S
@@ -197,6 +197,7 @@ __start:
 	bl	main
 
 	/* pass return value to sys exit */
+_exit:
 	mov    x1, x0
 	ldr    x0, =0x20026 /* ADP_Stopped_ApplicationExit */
 	stp    x0, x1, [sp, #-16]!
diff --git a/tests/tcg/i386/Makefile.softmmu-target b/tests/tcg/i386/Makefile.softmmu-target
index 1c8790eecd..5266f2335a 100644
--- a/tests/tcg/i386/Makefile.softmmu-target
+++ b/tests/tcg/i386/Makefile.softmmu-target
@@ -19,6 +19,7 @@ CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
 LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
 
 TESTS+=$(MULTIARCH_TESTS)
+EXTRA_RUNS+=$(MULTIARCH_RUNS)
 
 # building head blobs
 .PRECIOUS: $(CRT_OBJS)
diff --git a/tests/tcg/i386/system/boot.S b/tests/tcg/i386/system/boot.S
index 90aa174908..794c2cb0ad 100644
--- a/tests/tcg/i386/system/boot.S
+++ b/tests/tcg/i386/system/boot.S
@@ -76,7 +76,7 @@ _start:
          */
         call main
 
-        /* output any non-zero result in eax to isa-debug-exit device */
+_exit:	/* output any non-zero result in eax to isa-debug-exit device */
         test %al, %al
         jz 1f
         out %ax, $0xf4
diff --git a/tests/tcg/multiarch/gdbstub/memory.py b/tests/tcg/multiarch/gdbstub/memory.py
new file mode 100644
index 0000000000..67864ad902
--- /dev/null
+++ b/tests/tcg/multiarch/gdbstub/memory.py
@@ -0,0 +1,130 @@
+from __future__ import print_function
+#
+# Test some of the softmmu debug features with the multiarch memory
+# test. It is a port of the original vmlinux focused test case but
+# using the "memory" test instead.
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import gdb
+import sys
+
+failcount = 0
+
+
+def report(cond, msg):
+    "Report success/fail of test"
+    if cond:
+        print("PASS: %s" % (msg))
+    else:
+        print("FAIL: %s" % (msg))
+        global failcount
+        failcount += 1
+
+
+def check_step():
+    "Step an instruction, check it moved."
+    start_pc = gdb.parse_and_eval('$pc')
+    gdb.execute("si")
+    end_pc = gdb.parse_and_eval('$pc')
+
+    return not (start_pc == end_pc)
+
+
+#
+# Currently it's hard to create a hbreak with the pure python API and
+# manually matching PC to symbol address is a bit flaky thanks to
+# function prologues. However internally QEMU's gdbstub treats them
+# the same as normal breakpoints so it will do for now.
+#
+def check_break(sym_name):
+    "Setup breakpoint, continue and check we stopped."
+    sym, ok = gdb.lookup_symbol(sym_name)
+    bp = gdb.Breakpoint(sym_name, gdb.BP_BREAKPOINT)
+
+    gdb.execute("c")
+
+    # hopefully we came back
+    end_pc = gdb.parse_and_eval('$pc')
+    report(bp.hit_count == 1,
+           "break @ %s (%s %d hits)" % (end_pc, sym.value(), bp.hit_count))
+
+    bp.delete()
+
+
+def do_one_watch(sym, wtype, text):
+
+    wp = gdb.Breakpoint(sym, gdb.BP_WATCHPOINT, wtype)
+    gdb.execute("c")
+    report_str = "%s for %s" % (text, sym)
+
+    if wp.hit_count > 0:
+        report(True, report_str)
+        wp.delete()
+    else:
+        report(False, report_str)
+
+
+def check_watches(sym_name):
+    "Watch a symbol for any access."
+
+    # Should hit for any read
+    do_one_watch(sym_name, gdb.WP_ACCESS, "awatch")
+
+    # Again should hit for reads
+    do_one_watch(sym_name, gdb.WP_READ, "rwatch")
+
+    # Finally when it is written
+    do_one_watch(sym_name, gdb.WP_WRITE, "watch")
+
+
+def run_test():
+    "Run through the tests one by one"
+
+    print("Checking we can step the first few instructions")
+    step_ok = 0
+    for i in range(3):
+        if check_step():
+            step_ok += 1
+
+    report(step_ok == 3, "single step in boot code")
+
+    # If we get here we have missed some of the other breakpoints.
+    print("Setup catch-all for _exit")
+    cbp = gdb.Breakpoint("_exit", gdb.BP_BREAKPOINT)
+
+    check_break("main")
+    check_watches("test_data[128]")
+
+    report(cbp.hit_count == 0, "didn't reach backstop")
+
+#
+# This runs as the script it sourced (via -x, via run-test.py)
+#
+try:
+    inferior = gdb.selected_inferior()
+    arch = inferior.architecture()
+    print("ATTACHED: %s" % arch.name())
+except (gdb.error, AttributeError):
+    print("SKIPPING (not connected)", file=sys.stderr)
+    exit(0)
+
+if gdb.parse_and_eval('$pc') == 0:
+    print("SKIP: PC not set")
+    exit(0)
+
+try:
+    # These are not very useful in scripts
+    gdb.execute("set pagination off")
+
+    # Run the actual tests
+    run_test()
+except (gdb.error):
+    print("GDB Exception: %s" % (sys.exc_info()[0]))
+    failcount += 1
+    pass
+
+# Finally kill the inferior and exit gdb with a count of failures
+gdb.execute("kill")
+exit(failcount)
diff --git a/tests/tcg/multiarch/system/Makefile.softmmu-target b/tests/tcg/multiarch/system/Makefile.softmmu-target
index db4bbeda44..4657f6e4cf 100644
--- a/tests/tcg/multiarch/system/Makefile.softmmu-target
+++ b/tests/tcg/multiarch/system/Makefile.softmmu-target
@@ -7,8 +7,25 @@
 # complications of building.
 #
 
-MULTIARCH_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/multiarch/system
+MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
+MULTIARCH_SYSTEM_SRC=$(MULTIARCH_SRC)/system
 VPATH+=$(MULTIARCH_SYSTEM_SRC)
 
 MULTIARCH_TEST_SRCS=$(wildcard $(MULTIARCH_SYSTEM_SRC)/*.c)
 MULTIARCH_TESTS = $(patsubst $(MULTIARCH_SYSTEM_SRC)/%.c, %, $(MULTIARCH_TEST_SRCS))
+
+ifneq ($(HAVE_GDB_BIN),)
+GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
+
+run-gdbstub-memory: memory
+	$(call run-test, $@, $(GDB_SCRIPT) \
+		--gdb $(HAVE_GDB_BIN) \
+		--qemu $(QEMU) \
+		--output $<.gdb.out \
+		--qargs \
+		"-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \
+		--bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \
+	"softmmu gdbstub support")
+
+MULTIARCH_RUNS += run-gdbstub-memory
+endif
diff --git a/tests/tcg/x86_64/Makefile.softmmu-target b/tests/tcg/x86_64/Makefile.softmmu-target
index df252e761c..1bd763f2e6 100644
--- a/tests/tcg/x86_64/Makefile.softmmu-target
+++ b/tests/tcg/x86_64/Makefile.softmmu-target
@@ -19,6 +19,7 @@ CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
 LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
 
 TESTS+=$(MULTIARCH_TESTS)
+EXTRA_RUNS+=$(MULTIARCH_RUNS)
 
 # building head blobs
 .PRECIOUS: $(CRT_OBJS)
diff --git a/tests/tcg/x86_64/system/boot.S b/tests/tcg/x86_64/system/boot.S
index 73b19a2bda..f8a2fcc839 100644
--- a/tests/tcg/x86_64/system/boot.S
+++ b/tests/tcg/x86_64/system/boot.S
@@ -124,7 +124,7 @@ _start:
         /* don't worry about stack frame, assume everthing is garbage when we return */
 	call main
 
-        /* output any non-zero result in eax to isa-debug-exit device */
+_exit:	/* output any non-zero result in eax to isa-debug-exit device */
         test %al, %al
         jz 1f
         out %ax, $0xf4
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH  v2 5/9] gdbstub: add support to Xfer:auxv:read: packet
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (3 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 4/9] gdbstub: implement a softmmu based test Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit() Alex Bennée
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Alex Bennée, Lirong Yuan,
	Philippe Mathieu-Daudé

From: Lirong Yuan <yuanzi@google.com>

This allows gdb to access the target’s auxiliary vector,
which can be helpful for telling system libraries important details
about the hardware, operating system, and process.

[AJB: minor tweaks to test case, update MAINTAINERS]

Signed-off-by: Lirong Yuan <yuanzi@google.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20200730193932.3654677-1-yuanzi@google.com>
Message-Id: <20201214153012.12723-4-alex.bennee@linaro.org>
---
 gdbstub.c                                     | 54 ++++++++++++++++++
 MAINTAINERS                                   |  1 +
 tests/tcg/multiarch/Makefile.target           |  9 +++
 .../multiarch/gdbstub/test-qxfer-auxv-read.py | 57 +++++++++++++++++++
 4 files changed, 121 insertions(+)
 create mode 100644 tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py

diff --git a/gdbstub.c b/gdbstub.c
index d99bc0bf2e..15d3a8e1f5 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2172,6 +2172,12 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx)
             ";ReverseStep+;ReverseContinue+");
     }
 
+#ifdef CONFIG_USER_ONLY
+    if (gdbserver_state.c_cpu->opaque) {
+        g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
+    }
+#endif
+
     if (gdb_ctx->num_params &&
         strstr(gdb_ctx->params[0].data, "multiprocess+")) {
         gdbserver_state.multiprocess = true;
@@ -2233,6 +2239,46 @@ static void handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
                       gdbserver_state.str_buf->len, true);
 }
 
+#ifdef CONFIG_USER_ONLY
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
+{
+    TaskState *ts;
+    unsigned long offset, len, saved_auxv, auxv_len;
+    const char *mem;
+
+    if (gdb_ctx->num_params < 2) {
+        put_packet("E22");
+        return;
+    }
+
+    offset = gdb_ctx->params[0].val_ul;
+    len = gdb_ctx->params[1].val_ul;
+    ts = gdbserver_state.c_cpu->opaque;
+    saved_auxv = ts->info->saved_auxv;
+    auxv_len = ts->info->auxv_len;
+    mem = (const char *)(saved_auxv + offset);
+    if (offset > auxv_len) {
+        put_packet("E00");
+        return;
+    }
+
+    if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+        len = (MAX_PACKET_LENGTH - 5) / 2;
+    }
+
+    if (len < auxv_len - offset) {
+        g_string_assign(gdbserver_state.str_buf, "m");
+        memtox(gdbserver_state.str_buf, mem, len);
+    } else {
+        g_string_assign(gdbserver_state.str_buf, "l");
+        memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
+    }
+
+    put_packet_binary(gdbserver_state.str_buf->str,
+                      gdbserver_state.str_buf->len, true);
+}
+#endif
+
 static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
 {
     put_packet(GDB_ATTACHED);
@@ -2338,6 +2384,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
         .cmd_startswith = 1,
         .schema = "s:l,l0"
     },
+#ifdef CONFIG_USER_ONLY
+    {
+        .handler = handle_query_xfer_auxv,
+        .cmd = "Xfer:auxv:read::",
+        .cmd_startswith = 1,
+        .schema = "l,l0"
+    },
+#endif
     {
         .handler = handle_query_attached,
         .cmd = "Attached:",
diff --git a/MAINTAINERS b/MAINTAINERS
index d5ea7fbb8f..a4f04e19ca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2311,6 +2311,7 @@ R: Philippe Mathieu-Daudé <philmd@redhat.com>
 S: Maintained
 F: gdbstub*
 F: gdb-xml/
+F: tests/tcg/multiarch/gdbstub/
 
 Memory API
 M: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index cb49cc9ccb..1dd0f64d23 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -55,6 +55,15 @@ run-gdbstub-sha1: sha1
 	"basic gdbstub support")
 
 EXTRA_RUNS += run-gdbstub-sha1
+
+run-gdbstub-qxfer-auxv-read: sha1
+	$(call run-test, $@, $(GDB_SCRIPT) \
+		--gdb $(HAVE_GDB_BIN) \
+		--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+		--bin $< --test $(MULTIARCH_SRC)/gdbstub/test-qxfer-auxv-read.py, \
+	"basic gdbstub qXfer:auxv:read support")
+
+EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read
 endif
 
 
diff --git a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
new file mode 100644
index 0000000000..d91e8fdf19
--- /dev/null
+++ b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
@@ -0,0 +1,57 @@
+from __future__ import print_function
+#
+# Test auxiliary vector is loaded via gdbstub
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import gdb
+import sys
+
+failcount = 0
+
+def report(cond, msg):
+    "Report success/fail of test"
+    if cond:
+        print ("PASS: %s" % (msg))
+    else:
+        print ("FAIL: %s" % (msg))
+        global failcount
+        failcount += 1
+
+def run_test():
+    "Run through the tests one by one"
+
+    auxv = gdb.execute("info auxv", False, True)
+    report(isinstance(auxv, str), "Fetched auxv from inferior")
+    report(auxv.find("sha1"), "Found test binary name in auxv")
+
+#
+# This runs as the script it sourced (via -x, via run-test.py)
+#
+try:
+    inferior = gdb.selected_inferior()
+    arch = inferior.architecture()
+    print("ATTACHED: %s" % arch.name())
+except (gdb.error, AttributeError):
+    print("SKIPPING (not connected)", file=sys.stderr)
+    exit(0)
+
+if gdb.parse_and_eval('$pc') == 0:
+    print("SKIP: PC not set")
+    exit(0)
+
+try:
+    # These are not very useful in scripts
+    gdb.execute("set pagination off")
+    gdb.execute("set confirm off")
+
+    # Run the actual tests
+    run_test()
+except (gdb.error):
+    print ("GDB Exception: %s" % (sys.exc_info()[0]))
+    failcount += 1
+    pass
+
+print("All tests complete: %d failures" % failcount)
+exit(failcount)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH  v2 6/9] gdbstub: drop CPUEnv from gdb_exit()
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (4 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 5/9] gdbstub: add support to Xfer:auxv:read: packet Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 11:59   ` Laurent Vivier
  2020-12-18 14:10   ` Philippe Mathieu-Daudé
  2020-12-18 11:27 ` [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit Alex Bennée
                   ` (2 subsequent siblings)
  8 siblings, 2 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marek Vasut, Peter Maydell, Philippe Mathieu-Daudé,
	Chris Wulff, Richard Henderson, Laurent Vivier,
	open list:ARM TCG CPUs, Alex Bennée

gdb_exit() has never needed anything from env and I doubt we are going
to start now.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201214153012.12723-5-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 include/exec/gdbstub.h    | 2 +-
 bsd-user/syscall.c        | 6 +++---
 gdbstub.c                 | 2 +-
 linux-user/exit.c         | 2 +-
 target/arm/arm-semi.c     | 2 +-
 target/m68k/m68k-semi.c   | 2 +-
 target/nios2/nios2-semi.c | 2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 94d8f83e92..492db0f512 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -46,7 +46,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
 int use_gdb_syscalls(void);
 void gdb_set_stop_cpu(CPUState *cpu);
-void gdb_exit(CPUArchState *, int);
+void gdb_exit(int);
 #ifdef CONFIG_USER_ONLY
 /**
  * gdb_handlesig: yield control to gdb
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index d38ec7a162..adc3d21b54 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -333,7 +333,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef CONFIG_GPROF
         _mcleanup();
 #endif
-        gdb_exit(cpu_env, arg1);
+        gdb_exit(arg1);
         qemu_plugin_atexit_cb();
         /* XXX: should free thread stack and CPU env */
         _exit(arg1);
@@ -435,7 +435,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef CONFIG_GPROF
         _mcleanup();
 #endif
-        gdb_exit(cpu_env, arg1);
+        gdb_exit(arg1);
         qemu_plugin_atexit_cb();
         /* XXX: should free thread stack and CPU env */
         _exit(arg1);
@@ -514,7 +514,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef CONFIG_GPROF
         _mcleanup();
 #endif
-        gdb_exit(cpu_env, arg1);
+        gdb_exit(arg1);
         qemu_plugin_atexit_cb();
         /* XXX: should free thread stack and CPU env */
         _exit(arg1);
diff --git a/gdbstub.c b/gdbstub.c
index 15d3a8e1f5..afa553e8fc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3068,7 +3068,7 @@ static void gdb_read_byte(uint8_t ch)
 }
 
 /* Tell the remote gdb that the process has exited.  */
-void gdb_exit(CPUArchState *env, int code)
+void gdb_exit(int code)
 {
   char buf[4];
 
diff --git a/linux-user/exit.c b/linux-user/exit.c
index 1594015444..70b344048c 100644
--- a/linux-user/exit.c
+++ b/linux-user/exit.c
@@ -34,6 +34,6 @@ void preexit_cleanup(CPUArchState *env, int code)
 #ifdef CONFIG_GCOV
         __gcov_dump();
 #endif
-        gdb_exit(env, code);
+        gdb_exit(code);
         qemu_plugin_atexit_cb();
 }
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
index f7b7bff522..93360e28c7 100644
--- a/target/arm/arm-semi.c
+++ b/target/arm/arm-semi.c
@@ -1101,7 +1101,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
              */
             ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
         }
-        gdb_exit(env, ret);
+        gdb_exit(ret);
         exit(ret);
     case TARGET_SYS_SYNCCACHE:
         /*
diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 27600e0cc0..d919245e4f 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -195,7 +195,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
     args = env->dregs[1];
     switch (nr) {
     case HOSTED_EXIT:
-        gdb_exit(env, env->dregs[0]);
+        gdb_exit(env->dregs[0]);
         exit(env->dregs[0]);
     case HOSTED_OPEN:
         GET_ARG(0);
diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index d7a80dd303..e508b2fafc 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -215,7 +215,7 @@ void do_nios2_semihosting(CPUNios2State *env)
     args = env->regs[R_ARG1];
     switch (nr) {
     case HOSTED_EXIT:
-        gdb_exit(env, env->regs[R_ARG0]);
+        gdb_exit(env->regs[R_ARG0]);
         exit(env->regs[R_ARG0]);
     case HOSTED_OPEN:
         GET_ARG(0);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (5 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit() Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 14:10   ` Philippe Mathieu-Daudé
  2020-12-18 11:27 ` [PATCH v2 8/9] gdbstub: ensure we clean-up when terminated Alex Bennée
  2020-12-18 11:27 ` [PATCH v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers Alex Bennée
  8 siblings, 1 reply; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Alex Bennée, Philippe Mathieu-Daudé

Despite it's name it didn't actually clean-up so let us document
gdb_exit() better and use that.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201214153012.12723-6-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 include/exec/gdbstub.h | 14 +++++++++++---
 gdbstub.c              |  7 -------
 softmmu/runstate.c     |  2 +-
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 492db0f512..ff0b7bc45e 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -46,7 +46,17 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
 int use_gdb_syscalls(void);
 void gdb_set_stop_cpu(CPUState *cpu);
-void gdb_exit(int);
+
+/**
+ * gdb_exit: exit gdb session, reporting inferior status
+ * @code: exit code reported
+ *
+ * This closes the session and sends a final packet to GDB reporting
+ * the exit status of the program. It also cleans up any connections
+ * detritus before returning.
+ */
+void gdb_exit(int code);
+
 #ifdef CONFIG_USER_ONLY
 /**
  * gdb_handlesig: yield control to gdb
@@ -187,8 +197,6 @@ static inline uint8_t * gdb_get_reg_ptr(GByteArray *buf, int len)
  */
 int gdbserver_start(const char *port_or_device);
 
-void gdbserver_cleanup(void);
-
 /**
  * gdb_has_xml:
  * This is an ugly hack to cope with both new and old gdb.
diff --git a/gdbstub.c b/gdbstub.c
index afa553e8fc..bab8476357 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3547,13 +3547,6 @@ int gdbserver_start(const char *device)
     return 0;
 }
 
-void gdbserver_cleanup(void)
-{
-    if (gdbserver_state.init) {
-        put_packet("W00");
-    }
-}
-
 static void register_types(void)
 {
     type_register_static(&char_gdb_type_info);
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 636aab0add..6177693a30 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -775,7 +775,7 @@ void qemu_init_subsystems(void)
 
 void qemu_cleanup(void)
 {
-    gdbserver_cleanup();
+    gdb_exit(0);
 
     /*
      * cleaning up the migration object cancels any existing migration
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH  v2 8/9] gdbstub: ensure we clean-up when terminated
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (6 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 14:12   ` Philippe Mathieu-Daudé
  2020-12-18 11:27 ` [PATCH v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers Alex Bennée
  8 siblings, 1 reply; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Alex Bennée, Philippe Mathieu-Daudé

If you kill the inferior from GDB we end up leaving our socket lying
around. Fix this by calling gdb_exit() first.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201214153012.12723-7-alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 gdbstub.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index bab8476357..8c301edf32 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1978,6 +1978,7 @@ static void handle_v_kill(GdbCmdContext *gdb_ctx, void *user_ctx)
     /* Kill the target */
     put_packet("OK");
     error_report("QEMU: Terminated via GDBstub");
+    gdb_exit(0);
     exit(0);
 }
 
@@ -2539,6 +2540,7 @@ static int gdb_handle_packet(const char *line_buf)
     case 'k':
         /* Kill the target */
         error_report("QEMU: Terminated via GDBstub");
+        gdb_exit(0);
         exit(0);
     case 'D':
         {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers
  2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
                   ` (7 preceding siblings ...)
  2020-12-18 11:27 ` [PATCH v2 8/9] gdbstub: ensure we clean-up when terminated Alex Bennée
@ 2020-12-18 11:27 ` Alex Bennée
  2020-12-18 15:17   ` Alex Bennée
  8 siblings, 1 reply; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 11:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Luis Machado, open list:ARM TCG CPUs, Alex Bennée, Peter Maydell

While GDB can work with any XML description given to it there is
special handling for SVE registers on the GDB side which makes the
users life a little better. The changes aren't that major and all the
registers save the $vg reported the same. All that changes is:

  - report org.gnu.gdb.aarch64.sve
  - use gdb nomenclature for names and types
  - minor re-ordering of the types to match reference
  - re-enable ieee_half (as we know gdb supports it now)
  - $vg is now a 64 bit int
  - check $vN and $zN aliasing in test

[NOTE: there seems a limitation on the indexing of the pseudo $vN
registers which I'm not sure if it's intentional]

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Cc: Luis Machado <luis.machado@linaro.org>
---
 target/arm/gdbstub.c                        | 75 ++++++++-------------
 target/arm/helper.c                         |  2 +-
 tests/tcg/aarch64/gdbstub/test-sve-ioctl.py | 11 +++
 3 files changed, 41 insertions(+), 47 deletions(-)

diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 866595b4f1..a8fff2a3d0 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -195,22 +195,17 @@ static const struct TypeSize vec_lanes[] = {
     { "uint128", 128, 'q', 'u' },
     { "int128", 128, 'q', 's' },
     /* 64 bit */
+    { "ieee_double", 64, 'd', 'f' },
     { "uint64", 64, 'd', 'u' },
     { "int64", 64, 'd', 's' },
-    { "ieee_double", 64, 'd', 'f' },
     /* 32 bit */
+    { "ieee_single", 32, 's', 'f' },
     { "uint32", 32, 's', 'u' },
     { "int32", 32, 's', 's' },
-    { "ieee_single", 32, 's', 'f' },
     /* 16 bit */
+    { "ieee_half", 16, 'h', 'f' },
     { "uint16", 16, 'h', 'u' },
     { "int16", 16, 'h', 's' },
-    /*
-     * TODO: currently there is no reliable way of telling
-     * if the remote gdb actually understands ieee_half so
-     * we don't expose it in the target description for now.
-     * { "ieee_half", 16, 'h', 'f' },
-     */
     /* bytes */
     { "uint8", 8, 'b', 'u' },
     { "int8", 8, 'b', 's' },
@@ -223,17 +218,16 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
     GString *s = g_string_new(NULL);
     DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml;
     g_autoptr(GString) ts = g_string_new("");
-    int i, bits, reg_width = (cpu->sve_max_vq * 128);
+    int i, j, bits, reg_width = (cpu->sve_max_vq * 128);
     info->num = 0;
     g_string_printf(s, "<?xml version=\"1.0\"?>");
     g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
-    g_string_append_printf(s, "<feature name=\"org.qemu.gdb.aarch64.sve\">");
+    g_string_append_printf(s, "<feature name=\"org.gnu.gdb.aarch64.sve\">");
 
     /* First define types and totals in a whole VL */
     for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
         int count = reg_width / vec_lanes[i].size;
-        g_string_printf(ts, "vq%d%c%c", count,
-                        vec_lanes[i].sz, vec_lanes[i].suffix);
+        g_string_printf(ts, "svev%c%c", vec_lanes[i].sz, vec_lanes[i].suffix);
         g_string_append_printf(s,
                                "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
                                ts->str, vec_lanes[i].gdb_type, count);
@@ -243,39 +237,37 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
      * signed and potentially float versions of each size from 128 to
      * 8 bits.
      */
-    for (bits = 128; bits >= 8; bits /= 2) {
-        int count = reg_width / bits;
-        g_string_append_printf(s, "<union id=\"vq%dn\">", count);
-        for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
-            if (vec_lanes[i].size == bits) {
-                g_string_append_printf(s, "<field name=\"%c\" type=\"vq%d%c%c\"/>",
-                                       vec_lanes[i].suffix,
-                                       count,
-                                       vec_lanes[i].sz, vec_lanes[i].suffix);
+    for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) {
+        const char suf[] = { 'q', 'd', 's', 'h', 'b' };
+        g_string_append_printf(s, "<union id=\"svevn%c\">", suf[i]);
+        for (j = 0; j < ARRAY_SIZE(vec_lanes); j++) {
+            if (vec_lanes[j].size == bits) {
+                g_string_append_printf(s, "<field name=\"%c\" type=\"svev%c%c\"/>",
+                                       vec_lanes[j].suffix,
+                                       vec_lanes[j].sz, vec_lanes[j].suffix);
             }
         }
         g_string_append(s, "</union>");
     }
     /* And now the final union of unions */
-    g_string_append(s, "<union id=\"vq\">");
-    for (bits = 128; bits >= 8; bits /= 2) {
-        int count = reg_width / bits;
-        for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
-            if (vec_lanes[i].size == bits) {
-                g_string_append_printf(s, "<field name=\"%c\" type=\"vq%dn\"/>",
-                                       vec_lanes[i].sz, count);
-                break;
-            }
-        }
+    g_string_append(s, "<union id=\"svev\">");
+    for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) {
+        const char suf[] = { 'q', 'd', 's', 'h', 'b' };
+        g_string_append_printf(s, "<field name=\"%c\" type=\"svevn%c\"/>",
+                               suf[i], suf[i]);
     }
     g_string_append(s, "</union>");
 
+    /* Finally the sve prefix type */
+    g_string_append_printf(s,
+                           "<vector id=\"svep\" type=\"uint8\" count=\"%d\"/>",
+                           reg_width / 8);
+
     /* Then define each register in parts for each vq */
     for (i = 0; i < 32; i++) {
         g_string_append_printf(s,
                                "<reg name=\"z%d\" bitsize=\"%d\""
-                               " regnum=\"%d\" group=\"vector\""
-                               " type=\"vq\"/>",
+                               " regnum=\"%d\" type=\"svev\"/>",
                                i, reg_width, base_reg++);
         info->num++;
     }
@@ -287,31 +279,22 @@ int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
                            " regnum=\"%d\" group=\"float\""
                            " type=\"int\"/>", base_reg++);
     info->num += 2;
-    /*
-     * Predicate registers aren't so big they are worth splitting up
-     * but we do need to define a type to hold the array of quad
-     * references.
-     */
-    g_string_append_printf(s,
-                           "<vector id=\"vqp\" type=\"uint16\" count=\"%d\"/>",
-                           cpu->sve_max_vq);
+
     for (i = 0; i < 16; i++) {
         g_string_append_printf(s,
                                "<reg name=\"p%d\" bitsize=\"%d\""
-                               " regnum=\"%d\" group=\"vector\""
-                               " type=\"vqp\"/>",
+                               " regnum=\"%d\" type=\"svep\"/>",
                                i, cpu->sve_max_vq * 16, base_reg++);
         info->num++;
     }
     g_string_append_printf(s,
                            "<reg name=\"ffr\" bitsize=\"%d\""
                            " regnum=\"%d\" group=\"vector\""
-                           " type=\"vqp\"/>",
+                           " type=\"svep\"/>",
                            cpu->sve_max_vq * 16, base_reg++);
     g_string_append_printf(s,
                            "<reg name=\"vg\" bitsize=\"64\""
-                           " regnum=\"%d\" group=\"vector\""
-                           " type=\"uint32\"/>",
+                           " regnum=\"%d\" type=\"int\"/>",
                            base_reg++);
     info->num += 2;
     g_string_append_printf(s, "</feature>");
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7b8bcd6903..8633b3eef6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -276,7 +276,7 @@ static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
          * while the ZCR works in Vector Quads (VQ) which is 128bit chunks.
          */
         int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
-        return gdb_get_reg32(buf, vq * 2);
+        return gdb_get_reg64(buf, vq * 2);
     }
     default:
         /* gdbstub asked for something out our range */
diff --git a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
index 972cf73c31..f8cdab2e14 100644
--- a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
+++ b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
@@ -40,6 +40,17 @@ class TestBreakpoint(gdb.Breakpoint):
         except gdb.error:
             report(False, "checking zregs (out of range)")
 
+        # check the v pseudo regs - I'm not sure if them capping out
+        # at [15] is intentional though.
+        try:
+            for i in range(0, 16):
+                val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i)
+                val_v = gdb.parse_and_eval("$v0.b.u[%d]" % i)
+                report(int(val_z) == int(val_v),
+                       "v0.b.u[%d] == z0.b.u[%d]" % (i, i))
+        except gdb.error:
+            report(False, "checking vregs (out of range)")
+
 
 def run_test():
     "Run through the tests one by one"
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit()
  2020-12-18 11:27 ` [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit() Alex Bennée
@ 2020-12-18 11:59   ` Laurent Vivier
  2020-12-18 14:10   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Laurent Vivier @ 2020-12-18 11:59 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel
  Cc: Marek Vasut, Peter Maydell, Chris Wulff, Richard Henderson,
	open list:ARM TCG CPUs, Philippe Mathieu-Daudé

Le 18/12/2020 à 12:27, Alex Bennée a écrit :
> gdb_exit() has never needed anything from env and I doubt we are going
> to start now.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20201214153012.12723-5-alex.bennee@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  include/exec/gdbstub.h    | 2 +-
>  bsd-user/syscall.c        | 6 +++---
>  gdbstub.c                 | 2 +-
>  linux-user/exit.c         | 2 +-
>  target/arm/arm-semi.c     | 2 +-
>  target/m68k/m68k-semi.c   | 2 +-
>  target/nios2/nios2-semi.c | 2 +-
>  7 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
> index 94d8f83e92..492db0f512 100644
> --- a/include/exec/gdbstub.h
> +++ b/include/exec/gdbstub.h
> @@ -46,7 +46,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
>  void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
>  int use_gdb_syscalls(void);
>  void gdb_set_stop_cpu(CPUState *cpu);
> -void gdb_exit(CPUArchState *, int);
> +void gdb_exit(int);
>  #ifdef CONFIG_USER_ONLY
>  /**
>   * gdb_handlesig: yield control to gdb
> diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
> index d38ec7a162..adc3d21b54 100644
> --- a/bsd-user/syscall.c
> +++ b/bsd-user/syscall.c
> @@ -333,7 +333,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
>  #ifdef CONFIG_GPROF
>          _mcleanup();
>  #endif
> -        gdb_exit(cpu_env, arg1);
> +        gdb_exit(arg1);
>          qemu_plugin_atexit_cb();
>          /* XXX: should free thread stack and CPU env */
>          _exit(arg1);
> @@ -435,7 +435,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
>  #ifdef CONFIG_GPROF
>          _mcleanup();
>  #endif
> -        gdb_exit(cpu_env, arg1);
> +        gdb_exit(arg1);
>          qemu_plugin_atexit_cb();
>          /* XXX: should free thread stack and CPU env */
>          _exit(arg1);
> @@ -514,7 +514,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
>  #ifdef CONFIG_GPROF
>          _mcleanup();
>  #endif
> -        gdb_exit(cpu_env, arg1);
> +        gdb_exit(arg1);
>          qemu_plugin_atexit_cb();
>          /* XXX: should free thread stack and CPU env */
>          _exit(arg1);
> diff --git a/gdbstub.c b/gdbstub.c
> index 15d3a8e1f5..afa553e8fc 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -3068,7 +3068,7 @@ static void gdb_read_byte(uint8_t ch)
>  }
>  
>  /* Tell the remote gdb that the process has exited.  */
> -void gdb_exit(CPUArchState *env, int code)
> +void gdb_exit(int code)
>  {
>    char buf[4];
>  
> diff --git a/linux-user/exit.c b/linux-user/exit.c
> index 1594015444..70b344048c 100644
> --- a/linux-user/exit.c
> +++ b/linux-user/exit.c
> @@ -34,6 +34,6 @@ void preexit_cleanup(CPUArchState *env, int code)
>  #ifdef CONFIG_GCOV
>          __gcov_dump();
>  #endif
> -        gdb_exit(env, code);
> +        gdb_exit(code);
>          qemu_plugin_atexit_cb();
>  }
> diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
> index f7b7bff522..93360e28c7 100644
> --- a/target/arm/arm-semi.c
> +++ b/target/arm/arm-semi.c
> @@ -1101,7 +1101,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>               */
>              ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
>          }
> -        gdb_exit(env, ret);
> +        gdb_exit(ret);
>          exit(ret);
>      case TARGET_SYS_SYNCCACHE:
>          /*
> diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
> index 27600e0cc0..d919245e4f 100644
> --- a/target/m68k/m68k-semi.c
> +++ b/target/m68k/m68k-semi.c
> @@ -195,7 +195,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
>      args = env->dregs[1];
>      switch (nr) {
>      case HOSTED_EXIT:
> -        gdb_exit(env, env->dregs[0]);
> +        gdb_exit(env->dregs[0]);
>          exit(env->dregs[0]);
>      case HOSTED_OPEN:
>          GET_ARG(0);
> diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
> index d7a80dd303..e508b2fafc 100644
> --- a/target/nios2/nios2-semi.c
> +++ b/target/nios2/nios2-semi.c
> @@ -215,7 +215,7 @@ void do_nios2_semihosting(CPUNios2State *env)
>      args = env->regs[R_ARG1];
>      switch (nr) {
>      case HOSTED_EXIT:
> -        gdb_exit(env, env->regs[R_ARG0]);
> +        gdb_exit(env->regs[R_ARG0]);
>          exit(env->regs[R_ARG0]);
>      case HOSTED_OPEN:
>          GET_ARG(0);
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit
  2020-12-18 11:27 ` [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit Alex Bennée
@ 2020-12-18 14:10   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-18 14:10 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel; +Cc: Richard Henderson

On 12/18/20 12:27 PM, Alex Bennée wrote:
> Despite it's name it didn't actually clean-up so let us document
> gdb_exit() better and use that.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20201214153012.12723-6-alex.bennee@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  include/exec/gdbstub.h | 14 +++++++++++---
>  gdbstub.c              |  7 -------
>  softmmu/runstate.c     |  2 +-
>  3 files changed, 12 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit()
  2020-12-18 11:27 ` [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit() Alex Bennée
  2020-12-18 11:59   ` Laurent Vivier
@ 2020-12-18 14:10   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-18 14:10 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel
  Cc: Marek Vasut, Peter Maydell, Chris Wulff, Richard Henderson,
	Laurent Vivier, open list:ARM TCG CPUs

On 12/18/20 12:27 PM, Alex Bennée wrote:
> gdb_exit() has never needed anything from env and I doubt we are going
> to start now.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20201214153012.12723-5-alex.bennee@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  include/exec/gdbstub.h    | 2 +-
>  bsd-user/syscall.c        | 6 +++---
>  gdbstub.c                 | 2 +-
>  linux-user/exit.c         | 2 +-
>  target/arm/arm-semi.c     | 2 +-
>  target/m68k/m68k-semi.c   | 2 +-
>  target/nios2/nios2-semi.c | 2 +-
>  7 files changed, 9 insertions(+), 9 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 8/9] gdbstub: ensure we clean-up when terminated
  2020-12-18 11:27 ` [PATCH v2 8/9] gdbstub: ensure we clean-up when terminated Alex Bennée
@ 2020-12-18 14:12   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-18 14:12 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel; +Cc: Richard Henderson

On 12/18/20 12:27 PM, Alex Bennée wrote:
> If you kill the inferior from GDB we end up leaving our socket lying
> around. Fix this by calling gdb_exit() first.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20201214153012.12723-7-alex.bennee@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  gdbstub.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 4/9] gdbstub: implement a softmmu based test
  2020-12-18 11:27 ` [PATCH v2 4/9] gdbstub: implement a softmmu based test Alex Bennée
@ 2020-12-18 14:45   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-18 14:45 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel
  Cc: Peter Maydell, open list:ARM TCG CPUs, Richard Henderson,
	Eduardo Habkost, Paolo Bonzini

On 12/18/20 12:27 PM, Alex Bennée wrote:
> This adds a new tests that allows us to test softmmu only features
> including watchpoints. To do achieve this we need to:
> 
>   - add _exit: labels to the boot codes
>   - write a memory.py test case
>   - plumb the test case into the build system
>   - tweak the run_test script to:
>     - re-direct output when asked
>     - use socket based connection for all tests
>     - add a small pause before connection
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  tests/guest-debug/run-test.py                 |  36 +++--
>  tests/tcg/aarch64/Makefile.softmmu-target     |   1 +
>  tests/tcg/aarch64/system/boot.S               |   1 +
>  tests/tcg/i386/Makefile.softmmu-target        |   1 +
>  tests/tcg/i386/system/boot.S                  |   2 +-
>  tests/tcg/multiarch/gdbstub/memory.py         | 130 ++++++++++++++++++
>  .../multiarch/system/Makefile.softmmu-target  |  19 ++-
>  tests/tcg/x86_64/Makefile.softmmu-target      |   1 +
>  tests/tcg/x86_64/system/boot.S                |   2 +-
>  9 files changed, 181 insertions(+), 12 deletions(-)
>  create mode 100644 tests/tcg/multiarch/gdbstub/memory.py
> 
> diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
> index 0c4f5c3808..8b91ff95af 100755
> --- a/tests/guest-debug/run-test.py
> +++ b/tests/guest-debug/run-test.py
> @@ -16,6 +16,7 @@ import subprocess
>  import shutil
>  import shlex
>  import os
> +from time import sleep
>  from tempfile import TemporaryDirectory
>  
>  def get_args():
> @@ -27,10 +28,21 @@ def get_args():
>                          required=True)
>      parser.add_argument("--test", help="GDB test script",
>                          required=True)
> -    parser.add_argument("--gdb", help="The gdb binary to use", default=None)
> +    parser.add_argument("--gdb", help="The gdb binary to use",
> +                        default=None)
> +    parser.add_argument("--output", help="A file to redirect output to")
>  
>      return parser.parse_args()
>  
> +
> +def log(output, msg):

Maybe simplify as:

  def log(msg, out=sys.stdout):
      output.write(msg + "\n")
      output.flush()

> +    if output:
> +        output.write(msg + "\n")
> +        output.flush()
> +    else:
> +        print(msg)
> +
> +
>  if __name__ == '__main__':
>      args = get_args()
>  
> @@ -42,18 +54,25 @@ if __name__ == '__main__':
>      if not args.gdb:
>          print("We need gdb to run the test")
>          exit(-1)
> +    if args.output:
> +        output = open(args.output, "w")
> +    else:
> +        output = None
>  
>      socket_dir = TemporaryDirectory("qemu-gdbstub")
>      socket_name = os.path.join(socket_dir.name, "gdbstub.socket")
>  
>      # Launch QEMU with binary
>      if "system" in args.qemu:
> -        cmd = "%s %s %s -s -S" % (args.qemu, args.qargs, args.binary)
> +        cmd = "%s %s %s -gdb unix:path=%s,server" % (args.qemu,
> +                                                     args.qargs,
> +                                                     args.binary,
> +                                                     socket_name)

What about Windows hosts?

>      else:
>          cmd = "%s %s -g %s %s" % (args.qemu, args.qargs, socket_name,
>                                    args.binary)
>  
> -    print("QEMU CMD: %s" % (cmd))
> +    log(output, "QEMU CMD: %s" % (cmd))
>      inferior = subprocess.Popen(shlex.split(cmd))
>  
>      # Now launch gdb with our test and collect the result
> @@ -63,16 +82,15 @@ if __name__ == '__main__':
>      # disable prompts in case of crash
>      gdb_cmd += " -ex 'set confirm off'"
>      # connect to remote
> -    if "system" in args.qemu:
> -        gdb_cmd += " -ex 'target remote localhost:1234'"
> -    else:
> -        gdb_cmd += " -ex 'target remote %s'" % (socket_name)
> +    gdb_cmd += " -ex 'target remote %s'" % (socket_name)
>      # finally the test script itself
>      gdb_cmd += " -x %s" % (args.test)
>  
> -    print("GDB CMD: %s" % (gdb_cmd))
>  
> -    result = subprocess.call(gdb_cmd, shell=True);
> +    sleep(1)
> +    log(output, "GDB CMD: %s" % (gdb_cmd))
> +
> +    result = subprocess.call(gdb_cmd, shell=True, stdout=output)
>  
>      # A negative result is the result of an internal gdb failure like
>      # a crash. We force a return of 0 so we don't fail the test on
> diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
> index 1057a8ac49..a7286ac295 100644
> --- a/tests/tcg/aarch64/Makefile.softmmu-target
> +++ b/tests/tcg/aarch64/Makefile.softmmu-target
> @@ -15,6 +15,7 @@ CRT_PATH=$(AARCH64_SYSTEM_SRC)
>  LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
>  LDFLAGS=-Wl,-T$(LINK_SCRIPT)
>  TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
> +EXTRA_RUNS+=$(MULTIARCH_RUNS)
>  CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
>  LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
>  
> diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
> index b14e94f332..e190b1efa6 100644
> --- a/tests/tcg/aarch64/system/boot.S
> +++ b/tests/tcg/aarch64/system/boot.S
> @@ -197,6 +197,7 @@ __start:
>  	bl	main
>  
>  	/* pass return value to sys exit */
> +_exit:
>  	mov    x1, x0
>  	ldr    x0, =0x20026 /* ADP_Stopped_ApplicationExit */
>  	stp    x0, x1, [sp, #-16]!
> diff --git a/tests/tcg/i386/Makefile.softmmu-target b/tests/tcg/i386/Makefile.softmmu-target
> index 1c8790eecd..5266f2335a 100644
> --- a/tests/tcg/i386/Makefile.softmmu-target
> +++ b/tests/tcg/i386/Makefile.softmmu-target
> @@ -19,6 +19,7 @@ CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
>  LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
>  
>  TESTS+=$(MULTIARCH_TESTS)
> +EXTRA_RUNS+=$(MULTIARCH_RUNS)
>  
>  # building head blobs
>  .PRECIOUS: $(CRT_OBJS)
> diff --git a/tests/tcg/i386/system/boot.S b/tests/tcg/i386/system/boot.S
> index 90aa174908..794c2cb0ad 100644
> --- a/tests/tcg/i386/system/boot.S
> +++ b/tests/tcg/i386/system/boot.S
> @@ -76,7 +76,7 @@ _start:
>           */
>          call main
>  
> -        /* output any non-zero result in eax to isa-debug-exit device */
> +_exit:	/* output any non-zero result in eax to isa-debug-exit device */
>          test %al, %al
>          jz 1f
>          out %ax, $0xf4
> diff --git a/tests/tcg/multiarch/gdbstub/memory.py b/tests/tcg/multiarch/gdbstub/memory.py
> new file mode 100644
> index 0000000000..67864ad902
> --- /dev/null
> +++ b/tests/tcg/multiarch/gdbstub/memory.py
> @@ -0,0 +1,130 @@
> +from __future__ import print_function

Missing license.

> +#
> +# Test some of the softmmu debug features with the multiarch memory
> +# test. It is a port of the original vmlinux focused test case but
> +# using the "memory" test instead.
> +#
> +# This is launched via tests/guest-debug/run-test.py
> +#
> +
> +import gdb
> +import sys
> +
> +failcount = 0
> +
> +
> +def report(cond, msg):
> +    "Report success/fail of test"
> +    if cond:
> +        print("PASS: %s" % (msg))
> +    else:
> +        print("FAIL: %s" % (msg))
> +        global failcount
> +        failcount += 1
> +
> +
> +def check_step():
> +    "Step an instruction, check it moved."
> +    start_pc = gdb.parse_and_eval('$pc')
> +    gdb.execute("si")
> +    end_pc = gdb.parse_and_eval('$pc')
> +
> +    return not (start_pc == end_pc)
> +
> +
> +#
> +# Currently it's hard to create a hbreak with the pure python API and
> +# manually matching PC to symbol address is a bit flaky thanks to
> +# function prologues. However internally QEMU's gdbstub treats them
> +# the same as normal breakpoints so it will do for now.
> +#
> +def check_break(sym_name):
> +    "Setup breakpoint, continue and check we stopped."
> +    sym, ok = gdb.lookup_symbol(sym_name)
> +    bp = gdb.Breakpoint(sym_name, gdb.BP_BREAKPOINT)
> +
> +    gdb.execute("c")
> +
> +    # hopefully we came back

What if we don't? Not a blocking problem today, we'll figure
if we need to improve that later.

> +    end_pc = gdb.parse_and_eval('$pc')
> +    report(bp.hit_count == 1,
> +           "break @ %s (%s %d hits)" % (end_pc, sym.value(), bp.hit_count))
> +
> +    bp.delete()
> +
> +
> +def do_one_watch(sym, wtype, text):
> +
> +    wp = gdb.Breakpoint(sym, gdb.BP_WATCHPOINT, wtype)
> +    gdb.execute("c")
> +    report_str = "%s for %s" % (text, sym)
> +
> +    if wp.hit_count > 0:
> +        report(True, report_str)
> +        wp.delete()
> +    else:
> +        report(False, report_str)
> +
> +
> +def check_watches(sym_name):
> +    "Watch a symbol for any access."
> +
> +    # Should hit for any read
> +    do_one_watch(sym_name, gdb.WP_ACCESS, "awatch")
> +
> +    # Again should hit for reads
> +    do_one_watch(sym_name, gdb.WP_READ, "rwatch")
> +
> +    # Finally when it is written
> +    do_one_watch(sym_name, gdb.WP_WRITE, "watch")
> +
> +
> +def run_test():
> +    "Run through the tests one by one"
> +
> +    print("Checking we can step the first few instructions")
> +    step_ok = 0
> +    for i in range(3):
> +        if check_step():
> +            step_ok += 1
> +
> +    report(step_ok == 3, "single step in boot code")
> +
> +    # If we get here we have missed some of the other breakpoints.
> +    print("Setup catch-all for _exit")
> +    cbp = gdb.Breakpoint("_exit", gdb.BP_BREAKPOINT)
> +
> +    check_break("main")
> +    check_watches("test_data[128]")
> +
> +    report(cbp.hit_count == 0, "didn't reach backstop")
> +
> +#
> +# This runs as the script it sourced (via -x, via run-test.py)
> +#
> +try:
> +    inferior = gdb.selected_inferior()
> +    arch = inferior.architecture()
> +    print("ATTACHED: %s" % arch.name())
> +except (gdb.error, AttributeError):
> +    print("SKIPPING (not connected)", file=sys.stderr)
> +    exit(0)
> +
> +if gdb.parse_and_eval('$pc') == 0:
> +    print("SKIP: PC not set")
> +    exit(0)
> +
> +try:
> +    # These are not very useful in scripts
> +    gdb.execute("set pagination off")
> +
> +    # Run the actual tests
> +    run_test()
> +except (gdb.error):
> +    print("GDB Exception: %s" % (sys.exc_info()[0]))
> +    failcount += 1
> +    pass
> +
> +# Finally kill the inferior and exit gdb with a count of failures
> +gdb.execute("kill")
> +exit(failcount)
> diff --git a/tests/tcg/multiarch/system/Makefile.softmmu-target b/tests/tcg/multiarch/system/Makefile.softmmu-target
> index db4bbeda44..4657f6e4cf 100644
> --- a/tests/tcg/multiarch/system/Makefile.softmmu-target
> +++ b/tests/tcg/multiarch/system/Makefile.softmmu-target
> @@ -7,8 +7,25 @@
>  # complications of building.
>  #
>  
> -MULTIARCH_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/multiarch/system
> +MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
> +MULTIARCH_SYSTEM_SRC=$(MULTIARCH_SRC)/system
>  VPATH+=$(MULTIARCH_SYSTEM_SRC)
>  
>  MULTIARCH_TEST_SRCS=$(wildcard $(MULTIARCH_SYSTEM_SRC)/*.c)
>  MULTIARCH_TESTS = $(patsubst $(MULTIARCH_SYSTEM_SRC)/%.c, %, $(MULTIARCH_TEST_SRCS))
> +
> +ifneq ($(HAVE_GDB_BIN),)
> +GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
> +
> +run-gdbstub-memory: memory
> +	$(call run-test, $@, $(GDB_SCRIPT) \
> +		--gdb $(HAVE_GDB_BIN) \
> +		--qemu $(QEMU) \
> +		--output $<.gdb.out \
> +		--qargs \
> +		"-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \
> +		--bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \
> +	"softmmu gdbstub support")
> +
> +MULTIARCH_RUNS += run-gdbstub-memory
> +endif
> diff --git a/tests/tcg/x86_64/Makefile.softmmu-target b/tests/tcg/x86_64/Makefile.softmmu-target
> index df252e761c..1bd763f2e6 100644
> --- a/tests/tcg/x86_64/Makefile.softmmu-target
> +++ b/tests/tcg/x86_64/Makefile.softmmu-target
> @@ -19,6 +19,7 @@ CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
>  LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
>  
>  TESTS+=$(MULTIARCH_TESTS)
> +EXTRA_RUNS+=$(MULTIARCH_RUNS)
>  
>  # building head blobs
>  .PRECIOUS: $(CRT_OBJS)
> diff --git a/tests/tcg/x86_64/system/boot.S b/tests/tcg/x86_64/system/boot.S
> index 73b19a2bda..f8a2fcc839 100644
> --- a/tests/tcg/x86_64/system/boot.S
> +++ b/tests/tcg/x86_64/system/boot.S
> @@ -124,7 +124,7 @@ _start:
>          /* don't worry about stack frame, assume everthing is garbage when we return */
>  	call main
>  
> -        /* output any non-zero result in eax to isa-debug-exit device */
> +_exit:	/* output any non-zero result in eax to isa-debug-exit device */
>          test %al, %al
>          jz 1f
>          out %ax, $0xf4
> 

LGTM. With license:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH  v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers
  2020-12-18 11:27 ` [PATCH v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers Alex Bennée
@ 2020-12-18 15:17   ` Alex Bennée
  0 siblings, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2020-12-18 15:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Luis Machado, open list:ARM TCG CPUs, Alex Bennée, Peter Maydell


Alex Bennée <alex.bennee@linaro.org> writes:

> While GDB can work with any XML description given to it there is
> special handling for SVE registers on the GDB side which makes the
> users life a little better. The changes aren't that major and all the
> registers save the $vg reported the same. All that changes is:
>
>   - report org.gnu.gdb.aarch64.sve
>   - use gdb nomenclature for names and types
>   - minor re-ordering of the types to match reference
>   - re-enable ieee_half (as we know gdb supports it now)
>   - $vg is now a 64 bit int
>   - check $vN and $zN aliasing in test
>
> [NOTE: there seems a limitation on the indexing of the pseudo $vN
> registers which I'm not sure if it's intentional]

It is (v registers are the aliased vector registers, not an alternative
to the z register).
>  
> +        # check the v pseudo regs - I'm not sure if them capping out
> +        # at [15] is intentional though.

I'm going to change this comment to:

  Check the aliased V registers are set and GDB has correctly
  created them for us having recognised and handled SVE.

> +        try:
> +            for i in range(0, 16):
> +                val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i)
> +                val_v = gdb.parse_and_eval("$v0.b.u[%d]" % i)
> +                report(int(val_z) == int(val_v),
> +                       "v0.b.u[%d] == z0.b.u[%d]" % (i, i))
> +        except gdb.error:
> +            report(False, "checking vregs (out of range)")
> +
>  
>  def run_test():
>      "Run through the tests one by one"


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-12-18 15:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-18 11:26 [PATCH v2 0/9] gdbstub/next (cleanups, softmmu, SVE) Alex Bennée
2020-12-18 11:26 ` [PATCH v2 1/9] test/guest-debug: echo QEMU command as well Alex Bennée
2020-12-18 11:27 ` [PATCH v2 2/9] configure: gate our use of GDB to 8.3.1 or above Alex Bennée
2020-12-18 11:27 ` [PATCH v2 3/9] Revert "tests/tcg/multiarch/Makefile.target: Disable run-gdbstub-sha1 test" Alex Bennée
2020-12-18 11:27 ` [PATCH v2 4/9] gdbstub: implement a softmmu based test Alex Bennée
2020-12-18 14:45   ` Philippe Mathieu-Daudé
2020-12-18 11:27 ` [PATCH v2 5/9] gdbstub: add support to Xfer:auxv:read: packet Alex Bennée
2020-12-18 11:27 ` [PATCH v2 6/9] gdbstub: drop CPUEnv from gdb_exit() Alex Bennée
2020-12-18 11:59   ` Laurent Vivier
2020-12-18 14:10   ` Philippe Mathieu-Daudé
2020-12-18 11:27 ` [PATCH v2 7/9] gdbstub: drop gdbserver_cleanup in favour of gdb_exit Alex Bennée
2020-12-18 14:10   ` Philippe Mathieu-Daudé
2020-12-18 11:27 ` [PATCH v2 8/9] gdbstub: ensure we clean-up when terminated Alex Bennée
2020-12-18 14:12   ` Philippe Mathieu-Daudé
2020-12-18 11:27 ` [PATCH v2 9/9] target/arm: use official org.gnu.gdb.aarch64.sve layout for registers Alex Bennée
2020-12-18 15:17   ` Alex Bennée

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).