Testing and gdbstub updates:

- travis: drop macosx, tweak ppc64 native
   - cirrus: fix FreeBSD, guard against future breakage
   - gdbstub: support socket debug for linux-user
   - gdbstub: add multiarch tests
   - gdbstub: fixes for m68k
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAl6ydk0ACgkQ+9DbCVqe
 KkTcKQf+M+5B0HQsLVW5Z/n7zIL4v5LNRwtOt+a1zBusDgAUIsWKvfSpezk8ddCB
 hr1qIgN9jdi3OfR/HDPTwqd++n+t7HTCadL4tO7to2iKRzdpM0oDbjo2+hgSNSX4
 L5Nv79eEr1askD5rWq6QJZqJpeversvp2vvJcgJU4ukjsv7eTSfEW5iDS0DhOlx3
 KM3prMY36KEYvch6yFwEatA7qerc08K06xi9M5Z2ZAjm5qKVNeC3tVkZSyxmubBn
 LvmWt6zN/eHEUYM9qK+e9fAVhcreGNTJ7d2uB4XI+dA3tQOUXgdDKruxMc3rhoWZ
 JlB2Tipj3R2I3fVJwwSAnpmxV+xZ4g==
 =Uy3H
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-and-gdbstub-060520-1' into staging

Testing and gdbstub updates:

  - travis: drop macosx, tweak ppc64 native
  - cirrus: fix FreeBSD, guard against future breakage
  - gdbstub: support socket debug for linux-user
  - gdbstub: add multiarch tests
  - gdbstub: fixes for m68k

# gpg: Signature made Wed 06 May 2020 09:33:17 BST
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* remotes/stsquad/tags/pull-testing-and-gdbstub-060520-1:
  target/m68k: fix gdb for m68xxx
  tests/tcg: add a multiarch linux-user gdb test
  tests/guest-debug: use the unix socket for linux-user tests
  gdbstub/linux-user: support debugging over a unix socket
  gdbstub: eliminate gdbserver_fd global
  tests/tcg: drop inferior.was_attached() test
  tests/tcg: better trap gdb failures
  gdbstub: Introduce gdb_get_float64() to get 64-bit float registers
  configure: favour gdb-multiarch if we have it
  .travis.yml: reduce the load on [ppc64] GCC check-tcg
  .cirrus.yml: bootstrap pkg unconditionally
  .cirrus.yml: bump FreeBSD to the current stable release
  .travis.yml: drop MacOSX
  .travis.yml: show free disk space at end of run

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-05-06 14:06:00 +01:00
commit a36d64f433
19 changed files with 328 additions and 104 deletions

View file

@ -3,10 +3,10 @@ env:
freebsd_12_task:
freebsd_instance:
image: freebsd-12-0-release-amd64
image_family: freebsd-12-1
cpu: 8
memory: 8G
install_script: pkg install -y
install_script: ASSUME_ALWAYS_YES=yes pkg bootstrap -f ; pkg install -y
bash bison curl cyrus-sasl git glib gmake gnutls gsed
nettle perl5 pixman pkgconf png usbredir
script:

View file

