Add check-tcg machinary

This restores the ability to run TCG smoke tests by using our docker
 infrastructure to support cross building simple tests. It represents
 the first step to making better cross-architecture testing available
 straight from the source tree ;-)
 
 v2
   - fix quoting of target_compiler
   - make docker.py Py3 safe
   - tweak .travis.yml recipe
   - don't probe docker when HAVE_USER_DOCKER not set
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAlsrRHEACgkQ+9DbCVqe
 KkSRhAf9EkJLIkB0uUs6NXu8ZKbMoAFlpQtbHZ36/YvTWHW+oDOBjYkZyrRlsTMR
 lIpm51wSAtVOJnScFASKbYQAD4ZTw2CUjwRqkCUhWI/vJOR7NvzZHfF+SHCNl8QE
 un7N/n3pWga7vY3j5Pd9cXz14im42Lcyl/xL5juh0lpCo+dw9OTdMT49sPF3YJGC
 N7uK3gIqFg24nofCAZq/YyUGzfftSkZ8x6D9k9fhHyPUGh+28sE2Ahptb6jGAYnr
 IcfHSUFkHpvliEJCJ50ho3iNF/JvV57gluW/LLQua35XBJ7sgiXHlhJP6Fnkobps
 Z8tzaEFGg96fFOreSs0PkqTrLhMO5w==
 =BIF8
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stsquad/tags/pull-tcg-testing-revivial-210618-2' into staging

Add check-tcg machinary

This restores the ability to run TCG smoke tests by using our docker
infrastructure to support cross building simple tests. It represents
the first step to making better cross-architecture testing available
straight from the source tree ;-)

v2
  - fix quoting of target_compiler
  - make docker.py Py3 safe
  - tweak .travis.yml recipe
  - don't probe docker when HAVE_USER_DOCKER not set

# gpg: Signature made Thu 21 Jun 2018 07:23:45 BST
# gpg:                using RSA key FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>"
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* remotes/stsquad/tags/pull-tcg-testing-revivial-210618-2: (57 commits)
  .travis.yml: add check-tcg test
  tests/docker/Makefile.include: only force SID to NOCACHE if old
  docker: docker.py adding age check command
  tests/Makefile: call sub-makes with SKIP_DOCKER_BUILD=1
  docker: docker.py add check sub-command
  docker: docker.py don't conflate checksums for extra_files
  docker: docker.py use "version" to probe usage
  tests: add top-level make dependency for docker builds
  tests/tcg/i386: extend timeout for runcom test
  tests/tcg: override runners for broken tests
  tests/tcg: add run, diff, and skip helper macros
  tests/Makefile.include: add [build|clean|check]-tcg targets
  Makefile.target: add (clean-/build-)guest-tests targets
  tests/tcg/Makefile: update to be called from Makefile.target
  tests/tcg: enable building for PowerPC
  docker: move debian-powerpc-cross to sid based build
  tests/tcg: enable building for RISCV64
  tests/tcg: enable building for mips64
  tests/tcg: enable building for sparc64
  tests/tcg: enable building for sh4
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-06-22 10:57:47 +01:00
commit de44c04442
77 changed files with 8138 additions and 630 deletions

View file

@ -153,3 +153,11 @@ matrix:
- TEST_CMD=""
before_script:
- ./configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread -fuse-ld=gold" || { cat config.log && exit 1; }
- env:
- CONFIG="--disable-system --disable-docs"
- TEST_CMD="make check-tcg"
script:
- make ${MAKEFLAGS} && ${TEST_CMD} ${MAKEFLAGS}
sudo: required
dist: trusty
compiler: gcc

View file

@ -135,6 +135,8 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: target/arm/
F: tests/tcg/arm/
F: tests/tcg/aarch64/
F: hw/arm/
F: hw/cpu/a*mpcore.c
F: include/hw/cpu/a*mpcore.h
@ -283,6 +285,8 @@ M: Richard Henderson <rth@twiddle.net>
M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
F: target/i386/
F: tests/tcg/i386/
F: tests/tcg/x86_64/
F: hw/i386/
F: disas/i386.c
T: git git://github.com/ehabkost/qemu.git x86-next
@ -303,6 +307,10 @@ F: target/tricore/
F: hw/tricore/
F: include/hw/tricore/
Multiarch Linux User Tests
M: Alex Bennée <alex.bennee@linaro.org>
F: tests/tcg/multiarch/
Guest CPU Cores (KVM):
----------------------
@ -2149,6 +2157,13 @@ W: https://travis-ci.org/qemu/qemu
W: https://app.shippable.com/github/qemu/qemu
W: http://patchew.org/QEMU/
Guest Test Compilation Support
M: Alex Bennée <alex.bennee@linaro.org>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
F: tests/tcg/Makefile
F: tests/tcg/Makefile.include
L: qemu-devel@nongnu.org
Documentation
-------------
Build system architecture

View file

@ -36,6 +36,11 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
# Makefile Tests
ifdef CONFIG_USER_ONLY
include $(SRC_PATH)/tests/tcg/Makefile.include
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak

133
configure vendored
View file

