Import QEMU upstream snapshot d2e570c

Upstream: https://gitlab.com/qemu-project/qemu.git

Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
2026-08-31 02:15:30 +02:00
commit cf256aa081
11315 changed files with 3598369 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
This is the list of currently configured Coverity components:
alpha
~ .*/qemu((/include)?/hw/alpha/.*|/target/alpha/.*)
arm
~ .*/qemu((/include)?/hw/arm/.*|(/include)?/hw/.*/(arm|allwinner-a10|bcm28|digic|exynos|imx|omap|stellaris|pxa2xx|versatile|zynq|cadence).*|/hw/ssi/xilinx_spips.c|/target/arm/.*)
avr
~ .*/qemu((/include)?/hw/avr/.*|/target/avr/.*)
hexagon-gen (component should be ignored in analysis)
~ .*/qemu(/target/hexagon/.*generated.*)
hexagon
~ .*/qemu(/target/hexagon/.*)
hppa
~ .*/qemu((/include)?/hw/hppa/.*|/target/hppa/.*)
i386
~ .*/qemu((/include)?/hw/i386/.*|/target/i386/.*|/hw/intc/[^/]*apic[^/]*\.c)
loongarch
~ .*/qemu((/include)?/hw/(loongarch/.*|.*/loongarch.*)|/target/loongarch/.*)
m68k
~ .*/qemu((/include)?/hw/m68k/.*|/target/m68k/.*|(/include)?/hw(/.*)?/mcf.*|(/include)?/hw/nubus/.*)
microblaze
~ .*/qemu((/include)?/hw/microblaze/.*|/target/microblaze/.*)
mips
~ .*/qemu((/include)?/hw/mips/.*|/target/mips/.*)
openrisc
~ .*/qemu((/include)?/hw/openrisc/.*|/target/openrisc/.*)
ppc
~ .*/qemu((/include)?/hw/ppc/.*|/target/ppc/.*|/hw/pci-host/(uninorth.*|dec.*|prep.*|ppc.*)|/hw/misc/macio/.*|(/include)?/hw/.*/(xics|openpic|spapr).*)
riscv
~ .*/qemu((/include)?/hw/riscv/.*|/target/riscv/.*|/hw/.*/(riscv_|ibex_|sifive_).*)
rx
~ .*/qemu((/include)?/hw/rx/.*|/target/rx/.*)
s390
~ .*/qemu((/include)?/hw/s390x/.*|/target/s390x/.*|/hw/.*/s390_.*)
sh4
~ .*/qemu((/include)?/hw/sh4/.*|/target/sh4/.*)
sparc
~ .*/qemu((/include)?/hw/sparc(64)?.*|/target/sparc/.*|/hw/.*/grlib.*|/hw/display/cg3.c)
tricore
~ .*/qemu((/include)?/hw/tricore/.*|/target/tricore/.*)
xtensa
~ .*/qemu((/include)?/hw/xtensa/.*|/target/xtensa/.*)
9pfs
~ .*/qemu(/hw/9pfs/.*|/fsdev/.*)
audio
~ .*/qemu((/include)?/(audio|hw/audio)/.*)
block
~ .*/qemu(/block.*|(/include?)/(block|storage-daemon)/.*|(/include)?/hw/(block|ide|nvme)/.*|/qemu-(img|io).*|/util/(aio|async|thread-pool).*)
char
~ .*/qemu((/include)?/hw/char/.*)
chardev
~ .*/qemu((/include)?/chardev/.*)
crypto
~ .*/qemu((/include)?/crypto/.*|/hw/.*/.*crypto.*|(/include/system|/backends)/cryptodev.*|/host/include/.*/host/crypto/.*)
disas
~ .*/qemu((/include)?/disas.*)
fpu
~ .*/qemu((/include)?(/fpu|/libdecnumber)/.*)
io
~ .*/qemu((/include)?/io/.*)
ipmi
~ .*/qemu((/include)?/hw/ipmi/.*)
migration
~ .*/qemu((/include)?/migration/.*)
monitor
~ .*/qemu((/include)?/(qapi|qobject|monitor)/.*|/job-qmp.c)
nbd
~ .*/qemu(/nbd/.*|/include/block/nbd.*|/qemu-nbd\.c)
net
~ .*/qemu((/include)?(/hw)?/(net|rdma)/.*)
pci
~ .*/qemu(/include)?/hw/(cxl/|pci).*
qemu-ga
~ .*/qemu(/qga/.*)
scsi
~ .*/qemu(/scsi/.*|/hw/scsi/.*|/include/hw/scsi/.*)
trace
~ .*/qemu(/.*trace.*\.[ch])
ui
~ .*/qemu((/include)?(/ui|/hw/display|/hw/input)/.*)
usb
~ .*/qemu(/hw/usb/.*|/include/hw/usb/.*)
user
~ .*/qemu(/linux-user/.*|/bsd-user/.*|/user-exec\.c|/thunk\.c|/include/user/.*)
util
~ .*/qemu(/util/.*|/include/qemu/.*)
vfio
~ .*/qemu(/include)?/hw/vfio/.*
virtio
~ .*/qemu(/include)?/hw/virtio/.*
xen
~ .*/qemu(.*/xen.*)
hvf
~ .*/qemu(.*/hvf.*)
kvm
~ .*/qemu(.*/kvm.*)
tcg
~ .*/qemu(/accel/tcg|/replay|/tcg)/.*
system
~ .*/qemu(/system/.*|/accel/.*)
plugins
~ .*/qemu(/contrib|/tests/tcg)?/plugins/.*
(headers)
~ .*/qemu(/include/.*)
testlibs
~ .*/qemu(/tests/qtest(/libqos/.*|/libqtest.*|/libqmp.*))
tests
~ .*/qemu(/tests/.*)
+166
View File
@@ -0,0 +1,166 @@
# syntax=docker/dockerfile:1.0.0-experimental
#
# Docker setup for running the "Coverity Scan" tools over the source
# tree and uploading them to the website, as per
# https://scan.coverity.com/projects/qemu/builds/new
# We do this on a fixed config (currently Fedora 30 with a known
# set of dependencies and a configure command that enables a specific
# set of options) so that random changes don't result in our accidentally
# dropping some files from the scan.
#
# We don't build on top of the fedora.docker file because we don't
# want to accidentally change or break the scan config when that
# is updated.
# The work of actually doing the build is handled by the
# run-coverity-scan script.
FROM registry.fedoraproject.org/fedora:37
RUN dnf install -y nosync && \
echo -e '#!/bin/sh\n\
if test -d /usr/lib64\n\
then\n\
export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
else\n\
export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
fi\n\
exec "$@"' > /usr/bin/nosync && \
chmod +x /usr/bin/nosync && \
nosync dnf update -y && \
nosync dnf install -y \
SDL2-devel \
SDL2_image-devel \
alsa-lib-devel \
bash \
bc \
bison \
brlapi-devel \
bzip2 \
bzip2-devel \
ca-certificates \
capstone-devel \
ccache \
clang \
ctags \
cyrus-sasl-devel \
daxctl-devel \
dbus-daemon \
device-mapper-multipath-devel \
diffutils \
findutils \
flex \
fuse3-devel \
gcc \
gcc-c++ \
gcovr \
genisoimage \
gettext \
git \
glib2-devel \
glib2-static \
glibc-langpack-en \
glibc-static \
gnutls-devel \
gtk3-devel \
hostname \
jemalloc-devel \
json-c-devel \
libaio-devel \
libasan \
libattr-devel \
libbpf-devel \
libcacard-devel \
libcap-ng-devel \
libcmocka-devel \
libcurl-devel \
libdrm-devel \
libepoxy-devel \
libfdt-devel \
libffi-devel \
libgcrypt-devel \
libiscsi-devel \
libjpeg-devel \
libnfs-devel \
libpmem-devel \
libpng-devel \
librbd-devel \
libseccomp-devel \
libselinux-devel \
libslirp-devel \
libssh-devel \
libtasn1-devel \
libubsan \
liburing-devel \
libusbx-devel \
libzstd-devel \
llvm \
lttng-ust-devel \
lzo-devel \
make \
mesa-libgbm-devel \
meson \
ncurses-devel \
nettle-devel \
ninja-build \
nmap-ncat \
numactl-devel \
openssh-clients \
pam-devel \
pcre-static \
pixman-devel \
pkgconfig \
pulseaudio-libs-devel \
python3 \
python3-PyYAML \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pip \
python3-sphinx \
python3-sphinx_rtd_theme \
rdma-core-devel \
rpm \
sed \
snappy-devel \
socat \
sparse \
spice-protocol \
spice-server-devel \
systemd-devel \
systemtap-sdt-devel \
tar \
tesseract \
tesseract-langpack-eng \
usbredir-devel \
util-linux \
virglrenderer-devel \
vte291-devel \
which \
xen-devel \
xfsprogs-devel \
zlib-devel \
zlib-static \
zstd && \
nosync dnf autoremove -y && \
nosync dnf clean all -y && \
rpm -qa | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
ENV CCACHE_WRAPPERSDIR=/usr/libexec/ccache-wrappers
ENV LANG=en_US.UTF-8
ENV MAKE=/usr/bin/make
ENV NINJA=/usr/bin/ninja
ENV PYTHON=/usr/bin/python3
ENV QEMU_CONFIGURE_OPTS=--meson=internal
RUN dnf install -y curl wget
ENV COVERITY_TOOL_BASE=/coverity-tools
COPY coverity_tool.tgz coverity_tool.tgz
RUN mkdir -p /coverity-tools/coverity_tool && cd /coverity-tools/coverity_tool && tar xf /coverity_tool.tgz
COPY run-coverity-scan run-coverity-scan
+284
View File
@@ -0,0 +1,284 @@
/* Coverity Scan model
*
* Copyright (C) 2014 Red Hat, Inc.
*
* Authors:
* Markus Armbruster <[email protected]>
* Paolo Bonzini <[email protected]>
*
* 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.
*/
/*
* This is the source code for our Coverity user model file. The
* purpose of user models is to increase scanning accuracy by explaining
* code Coverity can't see (out of tree libraries) or doesn't
* sufficiently understand. Better accuracy means both fewer false
* positives and more true defects. Memory leaks in particular.
*
* - A model file can't import any header files. Some built-in primitives are
* available but not wchar_t, NULL etc.
* - Modeling doesn't need full structs and typedefs. Rudimentary structs
* and similar types are sufficient.
* - An uninitialized local variable signifies that the variable could be
* any value.
*
* The model file must be uploaded by an admin in the analysis settings of
* http://scan.coverity.com/projects/378
*/
#define NULL ((void *)0)
typedef unsigned char uint8_t;
typedef char int8_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef long ssize_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef _Bool bool;
typedef struct va_list_str *va_list;
/* Tainting */
typedef struct {} name2keysym_t;
static int get_keysym(const name2keysym_t *table,
const char *name)
{
int result;
if (result > 0) {
__coverity_tainted_string_sanitize_content__(name);
return result;
} else {
return 0;
}
}
/* Replay data is considered trusted. */
uint8_t replay_get_byte(void)
{
uint8_t byte;
return byte;
}
/*
* GLib memory allocation functions.
*
* Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
* and g_realloc of 0 bytes frees the pointer.
*
* Modeling this would result in Coverity flagging a lot of memory
* allocations as potentially returning NULL, and asking us to check
* whether the result of the allocation is NULL or not. However, the
* resulting pointer should never be dereferenced anyway, and in fact
* it is not in the vast majority of cases.
*
* If a dereference did happen, this would suppress a defect report
* for an actual null pointer dereference. But it's too unlikely to
* be worth wading through the false positives, and with some luck
* we'll get a buffer overflow reported anyway.
*/
/*
* Allocation primitives, cannot return NULL
* See also Coverity's library/generic/libc/all/all.c
*/
void *g_malloc_n(size_t nmemb, size_t size)
{
void *ptr;
__coverity_negative_sink__(nmemb);
__coverity_negative_sink__(size);
ptr = __coverity_alloc__(nmemb * size);
if (!ptr) {
__coverity_panic__();
}
__coverity_mark_as_uninitialized_buffer__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void *g_malloc0_n(size_t nmemb, size_t size)
{
void *ptr;
__coverity_negative_sink__(nmemb);
__coverity_negative_sink__(size);
ptr = __coverity_alloc__(nmemb * size);
if (!ptr) {
__coverity_panic__();
}
__coverity_writeall0__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
{
__coverity_negative_sink__(nmemb);
__coverity_negative_sink__(size);
__coverity_escape__(ptr);
ptr = __coverity_alloc__(nmemb * size);
if (!ptr) {
__coverity_panic__();
}
/*
* Memory beyond the old size isn't actually initialized. Can't
* model that. See Coverity's realloc() model
*/
__coverity_writeall__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void g_free(void *ptr)
{
__coverity_free__(ptr);
__coverity_mark_as_afm_freed__(ptr, AFM_free);
}
/*
* Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
* out of memory conditions
*/
void *g_try_malloc_n(size_t nmemb, size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_malloc_n(nmemb, size);
}
void *g_try_malloc0_n(size_t nmemb, size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_malloc0_n(nmemb, size);
}
void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_realloc_n(ptr, nmemb, size);
}
/* Derive the g_FOO() from the g_FOO_n() */
void *g_malloc(size_t size)
{
void *ptr;
__coverity_negative_sink__(size);
ptr = __coverity_alloc__(size);
if (!ptr) {
__coverity_panic__();
}
__coverity_mark_as_uninitialized_buffer__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void *g_malloc0(size_t size)
{
void *ptr;
__coverity_negative_sink__(size);
ptr = __coverity_alloc__(size);
if (!ptr) {
__coverity_panic__();
}
__coverity_writeall0__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void *g_realloc(void *ptr, size_t size)
{
__coverity_negative_sink__(size);
__coverity_escape__(ptr);
ptr = __coverity_alloc__(size);
if (!ptr) {
__coverity_panic__();
}
/*
* Memory beyond the old size isn't actually initialized. Can't
* model that. See Coverity's realloc() model
*/
__coverity_writeall__(ptr);
__coverity_mark_as_afm_allocated__(ptr, AFM_free);
return ptr;
}
void *g_try_malloc(size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_malloc(size);
}
void *g_try_malloc0(size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_malloc0(size);
}
void *g_try_realloc(void *ptr, size_t size)
{
int nomem;
if (nomem) {
return NULL;
}
return g_realloc(ptr, size);
}
/* Other glib functions */
typedef struct pollfd GPollFD;
int poll();
int g_poll (GPollFD *fds, unsigned nfds, int timeout)
{
return poll(fds, nfds, timeout);
}
typedef struct _GIOChannel GIOChannel;
GIOChannel *g_io_channel_unix_new(int fd)
{
/* cannot use incomplete type, the actual struct is roughly this size. */
GIOChannel *c = g_malloc0(20 * sizeof(void *));
__coverity_escape__(fd);
return c;
}
void g_assertion_message_expr(const char *domain,
const char *file,
int line,
const char *func,
const char *expr)
{
__coverity_panic__();
}
+458
View File
@@ -0,0 +1,458 @@
#!/bin/sh -e
# Upload a created tarball to Coverity Scan, as per
# https://scan.coverity.com/projects/qemu/builds/new
# 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.
#
# Copyright (c) 2017-2020 Linaro Limited
# Written by Peter Maydell
# Note that this script will automatically download and
# run the (closed-source) coverity build tools, so don't
# use it if you don't trust them!
# This script assumes that you're running it from a QEMU source
# tree, and that tree is a fresh clean one, because we do an in-tree
# build. (This is necessary so that the filenames that the Coverity
# Scan server sees are relative paths that match up with the component
# regular expressions it uses; an out-of-tree build won't work for this.)
# The host machine should have as many of QEMU's dependencies
# installed as possible, for maximum coverity coverage.
# To do an upload you need to be a maintainer in the Coverity online
# service, and you will need to know the "Coverity token", which is a
# secret 8 digit hex string. You can find that from the web UI in the
# project settings, if you have maintainer access there.
# Command line options:
# --check-upload-only : return success if upload is possible
# --dry-run : run the tools, but don't actually do the upload
# --docker : create and work inside a container
# --docker-engine : specify the container engine to use (docker/podman/auto);
# implies --docker
# --update-tools-only : update the cached copy of the tools, but don't run them
# --no-update-tools : do not update the cached copy of the tools
# --tokenfile : file to read Coverity token from
# --version ver : specify version being analyzed (default: ask git)
# --description desc : specify description of this version (default: ask git)
# --srcdir : QEMU source tree to analyze (default: current working dir)
# --results-tarball : path to copy the results tarball to (default: don't
# copy it anywhere, just upload it)
# --src-tarball : tarball to untar into src dir (default: none); this
# is intended mainly for internal use by the Docker support
#
# User-specifiable environment variables:
# COVERITY_TOKEN -- Coverity token (default: looks at your
# coverity.token config)
# COVERITY_EMAIL -- the email address to use for uploads (default:
# looks at your git coverity.email or user.email config)
# COVERITY_BUILD_CMD -- make command (default: 'make -jN' where N is
# number of CPUs as determined by 'nproc')
# COVERITY_TOOL_BASE -- set to directory to put coverity tools
# (default: /tmp/coverity-tools)
#
# You must specify the token, either by environment variable or by
# putting it in a file and using --tokenfile. Everything else has
# a reasonable default if this is run from a git tree.
upload_permitted() {
# Check whether we can do an upload to the server; will exit *the script*
# with status 99 if the check failed (usually a bad token);
# will return from the function with status 1 if the check indicated
# that we can't upload yet (ie we are at quota)
# Assumes that COVERITY_TOKEN and PROJNAME have been initialized.
echo "Checking upload permissions..."
if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$COVERITY_TOKEN&project=$PROJNAME" -q -O -)"; then
echo "Coverity Scan API access denied: bad token?"
exit 99
fi
# Really up_perm is a JSON response with either
# {upload_permitted:true} or {next_upload_permitted_at:<date>}
# We do some hacky string parsing instead of properly parsing it.
case "$up_perm" in
*upload_permitted*true*)
return 0
;;
*next_upload_permitted_at*)
return 1
;;
*)
echo "Coverity Scan upload check: unexpected result $up_perm"
exit 99
;;
esac
}
check_upload_permissions() {
# Check whether we can do an upload to the server; will exit the script
# with status 99 if the check failed (usually a bad token);
# will exit the script with status 0 if the check indicated that we
# can't upload yet (ie we are at quota)
# Assumes that COVERITY_TOKEN, PROJNAME and DRYRUN have been initialized.
if upload_permitted; then
echo "Coverity Scan: upload permitted"
else
if [ "$DRYRUN" = yes ]; then
echo "Coverity Scan: upload quota reached, continuing dry run"
else
echo "Coverity Scan: upload quota reached; stopping here"
# Exit success as this isn't a build error.
exit 0
fi
fi
}
build_docker_image() {
# build docker container including the coverity-scan tools
echo "Building docker container..."
# TODO: This re-unpacks the tools every time, rather than caching
# and reusing the image produced by the COPY of the .tgz file.
# Not sure why.
tests/docker/docker.py --engine ${DOCKER_ENGINE} build \
-t coverity-scanner -f scripts/coverity-scan/coverity-scan.docker \
--extra-files scripts/coverity-scan/run-coverity-scan \
"$COVERITY_TOOL_BASE"/coverity_tool.tgz
}
update_coverity_tools () {
# Check for whether we need to download the Coverity tools
# (either because we don't have a copy, or because it's out of date)
# Assumes that COVERITY_TOOL_BASE, COVERITY_TOKEN and PROJNAME are set.
mkdir -p "$COVERITY_TOOL_BASE"
cd "$COVERITY_TOOL_BASE"
echo "Checking for new version of coverity build tools..."
wget https://scan.coverity.com/download/cxx/linux64 --post-data "token=$COVERITY_TOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new
if ! cmp -s coverity_tool.md5 coverity_tool.md5.new; then
# out of date md5 or no md5: download new build tool
# blow away the old build tool
echo "Downloading coverity build tools..."
rm -rf coverity_tool coverity_tool.tgz
wget https://scan.coverity.com/download/cxx/linux64 --post-data "token=$COVERITY_TOKEN&project=$PROJNAME" -O coverity_tool.tgz
if ! (cat coverity_tool.md5.new; echo " coverity_tool.tgz") | md5sum -c --status; then
echo "Downloaded tarball didn't match md5sum!"
exit 1
fi
if [ "$DOCKER" != yes ]; then
# extract the new one, keeping it corralled in a 'coverity_tool' directory
echo "Unpacking coverity build tools..."
mkdir -p coverity_tool
cd coverity_tool
tar xf ../coverity_tool.tgz
cd ..
mv coverity_tool.md5.new coverity_tool.md5
fi
fi
rm -f coverity_tool.md5.new
cd "$SRCDIR"
if [ "$DOCKER" = yes ]; then
build_docker_image
fi
}
# Check user-provided environment variables and arguments
DRYRUN=no
UPDATE=yes
DOCKER=no
PROJNAME=QEMU
while [ "$#" -ge 1 ]; do
case "$1" in
--check-upload-only)
shift
DRYRUN=check
;;
--dry-run)
shift
DRYRUN=yes
;;
--no-update-tools)
shift
UPDATE=no
;;
--update-tools-only)
shift
UPDATE=only
;;
--version)
shift
if [ $# -eq 0 ]; then
echo "--version needs an argument"
exit 1
fi
VERSION="$1"
shift
;;
--description)
shift
if [ $# -eq 0 ]; then
echo "--description needs an argument"
exit 1
fi
DESCRIPTION="$1"
shift
;;
--tokenfile)
shift
if [ $# -eq 0 ]; then
echo "--tokenfile needs an argument"
exit 1
fi
COVERITY_TOKEN="$(cat "$1")"
shift
;;
--srcdir)
shift
if [ $# -eq 0 ]; then
echo "--srcdir needs an argument"
exit 1
fi
SRCDIR="$1"
shift
;;
--results-tarball)
shift
if [ $# -eq 0 ]; then
echo "--results-tarball needs an argument"
exit 1
fi
RESULTSTARBALL="$1"
shift
;;
--src-tarball)
shift
if [ $# -eq 0 ]; then
echo "--src-tarball needs an argument"
exit 1
fi
SRCTARBALL="$1"
shift
;;
--docker)
DOCKER=yes
DOCKER_ENGINE=auto
shift
;;
--docker-engine)
shift
if [ $# -eq 0 ]; then
echo "--docker-engine needs an argument"
exit 1
fi
DOCKER=yes
DOCKER_ENGINE="$1"
shift
;;
*)
echo "Unexpected argument '$1'"
exit 1
;;
esac
done
if [ -z "$COVERITY_TOKEN" ]; then
COVERITY_TOKEN="$(git config coverity.token)"
fi
if [ -z "$COVERITY_TOKEN" ]; then
echo "COVERITY_TOKEN environment variable not set"
exit 1
fi
if [ "$DRYRUN" = check ]; then
upload_permitted
exit $?
fi
if [ -z "$COVERITY_BUILD_CMD" ]; then
NPROC=$(nproc)
COVERITY_BUILD_CMD="make -j$NPROC"
echo "COVERITY_BUILD_CMD: using default '$COVERITY_BUILD_CMD'"
fi
if [ -z "$COVERITY_TOOL_BASE" ]; then
echo "COVERITY_TOOL_BASE: using default /tmp/coverity-tools"
COVERITY_TOOL_BASE=/tmp/coverity-tools
fi
if [ -z "$SRCDIR" ]; then
SRCDIR="$PWD"
fi
TARBALL=cov-int.tar.xz
if [ "$UPDATE" = only ]; then
# Just do the tools update; we don't need to check whether
# we are in a source tree or have upload rights for this,
# so do it before some of the command line and source tree checks.
if [ "$DOCKER" = yes ] && [ ! -z "$SRCTARBALL" ]; then
echo --update-tools-only --docker is incompatible with --src-tarball.
exit 1
fi
update_coverity_tools
exit 0
fi
if [ ! -e "$SRCDIR" ]; then
mkdir "$SRCDIR"
fi
cd "$SRCDIR"
if [ ! -z "$SRCTARBALL" ]; then
echo "Untarring source tarball into $SRCDIR..."
tar xvf "$SRCTARBALL"
fi
echo "Checking this is a QEMU source tree..."
if ! [ -e "$SRCDIR/VERSION" ]; then
echo "Not in a QEMU source tree?"
exit 1
fi
# Fill in defaults used by the non-update-only process
if [ -z "$VERSION" ]; then
VERSION="$(git describe --always HEAD)"
fi
if [ -z "$DESCRIPTION" ]; then
DESCRIPTION="$(git rev-parse HEAD)"
fi
if [ -z "$COVERITY_EMAIL" ]; then
COVERITY_EMAIL="$(git config coverity.email)"
fi
if [ -z "$COVERITY_EMAIL" ]; then
COVERITY_EMAIL="$(git config user.email)"
fi
# Otherwise, continue with the full build and upload process.
check_upload_permissions
if [ "$UPDATE" != no ]; then
update_coverity_tools
fi
# Run ourselves inside docker if that's what the user wants
if [ "$DOCKER" = yes ]; then
# Put the Coverity token into a temporary file that only
# we have read access to, and then pass it to docker build
# using a volume. A volume is enough for the token not to
# leak into the Docker image.
umask 077
SECRETDIR=$(mktemp -d)
if [ -z "$SECRETDIR" ]; then
echo "Failed to create temporary directory"
exit 1
fi
trap 'rm -rf "$SECRETDIR"' INT TERM EXIT
echo "Created temporary directory $SECRETDIR"
SECRET="$SECRETDIR/token"
echo "$COVERITY_TOKEN" > "$SECRET"
echo "Archiving sources to be analyzed..."
./scripts/archive-source.sh "$SECRETDIR/qemu-sources.tgz"
ARGS="--no-update-tools"
if [ "$DRYRUN" = yes ]; then
ARGS="$ARGS --dry-run"
fi
echo "Running scanner..."
# If we need to capture the output tarball, get the inner run to
# save it to the secrets directory so we can copy it out before the
# directory is cleaned up.
if [ ! -z "$RESULTSTARBALL" ]; then
ARGS="$ARGS --results-tarball /work/cov-int.tar.xz"
fi
# Arrange for this docker run to get access to the sources with -v.
# We pass through all the configuration from the outer script to the inner.
export COVERITY_EMAIL COVERITY_BUILD_CMD
tests/docker/docker.py run -it --env COVERITY_EMAIL --env COVERITY_BUILD_CMD \
-v "$SECRETDIR:/work" coverity-scanner \
./run-coverity-scan --version "$VERSION" \
--description "$DESCRIPTION" $ARGS --tokenfile /work/token \
--srcdir /qemu --src-tarball /work/qemu-sources.tgz
if [ ! -z "$RESULTSTARBALL" ]; then
echo "Copying results tarball to $RESULTSTARBALL..."
cp "$SECRETDIR/cov-int.tar.xz" "$RESULTSTARBALL"
fi
echo "Docker work complete."
exit 0
fi
TOOLBIN="$(cd "$COVERITY_TOOL_BASE" && echo $PWD/coverity_tool/cov-analysis-*/bin)"
if ! test -x "$TOOLBIN/cov-build"; then
echo "Couldn't find cov-build in the coverity build-tool directory??"
exit 1
fi
export PATH="$TOOLBIN:$PATH"
cd "$SRCDIR"
echo "Nuking build directory..."
rm -rf +build
mkdir +build
cd +build
echo "Configuring..."
# We configure with a fixed set of enables here to ensure that we don't
# accidentally reduce the scope of the analysis by doing the build on
# the system that's missing a dependency that we need to build part of
# the codebase.
../configure --disable-modules --enable-sdl --enable-gtk \
--enable-opengl --enable-vte --enable-gnutls \
--enable-nettle --enable-curses --enable-curl \
--audio-drv-list=oss,alsa,sdl,pa --enable-virtfs \
--enable-vnc --enable-vnc-sasl --enable-vnc-jpeg --enable-png \
--enable-xen --enable-brlapi \
--enable-linux-aio --enable-attr \
--enable-cap-ng --enable-trace-backends=log --enable-spice --enable-rbd \
--enable-libusb --enable-usb-redir \
--enable-libiscsi --enable-seccomp \
--enable-tpm --enable-libssh --enable-lzo --enable-snappy --enable-bzip2 \
--enable-numa --enable-rdma --enable-smartcard --enable-virglrenderer \
--enable-mpath \
--enable-virtfs --enable-zstd
echo "Running cov-build..."
rm -rf cov-int
mkdir cov-int
cov-build --dir cov-int $COVERITY_BUILD_CMD
echo "Creating results tarball..."
tar cvf - cov-int | xz > "$TARBALL"
if [ ! -z "$RESULTSTARBALL" ]; then
echo "Copying results tarball to $RESULTSTARBALL..."
cp "$TARBALL" "$RESULTSTARBALL"
fi
echo "Uploading results tarball..."
if [ "$DRYRUN" = yes ]; then
echo "Dry run only, not uploading $TARBALL"
exit 0
fi
curl --form token="$COVERITY_TOKEN" --form email="$COVERITY_EMAIL" \
--form file=@"$TARBALL" --form version="$VERSION" \
--form description="$DESCRIPTION" \
https://scan.coverity.com/builds?project="$PROJNAME"
echo "Done."