@ -9,9 +9,8 @@ compiler:
cache:
# There is one cache per branch and compiler version.
# characteristics of each job are used to identify the cache:
# - OS name (currently, linux, osx, or windows)
# - OS name (currently only linux)
# - OS distribution (for Linux, xenial, trusty, or precise)
# - macOS image name (e.g., xcode7.2)
# - Names and values of visible environment variables set in .travis.yml or Settings panel
timeout: 1200
ccache: true
@ -113,6 +112,7 @@ script:
$(exit $BUILD_RC);
fi
after_script:
- df -h
- if command -v ccache ; then ccache --show-stats ; fi
@ -270,31 +270,6 @@ jobs:
- TEST_CMD=""
# MacOSX builds - cirrus.yml also tests some MacOS builds including latest Xcode
- name: "OSX Xcode 10.3"
env:
- BASE_CONFIG="--disable-docs --enable-tools"
- CONFIG="--target-list=i386-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,x86_64-softmmu"
os: osx
osx_image: xcode10.3
compiler: clang
addons:
homebrew:
packages:
- ccache
- glib
- pixman
- gnu-sed
- python
update: true
before_script:
- brew link --overwrite python
- export PATH="/usr/local/opt/ccache/libexec:$PATH"
- mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
- ${SRC_DIR}/configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; }
# Python builds
- name: "GCC Python 3.5 (x86_64-softmmu)"
env:
@ -483,7 +458,7 @@ jobs:
- genisoimage
env:
- TEST_CMD="make check check-tcg V=1"
- CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS},ppc64le-linux-user"
- CONFIG="--disable-containers --target-list=ppc64-softmmu,ppc64le-linux-user"
- name: "[s390x] GCC check-tcg"
arch: s390x

View file

@ -738,7 +738,7 @@ int main(int argc, char **argv)
CPUState *cpu;
int optind;
const char *r;
int gdbstub_port = 0;
const char *gdbstub = NULL;
char **target_environ, **wrk;
envlist_t *envlist = NULL;
char *trace_file = NULL;
@ -814,7 +814,7 @@ int main(int argc, char **argv)
exit(1);
}
} else if (!strcmp(r, "g")) {
gdbstub_port = atoi(argv[optind++]);
gdbstub = g_strdup(argv[optind++]);
} else if (!strcmp(r, "r")) {
qemu_uname_release = argv[optind++];
} else if (!strcmp(r, "cpu")) {
@ -1124,8 +1124,8 @@ int main(int argc, char **argv)
#error unsupported target CPU
#endif
if (gdbstub_port) {
gdbserver_start (gdbstub_port);
if (gdbstub) {
gdbserver_start(gdbstub);
gdb_handlesig(cpu, 0);
}
cpu_loop(env);

4
configure vendored
View file

@ -303,7 +303,7 @@ libs_qga=""
debug_info="yes"
stack_protector=""
use_containers="yes"
gdb_bin=$(command -v "gdb")
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
if test -e "$source_path/.git"
then
@ -7825,7 +7825,7 @@ case "$target_name" in
;;
m68k)
bflt="yes"
gdb_xml_files="cf-core.xml cf-fp.xml m68k-fp.xml"
gdb_xml_files="cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml"
TARGET_SYSTBL_ABI=common
;;
microblaze|microblazeel)

29
gdb-xml/m68k-core.xml Normal file
View file

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.m68k.core">
<reg name="d0" bitsize="32"/>
<reg name="d1" bitsize="32"/>
<reg name="d2" bitsize="32"/>
<reg name="d3" bitsize="32"/>
<reg name="d4" bitsize="32"/>
<reg name="d5" bitsize="32"/>
<reg name="d6" bitsize="32"/>
<reg name="d7" bitsize="32"/>
<reg name="a0" bitsize="32" type="data_ptr"/>
<reg name="a1" bitsize="32" type="data_ptr"/>
<reg name="a2" bitsize="32" type="data_ptr"/>
<reg name="a3" bitsize="32" type="data_ptr"/>
<reg name="a4" bitsize="32" type="data_ptr"/>
<reg name="a5" bitsize="32" type="data_ptr"/>
<reg name="fp" bitsize="32" type="data_ptr"/>
<reg name="sp" bitsize="32" type="data_ptr"/>
<reg name="ps" bitsize="32"/>
<reg name="pc" bitsize="32" type="code_ptr"/>
</feature>

119
gdbstub.c
View file