@ -289,7 +289,6 @@ libs_softmmu=""
libs_tools=""
audio_pt_int=""
audio_win_int=""
cc_i386=i386-pc-linux-gnu-gcc
libs_qga=""
debug_info="yes"
stack_protector=""
@ -458,6 +457,19 @@ vxhs=""
libxml2=""
docker="no"
# cross compilers defaults, can be overridden with --cross-cc-ARCH
cross_cc_aarch64="aarch64-linux-gnu-gcc"
cross_cc_aarch64_be="$cross_cc_aarch64"
cross_cc_cflags_aarch64_be="-mbig-endian"
cross_cc_arm="arm-linux-gnueabihf-gcc"
cross_cc_cflags_armeb="-mbig-endian"
cross_cc_i386="i386-pc-linux-gnu-gcc"
cross_cc_cflags_i386=""
cross_cc_powerpc="powerpc-linux-gnu-gcc"
cross_cc_powerpc="powerpc-linux-gnu-gcc"
enabled_cross_compilers=""
supported_cpu="no"
supported_os="no"
bogus_os="no"
@ -488,6 +500,14 @@ for opt do
;;
--disable-debug-info) debug_info="no"
;;
--cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option"
;;
--cross-cc-cflags-*) cc_arch=${opt#--cross-cc-flags-}; cc_arch=${cc_arch%%=*}
eval "cross_cc_cflags_${cc_arch}=\$optarg"
;;
--cross-cc-*) cc_arch=${opt#--cross-cc-}; cc_arch=${cc_arch%%=*}
eval "cross_cc_${cc_arch}=\$optarg"
;;
esac
done
# OS specific
@ -676,30 +696,37 @@ case "$cpu" in
ppc|ppc64|s390|s390x|sparc64|x32)
cpu="$cpu"
supported_cpu="yes"
eval "cross_cc_${cpu}=\$host_cc"
;;
i386|i486|i586|i686|i86pc|BePC)
cpu="i386"
supported_cpu="yes"
cross_cc_i386=$host_cc
;;
x86_64|amd64)
cpu="x86_64"
supported_cpu="yes"
cross_cc_x86_64=$host_cc
;;
armv*b|armv*l|arm)
cpu="arm"
supported_cpu="yes"
cross_cc_arm=$host_cc
;;
aarch64)
cpu="aarch64"
supported_cpu="yes"
cross_cc_aarch64=$host_cc
;;
mips*)
cpu="mips"
supported_cpu="yes"
cross_cc_mips=$host_cc
;;
sparc|sun4[cdmuv])
cpu="sparc"
supported_cpu="yes"
cross_cc_sparc=$host_cc
;;
*)
# This will result in either an error or falling back to TCI later
@ -917,6 +944,8 @@ for opt do
;;
--disable-debug-info)
;;
--cross-cc-*)
;;
--enable-modules)
modules="yes"
;;
@ -1402,31 +1431,44 @@ case "$cpu" in
ppc)
CPU_CFLAGS="-m32"
LDFLAGS="-m32 $LDFLAGS"
cross_cc_powerpc=$cc
cross_cc_cflags_powerpc=$CPU_CFLAGS
;;
ppc64)
CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_ppc64=$cc
cross_cc_cflags_ppc64=$CPU_CFLAGS
;;
sparc)
CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc"
LDFLAGS="-m32 -mv8plus $LDFLAGS"
cross_cc_sparc=$cc
cross_cc_cflags_sparc=$CPU_CFLAGS
;;
sparc64)
CPU_CFLAGS="-m64 -mcpu=ultrasparc"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_sparc64=$cc
cross_cc_cflags_sparc64=$CPU_CFLAGS
;;
s390)
CPU_CFLAGS="-m31"
LDFLAGS="-m31 $LDFLAGS"
cross_cc_s390=$cc
cross_cc_cflags_s390=$CPU_CFLAGS
;;
s390x)
CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_s390x=$cc
cross_cc_cflags_s390x=$CPU_CFLAGS
;;
i386)
CPU_CFLAGS="-m32"
LDFLAGS="-m32 $LDFLAGS"
cc_i386='$(CC) -m32'
cross_cc_i386=$cc
cross_cc_cflags_i386=$CPU_CFLAGS
;;
x86_64)
# ??? Only extremely old AMD cpus do not have cmpxchg16b.
@ -1434,12 +1476,14 @@ case "$cpu" in
# runtime and generate the fallback to serial emulation.
CPU_CFLAGS="-m64 -mcx16"
LDFLAGS="-m64 $LDFLAGS"
cc_i386='$(CC) -m32'
cross_cc_x86_64=$cc
cross_cc_cflags_x86_64=$CPU_CFLAGS
;;
x32)
CPU_CFLAGS="-mx32"
LDFLAGS="-mx32 $LDFLAGS"
cc_i386='$(CC) -m32'
cross_cc_i386=$cc
cross_cc_cflags_i386=$CPU_CFLAGS
;;
# No special flags required for other host CPUs
esac
@ -1501,6 +1545,8 @@ Advanced options (experts only):
--extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags QEMU_CXXFLAGS
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
--cross-cc-flags-ARCH= use compiler flags when building ARCH guest tests
--make=MAKE use specified make [$make]
--install=INSTALL use specified install [$install]
--python=PYTHON use specified python [$python]
@ -6702,7 +6748,6 @@ echo "CC=$cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then
echo "IASL=$iasl" >> $config_host_mak
fi
echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak
echo "CXX=$cxx" >> $config_host_mak
echo "OBJCC=$objcc" >> $config_host_mak
@ -6821,6 +6866,10 @@ case "$target" in
;;
esac
target_compiler=""
target_compiler_static=""
target_compiler_cflags=""
mkdir -p $target_dir
echo "# Automatically generated by configure - do not modify" > $config_target_mak
@ -6836,19 +6885,25 @@ TARGET_ABI_DIR=""
case "$target_name" in
i386)
gdb_xml_files="i386-32bit.xml i386-32bit-core.xml i386-32bit-sse.xml"
target_compiler=$cross_cc_i386
target_compiler_cflags=$cross_cc_ccflags_i386
;;
x86_64)
TARGET_BASE_ARCH=i386
gdb_xml_files="i386-64bit.xml i386-64bit-core.xml i386-64bit-sse.xml"
target_compiler=$cross_cc_x86_64
;;
alpha)
mttcg="yes"
target_compiler=$cross_cc_alpha
;;
arm|armeb)
TARGET_ARCH=arm
bflt="yes"
mttcg="yes"
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
target_compiler=$cross_cc_arm
eval "target_compiler_cflags=\$cross_cc_cflags_${target_name}"
;;
aarch64|aarch64_be)
TARGET_ARCH=aarch64
@ -6856,59 +6911,75 @@ case "$target_name" in
bflt="yes"
mttcg="yes"
gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
target_compiler=$cross_cc_aarch64
eval "target_compiler_cflags=\$cross_cc_cflags_${target_name}"
;;
cris)
target_compiler=$cross_cc_cris
;;
hppa)
mttcg="yes"
target_compiler=$cross_cc_hppa
;;
lm32)
target_compiler=$cross_cc_lm32
;;
m68k)
bflt="yes"
gdb_xml_files="cf-core.xml cf-fp.xml m68k-fp.xml"
target_compiler=$cross_cc_m68k
;;
microblaze|microblazeel)
TARGET_ARCH=microblaze
bflt="yes"
echo "TARGET_ABI32=y" >> $config_target_mak
target_compiler=$cross_cc_microblaze
;;
mips|mipsel)
TARGET_ARCH=mips
target_compiler=$cross_cc_mips
echo "TARGET_ABI_MIPSO32=y" >> $config_target_mak
;;
mipsn32|mipsn32el)
TARGET_ARCH=mips64
TARGET_BASE_ARCH=mips
target_compiler=$cross_cc_mipsn32
echo "TARGET_ABI_MIPSN32=y" >> $config_target_mak
echo "TARGET_ABI32=y" >> $config_target_mak
;;
mips64|mips64el)
TARGET_ARCH=mips64
TARGET_BASE_ARCH=mips
target_compiler=$cross_cc_mips64
echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
;;
moxie)
target_compiler=$cross_cc_moxie
;;
nios2)
target_compiler=$cross_cc_nios2
;;
or1k)
target_compiler=$cross_cc_or1k
TARGET_ARCH=openrisc
TARGET_BASE_ARCH=openrisc
;;
ppc)
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
target_compiler=$cross_cc_powerpc
;;
ppcemb)
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
target_compiler=$cross_cc_ppcemb
;;
ppc64)
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
mttcg=yes
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64
;;
ppc64le)
TARGET_ARCH=ppc64
@ -6916,6 +6987,7 @@ case "$target_name" in
TARGET_ABI_DIR=ppc
mttcg=yes
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64le
;;
ppc64abi32)
TARGET_ARCH=ppc64
@ -6923,45 +6995,57 @@ case "$target_name" in
TARGET_ABI_DIR=ppc
echo "TARGET_ABI32=y" >> $config_target_mak
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64abi32
;;
riscv32)
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
target_compiler=$cross_cc_riscv32
;;
riscv64)
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
target_compiler=$cross_cc_riscv64
;;
sh4|sh4eb)
TARGET_ARCH=sh4
bflt="yes"
target_compiler=$cross_cc_sh4
;;
sparc)
target_compiler=$cross_cc_sparc
;;
sparc64)
TARGET_BASE_ARCH=sparc
target_compiler=$cross_cc_sparc64
;;
sparc32plus)
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_ABI_DIR=sparc
target_compiler=$cross_cc_sparc32plus
echo "TARGET_ABI32=y" >> $config_target_mak
;;
s390x)
mttcg=yes
gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml s390-cr.xml s390-virt.xml s390-gs.xml"
target_compiler=$cross_cc_s390x
;;
tilegx)
target_compiler=$cross_cc_tilegx
;;
tricore)
target_compiler=$cross_cc_tricore
;;
unicore32)
target_compiler=$cross_cc_unicore32
;;
xtensa|xtensaeb)
TARGET_ARCH=xtensa
mttcg="yes"
target_compiler=$cross_cc_xtensa
;;
*)
error_exit "Unsupported target CPU"
@ -6972,6 +7056,27 @@ if [ "$TARGET_BASE_ARCH" = "" ]; then
TARGET_BASE_ARCH=$TARGET_ARCH
fi
# Do we have a cross compiler for this target?
if has $target_compiler; then
write_c_skeleton
if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC -static ; then
# For host systems we might get away with building without -static
if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC ; then
target_compiler=""
else
enabled_cross_compilers="${enabled_cross_compilers} '${target_compiler}'"
target_compiler_static="n"
fi
else
enabled_cross_compilers="${enabled_cross_compilers} '${target_compiler}'"
target_compiler_static="y"
fi
else
target_compiler=""
fi
symlink "$source_path/Makefile.target" "$target_dir/Makefile"
upper() {
@ -7045,6 +7150,19 @@ if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=y" >> $config_target_mak
fi
if test -n "$target_compiler"; then
echo "CROSS_CC_GUEST=\"$target_compiler\"" >> $config_target_mak
if test -n "$target_compiler_static"; then
echo "CROSS_CC_GUEST_STATIC=$target_compiler_static" >> $config_target_mak
fi
if test -n "$target_compiler_cflags"; then
echo "CROSS_CC_GUEST_CFLAGS=$target_compiler_cflags" >> $config_target_mak
fi
fi
# generate QEMU_CFLAGS/LDFLAGS for targets
cflags=""
@ -7167,6 +7285,11 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
done # for target in $targets
if test -n "$enabled_cross_compilers"; then
echo
echo "NOTE: cross-compilers enabled: $enabled_cross_compilers"
fi
if [ "$fdt" = "git" ]; then
echo "config-host.h: subdir-dtc" >> $config_host_mak
fi

View file

@ -10,6 +10,7 @@ check-help:
@echo " $(MAKE) check-speed Run qobject speed tests"
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
@echo " $(MAKE) check-block Run block tests"
@echo " $(MAKE) check-tcg Run TCG tests"
@echo " $(MAKE) check-report.html Generates an HTML test report"
@echo " $(MAKE) check-clean Clean the tests"
@echo
@ -930,6 +931,42 @@ check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check
check-report.html: check-report.xml
$(call quiet-command,gtester-report $< > $@,"GEN","$@")
# Per guest TCG tests
LINUX_USER_TARGETS=$(filter %-linux-user,$(TARGET_LIST))
BUILD_TCG_TARGET_RULES=$(patsubst %,build-tcg-tests-%, $(LINUX_USER_TARGETS))
CLEAN_TCG_TARGET_RULES=$(patsubst %,clean-tcg-tests-%, $(LINUX_USER_TARGETS))
RUN_TCG_TARGET_RULES=$(patsubst %,run-tcg-tests-%, $(LINUX_USER_TARGETS))
ifeq ($(HAVE_USER_DOCKER),y)
# Probe for the Docker Builds needed for each build
$(foreach PROBE_TARGET,$(TARGET_LIST), \
$(eval -include $(SRC_PATH)/tests/tcg/Makefile.probe) \
$(if $(DOCKER_PREREQ), \
$(eval build-tcg-tests-$(PROBE_TARGET): $(DOCKER_PREREQ))))
endif
build-tcg-tests-%:
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" \
SKIP_DOCKER_BUILD=1 TARGET_DIR="$*/" guest-tests, \
"BUILD", "TCG tests for $*")
run-tcg-tests-%: % build-tcg-tests-%
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" \
SKIP_DOCKER_BUILD=1 TARGET_DIR="$*/" run-guest-tests, \
"RUN", "TCG tests for $*")
clean-tcg-tests-%:
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $* V="$(V)" TARGET_DIR="$*/" clean-guest-tests,)
.PHONY: build-tcg
build-tcg: $(BUILD_TCG_TARGET_RULES)
.PHONY: check-tcg
check-tcg: $(RUN_TCG_TARGET_RULES)
.PHONY: clean-tcg
clean-tcg: $(CLEAN_TCG_TARGET_RULES)
# Other tests
@ -972,7 +1009,6 @@ check-speed: $(patsubst %,check-%, $(check-speed-y))
check-block: $(patsubst %,check-%, $(check-block-y))
check: check-qapi-schema check-unit check-qtest check-decodetree
check-clean:
$(MAKE) -C tests/tcg clean
rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y)) $(check-qtest-generic-y))
rm -f tests/test-qapi-gen-timestamp

View file

