testing, gdbstub and plugin updates
- enable more sbsa-ref tests in avocado - add swtpm to the package lists - reduce avocado noise in gitlab by limiting tests - make docker engine choice driven by configure and enable override - remove unneeded gcc suffix on some cross compilers - fix some NULL returns in gdbstub - improve locking in execlog plugin - introduce the GDBFeature structure - consistently set gdb_core_xml_file - use cleaner escaping for gdb xml - drop ancient gdb_has_xml() test - disable multi-instruction GUSA emulation when plugins enabled - fix some coverity issues in plugins -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmUmVJkACgkQ+9DbCVqe KkTfNggAiS02FcL3faGjAN9+60xhvEQ3DJjI473hjvFWu0bSkQTjObcQqGc+V7Cw 9yNtnxOOWB6KdAU8At7HlVqiUXeyTCJB7Att5/UgNUZj63j+cs7PXb4p7cVCcJOc 17zni22tnmCBcC8wZaz0yj68jaftL3hz1QNUZOmv6CBt42q0+/4g1WKfaJ+w+SbK T7cJEiMDObm8qeNAAXpDLB+9v3bRDxMZ8hFJ3p3CatQC8jbDrkuH7RrVPHDWiWQx w0uXpUHlZEOVX23v6+iIoeb8YQW2bZI9UsfeyIHJlENaVgyL200LHgLvvAE4Qd63 dCtfQUZzj4t9sfoL4XgxaB7G4qtXTg== =7PLI -----END PGP SIGNATURE----- Merge tag 'pull-omnibus-111023-1' of https://gitlab.com/stsquad/qemu into staging testing, gdbstub and plugin updates - enable more sbsa-ref tests in avocado - add swtpm to the package lists - reduce avocado noise in gitlab by limiting tests - make docker engine choice driven by configure and enable override - remove unneeded gcc suffix on some cross compilers - fix some NULL returns in gdbstub - improve locking in execlog plugin - introduce the GDBFeature structure - consistently set gdb_core_xml_file - use cleaner escaping for gdb xml - drop ancient gdb_has_xml() test - disable multi-instruction GUSA emulation when plugins enabled - fix some coverity issues in plugins # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmUmVJkACgkQ+9DbCVqe # KkTfNggAiS02FcL3faGjAN9+60xhvEQ3DJjI473hjvFWu0bSkQTjObcQqGc+V7Cw # 9yNtnxOOWB6KdAU8At7HlVqiUXeyTCJB7Att5/UgNUZj63j+cs7PXb4p7cVCcJOc # 17zni22tnmCBcC8wZaz0yj68jaftL3hz1QNUZOmv6CBt42q0+/4g1WKfaJ+w+SbK # T7cJEiMDObm8qeNAAXpDLB+9v3bRDxMZ8hFJ3p3CatQC8jbDrkuH7RrVPHDWiWQx # w0uXpUHlZEOVX23v6+iIoeb8YQW2bZI9UsfeyIHJlENaVgyL200LHgLvvAE4Qd63 # dCtfQUZzj4t9sfoL4XgxaB7G4qtXTg== # =7PLI # -----END PGP SIGNATURE----- # gpg: Signature made Wed 11 Oct 2023 03:54:01 EDT # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * tag 'pull-omnibus-111023-1' of https://gitlab.com/stsquad/qemu: (25 commits) contrib/plugins: fix coverity warning in hotblocks contrib/plugins: fix coverity warning in lockstep contrib/plugins: fix coverity warning in cache plugins: Set final instruction count in plugin_gen_tb_end target/sh4: Disable decode_gusa when plugins enabled accel/tcg: Add plugin_enabled to DisasContextBase gdbstub: Replace gdb_regs with an array gdbstub: Remove gdb_has_xml variable target/ppc: Remove references to gdb_has_xml target/arm: Remove references to gdb_has_xml gdbstub: Use g_markup_printf_escaped() hw/core/cpu: Return static value with gdb_arch_name() target/arm: Move the reference to arm-core.xml gdbstub: Introduce GDBFeature structure contrib/plugins: Use GRWLock in execlog plugins: Check if vCPU is realized gdbstub: Fix target.xml response gdbstub: Fix target_xml initialization configure: remove gcc version suffixes configure: allow user to override docker engine ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
a51e5124a6
@ -30,6 +30,7 @@ avocado-system-alpine:
|
||||
variables:
|
||||
IMAGE: alpine
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
|
||||
|
||||
build-system-ubuntu:
|
||||
extends:
|
||||
@ -40,8 +41,7 @@ build-system-ubuntu:
|
||||
variables:
|
||||
IMAGE: ubuntu2204
|
||||
CONFIGURE_ARGS: --enable-docs
|
||||
TARGETS: alpha-softmmu cris-softmmu hppa-softmmu
|
||||
microblazeel-softmmu mips64el-softmmu
|
||||
TARGETS: alpha-softmmu microblazeel-softmmu mips64el-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
|
||||
check-system-ubuntu:
|
||||
@ -61,6 +61,7 @@ avocado-system-ubuntu:
|
||||
variables:
|
||||
IMAGE: ubuntu2204
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:alpha arch:microblaze arch:mips64el
|
||||
|
||||
build-system-debian:
|
||||
extends:
|
||||
@ -72,7 +73,7 @@ build-system-debian:
|
||||
IMAGE: debian-amd64
|
||||
CONFIGURE_ARGS: --with-coroutine=sigaltstack
|
||||
TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
|
||||
sparc-softmmu xtensaeb-softmmu
|
||||
sparc-softmmu xtensa-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
|
||||
check-system-debian:
|
||||
@ -92,6 +93,7 @@ avocado-system-debian:
|
||||
variables:
|
||||
IMAGE: debian-amd64
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
|
||||
|
||||
crash-test-debian:
|
||||
extends: .native_test_job_template
|
||||
@ -114,7 +116,7 @@ build-system-fedora:
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
|
||||
TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu
|
||||
TARGETS: microblaze-softmmu mips-softmmu
|
||||
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
|
||||
@ -135,6 +137,8 @@ avocado-system-fedora:
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
|
||||
arch:riscv32 arch:ppc arch:sparc64
|
||||
|
||||
crash-test-fedora:
|
||||
extends: .native_test_job_template
|
||||
@ -180,6 +184,8 @@ avocado-system-centos:
|
||||
variables:
|
||||
IMAGE: centos8
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:390x arch:x86_64 arch:rx
|
||||
arch:sh4 arch:nios2
|
||||
|
||||
build-system-opensuse:
|
||||
extends:
|
||||
@ -209,6 +215,7 @@ avocado-system-opensuse:
|
||||
variables:
|
||||
IMAGE: opensuse-leap
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
|
||||
|
||||
|
||||
# This jobs explicitly disable TCG (--disable-tcg), KVM is detected by
|
||||
|
@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
|
||||
NINJA='/opt/homebrew/bin/ninja'
|
||||
PACKAGING_COMMAND='brew'
|
||||
PIP3='/opt/homebrew/bin/pip3'
|
||||
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol tesseract usbredir vde vte3 xorriso zlib zstd'
|
||||
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
|
||||
PYTHON='/opt/homebrew/bin/python3'
|
||||
|
@ -2842,7 +2842,7 @@ F: include/exec/gdbstub.h
|
||||
F: include/gdbstub/*
|
||||
F: gdb-xml/
|
||||
F: tests/tcg/multiarch/gdbstub/
|
||||
F: scripts/feature_to_c.sh
|
||||
F: scripts/feature_to_c.py
|
||||
F: scripts/probe-gdb-support.py
|
||||
|
||||
Memory API
|
||||
|
@ -866,10 +866,14 @@ void plugin_gen_insn_end(void)
|
||||
* do any clean-up here and make sure things are reset in
|
||||
* plugin_gen_tb_start.
|
||||
*/
|
||||
void plugin_gen_tb_end(CPUState *cpu)
|
||||
void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
|
||||
{
|
||||
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
||||
|
||||
/* translator may have removed instructions, update final count */
|
||||
g_assert(num_insns <= ptb->n);
|
||||
ptb->n = num_insns;
|
||||
|
||||
/* collect instrumentation requests */
|
||||
qemu_plugin_tb_trans_cb(cpu, ptb);
|
||||
|
||||
|
@ -158,6 +158,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
||||
} else {
|
||||
plugin_enabled = plugin_gen_tb_start(cpu, db, false);
|
||||
}
|
||||
db->plugin_enabled = plugin_enabled;
|
||||
|
||||
while (true) {
|
||||
*max_insns = ++db->num_insns;
|
||||
@ -209,7 +210,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
||||
gen_tb_end(tb, cflags, icount_start_insn, db->num_insns);
|
||||
|
||||
if (plugin_enabled) {
|
||||
plugin_gen_tb_end(cpu);
|
||||
plugin_gen_tb_end(cpu, db->num_insns);
|
||||
}
|
||||
|
||||
/* The disas_log hook may use these values rather than recompute. */
|
||||
|
13
configure
vendored
13
configure
vendored
@ -180,6 +180,7 @@ fi
|
||||
# some defaults, based on the host environment
|
||||
|
||||
# default parameters
|
||||
container_engine="auto"
|
||||
cpu=""
|
||||
cross_compile="no"
|
||||
cross_prefix=""
|
||||
@ -787,6 +788,8 @@ for opt do
|
||||
;;
|
||||
--disable-containers) use_containers="no"
|
||||
;;
|
||||
--container-engine=*) container_engine="$optarg"
|
||||
;;
|
||||
--gdb=*) gdb_bin="$optarg"
|
||||
;;
|
||||
# everything else has the same name in configure and meson
|
||||
@ -921,6 +924,7 @@ Advanced options (experts only):
|
||||
--enable-plugins
|
||||
enable plugins via shared library loading
|
||||
--disable-containers don't use containers for cross-building
|
||||
--container-engine=TYPE which container engine to use [$container_engine]
|
||||
--gdb=GDB-path gdb to use for gdbstub tests [$gdb_bin]
|
||||
EOF
|
||||
meson_options_help
|
||||
@ -1195,14 +1199,14 @@ fi
|
||||
container="no"
|
||||
runc=""
|
||||
if test $use_containers = "yes" && (has "docker" || has "podman"); then
|
||||
case $($python "$source_path"/tests/docker/docker.py probe) in
|
||||
case $($python "$source_path"/tests/docker/docker.py --engine "$container_engine" probe) in
|
||||
*docker) container=docker ;;
|
||||
podman) container=podman ;;
|
||||
no) container=no ;;
|
||||
esac
|
||||
if test "$container" != "no"; then
|
||||
docker_py="$python $source_path/tests/docker/docker.py --engine $container"
|
||||
runc=$($python "$source_path"/tests/docker/docker.py probe)
|
||||
runc=$container
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -1330,7 +1334,7 @@ probe_target_compiler() {
|
||||
# We don't have any bigendian build tools so we only use this for AArch64
|
||||
container_image=debian-arm64-cross
|
||||
container_cross_prefix=aarch64-linux-gnu-
|
||||
container_cross_cc=${container_cross_prefix}gcc-10
|
||||
container_cross_cc=${container_cross_prefix}gcc
|
||||
;;
|
||||
alpha)
|
||||
container_image=debian-alpha-cross
|
||||
@ -1393,7 +1397,7 @@ probe_target_compiler() {
|
||||
ppc)
|
||||
container_image=debian-powerpc-test-cross
|
||||
container_cross_prefix=powerpc-linux-gnu-
|
||||
container_cross_cc=${container_cross_prefix}gcc-10
|
||||
container_cross_cc=${container_cross_prefix}gcc
|
||||
;;
|
||||
ppc64|ppc64le)
|
||||
container_image=debian-powerpc-test-cross
|
||||
@ -1694,7 +1698,6 @@ if test -n "$gdb_bin"; then
|
||||
fi
|
||||
|
||||
if test "$container" != no; then
|
||||
echo "ENGINE=$container" >> $config_host_mak
|
||||
echo "RUNC=$runc" >> $config_host_mak
|
||||
fi
|
||||
echo "SUBDIRS=$subdirs" >> $config_host_mak
|
||||
|
@ -535,15 +535,13 @@ static void caches_free(Cache **caches)
|
||||
}
|
||||
}
|
||||
|
||||
static void append_stats_line(GString *line, uint64_t l1_daccess,
|
||||
uint64_t l1_dmisses, uint64_t l1_iaccess,
|
||||
uint64_t l1_imisses, uint64_t l2_access,
|
||||
uint64_t l2_misses)
|
||||
static void append_stats_line(GString *line,
|
||||
uint64_t l1_daccess, uint64_t l1_dmisses,
|
||||
uint64_t l1_iaccess, uint64_t l1_imisses,
|
||||
uint64_t l2_access, uint64_t l2_misses)
|
||||
{
|
||||
double l1_dmiss_rate, l1_imiss_rate, l2_miss_rate;
|
||||
|
||||
l1_dmiss_rate = ((double) l1_dmisses) / (l1_daccess) * 100.0;
|
||||
l1_imiss_rate = ((double) l1_imisses) / (l1_iaccess) * 100.0;
|
||||
double l1_dmiss_rate = ((double) l1_dmisses) / (l1_daccess) * 100.0;
|
||||
double l1_imiss_rate = ((double) l1_imisses) / (l1_iaccess) * 100.0;
|
||||
|
||||
g_string_append_printf(line, "%-14" PRIu64 " %-12" PRIu64 " %9.4lf%%"
|
||||
" %-14" PRIu64 " %-12" PRIu64 " %9.4lf%%",
|
||||
@ -554,8 +552,8 @@ static void append_stats_line(GString *line, uint64_t l1_daccess,
|
||||
l1_imisses,
|
||||
l1_iaccess ? l1_imiss_rate : 0.0);
|
||||
|
||||
if (use_l2) {
|
||||
l2_miss_rate = ((double) l2_misses) / (l2_access) * 100.0;
|
||||
if (l2_access && l2_misses) {
|
||||
double l2_miss_rate = ((double) l2_misses) / (l2_access) * 100.0;
|
||||
g_string_append_printf(line,
|
||||
" %-12" PRIu64 " %-11" PRIu64 " %10.4lf%%",
|
||||
l2_access,
|
||||
|
@ -19,7 +19,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
|
||||
|
||||
/* Store last executed instruction on each vCPU as a GString */
|
||||
static GPtrArray *last_exec;
|
||||
static GMutex expand_array_lock;
|
||||
static GRWLock expand_array_lock;
|
||||
|
||||
static GPtrArray *imatches;
|
||||
static GArray *amatches;
|
||||
@ -28,18 +28,16 @@ static GArray *amatches;
|
||||
* Expand last_exec array.
|
||||
*
|
||||
* As we could have multiple threads trying to do this we need to
|
||||
* serialise the expansion under a lock. Threads accessing already
|
||||
* created entries can continue without issue even if the ptr array
|
||||
* gets reallocated during resize.
|
||||
* serialise the expansion under a lock.
|
||||
*/
|
||||
static void expand_last_exec(int cpu_index)
|
||||
{
|
||||
g_mutex_lock(&expand_array_lock);
|
||||
g_rw_lock_writer_lock(&expand_array_lock);
|
||||
while (cpu_index >= last_exec->len) {
|
||||
GString *s = g_string_new(NULL);
|
||||
g_ptr_array_add(last_exec, s);
|
||||
}
|
||||
g_mutex_unlock(&expand_array_lock);
|
||||
g_rw_lock_writer_unlock(&expand_array_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,8 +49,10 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
|
||||
GString *s;
|
||||
|
||||
/* Find vCPU in array */
|
||||
g_rw_lock_reader_lock(&expand_array_lock);
|
||||
g_assert(cpu_index < last_exec->len);
|
||||
s = g_ptr_array_index(last_exec, cpu_index);
|
||||
g_rw_lock_reader_unlock(&expand_array_lock);
|
||||
|
||||
/* Indicate type of memory access */
|
||||
if (qemu_plugin_mem_is_store(info)) {
|
||||
@ -80,10 +80,14 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
|
||||
GString *s;
|
||||
|
||||
/* Find or create vCPU in array */
|
||||
g_rw_lock_reader_lock(&expand_array_lock);
|
||||
if (cpu_index >= last_exec->len) {
|
||||
g_rw_lock_reader_unlock(&expand_array_lock);
|
||||
expand_last_exec(cpu_index);
|
||||
g_rw_lock_reader_lock(&expand_array_lock);
|
||||
}
|
||||
s = g_ptr_array_index(last_exec, cpu_index);
|
||||
g_rw_lock_reader_unlock(&expand_array_lock);
|
||||
|
||||
/* Print previous instruction in cache */
|
||||
if (s->len) {
|
||||
|
@ -69,8 +69,8 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
|
||||
}
|
||||
|
||||
g_list_free(it);
|
||||
g_mutex_unlock(&lock);
|
||||
}
|
||||
g_mutex_unlock(&lock);
|
||||
|
||||
qemu_plugin_outs(report->str);
|
||||
}
|
||||
|
@ -245,6 +245,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
|
||||
static bool setup_socket(const char *path)
|
||||
{
|
||||
struct sockaddr_un sockaddr;
|
||||
const gsize pathlen = sizeof(sockaddr.sun_path) - 1;
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
@ -254,7 +255,11 @@ static bool setup_socket(const char *path)
|
||||
}
|
||||
|
||||
sockaddr.sun_family = AF_UNIX;
|
||||
g_strlcpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1);
|
||||
if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
|
||||
perror("bad path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
|
||||
perror("bind socket");
|
||||
close(fd);
|
||||
@ -287,6 +292,7 @@ static bool connect_socket(const char *path)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_un sockaddr;
|
||||
const gsize pathlen = sizeof(sockaddr.sun_path) - 1;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
@ -295,7 +301,10 @@ static bool connect_socket(const char *path)
|
||||
}
|
||||
|
||||
sockaddr.sun_family = AF_UNIX;
|
||||
g_strlcpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1);
|
||||
if (g_strlcpy(sockaddr.sun_path, path, pathlen) >= pathlen) {
|
||||
perror("bad path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
|
||||
perror("failed to connect");
|
||||
|
@ -51,7 +51,6 @@ typedef struct GDBRegisterState {
|
||||
gdb_get_reg_cb get_reg;
|
||||
gdb_set_reg_cb set_reg;
|
||||
const char *xml;
|
||||
struct GDBRegisterState *next;
|
||||
} GDBRegisterState;
|
||||
|
||||
GDBState gdbserver_state;
|
||||
@ -349,11 +348,6 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
|
||||
}
|
||||
}
|
||||
|
||||
bool gdb_has_xml(void)
|
||||
{
|
||||
return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml;
|
||||
}
|
||||
|
||||
static const char *get_feature_xml(const char *p, const char **newp,
|
||||
GDBProcess *process)
|
||||
{
|
||||
@ -373,31 +367,37 @@ static const char *get_feature_xml(const char *p, const char **newp,
|
||||
if (strncmp(p, "target.xml", len) == 0) {
|
||||
if (!process->target_xml) {
|
||||
GDBRegisterState *r;
|
||||
GString *xml = g_string_new("<?xml version=\"1.0\"?>");
|
||||
g_autoptr(GPtrArray) xml = g_ptr_array_new_with_free_func(g_free);
|
||||
|
||||
g_string_append(xml,
|
||||
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
||||
"<target>");
|
||||
g_ptr_array_add(
|
||||
xml,
|
||||
g_strdup("<?xml version=\"1.0\"?>"
|
||||
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
||||
"<target>"));
|
||||
|
||||
if (cc->gdb_arch_name) {
|
||||
g_autofree gchar *arch = cc->gdb_arch_name(cpu);
|
||||
g_string_append_printf(xml,
|
||||
"<architecture>%s</architecture>",
|
||||
arch);
|
||||
g_ptr_array_add(
|
||||
xml,
|
||||
g_markup_printf_escaped("<architecture>%s</architecture>",
|
||||
cc->gdb_arch_name(cpu)));
|
||||
}
|
||||
g_string_append(xml, "<xi:include href=\"");
|
||||
g_string_append(xml, cc->gdb_core_xml_file);
|
||||
g_string_append(xml, "\"/>");
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
g_string_append(xml, "<xi:include href=\"");
|
||||
g_string_append(xml, r->xml);
|
||||
g_string_append(xml, "\"/>");
|
||||
g_ptr_array_add(
|
||||
xml,
|
||||
g_markup_printf_escaped("<xi:include href=\"%s\"/>",
|
||||
cc->gdb_core_xml_file));
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
g_ptr_array_add(
|
||||
xml,
|
||||
g_markup_printf_escaped("<xi:include href=\"%s\"/>",
|
||||
r->xml));
|
||||
}
|
||||
g_string_append(xml, "</target>");
|
||||
g_ptr_array_add(xml, g_strdup("</target>"));
|
||||
g_ptr_array_add(xml, NULL);
|
||||
|
||||
process->target_xml = g_string_free(xml, false);
|
||||
return process->target_xml;
|
||||
process->target_xml = g_strjoinv(NULL, (void *)xml->pdata);
|
||||
}
|
||||
return process->target_xml;
|
||||
}
|
||||
/* Is it dynamically generated by the target? */
|
||||
if (cc->gdb_get_dynamic_xml) {
|
||||
@ -408,11 +408,11 @@ static const char *get_feature_xml(const char *p, const char **newp,
|
||||
}
|
||||
}
|
||||
/* Is it one of the encoded gdb-xml/ files? */
|
||||
for (int i = 0; xml_builtin[i][0]; i++) {
|
||||
const char *name = xml_builtin[i][0];
|
||||
for (int i = 0; gdb_static_features[i].xmlname; i++) {
|
||||
const char *name = gdb_static_features[i].xmlname;
|
||||
if ((strncmp(name, p, len) == 0) &&
|
||||
strlen(name) == len) {
|
||||
return xml_builtin[i][1];
|
||||
return gdb_static_features[i].xml;
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,7 +430,8 @@ static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
|
||||
return cc->gdb_read_register(cpu, buf, reg);
|
||||
}
|
||||
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||
return r->get_reg(env, buf, reg - r->base_reg);
|
||||
}
|
||||
@ -448,7 +449,8 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||
return cc->gdb_write_register(cpu, mem_buf, reg);
|
||||
}
|
||||
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||
return r->set_reg(env, mem_buf, reg - r->base_reg);
|
||||
}
|
||||
@ -461,17 +463,23 @@ void gdb_register_coprocessor(CPUState *cpu,
|
||||
int num_regs, const char *xml, int g_pos)
|
||||
{
|
||||
GDBRegisterState *s;
|
||||
GDBRegisterState **p;
|
||||
guint i;
|
||||
|
||||
p = &cpu->gdb_regs;
|
||||
while (*p) {
|
||||
/* Check for duplicates. */
|
||||
if (strcmp((*p)->xml, xml) == 0)
|
||||
return;
|
||||
p = &(*p)->next;
|
||||
if (cpu->gdb_regs) {
|
||||
for (i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
/* Check for duplicates. */
|
||||
s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
if (strcmp(s->xml, xml) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState));
|
||||
i = 0;
|
||||
}
|
||||
|
||||
s = g_new0(GDBRegisterState, 1);
|
||||
g_array_set_size(cpu->gdb_regs, i + 1);
|
||||
s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
s->base_reg = cpu->gdb_num_regs;
|
||||
s->num_regs = num_regs;
|
||||
s->get_reg = get_reg;
|
||||
@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu,
|
||||
|
||||
/* Add to end of list. */
|
||||
cpu->gdb_num_regs += num_regs;
|
||||
*p = s;
|
||||
if (g_pos) {
|
||||
if (g_pos != s->base_reg) {
|
||||
error_report("Error: Bad gdb register numbering for '%s', "
|
||||
@ -1081,11 +1088,6 @@ static void handle_set_reg(GArray *params, void *user_ctx)
|
||||
{
|
||||
int reg_size;
|
||||
|
||||
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
||||
gdb_put_packet("");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->len != 2) {
|
||||
gdb_put_packet("E22");
|
||||
return;
|
||||
@ -1102,11 +1104,6 @@ static void handle_get_reg(GArray *params, void *user_ctx)
|
||||
{
|
||||
int reg_size;
|
||||
|
||||
if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) {
|
||||
gdb_put_packet("");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!params->len) {
|
||||
gdb_put_packet("E14");
|
||||
return;
|
||||
|
@ -32,8 +32,6 @@ enum {
|
||||
typedef struct GDBProcess {
|
||||
uint32_t pid;
|
||||
bool attached;
|
||||
|
||||
/* If gdb sends qXfer:features:read:target.xml this will be populated */
|
||||
char *target_xml;
|
||||
} GDBProcess;
|
||||
|
||||
|
@ -292,7 +292,7 @@ static int find_cpu_clusters(Object *child, void *opaque)
|
||||
assert(cluster->cluster_id != UINT32_MAX);
|
||||
process->pid = cluster->cluster_id + 1;
|
||||
process->attached = false;
|
||||
process->target_xml[0] = '\0';
|
||||
process->target_xml = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,6 +10,11 @@
|
||||
#define GDB_WATCHPOINT_READ 3
|
||||
#define GDB_WATCHPOINT_ACCESS 4
|
||||
|
||||
typedef struct GDBFeature {
|
||||
const char *xmlname;
|
||||
const char *xml;
|
||||
} GDBFeature;
|
||||
|
||||
|
||||
/* Get or set a register. Returns the size of the register. */
|
||||
typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
|
||||
@ -40,15 +45,7 @@ int gdbserver_start(const char *port_or_device);
|
||||
|
||||
void gdb_set_stop_cpu(CPUState *cpu);
|
||||
|
||||
/**
|
||||
* gdb_has_xml() - report of gdb supports modern target descriptions
|
||||
*
|
||||
* This will report true if the gdb negotiated qXfer:features:read
|
||||
* target descriptions.
|
||||
*/
|
||||
bool gdb_has_xml(void);
|
||||
|
||||
/* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
|
||||
extern const char *const xml_builtin[][2];
|
||||
/* in gdbstub-xml.c, generated by scripts/feature_to_c.py */
|
||||
extern const GDBFeature gdb_static_features[];
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@ struct DisasContextBase;
|
||||
|
||||
bool plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db,
|
||||
bool supress);
|
||||
void plugin_gen_tb_end(CPUState *cpu);
|
||||
void plugin_gen_tb_end(CPUState *cpu, size_t num_insns);
|
||||
void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db);
|
||||
void plugin_gen_insn_end(void);
|
||||
|
||||
@ -42,7 +42,7 @@ void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db)
|
||||
static inline void plugin_gen_insn_end(void)
|
||||
{ }
|
||||
|
||||
static inline void plugin_gen_tb_end(CPUState *cpu)
|
||||
static inline void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
|
||||
{ }
|
||||
|
||||
static inline void plugin_gen_disable_mem_helpers(void)
|
||||
|
@ -73,6 +73,7 @@ typedef enum DisasJumpType {
|
||||
* @max_insns: Maximum number of instructions to be translated in this TB.
|
||||
* @singlestep_enabled: "Hardware" single stepping enabled.
|
||||
* @saved_can_do_io: Known value of cpu->neg.can_do_io, or -1 for unknown.
|
||||
* @plugin_enabled: TCG plugin enabled in this TB.
|
||||
*
|
||||
* Architecture-agnostic disassembly context.
|
||||
*/
|
||||
@ -85,6 +86,7 @@ typedef struct DisasContextBase {
|
||||
int max_insns;
|
||||
bool singlestep_enabled;
|
||||
int8_t saved_can_do_io;
|
||||
bool plugin_enabled;
|
||||
void *host_addr[2];
|
||||
} DisasContextBase;
|
||||
|
||||
|
@ -165,7 +165,7 @@ struct CPUClass {
|
||||
vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr);
|
||||
|
||||
const char *gdb_core_xml_file;
|
||||
gchar * (*gdb_arch_name)(CPUState *cpu);
|
||||
const gchar * (*gdb_arch_name)(CPUState *cpu);
|
||||
const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname);
|
||||
|
||||
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
|
||||
@ -502,7 +502,7 @@ struct CPUState {
|
||||
|
||||
CPUJumpCache *tb_jmp_cache;
|
||||
|
||||
struct GDBRegisterState *gdb_regs;
|
||||
GArray *gdb_regs;
|
||||
int gdb_num_regs;
|
||||
int gdb_num_g_regs;
|
||||
QTAILQ_ENTRY(CPUState) node;
|
||||
|
@ -3693,7 +3693,7 @@ common_all = static_library('common',
|
||||
dependencies: common_all.dependencies(),
|
||||
name_suffix: 'fa')
|
||||
|
||||
feature_to_c = find_program('scripts/feature_to_c.sh')
|
||||
feature_to_c = find_program('scripts/feature_to_c.py')
|
||||
|
||||
if targetos == 'darwin'
|
||||
entitlement = find_program('scripts/entitlement.sh')
|
||||
|
@ -64,7 +64,7 @@ static void plugin_cpu_update__locked(gpointer k, gpointer v, gpointer udata)
|
||||
CPUState *cpu = container_of(k, CPUState, cpu_index);
|
||||
run_on_cpu_data mask = RUN_ON_CPU_HOST_ULONG(*plugin.mask);
|
||||
|
||||
if (cpu->created) {
|
||||
if (DEVICE(cpu)->realized) {
|
||||
async_run_on_cpu(cpu, plugin_cpu_update__async, mask);
|
||||
} else {
|
||||
plugin_cpu_update__async(cpu, mask);
|
||||
|
48
scripts/feature_to_c.py
Executable file
48
scripts/feature_to_c.py
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os, sys
|
||||
|
||||
def writeliteral(indent, bytes):
|
||||
sys.stdout.write(' ' * indent)
|
||||
sys.stdout.write('"')
|
||||
quoted = True
|
||||
|
||||
for c in bytes:
|
||||
if not quoted:
|
||||
sys.stdout.write('\n')
|
||||
sys.stdout.write(' ' * indent)
|
||||
sys.stdout.write('"')
|
||||
quoted = True
|
||||
|
||||
if c == b'"'[0]:
|
||||
sys.stdout.write('\\"')
|
||||
elif c == b'\\'[0]:
|
||||
sys.stdout.write('\\\\')
|
||||
elif c == b'\n'[0]:
|
||||
sys.stdout.write('\\n"')
|
||||
quoted = False
|
||||
elif c >= 32 and c < 127:
|
||||
sys.stdout.write(c.to_bytes(1, 'big').decode())
|
||||
else:
|
||||
sys.stdout.write(f'\{c:03o}')
|
||||
|
||||
if quoted:
|
||||
sys.stdout.write('"')
|
||||
|
||||
sys.stdout.write('#include "qemu/osdep.h"\n' \
|
||||
'#include "exec/gdbstub.h"\n' \
|
||||
'\n'
|
||||
'const GDBFeature gdb_static_features[] = {\n')
|
||||
|
||||
for input in sys.argv[1:]:
|
||||
with open(input, 'rb') as file:
|
||||
read = file.read()
|
||||
|
||||
sys.stdout.write(' {\n')
|
||||
writeliteral(8, bytes(os.path.basename(input), 'utf-8'))
|
||||
sys.stdout.write(',\n')
|
||||
writeliteral(8, read)
|
||||
sys.stdout.write('\n },\n')
|
||||
|
||||
sys.stdout.write(' { NULL }\n};\n')
|
@ -1,69 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Convert text files to compilable C arrays.
|
||||
#
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GDB.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if test -z "$1"; then
|
||||
echo "Usage: $0 INPUTFILE..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for input; do
|
||||
arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
|
||||
|
||||
${AWK:-awk} 'BEGIN { n = 0
|
||||
printf "#include \"qemu/osdep.h\"\n"
|
||||
print "static const char '$arrayname'[] = {"
|
||||
for (i = 0; i < 255; i++)
|
||||
_ord_[sprintf("%c", i)] = i
|
||||
} {
|
||||
split($0, line, "");
|
||||
printf " "
|
||||
for (i = 1; i <= length($0); i++) {
|
||||
c = line[i]
|
||||
if (c == "'\''") {
|
||||
printf "'\''\\'\'''\'', "
|
||||
} else if (c == "\\") {
|
||||
printf "'\''\\\\'\'', "
|
||||
} else if (_ord_[c] >= 32 && _ord_[c] < 127) {
|
||||
printf "'\''%s'\'', ", c
|
||||
} else {
|
||||
printf "'\''\\%03o'\'', ", _ord_[c]
|
||||
}
|
||||
if (i % 10 == 0)
|
||||
printf "\n "
|
||||
}
|
||||
printf "'\''\\n'\'', \n"
|
||||
} END {
|
||||
print " 0 };"
|
||||
}' < $input
|
||||
done
|
||||
|
||||
echo
|
||||
echo '#include "exec/gdbstub.h"'
|
||||
echo "const char *const xml_builtin[][2] = {"
|
||||
|
||||
for input; do
|
||||
basename=$(echo $input | sed 's,.*/,,')
|
||||
arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g')
|
||||
echo " { \"$basename\", $arrayname },"
|
||||
done
|
||||
|
||||
echo " { (char *)0, (char *)0 }"
|
||||
echo "};"
|
@ -1,6 +1,6 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "exec/gdbstub.h" /* xml_builtin */
|
||||
#include "exec/gdbstub.h" /* gdb_static_features */
|
||||
|
||||
const char *const xml_builtin[][2] = {
|
||||
{ NULL, NULL }
|
||||
const GDBFeature gdb_static_features[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -2319,15 +2319,15 @@ static Property arm_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static gchar *arm_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *arm_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
|
||||
return g_strdup("iwmmxt");
|
||||
return "iwmmxt";
|
||||
}
|
||||
return g_strdup("arm");
|
||||
return "arm";
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@ -2392,7 +2392,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
cc->sysemu_ops = &arm_sysemu_ops;
|
||||
#endif
|
||||
cc->gdb_num_core_regs = 26;
|
||||
cc->gdb_core_xml_file = "arm-core.xml";
|
||||
cc->gdb_arch_name = arm_gdb_arch_name;
|
||||
cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml;
|
||||
cc->gdb_stop_before_watchpoint = true;
|
||||
@ -2414,8 +2413,10 @@ static void arm_cpu_instance_init(Object *obj)
|
||||
static void cpu_register_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
|
||||
CPUClass *cc = CPU_CLASS(acc);
|
||||
|
||||
acc->info = data;
|
||||
cc->gdb_core_xml_file = "arm-core.xml";
|
||||
}
|
||||
|
||||
void arm_cpu_register(const ARMCPUInfo *info)
|
||||
|
@ -781,9 +781,9 @@ static void aarch64_cpu_finalizefn(Object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
static gchar *aarch64_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *aarch64_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
return g_strdup("aarch64");
|
||||
return "aarch64";
|
||||
}
|
||||
|
||||
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
@ -46,21 +46,7 @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
||||
/* Core integer register. */
|
||||
return gdb_get_reg32(mem_buf, env->regs[n]);
|
||||
}
|
||||
if (n < 24) {
|
||||
/* FPA registers. */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return gdb_get_zeroes(mem_buf, 12);
|
||||
}
|
||||
switch (n) {
|
||||
case 24:
|
||||
/* FPA status register. */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return gdb_get_reg32(mem_buf, 0);
|
||||
case 25:
|
||||
if (n == 25) {
|
||||
/* CPSR, or XPSR for M-profile */
|
||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||
return gdb_get_reg32(mem_buf, xpsr_read(env));
|
||||
@ -100,21 +86,7 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
env->regs[n] = tmp;
|
||||
return 4;
|
||||
}
|
||||
if (n < 24) { /* 16-23 */
|
||||
/* FPA registers (ignored). */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return 12;
|
||||
}
|
||||
switch (n) {
|
||||
case 24:
|
||||
/* FPA status register (ignored). */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return 4;
|
||||
case 25:
|
||||
if (n == 25) {
|
||||
/* CPSR, or XPSR for M-profile */
|
||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||
/*
|
||||
|
@ -5916,12 +5916,12 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
|
||||
memset(&env->user_features, 0, sizeof(env->user_features));
|
||||
}
|
||||
|
||||
static gchar *x86_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *x86_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
#ifdef TARGET_X86_64
|
||||
return g_strdup("i386:x86-64");
|
||||
return "i386:x86-64";
|
||||
#else
|
||||
return g_strdup("i386");
|
||||
return "i386";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -766,9 +766,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
||||
#endif
|
||||
}
|
||||
|
||||
static gchar *loongarch32_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *loongarch32_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
return g_strdup("loongarch32");
|
||||
return "loongarch32";
|
||||
}
|
||||
|
||||
static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
|
||||
@ -780,9 +780,9 @@ static void loongarch32_cpu_class_init(ObjectClass *c, void *data)
|
||||
cc->gdb_arch_name = loongarch32_gdb_arch_name;
|
||||
}
|
||||
|
||||
static gchar *loongarch64_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *loongarch64_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
return g_strdup("loongarch64");
|
||||
return "loongarch64";
|
||||
}
|
||||
|
||||
static void loongarch64_cpu_class_init(ObjectClass *c, void *data)
|
||||
|
@ -54,12 +54,6 @@ static int ppc_gdb_register_len(int n)
|
||||
case 0 ... 31:
|
||||
/* gprs */
|
||||
return sizeof(target_ulong);
|
||||
case 32 ... 63:
|
||||
/* fprs */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return 8;
|
||||
case 66:
|
||||
/* cr */
|
||||
case 69:
|
||||
@ -74,12 +68,6 @@ static int ppc_gdb_register_len(int n)
|
||||
case 68:
|
||||
/* ctr */
|
||||
return sizeof(target_ulong);
|
||||
case 70:
|
||||
/* fpscr */
|
||||
if (gdb_has_xml()) {
|
||||
return 0;
|
||||
}
|
||||
return sizeof(target_ulong);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -132,9 +120,6 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
|
||||
if (n < 32) {
|
||||
/* gprs */
|
||||
gdb_get_regl(buf, env->gpr[n]);
|
||||
} else if (n < 64) {
|
||||
/* fprs */
|
||||
gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
|
||||
} else {
|
||||
switch (n) {
|
||||
case 64:
|
||||
@ -158,9 +143,6 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
|
||||
case 69:
|
||||
gdb_get_reg32(buf, cpu_read_xer(env));
|
||||
break;
|
||||
case 70:
|
||||
gdb_get_reg32(buf, env->fpscr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mem_buf = buf->data + buf->len - r;
|
||||
@ -589,12 +571,12 @@ static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gchar *ppc_gdb_arch_name(CPUState *cs)
|
||||
const gchar *ppc_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
#if defined(TARGET_PPC64)
|
||||
return g_strdup("powerpc:common64");
|
||||
return "powerpc:common64";
|
||||
#else
|
||||
return g_strdup("powerpc:common");
|
||||
return "powerpc:common";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
|
||||
|
||||
/* gdbstub.c */
|
||||
void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
|
||||
gchar *ppc_gdb_arch_name(CPUState *cs);
|
||||
const gchar *ppc_gdb_arch_name(CPUState *cs);
|
||||
|
||||
/**
|
||||
* prot_for_access_type:
|
||||
|
@ -2004,17 +2004,17 @@ static Property riscv_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static gchar *riscv_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *riscv_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
switch (riscv_cpu_mxl(env)) {
|
||||
case MXL_RV32:
|
||||
return g_strdup("riscv:rv32");
|
||||
return "riscv:rv32";
|
||||
case MXL_RV64:
|
||||
case MXL_RV128:
|
||||
return g_strdup("riscv:rv64");
|
||||
return "riscv:rv64";
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
@ -282,9 +282,9 @@ static void s390_cpu_initfn(Object *obj)
|
||||
#endif
|
||||
}
|
||||
|
||||
static gchar *s390_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *s390_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
return g_strdup("s390:64-bit");
|
||||
return "s390:64-bit";
|
||||
}
|
||||
|
||||
static Property s390x_cpu_properties[] = {
|
||||
|
@ -1816,6 +1816,18 @@ static void decode_opc(DisasContext * ctx)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/*
|
||||
* Restart with the EXCLUSIVE bit set, within a TB run via
|
||||
* cpu_exec_step_atomic holding the exclusive lock.
|
||||
*/
|
||||
static void gen_restart_exclusive(DisasContext *ctx)
|
||||
{
|
||||
ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
|
||||
gen_save_cpu_state(ctx, false);
|
||||
gen_helper_exclusive(tcg_env);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
/* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
|
||||
Upon an interrupt, a real kernel would simply notice magic values in
|
||||
the registers and reset the PC to the start of the sequence.
|
||||
@ -2149,12 +2161,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
|
||||
qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
|
||||
pc, pc_end);
|
||||
|
||||
/* Restart with the EXCLUSIVE bit set, within a TB run via
|
||||
cpu_exec_step_atomic holding the exclusive lock. */
|
||||
ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
|
||||
gen_save_cpu_state(ctx, false);
|
||||
gen_helper_exclusive(tcg_env);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
gen_restart_exclusive(ctx);
|
||||
|
||||
/* We're not executing an instruction, but we must report one for the
|
||||
purposes of accounting within the TB. We might as well report the
|
||||
@ -2242,12 +2249,22 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
|
||||
&& !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
|
||||
/* We're in an gUSA region, and we have not already fallen
|
||||
back on using an exclusive region. Attempt to parse the
|
||||
region into a single supported atomic operation. Failure
|
||||
is handled within the parser by raising an exception to
|
||||
retry using an exclusive region. */
|
||||
decode_gusa(ctx, env);
|
||||
/*
|
||||
* We're in an gUSA region, and we have not already fallen
|
||||
* back on using an exclusive region. Attempt to parse the
|
||||
* region into a single supported atomic operation. Failure
|
||||
* is handled within the parser by raising an exception to
|
||||
* retry using an exclusive region.
|
||||
*
|
||||
* Parsing the region in one block conflicts with plugins,
|
||||
* so always use exclusive mode if plugins enabled.
|
||||
*/
|
||||
if (ctx->base.plugin_enabled) {
|
||||
gen_restart_exclusive(ctx);
|
||||
ctx->base.pc_next += 2;
|
||||
} else {
|
||||
decode_gusa(ctx, env);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -29,9 +29,9 @@ static inline void set_feature(CPUTriCoreState *env, int feature)
|
||||
env->features |= 1ULL << feature;
|
||||
}
|
||||
|
||||
static gchar *tricore_gdb_arch_name(CPUState *cs)
|
||||
static const gchar *tricore_gdb_arch_name(CPUState *cs)
|
||||
{
|
||||
return g_strdup("tricore");
|
||||
return "tricore";
|
||||
}
|
||||
|
||||
static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
|
@ -28,33 +28,33 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
"""
|
||||
Flash volumes generated using:
|
||||
|
||||
- Fedora GNU Toolchain version 13.1.1 20230511 (Red Hat 13.1.1-2)
|
||||
- Fedora GNU Toolchain version 13.2.1 20230728 (Red Hat 13.2.1-1)
|
||||
|
||||
- Trusted Firmware-A
|
||||
https://github.com/ARM-software/arm-trusted-firmware/tree/c0d8ee38
|
||||
https://github.com/ARM-software/arm-trusted-firmware/tree/7c3ff62d
|
||||
|
||||
- Tianocore EDK II
|
||||
https://github.com/tianocore/edk2/tree/0f9283429dd4
|
||||
https://github.com/tianocore/edk2-non-osi/tree/f0bb00937ad6
|
||||
https://github.com/tianocore/edk2-platforms/tree/7880b92e2a04
|
||||
https://github.com/tianocore/edk2/tree/ad1c0394b177
|
||||
https://github.com/tianocore/edk2-platforms/tree/d03a60523a60
|
||||
"""
|
||||
|
||||
# Secure BootRom (TF-A code)
|
||||
fs0_xz_url = (
|
||||
"https://fileserver.linaro.org/s/HrYMCjP7MEccjRP/"
|
||||
"https://fileserver.linaro.org/s/rE43RJyTfxPtBkc/"
|
||||
"download/SBSA_FLASH0.fd.xz"
|
||||
)
|
||||
fs0_xz_hash = "447eff64a90b84ce47703c6ec41fbfc25befaaea"
|
||||
fs0_xz_hash = "cdb8e4ffdaaa79292b7b465693f9e5fae6b7062d"
|
||||
tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash)
|
||||
archive.extract(tar_xz_path, self.workdir)
|
||||
fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd")
|
||||
|
||||
# Non-secure rom (UEFI and EFI variables)
|
||||
fs1_xz_url = (
|
||||
"https://fileserver.linaro.org/s/t8foNnMPz74DZZy/"
|
||||
"https://fileserver.linaro.org/s/AGWPDXbcqJTKS4R/"
|
||||
"download/SBSA_FLASH1.fd.xz"
|
||||
)
|
||||
fs1_xz_hash = "13a9a262953787c7fc5a9155dfaa26e703631e02"
|
||||
fs1_xz_hash = "411155ae6984334714dff08d5d628178e790c875"
|
||||
tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash)
|
||||
archive.extract(tar_xz_path, self.workdir)
|
||||
fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd")
|
||||
@ -75,7 +75,6 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
"sbsa-ref",
|
||||
)
|
||||
|
||||
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is not reliable')
|
||||
def test_sbsaref_edk2_firmware(self):
|
||||
"""
|
||||
:avocado: tags=cpu:cortex-a57
|
||||
@ -144,7 +143,7 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
|
||||
def test_sbsaref_alpine_linux_neoverse_n1(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=cpu:neoverse-n1
|
||||
"""
|
||||
self.boot_alpine_linux("neoverse-n1")
|
||||
|
||||
@ -152,4 +151,54 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
"""
|
||||
self.boot_alpine_linux("max,pauth-impdef=on")
|
||||
self.boot_alpine_linux("max")
|
||||
|
||||
|
||||
# This tests the whole boot chain from EFI to Userspace
|
||||
# We only boot a whole OS for the current top level CPU and GIC
|
||||
# Other test profiles should use more minimal boots
|
||||
def boot_openbsd73(self, cpu):
|
||||
self.fetch_firmware()
|
||||
|
||||
img_url = (
|
||||
"https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img"
|
||||
)
|
||||
|
||||
img_hash = "7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5"
|
||||
img_path = self.fetch_asset(img_url, algorithm="sha256", asset_hash=img_hash)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args(
|
||||
"-cpu",
|
||||
cpu,
|
||||
"-drive",
|
||||
f"file={img_path},format=raw",
|
||||
"-device",
|
||||
"virtio-rng-pci,rng=rng0",
|
||||
"-object",
|
||||
"rng-random,id=rng0,filename=/dev/urandom",
|
||||
)
|
||||
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self,
|
||||
"Welcome to the OpenBSD/arm64"
|
||||
" 7.3 installation program.")
|
||||
|
||||
def test_sbsaref_openbsd73_cortex_a57(self):
|
||||
"""
|
||||
:avocado: tags=cpu:cortex-a57
|
||||
"""
|
||||
self.boot_openbsd73("cortex-a57")
|
||||
|
||||
def test_sbsaref_openbsd73_neoverse_n1(self):
|
||||
"""
|
||||
:avocado: tags=cpu:neoverse-n1
|
||||
"""
|
||||
self.boot_openbsd73("neoverse-n1")
|
||||
|
||||
def test_sbsaref_openbsd73_max(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
"""
|
||||
self.boot_openbsd73("max")
|
||||
|
||||
|
@ -16,9 +16,8 @@ DOCKER_DEFAULT_REGISTRY := registry.gitlab.com/qemu-project/qemu
|
||||
endif
|
||||
DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),$(DOCKER_DEFAULT_REGISTRY))
|
||||
|
||||
RUNC ?= docker
|
||||
ENGINE ?= auto
|
||||
DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE)
|
||||
RUNC ?= $(if $(shell command -v docker), docker, podman)
|
||||
DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(RUNC)
|
||||
|
||||
CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$)
|
||||
DOCKER_SRC_COPY := $(BUILD_DIR)/docker-src.$(CUR_TIME)
|
||||
@ -158,7 +157,7 @@ $(foreach i,$(filter-out $(DOCKER_PARTIAL_IMAGES),$(DOCKER_IMAGES)), \
|
||||
)
|
||||
|
||||
docker:
|
||||
@echo 'Build QEMU and run tests inside Docker or Podman containers'
|
||||
@echo 'Build QEMU and run tests inside $(RUNC) containers'
|
||||
@echo
|
||||
@echo 'Available targets:'
|
||||
@echo
|
||||
@ -198,8 +197,6 @@ docker:
|
||||
@echo ' EXECUTABLE=<path> Include executable in image.'
|
||||
@echo ' EXTRA_FILES="<path> [... <path>]"'
|
||||
@echo ' Include extra files in image.'
|
||||
@echo ' ENGINE=auto/docker/podman'
|
||||
@echo ' Specify which container engine to run.'
|
||||
@echo ' REGISTRY=url Cache builds from registry (default:$(DOCKER_REGISTRY))'
|
||||
|
||||
docker-help: docker
|
||||
|
@ -100,6 +100,7 @@ RUN apk update && \
|
||||
sparse \
|
||||
spice-dev \
|
||||
spice-protocol \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
usbredir-dev \
|
||||
|
@ -107,6 +107,7 @@ RUN dnf distro-sync -y && \
|
||||
socat \
|
||||
spice-protocol \
|
||||
spice-server-devel \
|
||||
swtpm \
|
||||
systemd-devel \
|
||||
systemtap-sdt-devel \
|
||||
tar \
|
||||
|
@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
|
@ -124,6 +124,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
systemtap-sdt-dev \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
|
@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
|
@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
|
@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
|
@ -55,6 +55,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
|
@ -55,6 +55,7 @@ exec "$@"\n' > /usr/bin/nosync && \
|
||||
socat \
|
||||
sparse \
|
||||
spice-protocol \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract \
|
||||
tesseract-langpack-eng \
|
||||
|
@ -55,6 +55,7 @@ exec "$@"\n' > /usr/bin/nosync && \
|
||||
socat \
|
||||
sparse \
|
||||
spice-protocol \
|
||||
swtpm \
|
||||
tar \
|
||||
tesseract \
|
||||
tesseract-langpack-eng \
|
||||
|
@ -118,6 +118,7 @@ exec "$@"\n' > /usr/bin/nosync && \
|
||||
sparse \
|
||||
spice-protocol \
|
||||
spice-server-devel \
|
||||
swtpm \
|
||||
systemd-devel \
|
||||
systemtap-sdt-devel \
|
||||
tar \
|
||||
|
@ -100,6 +100,7 @@ RUN zypper update -y && \
|
||||
socat \
|
||||
sparse \
|
||||
spice-protocol-devel \
|
||||
swtpm \
|
||||
systemd-devel \
|
||||
systemtap-sdt-devel \
|
||||
tar \
|
||||
|
@ -124,6 +124,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
sed \
|
||||
socat \
|
||||
sparse \
|
||||
swtpm \
|
||||
systemtap-sdt-dev \
|
||||
tar \
|
||||
tesseract-ocr \
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e3ed1e5da101943e53d8d89424e17b22120743f5
|
||||
Subproject commit 36bc517161c45ead20224d47f2dc4fa428af6724
|
@ -110,6 +110,7 @@ packages:
|
||||
- spice-protocol
|
||||
- spice-server
|
||||
- ssh-client
|
||||
- swtpm
|
||||
- systemd
|
||||
- tar
|
||||
- tesseract
|
||||
|
Loading…
Reference in New Issue
Block a user