@ -355,6 +355,7 @@ typedef struct GDBState {
int signal;
#ifdef CONFIG_USER_ONLY
int fd;
char *socket_path;
int running_state;
#else
CharBackend chr;
@ -398,8 +399,6 @@ static void reset_gdbserver_state(void)
bool gdb_has_xml;
#ifdef CONFIG_USER_ONLY
/* XXX: This is not thread safe. Do we care? */
static int gdbserver_fd = -1;
static int get_char(void)
{
@ -2964,7 +2963,10 @@ void gdb_exit(CPUArchState *env, int code)
return;
}
#ifdef CONFIG_USER_ONLY
if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
if (gdbserver_state.socket_path) {
unlink(gdbserver_state.socket_path);
}
if (gdbserver_state.fd < 0) {
return;
}
#endif
@ -3011,7 +3013,7 @@ gdb_handlesig(CPUState *cpu, int sig)
char buf[256];
int n;
if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
if (!gdbserver_state.init || gdbserver_state.fd < 0) {
return sig;
}
@ -3060,7 +3062,7 @@ void gdb_signalled(CPUArchState *env, int sig)
{
char buf[4];
if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
if (!gdbserver_state.init || gdbserver_state.fd < 0) {
return;
}
@ -3068,7 +3070,66 @@ void gdb_signalled(CPUArchState *env, int sig)
put_packet(buf);
}
static bool gdb_accept(void)
static void gdb_accept_init(int fd)
{
init_gdbserver_state();
create_default_process(&gdbserver_state);
gdbserver_state.processes[0].attached = true;
gdbserver_state.c_cpu = gdb_first_attached_cpu();
gdbserver_state.g_cpu = gdbserver_state.c_cpu;
gdbserver_state.fd = fd;
gdb_has_xml = false;
}
static bool gdb_accept_socket(int gdb_fd)
{
int fd;
for(;;) {
fd = accept(gdb_fd, NULL, NULL);
if (fd < 0 && errno != EINTR) {
perror("accept socket");
return false;
} else if (fd >= 0) {
qemu_set_cloexec(fd);
break;
}
}
gdb_accept_init(fd);
return true;
}
static int gdbserver_open_socket(const char *path)
{
struct sockaddr_un sockaddr;
int fd, ret;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
perror("create socket");
return -1;
}
sockaddr.sun_family = AF_UNIX;
pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if (ret < 0) {
perror("bind socket");
close(fd);
return -1;
}
ret = listen(fd, 1);
if (ret < 0) {
perror("listen socket");
close(fd);
return -1;
}
return fd;
}
static bool gdb_accept_tcp(int gdb_fd)
{
struct sockaddr_in sockaddr;
socklen_t len;
@ -3076,7 +3137,7 @@ static bool gdb_accept(void)
for(;;) {
len = sizeof(sockaddr);
fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
if (fd < 0 && errno != EINTR) {
perror("accept");
return false;
@ -3093,17 +3154,11 @@ static bool gdb_accept(void)
return false;
}
init_gdbserver_state();
create_default_process(&gdbserver_state);
gdbserver_state.processes[0].attached = true;
gdbserver_state.c_cpu = gdb_first_attached_cpu();
gdbserver_state.g_cpu = gdbserver_state.c_cpu;
gdbserver_state.fd = fd;
gdb_has_xml = false;
gdb_accept_init(fd);
return true;
}
static int gdbserver_open(int port)
static int gdbserver_open_port(int port)
{
struct sockaddr_in sockaddr;
int fd, ret;
@ -3132,27 +3187,41 @@ static int gdbserver_open(int port)
close(fd);
return -1;
}
return fd;
}
int gdbserver_start(int port)
int gdbserver_start(const char *port_or_path)
{
gdbserver_fd = gdbserver_open(port);
if (gdbserver_fd < 0)
return -1;
/* accept connections */
if (!gdb_accept()) {
close(gdbserver_fd);
gdbserver_fd = -1;
int port = g_ascii_strtoull(port_or_path, NULL, 10);
int gdb_fd;
if (port > 0) {
gdb_fd = gdbserver_open_port(port);
} else {
gdb_fd = gdbserver_open_socket(port_or_path);
}
if (gdb_fd < 0) {
return -1;
}
return 0;
if (port > 0 && gdb_accept_tcp(gdb_fd)) {
return 0;
} else if (gdb_accept_socket(gdb_fd)) {
gdbserver_state.socket_path = g_strdup(port_or_path);
return 0;
}
/* gone wrong */
close(gdb_fd);
return -1;
}
/* Disable gdb stub for child processes. */
void gdbserver_fork(CPUState *cpu)
{
if (gdbserver_fd < 0 || gdbserver_state.fd < 0) {
if (!gdbserver_state.init || gdbserver_state.fd < 0) {
return;
}
close(gdbserver_state.fd);

View file

@ -134,6 +134,17 @@ static inline int gdb_get_float32(GByteArray *array, float32 val)
return sizeof(buf);
}
static inline int gdb_get_float64(GByteArray *array, float64 val)
{
uint8_t buf[sizeof(CPU_DoubleU)];
stfq_p(buf, val);
g_byte_array_append(array, buf, sizeof(buf));
return sizeof(buf);
}
static inline int gdb_get_zeroes(GByteArray *array, size_t len)
{
guint oldlen = array->len;
@ -166,11 +177,15 @@ static inline uint8_t * gdb_get_reg_ptr(GByteArray *buf, int len)
#endif
#ifdef CONFIG_USER_ONLY
int gdbserver_start(int);
#else
int gdbserver_start(const char *port);
#endif
/**
* gdbserver_start: start the gdb server
* @port_or_device: connection spec for gdb
*
* For CONFIG_USER this is either a tcp port or a path to a fifo. For
* system emulation you can use a full chardev spec for your gdbserver
* port.
*/
int gdbserver_start(const char *port_or_device);
void gdbserver_cleanup(void);

View file

@ -51,7 +51,7 @@ char *exec_path;
int singlestep;
static const char *argv0;
static int gdbstub_port;
static const char *gdbstub;
static envlist_t *envlist;
static const char *cpu_model;
static const char *cpu_type;
@ -310,7 +310,7 @@ static void handle_arg_seed(const char *arg)
static void handle_arg_gdb(const char *arg)
{
gdbstub_port = atoi(arg);
gdbstub = g_strdup(arg);
}
static void handle_arg_uname(const char *arg)
@ -861,10 +861,10 @@ int main(int argc, char **argv, char **envp)
target_cpu_copy_regs(env, regs);
if (gdbstub_port) {
if (gdbserver_start(gdbstub_port) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on port %d\n",
gdbstub_port);
if (gdbstub) {
if (gdbserver_start(gdbstub) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on %s\n",
gdbstub);
exit(EXIT_FAILURE);
}
gdb_handlesig(cpu, 0);

View file

@ -292,16 +292,38 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->tcg_initialize = m68k_tcg_init;
cc->gdb_num_core_regs = 18;
cc->gdb_core_xml_file = "cf-core.xml";
dc->vmsd = &vmstate_m68k_cpu;
}
#define DEFINE_M68K_CPU_TYPE(cpu_model, initfn) \
{ \
.name = M68K_CPU_TYPE_NAME(cpu_model), \
.instance_init = initfn, \
.parent = TYPE_M68K_CPU, \
static void m68k_cpu_class_init_cf_core(ObjectClass *c, void *data)
{
CPUClass *cc = CPU_CLASS(c);
cc->gdb_core_xml_file = "cf-core.xml";
}
#define DEFINE_M68K_CPU_TYPE_CF(model) \
{ \
.name = M68K_CPU_TYPE_NAME(#model), \
.instance_init = model##_cpu_initfn, \
.parent = TYPE_M68K_CPU, \
.class_init = m68k_cpu_class_init_cf_core \
}
static void m68k_cpu_class_init_m68k_core(ObjectClass *c, void *data)
{
CPUClass *cc = CPU_CLASS(c);
cc->gdb_core_xml_file = "m68k-core.xml";
}
#define DEFINE_M68K_CPU_TYPE_M68K(model) \
{ \
.name = M68K_CPU_TYPE_NAME(#model), \
.instance_init = model##_cpu_initfn, \
.parent = TYPE_M68K_CPU, \
.class_init = m68k_cpu_class_init_m68k_core \
}
static const TypeInfo m68k_cpus_type_infos[] = {
@ -314,15 +336,15 @@ static const TypeInfo m68k_cpus_type_infos[] = {
.class_size = sizeof(M68kCPUClass),
.class_init = m68k_cpu_class_init,
},
DEFINE_M68K_CPU_TYPE("m68000", m68000_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m68020", m68020_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m68030", m68030_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m68040", m68040_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m68060", m68060_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m5206", m5206_cpu_initfn),
DEFINE_M68K_CPU_TYPE("m5208", m5208_cpu_initfn),
DEFINE_M68K_CPU_TYPE("cfv4e", cfv4e_cpu_initfn),
DEFINE_M68K_CPU_TYPE("any", any_cpu_initfn),
DEFINE_M68K_CPU_TYPE_M68K(m68000),
DEFINE_M68K_CPU_TYPE_M68K(m68020),
DEFINE_M68K_CPU_TYPE_M68K(m68030),
DEFINE_M68K_CPU_TYPE_M68K(m68040),
DEFINE_M68K_CPU_TYPE_M68K(m68060),
DEFINE_M68K_CPU_TYPE_CF(m5206),
DEFINE_M68K_CPU_TYPE_CF(m5208),
DEFINE_M68K_CPU_TYPE_CF(cfv4e),
DEFINE_M68K_CPU_TYPE_CF(any),
};
DEFINE_TYPES(m68k_cpus_type_infos)

View file

@ -72,7 +72,8 @@ static int cf_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
{
if (n < 8) {
float_status s;
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
return gdb_get_float64(mem_buf,
floatx80_to_float64(env->fregs[n].d, &s));
}
switch (n) {
case 8: /* fpcontrol */

View file

@ -130,7 +130,7 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
gdb_get_regl(buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
gdb_get_float64(buf, *cpu_fpr_ptr(env, n - 32));
} else {
switch (n) {
case 64:
@ -184,7 +184,7 @@ int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
gdb_get_reg64(buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
gdb_get_float64(buf, *cpu_fpr_ptr(env, n - 32));
} else if (n < 96) {
/* Altivec */
gdb_get_reg64(buf, n - 64);

View file

@ -9881,7 +9881,7 @@ static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
{
uint8_t *mem_buf;
if (n < 32) {
gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
gdb_get_float64(buf, *cpu_fpr_ptr(env, n));
mem_buf = gdb_get_reg_ptr(buf, 8);
ppc_maybe_bswap_register(env, mem_buf, 8);
return 8;

View file

@ -15,6 +15,8 @@ import argparse
import subprocess
import shutil
import shlex
import os
from tempfile import TemporaryDirectory
def get_args():
parser = argparse.ArgumentParser(description="A gdbstub test runner")
@ -41,17 +43,41 @@ if __name__ == '__main__':
print("We need gdb to run the test")
exit(-1)
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)
else:
cmd = "%s %s -g 1234 %s" % (args.qemu, args.qargs, args.binary)
cmd = "%s %s -g %s %s" % (args.qemu, args.qargs, socket_name,
args.binary)
inferior = subprocess.Popen(shlex.split(cmd))
# Now launch gdb with our test and collect the result
gdb_cmd = "%s %s -ex 'target remote localhost:1234' -x %s" % (args.gdb, args.binary, args.test)
gdb_cmd = "%s %s" % (args.gdb, args.binary)
# run quietly and ignore .gdbinit
gdb_cmd += " -q -n -batch"
# 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)
# finally the test script itself
gdb_cmd += " -x %s" % (args.test)
print("GDB CMD: %s" % (gdb_cmd))
result = subprocess.call(gdb_cmd, shell=True);
# 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
# account of broken external tools.
if result < 0:
print("GDB crashed? SKIPPING")
exit(0)
exit(result)

View file

@ -54,9 +54,6 @@ sve-ioctls: CFLAGS+=-march=armv8.1-a+sve
ifneq ($(HAVE_GDB_BIN),)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
AARCH64_TESTS += gdbstub-sysregs gdbstub-sve-ioctls
.PHONY: gdbstub-sysregs gdbstub-sve-ioctls
run-gdbstub-sysregs: sysregs
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \
@ -70,6 +67,8 @@ run-gdbstub-sve-ioctls: sve-ioctls
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \
"basic gdbstub SVE ZLEN support")
EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls
endif
endif

View file

@ -58,9 +58,6 @@ def run_test():
#
try:
inferior = gdb.selected_inferior()
if inferior.was_attached == False:
print("SKIPPING (failed to attach)", file=sys.stderr)
exit(0)
arch = inferior.architecture()
report(arch.name() == "aarch64", "connected to aarch64")
except (gdb.error, AttributeError):
@ -70,7 +67,6 @@ except (gdb.error, AttributeError):
try:
# These are not very useful in scripts
gdb.execute("set pagination off")
gdb.execute("set confirm off")
# Run the actual tests
run_test()

View file

@ -59,9 +59,6 @@ def run_test():
#
try:
inferior = gdb.selected_inferior()
if inferior.was_attached == False:
print("SKIPPING (failed to attach)", file=sys.stderr)
exit(0)
arch = inferior.architecture()
report(arch.name() == "aarch64", "connected to aarch64")
except (gdb.error, AttributeError):
@ -71,7 +68,6 @@ except (gdb.error, AttributeError):
try:
# These are not very useful in scripts
gdb.execute("set pagination off")
gdb.execute("set confirm off")
# Run the actual tests
run_test()

View file

@ -23,6 +23,7 @@ CRIS_RUNS = $(patsubst %, run-%, $(CRIS_USABLE_TESTS))
# override the list of tests, as we can't build the multiarch tests
TESTS = $(CRIS_USABLE_TESTS)
EXTRA_RUNS =
VPATH = $(CRIS_SRC)
AS = $(CC) -x assembler-with-cpp

View file

@ -42,5 +42,19 @@ run-test-mmap-%: test-mmap
$(call run-test, test-mmap-$*, $(QEMU) -p $* $<,\
"$< ($* byte pages) on $(TARGET_NAME)")
ifneq ($(HAVE_GDB_BIN),)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
run-gdbstub-sha1: sha1
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/sha1.py, \
"basic gdbstub support")
EXTRA_RUNS += run-gdbstub-sha1
endif
# Update TESTS
TESTS += $(MULTIARCH_TESTS)

View file

@ -0,0 +1,81 @@
from __future__ import print_function
#
# A very simple smoke test for debugging the SHA1 userspace test on
# each target.
#
# This is launched via tests/guest-debug/run-test.py
#
import gdb
import sys
initial_vlen = 0
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_break(sym_name):
"Setup breakpoint, continue and check we stopped."
sym, ok = gdb.lookup_symbol(sym_name)
bp = gdb.Breakpoint(sym_name)
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 run_test():
"Run through the tests one by one"
check_break("SHA1Init")
# check step and inspect values
gdb.execute("next")
val_ctx = gdb.parse_and_eval("context->state[0]")
exp_ctx = 0x67452301
report(int(val_ctx) == exp_ctx, "context->state[0] == %x" % exp_ctx);
gdb.execute("next")
val_ctx = gdb.parse_and_eval("context->state[1]")
exp_ctx = 0xEFCDAB89
report(int(val_ctx) == exp_ctx, "context->state[1] == %x" % exp_ctx);
# finally check we don't barf inspecting registers
gdb.execute("info registers")
#
# 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)
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)