@ -15,6 +15,8 @@ DOCKER_TESTS := $(notdir $(shell \
DOCKER_TOOLS := travis
DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py
TESTS ?= %
IMAGES ?= %
@ -32,20 +34,27 @@ docker-qemu-src: $(DOCKER_SRC_COPY)
docker-image: ${DOCKER_TARGETS}
# General rule for building docker images
# General rule for building docker images. If we are a sub-make
# invoked with SKIP_DOCKER_BUILD we still check the image is upto date
# though
ifdef SKIP_DOCKER_BUILD
docker-image-%: $(DOCKER_FILES_DIR)/%.docker
$(call quiet-command, \
$(DOCKER_SCRIPT) check --quiet qemu:$* $<, \
"CHECK", "$*")
else
docker-image-%: $(DOCKER_FILES_DIR)/%.docker
@if test "$@" = docker-image-debian-bootstrap -a -z "$(EXECUTABLE)"; then \
echo WARNING: EXECUTABLE is not set, debootstrap may fail. 2>&1 ; \
fi
$(call quiet-command,\
$(SRC_PATH)/tests/docker/docker.py build qemu:$* $< \
$(DOCKER_SCRIPT) build qemu:$* $< \
$(if $V,,--quiet) $(if $(NOCACHE),--no-cache) \
$(if $(NOUSER),,--add-current-user) \
$(if $(EXTRA_FILES),--extra-files $(EXTRA_FILES))\
$(if $(EXECUTABLE),--include-executable=$(EXECUTABLE)),\
"BUILD","$*")
docker-image-debian-powerpc-cross: EXTRA_FILES:=$(SRC_PATH)/tests/docker/dockerfiles/debian-apt-fake.sh
endif
# Enforce dependencies for composite images
docker-image-debian: docker-image-debian9
@ -55,12 +64,34 @@ docker-image-debian-armel-cross: docker-image-debian9
docker-image-debian-armhf-cross: docker-image-debian9
docker-image-debian-arm64-cross: docker-image-debian9
docker-image-debian-mips-cross: docker-image-debian9
docker-image-debian-mipsel-cross: docker-image-debian9
docker-image-debian-mips64el-cross: docker-image-debian9
docker-image-debian-powerpc-cross: docker-image-debian8
docker-image-debian-ppc64el-cross: docker-image-debian9
docker-image-debian-s390x-cross: docker-image-debian9
docker-image-debian-win32-cross: docker-image-debian8-mxe
docker-image-debian-win64-cross: docker-image-debian8-mxe
# Debian SID images - we are tracking a rolling distro so we want to
# force a re-build of the base image if we ever need to build one of
# its children.
ifndef SKIP_DOCKER_BUILD
ifeq ($(HAVE_USER_DOCKER),y)
SID_AGE=$(shell $(DOCKER_SCRIPT) check --checktype=age --olderthan=180 --quiet qemu:debian-sid)
ifeq ($(SID_AGE),)
else
docker-image-debian-sid: NOCACHE=1
endif
endif
endif
docker-image-debian-alpha-cross: docker-image-debian-sid
docker-image-debian-hppa-cross: docker-image-debian-sid
docker-image-debian-m68k-cross: docker-image-debian-sid
docker-image-debian-sh4-cross: docker-image-debian-sid
docker-image-debian-sparc64-cross: docker-image-debian-sid
docker-image-debian-mips64-cross: docker-image-debian-sid
docker-image-debian-riscv64-cross: docker-image-debian-sid
docker-image-debian-powerpc-cross: docker-image-debian-sid
docker-image-travis: NOUSER=1
# Specialist build images, sometimes very limited tools
@ -133,11 +164,11 @@ docker-run: docker-qemu-src
fi
$(if $(EXECUTABLE), \
$(call quiet-command, \
$(SRC_PATH)/tests/docker/docker.py update \
$(DOCKER_SCRIPT) update \
$(IMAGE) $(EXECUTABLE), \
" COPYING $(EXECUTABLE) to $(IMAGE)"))
$(call quiet-command, \
$(SRC_PATH)/tests/docker/docker.py run \
$(DOCKER_SCRIPT) run \
$(if $(NOUSER),,-u $(shell id -u)) \
--security-opt seccomp=unconfined \
$(if $V,,--rm) \
@ -167,4 +198,4 @@ docker-run-%:
@$(MAKE) docker-run TEST=$(CMD) IMAGE=qemu:$(IMAGE)
docker-clean:
$(call quiet-command, $(SRC_PATH)/tests/docker/docker.py clean)
$(call quiet-command, $(DOCKER_SCRIPT) clean)

View file

@ -26,9 +26,13 @@ import tempfile
import re
import signal
from tarfile import TarFile, TarInfo
from StringIO import StringIO
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from shutil import copy, rmtree
from pwd import getpwuid
from datetime import datetime,timedelta
FILTERED_ENV_NAMES = ['ftp_proxy', 'http_proxy', 'https_proxy']
@ -49,7 +53,9 @@ def _guess_docker_command():
commands = [["docker"], ["sudo", "-n", "docker"]]
for cmd in commands:
try:
if subprocess.call(cmd + ["images"],
# docker version will return the client details in stdout
# but still report a status of 1 if it can't contact the daemon
if subprocess.call(cmd + ["version"],
stdout=DEVNULL, stderr=DEVNULL) == 0:
return cmd
except OSError:
@ -179,8 +185,17 @@ class Docker(object):
stderr=subprocess.STDOUT,
**kwargs)
def inspect_tag(self, tag):
try:
return self._output(["inspect", tag])
except subprocess.CalledProcessError:
return None
def get_image_creation_time(self, info):
return json.loads(info)[0]["Created"]
def get_image_dockerfile_checksum(self, tag):
resp = self._output(["inspect", tag])
resp = self.inspect_tag(tag)
labels = json.loads(resp)[0]["Config"].get("Labels", {})
return labels.get("com.qemu.dockerfile-checksum", "")
@ -201,8 +216,10 @@ class Docker(object):
tmp_df.write("\n")
tmp_df.write("LABEL com.qemu.dockerfile-checksum=%s" %
_text_checksum("\n".join([dockerfile] +
extra_files_cksum)))
_text_checksum(_dockerfile_preprocess(dockerfile)))
for f, c in extra_files_cksum:
tmp_df.write("LABEL com.qemu.%s-checksum=%s" % (f, c))
tmp_df.flush()
self._do_check(["build", "-t", tag, "-f", tmp_df.name] + argv + \
@ -317,7 +334,7 @@ class BuildCommand(SubCommand):
_copy_binary_with_libs(args.include_executable, docker_dir)
for filename in args.extra_files or []:
_copy_with_mkdir(filename, docker_dir)
cksum += [_file_checksum(filename)]
cksum += [(filename, _file_checksum(filename))]
argv += ["--build-arg=" + k.lower() + "=" + v
for k, v in os.environ.iteritems()
@ -409,6 +426,89 @@ class ProbeCommand(SubCommand):
return
class CcCommand(SubCommand):
"""Compile sources with cc in images"""
name = "cc"
def args(self, parser):
parser.add_argument("--image", "-i", required=True,
help="The docker image in which to run cc")
parser.add_argument("--cc", default="cc",
help="The compiler executable to call")
parser.add_argument("--user",
help="The user-id to run under")
parser.add_argument("--source-path", "-s", nargs="*", dest="paths",
help="""Extra paths to (ro) mount into container for
reading sources""")
def run(self, args, argv):
if argv and argv[0] == "--":
argv = argv[1:]
cwd = os.getcwd()
cmd = ["--rm", "-w", cwd,
"-v", "%s:%s:rw" % (cwd, cwd)]
if args.paths:
for p in args.paths:
cmd += ["-v", "%s:%s:ro,z" % (p, p)]
if args.user:
cmd += ["-u", args.user]
cmd += [args.image, args.cc]
cmd += argv
return Docker().command("run", cmd, args.quiet)
class CheckCommand(SubCommand):
"""Check if we need to re-build a docker image out of a dockerfile.
Arguments: <tag> <dockerfile>"""
name = "check"
def args(self, parser):
parser.add_argument("tag",
help="Image Tag")
parser.add_argument("dockerfile", default=None,
help="Dockerfile name", nargs='?')
parser.add_argument("--checktype", choices=["checksum", "age"],
default="checksum", help="check type")
parser.add_argument("--olderthan", default=60, type=int,
help="number of minutes")
def run(self, args, argv):
tag = args.tag
dkr = Docker()
info = dkr.inspect_tag(tag)
if info is None:
print("Image does not exist")
return 1
if args.checktype == "checksum":
if not args.dockerfile:
print("Need a dockerfile for tag:%s" % (tag))
return 1
dockerfile = open(args.dockerfile, "rb").read()
if dkr.image_matches_dockerfile(tag, dockerfile):
if not args.quiet:
print("Image is up to date")
return 0
else:
print("Image needs updating")
return 1
elif args.checktype == "age":
timestr = dkr.get_image_creation_time(info).split(".")[0]
created = datetime.strptime(timestr, "%Y-%m-%dT%H:%M:%S")
past = datetime.now() - timedelta(minutes=args.olderthan)
if created < past:
print ("Image created @ %s more than %d minutes old" %
(timestr, args.olderthan))
return 1
else:
if not args.quiet:
print ("Image less than %d minutes old" % (args.olderthan))
return 0
def main():
parser = argparse.ArgumentParser(description="A Docker helper",
usage="%s <subcommand> ..." % os.path.basename(sys.argv[0]))

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-alpha-linux-gnu \
libc6.1-dev-alpha-cross || { echo "Failed to build - see debian-sid.docker notes"; exit 1; }

View file

@ -1,46 +0,0 @@
#! /bin/sh
#
# Generate fake debian package to resolve unimportant unmet dependencies held
# by upstream multiarch broken packages.
#
# Copyright (c) 2017 Philippe Mathieu-Daudé <f4bug@amsat.org>
#
# This work is licensed under the terms of the GNU GPL, version 2
# or (at your option) any later version. See the COPYING file in
# the top-level directory.
test $1 = "install" && shift 1
fake_install()
{
echo "Generating fake $2 $1 $3 ..."
(cd /var/cache/apt/archives
(cat << 'EOF'
Section: misc
Priority: optional
Standards-Version: 3.9.2
Package: NAME
Version: VERSION
Maintainer: qemu-devel@nongnu.org
Architecture: any
Multi-Arch: same
Description: fake NAME
EOF
) | sed s/NAME/$2/g | sed s/VERSION/$3/g > $2.control
equivs-build -a $1 $2.control 1>/dev/null 2>/dev/null
dpkg -i --force-overwrite $2_$3_$1.deb
)
}
try_install()
{
name=$(echo $1|sed "s/\(.*\):\(.*\)=\(.*\)/\1/")
arch=$(echo $1|sed "s/\(.*\):\(.*\)=\(.*\)/\2/")
vers=$(echo $1|sed "s/\(.*\):\(.*\)=\(.*\)/\3/")
apt-get install -q -yy $1 || fake_install $arch $name $vers
}
for package in $*; do
try_install $package
done

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-hppa-linux-gnu \
libc6-dev-hppa-cross

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-m68k-linux-gnu \
libc6-dev-m68k-cross

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-mips64-linux-gnuabi64 \
libc6-dev-mips64-cross

View file

@ -1,40 +1,13 @@
#
# Docker powerpc cross-compiler target
#
# This docker target builds on the debian Jessie base image.
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets. The original
# Jessie based no longer builds.
#
FROM qemu:debian8
MAINTAINER Philippe Mathieu-Daudé <f4bug@amsat.org>
# Add the foreign architecture we want and install dependencies
RUN dpkg --add-architecture powerpc
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
crossbuild-essential-powerpc
# <kludge> to fix "following packages have unmet dependencies" ...
ADD debian-apt-fake.sh /usr/local/bin/apt-fake
RUN apt-get install -y --no-install-recommends \
equivs \
pkg-config
RUN apt-fake install \
pkg-config:powerpc=0.28-1.1-fake && \
ln -s pkg-config /usr/bin/powerpc-linux-gnu-pkg-config
ENV PKG_CONFIG_PATH /usr/lib/powerpc-linux-gnu/pkgconfig
# </kludge>
# Specify the cross prefix for this image (see tests/docker/common.rc)
ENV QEMU_CONFIGURE_OPTS --cross-prefix=powerpc-linux-gnu-
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get build-dep -yy -a powerpc qemu
RUN DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
glusterfs-common:powerpc \
libbz2-dev:powerpc \
liblzo2-dev:powerpc \
libncursesw5-dev:powerpc \
libnfs-dev:powerpc \
librdmacm-dev:powerpc \
libsnappy-dev:powerpc
gcc-powerpc-linux-gnu \
libc6-dev-powerpc-cross || { echo "Failed to build - see debian-sid.docker notes"; exit 1; }

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-riscv64-linux-gnu \
libc6-dev-riscv64-cross

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-sh4-linux-gnu \
libc6-dev-sh4-cross

View file

@ -0,0 +1,32 @@
#
# Debian Sid Base
#
# A number of our guests exist as ports only. We can either use the
# ports repo or get everything from Sid. However Sid is a rolling
# distro which may be broken at any particular time. If you are
# unlucky and try and build your images while gcc is in the process of
# being uploaded this can fail. Your only recourse is to try again in
# a few hours when the repos have re-synced. Once built however you
# won't be affected by repo changes unless the docker recipies are
# updated and trigger a re-build.
#
FROM debian:sid-slim
# Duplicate deb line as deb-src
RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list
# Install common build utilities
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt install -y --no-install-recommends \
bison \
build-essential \
ca-certificates \
flex \
git \
pkg-config \
psmisc \
python \
texinfo || { echo "Failed to build - see debian-sid.docker notes"; exit 1; }

View file

@ -0,0 +1,12 @@
#
# Docker cross-compiler target
#
# This docker target builds on the debian sid base image which
# contains cross compilers for Debian "ports" targets.
#
FROM qemu:debian-sid
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
gcc-sparc64-linux-gnu \
libc6-dev-sparc64-cross

View file

@ -32,6 +32,3 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
pkg-config \
python-minimal
# Setup Emdebian [emdebian-archive-keyring]
RUN echo "deb http://emdebian.org/tools/debian/ jessie main" > /etc/apt/sources.list.d/emdebian.list && \
curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add -

View file

@ -1,156 +1,101 @@
# -*- Mode: makefile -*-
#
# TCG tests
#
# These are complicated by the fact we want to build them for guest
# systems. This requires knowing what guests we are building and which
# ones we have cross-compilers for or docker images with
# cross-compilers.
#
# The tests themselves should be as minimal as possible as
# cross-compilers don't always have a large amount of libraries
# available.
#
# We only include the host build system for SRC_PATH and we don't
# bother with the common rules.mk. We expect the following:
#
# CC - the C compiler command
# EXTRA_CFLAGS - any extra CFLAGS
# BUILD_STATIC - are we building static binaries
#
# By default all tests are statically compiled but some host systems
# may not package static libraries by default. If an external
# cross-compiler can only build dynamic libraries the user might need
# to make extra efforts to ensure ld.so can link at runtime when the
# tests are run.
#
# We also accept SPEED=slow to enable slower running tests
#
# We also expect to be in the tests build dir for the FOO-linux-user.
#
-include ../../config-host.mak
-include $(SRC_PATH)/rules.mak
-include ../config-target.mak
$(call set-vpath, $(SRC_PATH)/tests/tcg)
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1))
QEMU=../../i386-linux-user/qemu-i386
QEMU_X86_64=../../x86_64-linux-user/qemu-x86_64
CC_X86_64=$(CC_I386) -m64
# $1 = test name, $2 = cmd, $3 = desc
run-test = $(call quiet-command, timeout $(TIMEOUT) $2 > $1.out,"TEST",$3)
QEMU_INCLUDES += -I../..
CFLAGS=-Wall -O2 -g -fno-strict-aliasing
#CFLAGS+=-msse2
# $1 = test name, $2 = reference
diff-out = $(call quiet-command, diff -u $1.out $2 | head -n 10,"DIFF","$1.out with $2")
# $1 = test name, $2 = reason
skip-test = @printf " SKIPPED %s on $(TARGET_NAME) because %s\n" $1 $2
# Tests we are building
TESTS=
# Start with a blank slate, the build targets get to add stuff first
CFLAGS=
QEMU_CFLAGS=
LDFLAGS=
# TODO: automatically detect ARM and MIPS compilers, and run those too
# The QEMU for this TARGET
QEMU=../qemu-$(TARGET_NAME)
# runcom maps page 0, so it requires root privileges
# also, pi_10.com runs indefinitely
I386_TESTS=hello-i386 \
linux-test \
testthread \
sha1-i386 \
test-i386 \
test-i386-fprem \
test-mmap \
# runcom
# native i386 compilers sometimes are not biarch. assume cross-compilers are
ifneq ($(ARCH),i386)
I386_TESTS+=run-test-x86_64
# If TCG debugging is enabled things are a lot slower
ifeq ($(CONFIG_DEBUG_TCG),y)
TIMEOUT=45
else
TIMEOUT=15
endif
TESTS = test_path
ifneq ($(call find-in-path, $(CC_I386)),)
TESTS += $(I386_TESTS)
# The order we include is important. We include multiarch, base arch
# and finally arch if it's not the same as base arch.
-include $(SRC_PATH)/tests/tcg/multiarch/Makefile.target
-include $(SRC_PATH)/tests/tcg/$(TARGET_BASE_ARCH)/Makefile.target
ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.target
endif
all: $(patsubst %,run-%,$(TESTS))
test: all
# Add the common build options
CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
ifeq ($(BUILD_STATIC),y)
LDFLAGS+=-static
endif
# rules to run tests
%: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
.PHONY: $(patsubst %,run-%,$(TESTS))
all: $(TESTS)
#
# Test Runners
#
# By default we just run the test with the appropriate QEMU for the
# target. More advanced tests may want to override the runner in their
# specific make rules. Additional runners for the same binary should
# be added to EXTRA_RUNS.
#
RUN_TESTS=$(patsubst %,run-%, $(TESTS))
RUN_TESTS+=$(EXTRA_RUNS)
run-%: %
-$(QEMU) ./$*
$(call run-test, $<, $(QEMU) $<, "$< on $(TARGET_NAME)")
run-hello-i386: hello-i386
run-linux-test: linux-test
run-testthread: testthread
run-sha1-i386: sha1-i386
.PHONY: run
run: $(RUN_TESTS)
run-test-i386: test-i386
./test-i386 > test-i386.ref
-$(QEMU) test-i386 > test-i386.out
@if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
run-test-i386-fprem: test-i386-fprem
./test-i386-fprem > test-i386-fprem.ref
-$(QEMU) test-i386-fprem > test-i386-fprem.out
@if diff -u test-i386-fprem.ref test-i386-fprem.out ; then echo "Auto Test OK"; fi
run-test-x86_64: test-x86_64
./test-x86_64 > test-x86_64.ref
-$(QEMU_X86_64) test-x86_64 > test-x86_64.out
@if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi
run-test-mmap: test-mmap
-$(QEMU) ./test-mmap
-$(QEMU) -p 8192 ./test-mmap 8192
-$(QEMU) -p 16384 ./test-mmap 16384
-$(QEMU) -p 32768 ./test-mmap 32768
run-runcom: runcom
-$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com
run-test_path: test_path
./test_path
# rules to compile tests
test_path: test_path.o
test_path.o: test_path.c
hello-i386: hello-i386.c
$(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
strip $@
testthread: testthread.c
$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
# i386/x86_64 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC_I386) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ \
$(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
test-i386-fprem: test-i386-fprem.c
$(CC_I386) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $^
test-x86_64: test-i386.c \
test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC_X86_64) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm
# generic Linux and CPU test
linux-test: linux-test.c
$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
# vm86 test
runcom: runcom.c
$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
test-mmap: test-mmap.c
$(CC_I386) -m32 $(CFLAGS) -Wall -O2 $(LDFLAGS) -o $@ $<
# speed test
sha1-i386: sha1.c
$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
sha1: sha1.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
speed: sha1 sha1-i386
time ./sha1
time $(QEMU) ./sha1-i386
# arm test
hello-arm: hello-arm.o
arm-linux-ld -o $@ $<
hello-arm.o: hello-arm.c
arm-linux-gcc -Wall -g -O2 -c -o $@ $<
test-arm-iwmmxt: test-arm-iwmmxt.s
cpp < $< | arm-linux-gnu-gcc -Wall -static -march=iwmmxt -mabi=aapcs -x assembler - -o $@
# MIPS test
hello-mips: hello-mips.c
mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
hello-mipsel: hello-mips.c
mipsel-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
# testsuite for the CRIS port.
test-cris:
$(MAKE) -C cris check
# testsuite for the LM32 port.
test-lm32:
$(MAKE) -C lm32 check
clean:
rm -f *~ *.o test-i386.out test-i386.ref \
test-x86_64.log test-x86_64.ref qruncom $(TESTS)
# There is no clean target, the calling make just rm's the tests build dir

View file

@ -0,0 +1,88 @@
# -*- Mode: makefile -*-
#
# TCG tests (per-target rules)
#
# This Makefile fragement is included from the per-target
# Makefile.target so will be invoked for each linux-user program we
# build. We have two options for compiling, either using a configured
# guest compiler or calling one of our docker images to do it for us.
#
# The per ARCH makefile, if it exists, holds extra information about
# useful docker images or alternative compiler flags.
-include $(SRC_PATH)/tests/tcg/$(TARGET_BASE_ARCH)/Makefile.include
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.include
GUEST_BUILD=
TCG_MAKE=$(SRC_PATH)/tests/tcg/Makefile
# Support installed Cross Compilers
ifdef CROSS_CC_GUEST
.PHONY: cross-build-guest-tests
cross-build-guest-tests:
$(call quiet-command, \
(mkdir -p tests && cd tests && \
$(MAKE) -f $(TCG_MAKE) CC=$(CROSS_CC_GUEST) \
BUILD_STATIC=$(CROSS_CC_GUEST_STATIC) \
EXTRA_CFLAGS=$(CROSS_CC_GUEST_CFLAGS)), \
"BUILD","$(TARGET_NAME) guest-tests with $(CROSS_CC_GUEST)")
GUEST_BUILD=cross-build-guest-tests
endif
# Support building with Docker
ifeq ($(HAVE_USER_DOCKER)$(GUEST_BUILD),y)
ifneq ($(DOCKER_IMAGE),)
# We also need the Docker make rules to depend on
include $(SRC_PATH)/tests/docker/Makefile.include
DOCKER_COMPILE_CMD="$(DOCKER_SCRIPT) cc --user $(shell id -u) \
--cc $(DOCKER_CROSS_COMPILER) \
-i qemu:$(DOCKER_IMAGE) \
-s $(SRC_PATH) -- "
DOCKER_PREREQ=docker-image-$(DOCKER_IMAGE)
.PHONY: docker-build-guest-tests
docker-build-guest-tests: $(DOCKER_PREREQ)
$(call quiet-command, \
(mkdir -p tests && cd tests && \
$(MAKE) -f $(TCG_MAKE) CC=$(DOCKER_COMPILE_CMD) \
BUILD_STATIC=y \
EXTRA_CFLAGS=$(DOCKER_CROSS_COMPILER_CFLAGS)), \
"BUILD","$(TARGET_NAME) guest-tests with docker qemu:$(DOCKER_IMAGE)")
GUEST_BUILD=docker-build-guest-tests
endif
endif
# Final targets
.PHONY: guest-tests
ifneq ($(GUEST_BUILD),)
guest-tests: $(GUEST_BUILD)
run-guest-tests: guest-tests qemu-$(TARGET_NAME)
$(call quiet-command, \
(cd tests && $(MAKE) -f $(TCG_MAKE) SPEED=$(SPEED) run), \
"RUN", "tests for $(TARGET_NAME)")
else
guest-tests:
$(call quiet-command, /bin/true, "BUILD", \
"$(TARGET_NAME) guest-tests SKIPPED")
run-guest-tests:
$(call quiet-command, /bin/true, "RUN", \
"tests for $(TARGET_NAME) SKIPPED")
endif
# It doesn't matter if these don't exits
.PHONY: clean-guest-tests
clean-guest-tests:
rm -rf tests || echo "no $(TARGET_NAME) tests to remove"

31
tests/tcg/Makefile.probe Normal file
View file

@ -0,0 +1,31 @@
# -*- Mode: makefile -*-
#
# TCG Compiler Probe
#
# This Makefile fragement is included multiple times in the main make
# script to probe for available compilers. This is used to build up a
# selection of required docker targets before we invoke a sub-make for
# each target.
# First we need the target makefile which tells us the target architecture
-include $(BUILD_DIR)/$(PROBE_TARGET)/config-target.mak
# Then we load up the target architecture makefiles which tell us
# about the compilers
CROSS_CC_GUEST:=
DOCKER_IMAGE:=
DOCKER_PREREQ:=
-include $(SRC_PATH)/tests/tcg/$(TARGET_BASE_ARCH)/Makefile.include
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.include
ifndef CROSS_CC_GUEST
ifneq ($(DOCKER_IMAGE),)
DOCKER_PREREQ:=docker-image-$(DOCKER_IMAGE)
endif
endif
# Clean-up
# undefine TARGET_NAME
# undefine TARGET_BASE_ARCH
# undefine TARGET_ABI_DIR

View file

@ -1,68 +1,7 @@
This directory contains various interesting programs for
regression testing.
The target "make test" runs the programs and, if applicable,
runs "diff" to detect mismatches between output on the host and
output on QEMU.
i386
====
test-i386
---------
This program executes most of the 16 bit and 32 bit x86 instructions and
generates a text output, for comparison with the output obtained with
a real CPU or another emulator.
The Linux system call modify_ldt() is used to create x86 selectors
to test some 16 bit addressing and 32 bit with segmentation cases.
The Linux system call vm86() is used to test vm86 emulation.
Various exceptions are raised to test most of the x86 user space
exception reporting.
linux-test
----------
This program tests various Linux system calls. It is used to verify
that the system call parameters are correctly converted between target
and host CPUs.
test-i386-fprem
---------------
runcom
------
test-mmap
---------
sha1
----
hello-i386
----------
ARM
===
hello-arm
---------
test-arm-iwmmxt
---------------
MIPS
====
hello-mips
----------
hello-mipsel
------------
This directory contains various interesting guest programs for
regression testing. Tests are either multi-arch, meaning they can be
built for all guest architectures that support linux-user executable,
or they are architecture specific.
CRIS
====

View file

@ -0,0 +1,8 @@
# Makefile.include for AArch64 targets
#
# We don't have any bigendian build tools so we only use this for AArch64
ifeq ($(TARGET_NAME),aarch64)
DOCKER_IMAGE=debian-arm64-cross
DOCKER_CROSS_COMPILER=aarch64-linux-gnu-gcc
endif

View file

@ -0,0 +1,17 @@
# -*- Mode: makefile -*-
#
# AArch64 specific tweaks
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
VPATH += $(AARCH64_SRC)
# we don't build any of the ARM tests
AARCH64_TESTS=$(filter-out $(ARM_TESTS), $(TESTS))
AARCH64_TESTS+=fcvt
TESTS:=$(AARCH64_TESTS)
fcvt: LDFLAGS+=-lm
run-fcvt: fcvt
$(call run-test,$<,$(QEMU) $<, "$< on $(TARGET_NAME)")
$(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)

3268
tests/tcg/aarch64/fcvt.ref Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,35 +0,0 @@
CROSS=alpha-linux-gnu-
CC=$(CROSS)gcc
AS=$(CROSS)as
SIM=../../alpha-linux-user/qemu-alpha
CFLAGS=-O
LINK=$(CC) -o $@ crt.o $< -nostdlib
TESTS=test-cond test-cmov
all: hello-alpha $(TESTS)
hello-alpha: hello-alpha.o crt.o
$(LINK)
test-cond: test-cond.o crt.o
$(LINK)
test-cmov.o: test-cond.c
$(CC) -c $(CFLAGS) -DTEST_CMOV -o $@ $<
test-cmov: test-cmov.o crt.o
$(LINK)
test-ovf: test-ovf.o crt.o
$(LINK)
check: $(TESTS)
for f in $(TESTS); do $(SIM) $$f || exit 1; done
clean:
$(RM) *.o *~ hello-alpha $(TESTS)
.PHONY: clean all check

View file

@ -0,0 +1,2 @@
DOCKER_IMAGE=debian-alpha-cross
DOCKER_CROSS_COMPILER=alpha-linux-gnu-gcc

View file

@ -0,0 +1,18 @@
# -*- Mode: makefile -*-
#
# Alpha specific tweaks
ALPHA_SRC=$(SRC_PATH)/tests/tcg/alpha
VPATH+=$(ALPHA_SRC)
ALPHA_TESTS=hello-alpha test-cond test-cmov test-ovf
TESTS+=$(ALPHA_TESTS)
test-cmov: EXTRA_CFLAGS=-DTEST_CMOV
test-cmov: test-cond.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-test-cmov: test-cmov
# On Alpha Linux only supports 8k pages
EXTRA_RUNS+=run-test-mmap-8192

View file

@ -1,26 +0,0 @@
.text
.globl _start
.ent _start,0
_start:
.frame $15,0,$15
br $29,1f
1: ldgp $29, 0($29)
.prologue 0
ldq $27,main($29) !literal!1
jsr $26,($27)
or $0,$0,$16
.end _start
.globl _exit
_exit:
lda $0,1
callsys
call_pal 0
.globl write
write:
lda $0,4
callsys
ret

View file

@ -1,3 +1,5 @@
#include <unistd.h>
int main (void)
{
write (1, "hello\n", 6);

View file

@ -1,3 +1,4 @@
#include <unistd.h>
#ifdef TEST_CMOV

View file

@ -1,3 +1,5 @@
#include <unistd.h>
static long test_subqv (long a, long b)
{
long res;

View file

@ -0,0 +1,8 @@
# Makefile.include for all ARM targets
#
# We don't have any bigendian build tools so we only use this for armhf
ifeq ($(TARGET_NAME),arm)
DOCKER_IMAGE=debian-armhf-cross
DOCKER_CROSS_COMPILER=arm-linux-gnueabihf-gcc
endif

View file

@ -0,0 +1,32 @@
# -*- Mode: makefile -*-
#
# ARM - included from tests/tcg/Makefile
#
ARM_SRC=$(SRC_PATH)/tests/tcg/arm
# Set search path for all sources
VPATH += $(ARM_SRC)
ARM_TESTS=hello-arm test-arm-iwmmxt
TESTS += $(ARM_TESTS) fcvt
hello-arm: CFLAGS+=-marm -ffreestanding
hello-arm: LDFLAGS+=-nostdlib
test-arm-iwmmxt: CFLAGS+=-marm -march=iwmmxt -mabi=aapcs -mfpu=fpv4-sp-d16
test-arm-iwmmxt: test-arm-iwmmxt.S
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
ifeq ($(TARGET_NAME), arm)
fcvt: LDFLAGS+=-lm
# fcvt: CFLAGS+=-march=armv8.2-a+fp16 -mfpu=neon-fp-armv8
run-fcvt: fcvt
$(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
$(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
endif
# On ARM Linux only supports 4k pages
EXTRA_RUNS+=run-test-mmap-4096

11
tests/tcg/arm/README Normal file
View file

@ -0,0 +1,11 @@
These are ARM specific guest programs
hello-arm
---------
A very simple inline assembly, write syscall based hello world
test-arm-iwmmxt
---------------
A simple test case for older iwmmxt extended ARMs

458
tests/tcg/arm/fcvt.c Normal file
View file

@ -0,0 +1,458 @@
/*
* Test Floating Point Conversion
*/
/* we want additional float type definitions */
#define __STDC_WANT_IEC_60559_BFP_EXT__
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <stdio.h>
#include <inttypes.h>
#include <math.h>
#include <float.h>
#include <fenv.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static char flag_str[256];
static char *get_flag_state(int flags)
{
if (flags) {
snprintf(flag_str, sizeof(flag_str), "%s %s %s %s %s",
flags & FE_OVERFLOW ? "OVERFLOW" : "",
flags & FE_UNDERFLOW ? "UNDERFLOW" : "",
flags & FE_DIVBYZERO ? "DIV0" : "",
flags & FE_INEXACT ? "INEXACT" : "",
flags & FE_INVALID ? "INVALID" : "");
} else {
snprintf(flag_str, sizeof(flag_str), "OK");
}
return flag_str;
}
static void print_double_number(int i, double num)
{
uint64_t double_as_hex = *(uint64_t *) &num;
int flags = fetestexcept(FE_ALL_EXCEPT);
char *fstr = get_flag_state(flags);
printf("%02d DOUBLE: %02.20e / %#020" PRIx64 " (%#x => %s)\n",
i, num, double_as_hex, flags, fstr);
}
static void print_single_number(int i, float num)
{
uint32_t single_as_hex = *(uint32_t *) &num;
int flags = fetestexcept(FE_ALL_EXCEPT);
char *fstr = get_flag_state(flags);
printf("%02d SINGLE: %02.20e / %#010x (%#x => %s)\n",
i, num, single_as_hex, flags, fstr);
}
static void print_half_number(int i, uint16_t num)
{
int flags = fetestexcept(FE_ALL_EXCEPT);
char *fstr = get_flag_state(flags);
printf("%02d HALF: %#04x (%#x => %s)\n",
i, num, flags, fstr);
}
static void print_int64(int i, int64_t num)
{
uint64_t int64_as_hex = *(uint64_t *) &num;
int flags = fetestexcept(FE_ALL_EXCEPT);
char *fstr = get_flag_state(flags);
printf("%02d INT64: %20" PRId64 "/%#020" PRIx64 " (%#x => %s)\n",
i, num, int64_as_hex, flags, fstr);
}
#ifndef SNANF
/* Signaling NaN macros, if supported. */
# if __GNUC_PREREQ(3, 3)
# define SNANF (__builtin_nansf (""))
# define SNAN (__builtin_nans (""))
# define SNANL (__builtin_nansl (""))
# endif
#endif
float single_numbers[] = { -SNANF,
-NAN,
-INFINITY,
-FLT_MAX,
-1.111E+31,
-1.111E+30,
-1.08700982e-12,
-1.78051176e-20,
-FLT_MIN,
0.0,
FLT_MIN,
2.98023224e-08,
5.96046E-8, /* min positive FP16 subnormal */
6.09756E-5, /* max subnormal FP16 */
6.10352E-5, /* min positive normal FP16 */
1.0,
1.0009765625, /* smallest float after 1.0 FP16 */
2.0,
M_E, M_PI,
65503.0,
65504.0, /* max FP16 */
65505.0,
131007.0,
131008.0, /* max AFP */
131009.0,
1.111E+30,
FLT_MAX,
INFINITY,
NAN,
SNANF };
static void convert_single_to_half(void)
{
int i;
printf("Converting single-precision to half-precision\n");
for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
float input = single_numbers[i];
feclearexcept(FE_ALL_EXCEPT);
print_single_number(i, input);
#if defined(__arm__)
uint32_t output;
asm("vcvtb.f16.f32 %0, %1" : "=t" (output) : "x" (input));
#else
uint16_t output;
asm("fcvt %h0, %s1" : "=w" (output) : "x" (input));
#endif
print_half_number(i, output);
}
}
static void convert_single_to_double(void)
{
int i;
printf("Converting single-precision to double-precision\n");
for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
float input = single_numbers[i];
/* uint64_t output; */
double output;
feclearexcept(FE_ALL_EXCEPT);
print_single_number(i, input);
#if defined(__arm__)
asm("vcvt.f64.f32 %P0, %1" : "=w" (output) : "t" (input));
#else
asm("fcvt %d0, %s1" : "=w" (output) : "x" (input));
#endif
print_double_number(i, output);
}
}
static void convert_single_to_integer(void)
{
int i;
printf("Converting single-precision to integer\n");
for (i = 0; i < ARRAY_SIZE(single_numbers); ++i) {
float input = single_numbers[i];
int64_t output;
feclearexcept(FE_ALL_EXCEPT);
print_single_number(i, input);
#if defined(__arm__)
/* asm("vcvt.s32.f32 %s0, %s1" : "=t" (output) : "t" (input)); */
output = input;
#else
asm("fcvtzs %0, %s1" : "=r" (output) : "w" (input));
#endif
print_int64(i, output);
}
}
/* This allows us to initialise some doubles as pure hex */
typedef union {
double d;
uint64_t h;
} test_doubles;
test_doubles double_numbers[] = {
{SNAN},
{-NAN},
{-INFINITY},
{-DBL_MAX},
{-FLT_MAX-1.0},
{-FLT_MAX},
{-1.111E+31},
{-1.111E+30}, /* half prec */
{-2.0}, {-1.0},
{-DBL_MIN},
{-FLT_MIN},
{0.0},
{FLT_MIN},
{2.98023224e-08},
{5.96046E-8}, /* min positive FP16 subnormal */
{6.09756E-5}, /* max subnormal FP16 */
{6.10352E-5}, /* min positive normal FP16 */
{1.0},
{1.0009765625}, /* smallest float after 1.0 FP16 */
{DBL_MIN},
{1.3789972848607228e-308},
{1.4914738736681624e-308},
{1.0}, {2.0},
{M_E}, {M_PI},
{65503.0},
{65504.0}, /* max FP16 */
{65505.0},
{131007.0},
{131008.0}, /* max AFP */
{131009.0},
{.h = 0x41dfffffffc00000 }, /* to int = 0x7fffffff */
{FLT_MAX},
{FLT_MAX + 1.0},
{DBL_MAX},
{INFINITY},
{NAN},
{.h = 0x7ff0000000000001}, /* SNAN */
{SNAN},
};
static void convert_double_to_half(void)
{
int i;
printf("Converting double-precision to half-precision\n");
for (i = 0; i < ARRAY_SIZE(double_numbers); ++i) {
double input = double_numbers[i].d;
uint16_t output;
feclearexcept(FE_ALL_EXCEPT);
print_double_number(i, input);
/* as we don't have _Float16 support */
#if defined(__arm__)
/* asm("vcvtb.f16.f64 %0, %P1" : "=t" (output) : "x" (input)); */
output = input;
#else
asm("fcvt %h0, %d1" : "=w" (output) : "x" (input));
#endif
print_half_number(i, output);
}
}
static void convert_double_to_single(void)
{
int i;
printf("Converting double-precision to single-precision\n");
for (i = 0; i < ARRAY_SIZE(double_numbers); ++i) {
double input = double_numbers[i].d;
uint32_t output;
feclearexcept(FE_ALL_EXCEPT);
print_double_number(i, input);
#if defined(__arm__)
asm("vcvt.f32.f64 %0, %P1" : "=w" (output) : "x" (input));
#else
asm("fcvt %s0, %d1" : "=w" (output) : "x" (input));
#endif
print_single_number(i, output);
}
}
static void convert_double_to_integer(void)
{
int i;
printf("Converting double-precision to integer\n");
for (i = 0; i < ARRAY_SIZE(double_numbers); ++i) {
double input = double_numbers[i].d;
int64_t output;
feclearexcept(FE_ALL_EXCEPT);
print_double_number(i, input);
#if defined(__arm__)
/* asm("vcvt.s32.f32 %s0, %s1" : "=t" (output) : "t" (input)); */
output = input;
#else
asm("fcvtzs %0, %d1" : "=r" (output) : "w" (input));
#endif
print_int64(i, output);
}
}
/* no handy defines for these numbers */
uint16_t half_numbers[] = {
0xffff, /* -NaN / AHP -Max */
0xfcff, /* -NaN / AHP */
0xfc01, /* -NaN / AHP */
0xfc00, /* -Inf */
0xfbff, /* -Max */
0xc000, /* -2 */
0xbc00, /* -1 */
0x8001, /* -MIN subnormal */
0x8000, /* -0 */
0x0000, /* +0 */
0x0001, /* MIN subnormal */
0x3c00, /* 1 */
0x7bff, /* Max */
0x7c00, /* Inf */
0x7c01, /* NaN / AHP */
0x7cff, /* NaN / AHP */
0x7fff, /* NaN / AHP +Max*/
};
static void convert_half_to_double(void)
{
int i;
printf("Converting half-precision to double-precision\n");
for (i = 0; i < ARRAY_SIZE(half_numbers); ++i) {
uint16_t input = half_numbers[i];
double output;
feclearexcept(FE_ALL_EXCEPT);
print_half_number(i, input);
#if defined(__arm__)
/* asm("vcvtb.f64.f16 %P0, %1" : "=w" (output) : "t" (input)); */
output = input;
#else
asm("fcvt %d0, %h1" : "=w" (output) : "x" (input));
#endif
print_double_number(i, output);
}
}
static void convert_half_to_single(void)
{
int i;
printf("Converting half-precision to single-precision\n");
for (i = 0; i < ARRAY_SIZE(half_numbers); ++i) {
uint16_t input = half_numbers[i];
float output;
feclearexcept(FE_ALL_EXCEPT);
print_half_number(i, input);
#if defined(__arm__)
asm("vcvtb.f32.f16 %0, %1" : "=w" (output) : "x" ((uint32_t)input));
#else
asm("fcvt %s0, %h1" : "=w" (output) : "x" (input));
#endif
print_single_number(i, output);
}
}
static void convert_half_to_integer(void)
{
int i;
printf("Converting half-precision to integer\n");
for (i = 0; i < ARRAY_SIZE(half_numbers); ++i) {
uint16_t input = half_numbers[i];
int64_t output;
feclearexcept(FE_ALL_EXCEPT);
print_half_number(i, input);
#if defined(__arm__)
/* asm("vcvt.s32.f16 %0, %1" : "=t" (output) : "t" (input)); v8.2*/
output = input;
#else
asm("fcvt %s0, %h1" : "=w" (output) : "x" (input));
#endif
print_int64(i, output);
}
}
typedef struct {
int flag;
char *desc;
} float_mapping;
float_mapping round_flags[] = {
{ FE_TONEAREST, "to nearest" },
{ FE_UPWARD, "upwards" },
{ FE_DOWNWARD, "downwards" },
{ FE_TOWARDZERO, "to zero" }
};
int main(int argc, char *argv[argc])
{
int i;
printf("#### Enabling IEEE Half Precision\n");
for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
fesetround(round_flags[i].flag);
printf("### Rounding %s\n", round_flags[i].desc);
convert_single_to_half();
convert_single_to_double();
convert_double_to_half();
convert_double_to_single();
convert_half_to_single();
convert_half_to_double();
}
/* convert to integer */
convert_single_to_integer();
convert_double_to_integer();
convert_half_to_integer();
/* And now with ARM alternative FP16 */
#if defined(__arm__)
/* See glibc sysdeps/arm/fpu_control.h */
asm("mrc p10, 7, r1, cr1, cr0, 0\n\t"
"orr r1, r1, %[flags]\n\t"
"mcr p10, 7, r1, cr1, cr0, 0\n\t"
: /* no output */ : [flags] "n" (1 << 26) : "r1" );
#else
asm("mrs x1, fpcr\n\t"
"orr x1, x1, %[flags]\n\t"
"msr fpcr, x1\n\t"
: /* no output */ : [flags] "n" (1 << 26) : "x1" );
#endif
printf("#### Enabling ARM Alternative Half Precision\n");
for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
fesetround(round_flags[i].flag);
printf("### Rounding %s\n", round_flags[i].desc);
convert_single_to_half();
convert_single_to_double();
convert_double_to_half();
convert_double_to_single();
convert_half_to_single();
convert_half_to_double();
}
/* convert to integer */
convert_single_to_integer();
convert_double_to_integer();
convert_half_to_integer();
return 0;
}

3268
tests/tcg/arm/fcvt.ref Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
DOCKER_IMAGE=debian-hppa-cross
DOCKER_CROSS_COMPILER=hppa-linux-gnu-gcc

View file

@ -0,0 +1,6 @@
# -*- Mode: makefile -*-
#
# HPPA specific tweaks - specifically masking out broken tests
# On parisc Linux supports 4K/16K/64K (but currently only 4k works)
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-16384 run-test-mmap-65536

View file

@ -0,0 +1,9 @@
#
# Makefile.include for all i386
#
# There is enough brokeness in x86_64 compilers that we don't default
# to using the x86_64 system compiler for i386 binaries.
#
DOCKER_IMAGE=fedora-i386-cross
DOCKER_CROSS_COMPILER=gcc

View file

@ -0,0 +1,52 @@
# i386 cross compile notes
I386_SRC=$(SRC_PATH)/tests/tcg/i386
# Set search path for all sources
VPATH += $(I386_SRC)
I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c))
I386_TESTS=$(I386_SRCS:.c=)
I386_ONLY_TESTS=$(filter-out test-i386-ssse3, $(I386_TESTS))
# Update TESTS
TESTS+=$(I386_ONLY_TESTS)
ifneq ($(TARGET_NAME),x86_64)
CFLAGS+=-m32
endif
#
# hello-i386 is a barebones app
#
hello-i386: CFLAGS+=-ffreestanding
hello-i386: LDFLAGS+=-nostdlib
#
# test-386 includes a couple of additional objects that need to be linked together
#
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
$(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
# Specialist test runners
run-runcom: TIMEOUT=30
run-runcom: runcom pi_10.com
$(call run-test,$<,$(QEMU) ./runcom $(I386_SRC)/pi_10.com,"$< on $(TARGET_NAME)")
ifeq ($(SPEED), slow)
test-i386-fprem.ref: test-i386-fprem
$(call quiet-command, ./$< > $@,"GENREF","generating $@")
run-test-i386-fprem: TIMEOUT=60
run-test-i386-fprem: test-i386-fprem
$(call run-test,test-i386-fprem, $(QEMU) $<,"$< on $(TARGET_NAME)")
$(call diff-out,test-i386-fprem, $(I386_SRC)/$<.ref)
else
run-test-i386-fprem: test-i386-fprem
$(call skip-test, $<, "SLOW")
endif
# On i386 and x86_64 Linux only supports 4k pages (large pages are a different hack)
EXTRA_RUNS+=run-test-mmap-4096

38
tests/tcg/i386/README Normal file
View file

@ -0,0 +1,38 @@
These are i386 specific guest programs
test-i386
---------
This program executes most of the 16 bit and 32 bit x86 instructions and
generates a text output, for comparison with the output obtained with
a real CPU or another emulator.
The Linux system call modify_ldt() is used to create x86 selectors
to test some 16 bit addressing and 32 bit with segmentation cases.
The Linux system call vm86() is used to test vm86 emulation.
Various exceptions are raised to test most of the x86 user space
exception reporting.
linux-test
----------
This program tests various Linux system calls. It is used to verify
that the system call parameters are correctly converted between target
and host CPUs.
test-i386-fprem
---------------
runcom
------
test-mmap
---------
sha1
----
hello-i386
----------

View file

@ -20,6 +20,7 @@ static inline int write(int fd, const char * buf, int len)
return status;
}
void _start(void);
void _start(void)
{
write(1, "Hello World\n", 12);

View file

@ -23,7 +23,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include <stdio.h>
#include <stdint.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/*
* Inspired by <ieee754.h>'s union ieee854_long_double, but with single
@ -39,7 +42,7 @@ union float80u {
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
} QEMU_PACKED ieee;
} __attribute__((packed)) ieee;
/* This is for NaNs in the IEEE 854 double-extended-precision format. */
struct {
@ -49,7 +52,7 @@ union float80u {
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
} QEMU_PACKED ieee_nan;
} __attribute__((packed)) ieee_nan;
};
#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
@ -229,6 +232,7 @@ static void test_fprem_cases(void)
do_fprem_stack_underflow();
printf("= invalid operation =\n");
do_fprem(q_nan.d, 1.0);
do_fprem(s_nan.d, 1.0);
do_fprem(1.0, 0.0);
do_fprem(pos_inf.d, 1.0);
@ -238,6 +242,8 @@ static void test_fprem_cases(void)
do_fprem(pos_denorm.d, 1.0);
do_fprem(1.0, pos_denorm.d);
do_fprem(smallest_positive_norm.d, smallest_positive_norm.d);
/* printf("= underflow =\n"); */
/* TODO: Is there a case where FPREM raises underflow? */
}

View file

@ -17,7 +17,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#define _GNU_SOURCE
#include "qemu/compiler.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -2107,8 +2106,8 @@ static void test_enter(void)
#ifdef TEST_SSE
typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
typedef float __m128 __attribute__ ((__mode__(__V4SF__)));
typedef int __m64 __attribute__ ((vector_size(8)));
typedef float __m128 __attribute__ ((vector_size(16)));
typedef union {
double d[2];
@ -2259,7 +2258,7 @@ SSE_OP(a ## sd);
"pop %0\n"\
: "=rm" (eflags)\
: "x" (a.dq), "x" (b.dq));\
printf("%-9s: a=%f b=%f cc=%04x\n",\
printf("%-9s: a=%f b=%f cc=%04lx\n",\
#op, a1, b1,\
eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
}

View file

@ -0,0 +1,2 @@
DOCKER_IMAGE=debian-m68k-cross
DOCKER_CROSS_COMPILER=m68k-linux-gnu-gcc

View file

@ -0,0 +1,7 @@
# -*- Mode: makefile -*-
#
# m68k specific tweaks - specifically masking out broken tests
#
# On m68k Linux supports 4k and 8k pages (but 8k is currently broken)
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-8192

View file

@ -0,0 +1,20 @@
#
# Makefile.include for all MIPs targets
#
# As Debian doesn't support mip64 in big endian mode the only way to
# build BE is to pass a working cross compiler to ./configure
#
ifeq ($(TARGET_NAME),mips64el)
DOCKER_IMAGE=debian-mips64el-cross
DOCKER_CROSS_COMPILER=mips64el-linux-gnuabi64-gcc
else ifeq ($(TARGET_NAME),mips64)
DOCKER_IMAGE=debian-mips64-cross
DOCKER_CROSS_COMPILER=mips64-linux-gnuabi64-gcc
else ifeq ($(TARGET_NAME),mipsel)
DOCKER_IMAGE=debian-mipsel-cross
DOCKER_CROSS_COMPILER=mipsel-linux-gnu-gcc
else ifeq ($(TARGET_NAME),mips)
DOCKER_IMAGE=debian-mips-cross
DOCKER_CROSS_COMPILER=mips-linux-gnu-gcc
endif

View file

@ -0,0 +1,22 @@
# -*- Mode: makefile -*-
#
# MIPS - included from tests/tcg/Makefile.target
#
MIPS_SRC=$(SRC_PATH)/tests/tcg/mips
# Set search path for all sources
VPATH += $(MIPS_SRC)
MIPS_TESTS=hello-mips
TESTS += $(MIPS_TESTS)
hello-mips: CFLAGS+=-ffreestanding
hello-mips: LDFLAGS+=-nostdlib
# For MIPS32 and 64 we have a bunch of extra tests in sub-directories
# however they are intended for system tests.
run-hello-mips: hello-mips
$(call skip-test, $<, "BROKEN")

7
tests/tcg/mips/README Normal file
View file

@ -0,0 +1,7 @@
MIPS
====
hello-mips
----------
A very simple inline assembly, write syscall based hello world

View file

@ -0,0 +1,36 @@
# -*- Mode: makefile -*-
#
# Multiarch Tests - included from tests/tcg/Makefile.target
#
# These tests are plain C and built without any architecture specific code.
#
MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
# Set search path for all sources
VPATH += $(MULTIARCH_SRC)
MULTIARCH_SRCS =$(notdir $(wildcard $(MULTIARCH_SRC)/*.c))
MULTIARCH_TESTS =$(MULTIARCH_SRCS:.c=)
# Update TESTS
TESTS +=$(MULTIARCH_TESTS)
#
# The following are any additional rules needed to build things
#
testthread: LDFLAGS+=-lpthread
# We define the runner for test-mmap after the individual
# architectures have defined their supported pages sizes. If no
# additional page sizes are defined we only run the default test.
# default case (host page size)
run-test-mmap: test-mmap
$(call run-test, test-mmap, $(QEMU) $<, \
"$< (default) on $(TARGET_NAME)")
# additional page sizes (defined by each architecture adding to EXTRA_RUNS)
run-test-mmap-%: test-mmap
$(call run-test, test-mmap-$*, $(QEMU) -p $* $<,\
"$< ($* byte pages) on $(TARGET_NAME)")

View file

@ -0,0 +1 @@
Multi-architecture linux-user tests

View file

@ -31,6 +31,7 @@
#include <utime.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -39,13 +40,11 @@
#include <dirent.h>
#include <setjmp.h>
#include <sys/shm.h>
#include "qemu/cutils.h"
#include <assert.h>
#define TESTPATH "/tmp/linux-test.tmp"
#define TESTPORT 7654
#define STACK_SIZE 16384
void error1(const char *filename, int line, const char *fmt, ...)
static void error1(const char *filename, int line, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@ -56,11 +55,11 @@ void error1(const char *filename, int line, const char *fmt, ...)
exit(1);
}
int __chk_error(const char *filename, int line, int ret)
static int __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
error1(filename, line, "%m (ret=%d, errno=%d)",
ret, errno);
error1(filename, line, "%m (ret=%d, errno=%d/%s)",
ret, errno, strerror(errno));
}
return ret;
}
@ -73,7 +72,7 @@ int __chk_error(const char *filename, int line, int ret)
#define FILE_BUF_SIZE 300
void test_file(void)
static void test_file(void)
{
int fd, i, len, ret;
uint8_t buf[FILE_BUF_SIZE];
@ -85,19 +84,16 @@ void test_file(void)
struct iovec vecs[2];
DIR *dir;
struct dirent *de;
/* TODO: make common tempdir creation for tcg tests */
char template[] = "/tmp/linux-test-XXXXXX";
char *tmpdir = mkdtemp(template);
/* clean up, just in case */
unlink(TESTPATH "/file1");
unlink(TESTPATH "/file2");
unlink(TESTPATH "/file3");
rmdir(TESTPATH);
assert(tmpdir);
if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
error("getcwd");
chk_error(mkdir(TESTPATH, 0755));
chk_error(chdir(TESTPATH));
chk_error(chdir(tmpdir));
/* open/read/write/close/readv/writev/lseek */
@ -163,7 +159,7 @@ void test_file(void)
st.st_mtime != 1000)
error("stat time");
chk_error(stat(TESTPATH, &st));
chk_error(stat(tmpdir, &st));
if (!S_ISDIR(st.st_mode))
error("stat mode");
@ -185,7 +181,7 @@ void test_file(void)
error("stat mode");
/* getdents */
dir = opendir(TESTPATH);
dir = opendir(tmpdir);
if (!dir)
error("opendir");
len = 0;
@ -207,16 +203,17 @@ void test_file(void)
chk_error(unlink("file3"));
chk_error(unlink("file2"));
chk_error(chdir(cur_dir));
chk_error(rmdir(TESTPATH));
chk_error(rmdir(tmpdir));
}
void test_fork(void)
static void test_fork(void)
{
int pid, status;
pid = chk_error(fork());
if (pid == 0) {
/* child */
sleep(2);
exit(2);
}
chk_error(waitpid(pid, &status, 0));
@ -224,7 +221,7 @@ void test_fork(void)
error("waitpid status=0x%x", status);
}
void test_time(void)
static void test_time(void)
{
struct timeval tv, tv2;
struct timespec ts, rem;
@ -251,34 +248,7 @@ void test_time(void)
error("getrusage");
}
void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
char *q = buf;
if (buf_size <= 0)
return;
for(;;) {
c = *str++;
if (c == 0 || q >= buf + buf_size - 1)
break;
*q++ = c;
}
*q = '\0';
}
/* strcat and truncate. */
char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
len = strlen(buf);
if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
int server_socket(void)
static int server_socket(void)
{
int val, fd;
struct sockaddr_in sockaddr;
@ -290,7 +260,7 @@ int server_socket(void)
chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(TESTPORT);
sockaddr.sin_port = htons(0); /* choose random ephemeral port) */
sockaddr.sin_addr.s_addr = 0;
chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
chk_error(listen(fd, 0));
@ -298,7 +268,7 @@ int server_socket(void)
}
int client_socket(void)
static int client_socket(uint16_t port)
{
int fd;
struct sockaddr_in sockaddr;
@ -306,22 +276,29 @@ int client_socket(void)
/* server socket */
fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(TESTPORT);
sockaddr.sin_port = htons(port);
inet_aton("127.0.0.1", &sockaddr.sin_addr);
chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
return fd;
}
const char socket_msg[] = "hello socket\n";
static const char socket_msg[] = "hello socket\n";
void test_socket(void)
static void test_socket(void)
{
int server_fd, client_fd, fd, pid, ret, val;
struct sockaddr_in sockaddr;
socklen_t len;
struct sockaddr_in server_addr;
socklen_t len, socklen;
uint16_t server_port;
char buf[512];
server_fd = server_socket();
/* find out what port we got */
socklen = sizeof(server_addr);
ret = getsockname(server_fd, &server_addr, &socklen);
chk_error(ret);
server_port = ntohs(server_addr.sin_port);
/* test a few socket options */
len = sizeof(val);
@ -331,7 +308,7 @@ void test_socket(void)
pid = chk_error(fork());
if (pid == 0) {
client_fd = client_socket();
client_fd = client_socket(server_port);
send(client_fd, socket_msg, sizeof(socket_msg), 0);
close(client_fd);
exit(0);
@ -350,7 +327,7 @@ void test_socket(void)
#define WCOUNT_MAX 512
void test_pipe(void)
static void test_pipe(void)
{
fd_set rfds, wfds;
int fds[2], fd_max, ret;
@ -382,7 +359,7 @@ void test_pipe(void)
}
if (FD_ISSET(fds[1], &wfds)) {
ch = 'a';
chk_error(write(fds[0], &ch, 1));
chk_error(write(fds[1], &ch, 1));
wcount++;
}
}
@ -391,10 +368,10 @@ void test_pipe(void)
chk_error(close(fds[1]));
}
int thread1_res;
int thread2_res;
static int thread1_res;
static int thread2_res;
int thread1_func(void *arg)
static int thread1_func(void *arg)
{
int i;
for(i=0;i<5;i++) {
@ -404,7 +381,7 @@ int thread1_func(void *arg)
return 0;
}
int thread2_func(void *arg)
static int thread2_func(void *arg)
{
int i;
for(i=0;i<6;i++) {
@ -414,23 +391,37 @@ int thread2_func(void *arg)
return 0;
}
void test_clone(void)
static void wait_for_child(pid_t pid)
{
int status;
chk_error(waitpid(pid, &status, 0));
}
/* For test_clone we must match the clone flags used by glibc, see
* CLONE_THREAD_FLAGS in the QEMU source code.
*/
static void test_clone(void)
{
uint8_t *stack1, *stack2;
int pid1, pid2, status1, status2;
pid_t pid1, pid2;
stack1 = malloc(STACK_SIZE);
pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"));
CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM,
"hello1"));
stack2 = malloc(STACK_SIZE);
pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"));
CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM,
"hello2"));
while (waitpid(pid1, &status1, 0) != pid1);
wait_for_child(pid1);
free(stack1);
while (waitpid(pid2, &status2, 0) != pid2);
wait_for_child(pid2);
free(stack2);
if (thread1_res != 5 ||
thread2_res != 6)
error("clone");
@ -441,21 +432,21 @@ void test_clone(void)
volatile int alarm_count;
jmp_buf jmp_env;
void sig_alarm(int sig)
static void sig_alarm(int sig)
{
if (sig != SIGALRM)
error("signal");
alarm_count++;
}
void sig_segv(int sig, siginfo_t *info, void *puc)
static void sig_segv(int sig, siginfo_t *info, void *puc)
{
if (sig != SIGSEGV)
error("signal");
longjmp(jmp_env, 1);
}
void test_signal(void)
static void test_signal(void)
{
struct sigaction act;
struct itimerval it, oit;
@ -475,12 +466,10 @@ void test_signal(void)
it.it_value.tv_usec = 10 * 1000;
chk_error(setitimer(ITIMER_REAL, &it, NULL));
chk_error(getitimer(ITIMER_REAL, &oit));
if (oit.it_value.tv_sec != it.it_value.tv_sec ||
oit.it_value.tv_usec != it.it_value.tv_usec)
error("itimer");
while (alarm_count < 5) {
usleep(10 * 1000);
getitimer(ITIMER_REAL, &oit);
}
it.it_interval.tv_sec = 0;
@ -489,9 +478,6 @@ void test_signal(void)
it.it_value.tv_usec = 0;
memset(&oit, 0xff, sizeof(oit));
chk_error(setitimer(ITIMER_REAL, &it, &oit));
if (oit.it_value.tv_sec != 0 ||
oit.it_value.tv_usec != 10 * 1000)
error("setitimer");
/* SIGSEGV test */
act.sa_sigaction = sig_segv;
@ -510,7 +496,7 @@ void test_signal(void)
#define SHM_SIZE 32768
void test_shm(void)
static void test_shm(void)
{
void *ptr;
int shmid;
@ -529,10 +515,16 @@ void test_shm(void)
int main(int argc, char **argv)
{
test_file();
test_pipe();
test_fork();
test_time();
test_socket();
// test_clone();
if (argc > 1) {
printf("test_clone still considered buggy\n");
test_clone();
}
test_signal();
test_shm();
return 0;

View file

@ -36,7 +36,7 @@
do \
{ \
if (!(x)) { \
fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
fprintf(stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
exit (EXIT_FAILURE); \
} \
} while (0)
@ -57,7 +57,7 @@ void check_aligned_anonymous_unfixed_mmaps(void)
uintptr_t p;
int i;
fprintf (stderr, "%s", __func__);
fprintf(stdout, "%s", __func__);
for (i = 0; i < 0x1fff; i++)
{
size_t len;
@ -106,7 +106,7 @@ void check_aligned_anonymous_unfixed_mmaps(void)
munmap (p4, len);
munmap (p5, len);
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_large_anonymous_unfixed_mmap(void)
@ -115,7 +115,7 @@ void check_large_anonymous_unfixed_mmap(void)
uintptr_t p;
size_t len;
fprintf (stderr, "%s", __func__);
fprintf(stdout, "%s", __func__);
len = 0x02000000;
p1 = mmap(NULL, len, PROT_READ,
@ -130,7 +130,7 @@ void check_large_anonymous_unfixed_mmap(void)
/* Make sure we can read from the entire area. */
memcpy (dummybuf, p1, pagesize);
munmap (p1, len);
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_aligned_anonymous_unfixed_colliding_mmaps(void)
@ -141,7 +141,7 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
uintptr_t p;
int i;
fprintf (stderr, "%s", __func__);
fprintf(stdout, "%s", __func__);
for (i = 0; i < 0x2fff; i++)
{
int nlen;
@ -180,7 +180,7 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
munmap (p2, pagesize);
munmap (p3, nlen);
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_aligned_anonymous_fixed_mmaps(void)
@ -194,7 +194,7 @@ void check_aligned_anonymous_fixed_mmaps(void)
addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
fprintf (stderr, "%s addr=%p", __func__, addr);
fprintf(stdout, "%s addr=%p", __func__, addr);
fail_unless (addr != MAP_FAILED);
for (i = 0; i < 40; i++)
@ -212,7 +212,7 @@ void check_aligned_anonymous_fixed_mmaps(void)
munmap (p1, pagesize);
addr += pagesize;
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
@ -225,8 +225,8 @@ void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
/* Find a suitable address to start with. Right were the x86 hosts
stack is. */
addr = ((void *)0x80000000);
fprintf (stderr, "%s addr=%p", __func__, addr);
fprintf (stderr, "FIXME: QEMU fails to track pages used by the host.");
fprintf(stdout, "%s addr=%p", __func__, addr);
fprintf(stdout, "FIXME: QEMU fails to track pages used by the host.");
for (i = 0; i < 20; i++)
{
@ -243,7 +243,7 @@ void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
munmap (p1, pagesize);
addr += pagesize;
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_file_unfixed_mmaps(void)
@ -252,7 +252,7 @@ void check_file_unfixed_mmaps(void)
uintptr_t p;
int i;
fprintf (stderr, "%s", __func__);
fprintf(stdout, "%s", __func__);
for (i = 0; i < 0x10; i++)
{
size_t len;
@ -294,7 +294,7 @@ void check_file_unfixed_mmaps(void)
munmap (p2, len);
munmap (p3, len);
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_file_unfixed_eof_mmaps(void)
@ -304,7 +304,7 @@ void check_file_unfixed_eof_mmaps(void)
uintptr_t p;
int i;
fprintf (stderr, "%s", __func__);
fprintf(stdout, "%s", __func__);
for (i = 0; i < 0x10; i++)
{
p1 = mmap(NULL, pagesize, PROT_READ,
@ -327,7 +327,7 @@ void check_file_unfixed_eof_mmaps(void)
fail_unless (cp[pagesize - 4] == 0);
munmap (p1, pagesize);
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_file_fixed_eof_mmaps(void)
@ -343,7 +343,7 @@ void check_file_fixed_eof_mmaps(void)
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
fail_unless (addr != MAP_FAILED);
for (i = 0; i < 0x10; i++)
@ -371,7 +371,7 @@ void check_file_fixed_eof_mmaps(void)
munmap (p1, pagesize);
addr += pagesize;
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void check_file_fixed_mmaps(void)
@ -384,7 +384,7 @@ void check_file_fixed_mmaps(void)
addr = mmap(NULL, pagesize * 40 * 4, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
fail_unless (addr != MAP_FAILED);
for (i = 0; i < 40; i++)
@ -426,7 +426,7 @@ void check_file_fixed_mmaps(void)
munmap (p4, pagesize);
addr += pagesize * 4;
}
fprintf (stderr, " passed\n");
fprintf(stdout, " passed\n");
}
void checked_write(int fd, const void *buf, size_t count)

View file

@ -0,0 +1,7 @@
ifeq ($(TARGET_NAME),ppc)
DOCKER_IMAGE=debian-powerpc-cross
DOCKER_CROSS_COMPILER=powerpc-linux-gnu-gcc
else ifeq ($(TARGET_NAME),ppc64le)
DOCKER_IMAGE=debian-ppc64el-cross
DOCKER_CROSS_COMPILER=powerpc64le-linux-gnu-gcc
endif

View file

@ -0,0 +1,12 @@
# -*- Mode: makefile -*-
#
# PPC - included from tests/tcg/Makefile
#
ifneq (,$(findstring 64,$(TARGET_NAME)))
# On PPC64 Linux can be configured with 4k (default) or 64k pages (currently broken)
EXTRA_RUNS+=run-test-mmap-4096 #run-test-mmap-65536
else
# On PPC32 Linux supports 4K/16K/64K/256K (but currently only 4k works)
EXTRA_RUNS+=run-test-mmap-4096 #run-test-mmap-16384 run-test-mmap-65536 run-test-mmap-262144
endif

View file

@ -0,0 +1,10 @@
#
# Makefile.include for all RISCV targets
#
# Debian only really cares about 64 bit going forward
#
ifeq ($(TARGET_NAME),riscv64)
DOCKER_IMAGE=debian-riscv64-cross
DOCKER_CROSS_COMPILER=riscv64-linux-gnu-gcc
endif

View file

@ -0,0 +1,2 @@
DOCKER_IMAGE=debian-s390x-cross
DOCKER_CROSS_COMPILER=s390x-linux-gnu-gcc

View file

@ -0,0 +1,4 @@
ifneq ($(TARGET_NAME), sh4eb)
DOCKER_IMAGE=debian-sh4-cross
DOCKER_CROSS_COMPILER=sh4-linux-gnu-gcc
endif

View file

@ -0,0 +1,7 @@
# -*- Mode: makefile -*-
#
# SuperH specific tweaks
#
# On sh Linux supports 4k, 8k, 16k and 64k pages (but only 4k currently works)
EXTRA_RUNS+=run-test-mmap-4096 # run-test-mmap-8192 run-test-mmap-16384 run-test-mmap-65536

View file

@ -0,0 +1,2 @@
DOCKER_IMAGE=debian-sparc64-cross
DOCKER_CROSS_COMPILER=sparc64-linux-gnu-gcc

View file

@ -0,0 +1,11 @@
# -*- Mode: makefile -*-
#
# sparc specific tweaks and masking out broken tests
# different from the other hangs:
# tests/tcg/multiarch/linux-test.c:264: Value too large for defined data type (ret=-1, errno=92/Value too large for defined data type)
run-linux-test: linux-test
$(call skip-test, $<, "BROKEN")
# On Sparc64 Linux support 8k pages
EXTRA_RUNS+=run-test-mmap-8192

View file

@ -1,157 +0,0 @@
/* Test path override code */
#include "config-host.h"
#include "util/cutils.c"
#include "util/hexdump.c"
#include "util/iov.c"
#include "util/path.c"
#include "util/qemu-timer-common.c"
#include <stdarg.h>
#include <sys/stat.h>
#include <fcntl.h>
void qemu_log(const char *fmt, ...);
/* Any log message kills the test. */
void qemu_log(const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "FATAL: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
#define NO_CHANGE(_path) \
do { \
if (strcmp(path(_path), _path) != 0) return __LINE__; \
} while(0)
#define CHANGE_TO(_path, _newpath) \
do { \
if (strcmp(path(_path), _newpath) != 0) return __LINE__; \
} while(0)
static void cleanup(void)
{
unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE");
unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2");
unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3");
unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4");
unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5");
rmdir("/tmp/qemu-test_path/DIR1/DIR2");
rmdir("/tmp/qemu-test_path/DIR1/DIR3");
rmdir("/tmp/qemu-test_path/DIR1");
rmdir("/tmp/qemu-test_path");
}
static unsigned int do_test(void)
{
if (mkdir("/tmp/qemu-test_path", 0700) != 0)
return __LINE__;
if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0)
return __LINE__;
if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0)
return __LINE__;
if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0)
return __LINE__;
if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0)
return __LINE__;
if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0)
return __LINE__;
if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0)
return __LINE__;
if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0)
return __LINE__;
if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0)
return __LINE__;
init_paths("/tmp/qemu-test_path");
NO_CHANGE("/tmp");
NO_CHANGE("/tmp/");
NO_CHANGE("/tmp/qemu-test_path");
NO_CHANGE("/tmp/qemu-test_path/");
NO_CHANGE("/tmp/qemu-test_path/D");
NO_CHANGE("/tmp/qemu-test_path/DI");
NO_CHANGE("/tmp/qemu-test_path/DIR");
NO_CHANGE("/tmp/qemu-test_path/DIR1");
NO_CHANGE("/tmp/qemu-test_path/DIR1/");
NO_CHANGE("/D");
NO_CHANGE("/DI");
NO_CHANGE("/DIR");
NO_CHANGE("/DIR2");
NO_CHANGE("/DIR1.");
CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1");
CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1");
NO_CHANGE("/DIR1/D");
NO_CHANGE("/DIR1/DI");
NO_CHANGE("/DIR1/DIR");
NO_CHANGE("/DIR1/DIR1");
CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2");
CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3");
CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3");
NO_CHANGE("/DIR1/DIR2/F");
NO_CHANGE("/DIR1/DIR2/FI");
NO_CHANGE("/DIR1/DIR2/FIL");
NO_CHANGE("/DIR1/DIR2/FIL.");
CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2");
CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3");
CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4");
CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5");
NO_CHANGE("/DIR1/DIR2/FILE6");
NO_CHANGE("/DIR1/DIR2/FILE/X");
CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1");
CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1");
CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1");
CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1");
CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
NO_CHANGE("/DIR1/DIR2/../DIR1");
NO_CHANGE("/DIR1/DIR2/../FILE");
CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
return 0;
}
int main(int argc, char *argv[])
{
int ret;
ret = do_test();
cleanup();
if (ret) {
fprintf(stderr, "test_path: failed on line %i\n", ret);
return 1;
}
return 0;
}

View file

@ -0,0 +1,15 @@
# -*- Mode: makefile -*-
#
# x86_64 tests - included from tests/tcg/Makefile.target
#
# Currently we only build test-x86_64 and test-i386-ssse3 from
# $(SRC)/tests/tcg/i386/
#
X86_64_TESTS=$(filter-out $(I386_ONLY_TESTS), $(TESTS))
X86_64_TESTS+=test-x86_64
TESTS:=$(X86_64_TESTS)
test-x86_64: LDFLAGS+=-lm -lc
test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)