diff options
Diffstat (limited to 'scripts')
43 files changed, 611 insertions, 407 deletions
diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py index 96a31d3974..95838cbff3 100755 --- a/scripts/analyze-migration.py +++ b/scripts/analyze-migration.py @@ -25,11 +25,6 @@ import struct import sys -MIN_PYTHON = (3, 2) -if sys.version_info < MIN_PYTHON: - sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON) - - def mkdir_p(path): try: os.makedirs(path) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e658e6546f..2d2e922d89 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -35,8 +35,6 @@ my $summary_file = 0; my $root; my %debug; my $help = 0; -my $acpi_testexpected; -my $acpi_nontestexpected; sub help { my ($exitcode) = @_; @@ -1261,21 +1259,23 @@ sub WARN { # According to tests/qtest/bios-tables-test.c: do not # change expected file in the same commit with adding test sub checkfilename { - my ($name) = @_; - if ($name =~ m#^tests/data/acpi/# and - # make exception for a shell script that rebuilds the files - not $name =~ m#^\.sh$# or - $name =~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) { - $acpi_testexpected = $name; - } else { - $acpi_nontestexpected = $name; + my ($name, $acpi_testexpected, $acpi_nontestexpected) = @_; + + # Note: shell script that rebuilds the expected files is in the same + # directory as files themselves. + # Note: allowed diff list can be changed both when changing expected + # files and when changing tests. + if ($name =~ m#^tests/data/acpi/# and not $name =~ m#^\.sh$#) { + $$acpi_testexpected = $name; + } elsif ($name !~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) { + $$acpi_nontestexpected = $name; } - if (defined $acpi_testexpected and defined $acpi_nontestexpected) { + if (defined $$acpi_testexpected and defined $$acpi_nontestexpected) { ERROR("Do not add expected files together with tests, " . "follow instructions in " . "tests/qtest/bios-tables-test.c: both " . - $acpi_testexpected . " and " . - $acpi_nontestexpected . " found\n"); + $$acpi_testexpected . " and " . + $$acpi_nontestexpected . " found\n"); } } @@ -1325,6 +1325,9 @@ sub process { my %suppress_whiletrailers; my %suppress_export; + my $acpi_testexpected; + my $acpi_nontestexpected; + # Pre-scan the patch sanitizing the lines. sanitise_line_reset(); @@ -1454,11 +1457,11 @@ sub process { if ($line =~ /^diff --git.*?(\S+)$/) { $realfile = $1; $realfile =~ s@^([^/]*)/@@ if (!$file); - checkfilename($realfile); + checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); } elsif ($line =~ /^\+\+\+\s+(\S+)/) { $realfile = $1; $realfile =~ s@^([^/]*)/@@ if (!$file); - checkfilename($realfile); + checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); $p1_prefix = $1; if (!$file && $tree && $p1_prefix ne '' && diff --git a/scripts/clean-includes b/scripts/clean-includes index dd938daa3e..795b3bea31 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -123,6 +123,7 @@ for f in "$@"; do ;; *include/qemu/osdep.h | \ *include/qemu/compiler.h | \ + *include/qemu/qemu-plugin.h | \ *include/glib-compat.h | \ *include/sysemu/os-posix.h | \ *include/sysemu/os-win32.h | \ diff --git a/scripts/coverity-scan/coverity-scan.docker b/scripts/coverity-scan/coverity-scan.docker index a4f64d1283..018c03de6d 100644 --- a/scripts/coverity-scan/coverity-scan.docker +++ b/scripts/coverity-scan/coverity-scan.docker @@ -19,7 +19,6 @@ FROM fedora:30 ENV PACKAGES \ alsa-lib-devel \ bc \ - bison \ brlapi-devel \ bzip2 \ bzip2-devel \ @@ -30,7 +29,6 @@ ENV PACKAGES \ dbus-daemon \ device-mapper-multipath-devel \ findutils \ - flex \ gcc \ gcc-c++ \ gettext \ @@ -127,5 +125,6 @@ RUN dnf install -y $PACKAGES RUN rpm -q $PACKAGES | sort > /packages.txt ENV PATH $PATH:/usr/libexec/python3-sphinx/ 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 -RUN --mount=type=secret,id=coverity.token,required ./run-coverity-scan --update-tools-only --tokenfile /run/secrets/coverity.token diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan index 2e067ef5cf..03a791dec9 100755 --- a/scripts/coverity-scan/run-coverity-scan +++ b/scripts/coverity-scan/run-coverity-scan @@ -29,8 +29,11 @@ # Command line options: # --dry-run : run the tools, but don't actually do the upload -# --docker : create and work inside a docker container +# --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) @@ -41,9 +44,10 @@ # is intended mainly for internal use by the Docker support # # User-specifiable environment variables: -# COVERITY_TOKEN -- Coverity token +# 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 user.email config) +# 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 @@ -58,11 +62,11 @@ check_upload_permissions() { # with status 1 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 PROJTOKEN, PROJNAME and DRYRUN have been initialized. + # Assumes that COVERITY_TOKEN, PROJNAME and DRYRUN have been initialized. echo "Checking upload permissions..." - if ! up_perm="$(wget https://scan.coverity.com/api/upload_permitted --post-data "token=$PROJTOKEN&project=$PROJNAME" -q -O -)"; then + 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 1 fi @@ -91,43 +95,62 @@ check_upload_permissions() { } +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, PROJTOKEN and PROJNAME are set. + # 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/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME&md5=1" -O coverity_tool.md5.new + wget https://scan.coverity.com/download/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/linux64 --post-data "token=$PROJTOKEN&project=$PROJNAME" -O coverity_tool.tgz + wget https://scan.coverity.com/download/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 - # 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 + 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_ONLY=no +UPDATE=yes DOCKER=no while [ "$#" -ge 1 ]; do @@ -136,9 +159,13 @@ while [ "$#" -ge 1 ]; do shift DRYRUN=yes ;; + --no-update-tools) + shift + UPDATE=no + ;; --update-tools-only) shift - UPDATE_ONLY=yes + UPDATE=only ;; --version) shift @@ -196,6 +223,17 @@ while [ "$#" -ge 1 ]; do ;; --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 ;; *) @@ -206,6 +244,9 @@ while [ "$#" -ge 1 ]; do 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 @@ -225,19 +266,19 @@ if [ -z "$SRCDIR" ]; then SRCDIR="$PWD" fi -PROJTOKEN="$COVERITY_TOKEN" PROJNAME=QEMU TARBALL=cov-int.tar.xz -if [ "$UPDATE_ONLY" = yes ] && [ "$DOCKER" = yes ]; then - echo "Combining --docker and --update-only is not supported" - exit 1 -fi - -if [ "$UPDATE_ONLY" = yes ]; then +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 @@ -269,17 +310,26 @@ if [ -z "$DESCRIPTION" ]; then 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 - # build docker container including the coverity-scan tools # Put the Coverity token into a temporary file that only # we have read access to, and then pass it to docker build - # using --secret. This requires at least Docker 18.09. - # Mostly what we are trying to do here is ensure we don't leak - # the token into the Docker image. + # 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 @@ -290,38 +340,27 @@ if [ "$DOCKER" = yes ]; then echo "Created temporary directory $SECRETDIR" SECRET="$SECRETDIR/token" echo "$COVERITY_TOKEN" > "$SECRET" - echo "Building docker container..." - # TODO: This re-downloads the tools every time, rather than - # caching and reusing the image produced with the downloaded tools. - # Not sure why. - # TODO: how do you get 'docker build' to print the output of the - # commands it is running to its stdout? This would be useful for debug. - DOCKER_BUILDKIT=1 docker build -t coverity-scanner \ - --secret id=coverity.token,src="$SECRET" \ - -f scripts/coverity-scan/coverity-scan.docker \ - scripts/coverity-scan echo "Archiving sources to be analyzed..." ./scripts/archive-source.sh "$SECRETDIR/qemu-sources.tgz" + ARGS="--no-update-tools" if [ "$DRYRUN" = yes ]; then - DRYRUNARG=--dry-run + 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 - RTARGS="--results-tarball /work/cov-int.tar.xz" - else - RTARGS="" + 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 - docker run -it --env COVERITY_EMAIL --env 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" $DRYRUNARG --tokenfile /work/token \ - --srcdir /qemu --src-tarball /work/qemu-sources.tgz $RTARGS + --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" @@ -330,12 +369,6 @@ if [ "$DOCKER" = yes ]; then exit 0 fi -# Otherwise, continue with the full build and upload process. - -check_upload_permissions - -update_coverity_tools - TOOLBIN="$(cd "$COVERITY_TOOL_BASE" && echo $PWD/coverity_tool/cov-analysis-*/bin)" if ! test -x "$TOOLBIN/cov-build"; then @@ -393,7 +426,7 @@ if [ "$DRYRUN" = yes ]; then exit 0 fi -curl --form token="$PROJTOKEN" --form email="$COVERITY_EMAIL" \ +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" diff --git a/scripts/decodetree.py b/scripts/decodetree.py index 46ab917807..530d41ca62 100755 --- a/scripts/decodetree.py +++ b/scripts/decodetree.py @@ -31,7 +31,6 @@ variablewidth = False fields = {} arguments = {} formats = {} -patterns = [] allpatterns = [] anyextern = False @@ -51,23 +50,27 @@ def error_with_file(file, lineno, *args): global output_file global output_fd + prefix = '' + if file: + prefix += '{0}:'.format(file) if lineno: - r = '{0}:{1}: error:'.format(file, lineno) - elif input_file: - r = '{0}: error:'.format(file) - else: - r = 'error:' - for a in args: - r += ' ' + str(a) - r += '\n' - sys.stderr.write(r) + prefix += '{0}:'.format(lineno) + if prefix: + prefix += ' ' + print(prefix, end='error: ', file=sys.stderr) + print(*args, file=sys.stderr) + if output_file and output_fd: output_fd.close() os.remove(output_file) exit(1) +# end error_with_file + def error(lineno, *args): - error_with_file(input_file, lineno, args) + error_with_file(input_file, lineno, *args) +# end error + def output(*args): global output_fd @@ -75,13 +78,6 @@ def output(*args): output_fd.write(a) -if sys.version_info >= (3, 4): - re_fullmatch = re.fullmatch -else: - def re_fullmatch(pat, str): - return re.match('^' + pat + '$', str) - - def output_autogen(): output('/* This file is autogenerated by scripts/decodetree.py. */\n\n') @@ -127,6 +123,7 @@ def is_pow2(x): def ctz(x): """Return the number of times 2 factors into X.""" + assert x != 0 r = 0 while ((x >> r) & 1) == 0: r += 1 @@ -134,6 +131,8 @@ def ctz(x): def is_contiguous(bits): + if bits == 0: + return -1 shift = ctz(bits) if is_pow2((bits >> shift) + 1): return shift @@ -371,32 +370,99 @@ class Pattern(General): output(ind, 'u.f_', arg, '.', n, ' = ', f.str_extract(), ';\n') output(ind, 'if (', translate_prefix, '_', self.name, '(ctx, &u.f_', arg, ')) return true;\n') + + # Normal patterns do not have children. + def build_tree(self): + return + def prop_masks(self): + return + def prop_format(self): + return + def prop_width(self): + return + # end Pattern class MultiPattern(General): - """Class representing an overlapping set of instruction patterns""" + """Class representing a set of instruction patterns""" - def __init__(self, lineno, pats, fixb, fixm, udfm, w): + def __init__(self, lineno): self.file = input_file self.lineno = lineno - self.pats = pats + self.pats = [] self.base = None - self.fixedbits = fixb - self.fixedmask = fixm - self.undefmask = udfm - self.width = w + self.fixedbits = 0 + self.fixedmask = 0 + self.undefmask = 0 + self.width = None def __str__(self): - r = "{" - for p in self.pats: - r = r + ' ' + str(p) - return r + "}" + r = 'group' + if self.fixedbits is not None: + r += ' ' + str_match_bits(self.fixedbits, self.fixedmask) + return r def output_decl(self): for p in self.pats: p.output_decl() + def prop_masks(self): + global insnmask + + fixedmask = insnmask + undefmask = insnmask + + # Collect fixedmask/undefmask for all of the children. + for p in self.pats: + p.prop_masks() + fixedmask &= p.fixedmask + undefmask &= p.undefmask + + # Widen fixedmask until all fixedbits match + repeat = True + fixedbits = 0 + while repeat and fixedmask != 0: + fixedbits = None + for p in self.pats: + thisbits = p.fixedbits & fixedmask + if fixedbits is None: + fixedbits = thisbits + elif fixedbits != thisbits: + fixedmask &= ~(fixedbits ^ thisbits) + break + else: + repeat = False + + self.fixedbits = fixedbits + self.fixedmask = fixedmask + self.undefmask = undefmask + + def build_tree(self): + for p in self.pats: + p.build_tree() + + def prop_format(self): + for p in self.pats: + p.build_tree() + + def prop_width(self): + width = None + for p in self.pats: + p.prop_width() + if width is None: + width = p.width + elif width != p.width: + error_with_file(self.file, self.lineno, + 'width mismatch in patterns within braces') + self.width = width + +# end MultiPattern + + +class IncMultiPattern(MultiPattern): + """Class representing an overlapping set of instruction patterns""" + def output_code(self, i, extracted, outerbits, outermask): global translate_prefix ind = str_indent(i) @@ -413,7 +479,154 @@ class MultiPattern(General): output(ind, '}\n') else: p.output_code(i, extracted, p.fixedbits, p.fixedmask) -#end MultiPattern +#end IncMultiPattern + + +class Tree: + """Class representing a node in a decode tree""" + + def __init__(self, fm, tm): + self.fixedmask = fm + self.thismask = tm + self.subs = [] + self.base = None + + def str1(self, i): + ind = str_indent(i) + r = '{0}{1:08x}'.format(ind, self.fixedmask) + if self.format: + r += ' ' + self.format.name + r += ' [\n' + for (b, s) in self.subs: + r += '{0} {1:08x}:\n'.format(ind, b) + r += s.str1(i + 4) + '\n' + r += ind + ']' + return r + + def __str__(self): + return self.str1(0) + + def output_code(self, i, extracted, outerbits, outermask): + ind = str_indent(i) + + # If we identified all nodes below have the same format, + # extract the fields now. + if not extracted and self.base: + output(ind, self.base.extract_name(), + '(ctx, &u.f_', self.base.base.name, ', insn);\n') + extracted = True + + # Attempt to aid the compiler in producing compact switch statements. + # If the bits in the mask are contiguous, extract them. + sh = is_contiguous(self.thismask) + if sh > 0: + # Propagate SH down into the local functions. + def str_switch(b, sh=sh): + return '(insn >> {0}) & 0x{1:x}'.format(sh, b >> sh) + + def str_case(b, sh=sh): + return '0x{0:x}'.format(b >> sh) + else: + def str_switch(b): + return 'insn & 0x{0:08x}'.format(b) + + def str_case(b): + return '0x{0:08x}'.format(b) + + output(ind, 'switch (', str_switch(self.thismask), ') {\n') + for b, s in sorted(self.subs): + assert (self.thismask & ~s.fixedmask) == 0 + innermask = outermask | self.thismask + innerbits = outerbits | b + output(ind, 'case ', str_case(b), ':\n') + output(ind, ' /* ', + str_match_bits(innerbits, innermask), ' */\n') + s.output_code(i + 4, extracted, innerbits, innermask) + output(ind, ' return false;\n') + output(ind, '}\n') +# end Tree + + +class ExcMultiPattern(MultiPattern): + """Class representing a non-overlapping set of instruction patterns""" + + def output_code(self, i, extracted, outerbits, outermask): + # Defer everything to our decomposed Tree node + self.tree.output_code(i, extracted, outerbits, outermask) + + @staticmethod + def __build_tree(pats, outerbits, outermask): + # Find the intersection of all remaining fixedmask. + innermask = ~outermask & insnmask + for i in pats: + innermask &= i.fixedmask + + if innermask == 0: + # Edge condition: One pattern covers the entire insnmask + if len(pats) == 1: + t = Tree(outermask, innermask) + t.subs.append((0, pats[0])) + return t + + text = 'overlapping patterns:' + for p in pats: + text += '\n' + p.file + ':' + str(p.lineno) + ': ' + str(p) + error_with_file(pats[0].file, pats[0].lineno, text) + + fullmask = outermask | innermask + + # Sort each element of pats into the bin selected by the mask. + bins = {} + for i in pats: + fb = i.fixedbits & innermask + if fb in bins: + bins[fb].append(i) + else: + bins[fb] = [i] + + # We must recurse if any bin has more than one element or if + # the single element in the bin has not been fully matched. + t = Tree(fullmask, innermask) + + for b, l in bins.items(): + s = l[0] + if len(l) > 1 or s.fixedmask & ~fullmask != 0: + s = ExcMultiPattern.__build_tree(l, b | outerbits, fullmask) + t.subs.append((b, s)) + + return t + + def build_tree(self): + super().prop_format() + self.tree = self.__build_tree(self.pats, self.fixedbits, + self.fixedmask) + + @staticmethod + def __prop_format(tree): + """Propagate Format objects into the decode tree""" + + # Depth first search. + for (b, s) in tree.subs: + if isinstance(s, Tree): + ExcMultiPattern.__prop_format(s) + + # If all entries in SUBS have the same format, then + # propagate that into the tree. + f = None + for (b, s) in tree.subs: + if f is None: + f = s.base + if f is None: + return + if f is not s.base: + return + tree.base = f + + def prop_format(self): + super().prop_format() + self.__prop_format(self.tree) + +# end ExcMultiPattern def parse_field(lineno, name, toks): @@ -428,18 +641,18 @@ def parse_field(lineno, name, toks): width = 0 func = None for t in toks: - if re_fullmatch('!function=' + re_ident, t): + if re.fullmatch('!function=' + re_ident, t): if func: error(lineno, 'duplicate function') func = t.split('=') func = func[1] continue - if re_fullmatch('[0-9]+:s[0-9]+', t): + if re.fullmatch('[0-9]+:s[0-9]+', t): # Signed field extract subtoks = t.split(':s') sign = True - elif re_fullmatch('[0-9]+:[0-9]+', t): + elif re.fullmatch('[0-9]+:[0-9]+', t): # Unsigned field extract subtoks = t.split(':') sign = False @@ -488,11 +701,11 @@ def parse_arguments(lineno, name, toks): flds = [] extern = False for t in toks: - if re_fullmatch('!extern', t): + if re.fullmatch('!extern', t): extern = True anyextern = True continue - if not re_fullmatch(re_ident, t): + if not re.fullmatch(re_ident, t): error(lineno, 'invalid argument set token "{0}"'.format(t)) if t in flds: error(lineno, 'duplicate argument "{0}"'.format(t)) @@ -572,18 +785,19 @@ def infer_format(arg, fieldmask, flds, width): # end infer_format -def parse_generic(lineno, is_format, name, toks): +def parse_generic(lineno, parent_pat, name, toks): """Parse one instruction format from TOKS at LINENO""" global fields global arguments global formats - global patterns global allpatterns global re_ident global insnwidth global insnmask global variablewidth + is_format = parent_pat is None + fixedmask = 0 fixedbits = 0 undefmask = 0 @@ -621,13 +835,13 @@ def parse_generic(lineno, is_format, name, toks): continue # 'Foo=%Bar' imports a field with a different name. - if re_fullmatch(re_ident + '=%' + re_ident, t): + if re.fullmatch(re_ident + '=%' + re_ident, t): (fname, iname) = t.split('=%') flds = add_field_byname(lineno, flds, fname, iname) continue # 'Foo=number' sets an argument field to a constant value - if re_fullmatch(re_ident + '=[+-]?[0-9]+', t): + if re.fullmatch(re_ident + '=[+-]?[0-9]+', t): (fname, value) = t.split('=') value = int(value) flds = add_field(lineno, flds, fname, ConstField(value)) @@ -635,7 +849,7 @@ def parse_generic(lineno, is_format, name, toks): # Pattern of 0s, 1s, dots and dashes indicate required zeros, # required ones, or dont-cares. - if re_fullmatch('[01.-]+', t): + if re.fullmatch('[01.-]+', t): shift = len(t) fms = t.replace('0', '1') fms = fms.replace('.', '0') @@ -652,7 +866,7 @@ def parse_generic(lineno, is_format, name, toks): fixedmask = (fixedmask << shift) | fms undefmask = (undefmask << shift) | ubm # Otherwise, fieldname:fieldwidth - elif re_fullmatch(re_ident + ':s?[0-9]+', t): + elif re.fullmatch(re_ident + ':s?[0-9]+', t): (fname, flen) = t.split(':') sign = False if flen[0] == 's': @@ -734,7 +948,7 @@ def parse_generic(lineno, is_format, name, toks): error(lineno, 'field {0} not initialized'.format(f)) pat = Pattern(name, lineno, fmt, fixedbits, fixedmask, undefmask, fieldmask, flds, width) - patterns.append(pat) + parent_pat.pats.append(pat) allpatterns.append(pat) # Validate the masks that we have assembled. @@ -754,62 +968,16 @@ def parse_generic(lineno, is_format, name, toks): .format(allbits ^ insnmask)) # end parse_general -def build_multi_pattern(lineno, pats): - """Validate the Patterns going into a MultiPattern.""" - global patterns - global insnmask - - if len(pats) < 2: - error(lineno, 'less than two patterns within braces') - - fixedmask = insnmask - undefmask = insnmask - - # Collect fixed/undefmask for all of the children. - # Move the defining lineno back to that of the first child. - for p in pats: - fixedmask &= p.fixedmask - undefmask &= p.undefmask - if p.lineno < lineno: - lineno = p.lineno - - width = None - for p in pats: - if width is None: - width = p.width - elif width != p.width: - error(lineno, 'width mismatch in patterns within braces') - - repeat = True - while repeat: - if fixedmask == 0: - error(lineno, 'no overlap in patterns within braces') - fixedbits = None - for p in pats: - thisbits = p.fixedbits & fixedmask - if fixedbits is None: - fixedbits = thisbits - elif fixedbits != thisbits: - fixedmask &= ~(fixedbits ^ thisbits) - break - else: - repeat = False - - mp = MultiPattern(lineno, pats, fixedbits, fixedmask, undefmask, width) - patterns.append(mp) -# end build_multi_pattern -def parse_file(f): +def parse_file(f, parent_pat): """Parse all of the patterns within a file""" - global patterns - # Read all of the lines of the file. Concatenate lines # ending in backslash; discard empty lines and comments. toks = [] lineno = 0 nesting = 0 - saved_pats = [] + nesting_pats = [] for line in f: lineno += 1 @@ -853,17 +1021,23 @@ def parse_file(f): del toks[0] # End nesting? - if name == '}': - if nesting == 0: - error(start_lineno, 'mismatched close brace') + if name == '}' or name == ']': if len(toks) != 0: error(start_lineno, 'extra tokens after close brace') + + # Make sure { } and [ ] nest properly. + if (name == '}') != isinstance(parent_pat, IncMultiPattern): + error(lineno, 'mismatched close brace') + + try: + parent_pat = nesting_pats.pop() + except: + error(lineno, 'extra close brace') + nesting -= 2 if indent != nesting: - error(start_lineno, 'indentation ', indent, ' != ', nesting) - pats = patterns - patterns = saved_pats.pop() - build_multi_pattern(lineno, pats) + error(lineno, 'indentation ', indent, ' != ', nesting) + toks = [] continue @@ -872,11 +1046,18 @@ def parse_file(f): error(start_lineno, 'indentation ', indent, ' != ', nesting) # Start nesting? - if name == '{': + if name == '{' or name == '[': if len(toks) != 0: error(start_lineno, 'extra tokens after open brace') - saved_pats.append(patterns) - patterns = [] + + if name == '{': + nested_pat = IncMultiPattern(start_lineno) + else: + nested_pat = ExcMultiPattern(start_lineno) + parent_pat.pats.append(nested_pat) + nesting_pats.append(parent_pat) + parent_pat = nested_pat + nesting += 2 toks = [] continue @@ -887,113 +1068,14 @@ def parse_file(f): elif name[0] == '&': parse_arguments(start_lineno, name[1:], toks) elif name[0] == '@': - parse_generic(start_lineno, True, name[1:], toks) + parse_generic(start_lineno, None, name[1:], toks) else: - parse_generic(start_lineno, False, name, toks) + parse_generic(start_lineno, parent_pat, name, toks) toks = [] -# end parse_file - - -class Tree: - """Class representing a node in a decode tree""" - - def __init__(self, fm, tm): - self.fixedmask = fm - self.thismask = tm - self.subs = [] - self.base = None - - def str1(self, i): - ind = str_indent(i) - r = '{0}{1:08x}'.format(ind, self.fixedmask) - if self.format: - r += ' ' + self.format.name - r += ' [\n' - for (b, s) in self.subs: - r += '{0} {1:08x}:\n'.format(ind, b) - r += s.str1(i + 4) + '\n' - r += ind + ']' - return r - - def __str__(self): - return self.str1(0) - - def output_code(self, i, extracted, outerbits, outermask): - ind = str_indent(i) - - # If we identified all nodes below have the same format, - # extract the fields now. - if not extracted and self.base: - output(ind, self.base.extract_name(), - '(ctx, &u.f_', self.base.base.name, ', insn);\n') - extracted = True - - # Attempt to aid the compiler in producing compact switch statements. - # If the bits in the mask are contiguous, extract them. - sh = is_contiguous(self.thismask) - if sh > 0: - # Propagate SH down into the local functions. - def str_switch(b, sh=sh): - return '(insn >> {0}) & 0x{1:x}'.format(sh, b >> sh) - - def str_case(b, sh=sh): - return '0x{0:x}'.format(b >> sh) - else: - def str_switch(b): - return 'insn & 0x{0:08x}'.format(b) - - def str_case(b): - return '0x{0:08x}'.format(b) - - output(ind, 'switch (', str_switch(self.thismask), ') {\n') - for b, s in sorted(self.subs): - assert (self.thismask & ~s.fixedmask) == 0 - innermask = outermask | self.thismask - innerbits = outerbits | b - output(ind, 'case ', str_case(b), ':\n') - output(ind, ' /* ', - str_match_bits(innerbits, innermask), ' */\n') - s.output_code(i + 4, extracted, innerbits, innermask) - output(ind, ' return false;\n') - output(ind, '}\n') -# end Tree - - -def build_tree(pats, outerbits, outermask): - # Find the intersection of all remaining fixedmask. - innermask = ~outermask & insnmask - for i in pats: - innermask &= i.fixedmask - if innermask == 0: - text = 'overlapping patterns:' - for p in pats: - text += '\n' + p.file + ':' + str(p.lineno) + ': ' + str(p) - error_with_file(pats[0].file, pats[0].lineno, text) - - fullmask = outermask | innermask - - # Sort each element of pats into the bin selected by the mask. - bins = {} - for i in pats: - fb = i.fixedbits & innermask - if fb in bins: - bins[fb].append(i) - else: - bins[fb] = [i] - - # We must recurse if any bin has more than one element or if - # the single element in the bin has not been fully matched. - t = Tree(fullmask, innermask) - - for b, l in bins.items(): - s = l[0] - if len(l) > 1 or s.fixedmask & ~fullmask != 0: - s = build_tree(l, b | outerbits, fullmask) - t.subs.append((b, s)) - - return t -# end build_tree + if nesting != 0: + error(lineno, 'missing close brace') +# end parse_file class SizeTree: @@ -1137,28 +1219,6 @@ def build_size_tree(pats, width, outerbits, outermask): # end build_size_tree -def prop_format(tree): - """Propagate Format objects into the decode tree""" - - # Depth first search. - for (b, s) in tree.subs: - if isinstance(s, Tree): - prop_format(s) - - # If all entries in SUBS have the same format, then - # propagate that into the tree. - f = None - for (b, s) in tree.subs: - if f is None: - f = s.base - if f is None: - return - if f is not s.base: - return - tree.base = f -# end prop_format - - def prop_size(tree): """Propagate minimum widths up the decode size tree""" @@ -1179,7 +1239,6 @@ def prop_size(tree): def main(): global arguments global formats - global patterns global allpatterns global translate_scope global translate_prefix @@ -1226,19 +1285,30 @@ def main(): if len(args) < 1: error(0, 'missing input file') + + toppat = ExcMultiPattern(0) + for filename in args: input_file = filename f = open(filename, 'r') - parse_file(f) + parse_file(f, toppat) f.close() + # We do not want to compute masks for toppat, because those masks + # are used as a starting point for build_tree. For toppat, we must + # insist that decode begins from naught. + for i in toppat.pats: + i.prop_masks() + + toppat.build_tree() + toppat.prop_format() + if variablewidth: - stree = build_size_tree(patterns, 8, 0, 0) + for i in toppat.pats: + i.prop_width() + stree = build_size_tree(toppat.pats, 8, 0, 0) prop_size(stree) - dtree = build_tree(patterns, 0, 0) - prop_format(dtree) - if output_file: output_fd = open(output_file, 'w') else: @@ -1296,7 +1366,7 @@ def main(): f = arguments[n] output(i4, i4, f.struct_name(), ' f_', f.name, ';\n') output(i4, '} u;\n\n') - dtree.output_code(4, False, 0, 0) + toppat.output_code(4, False, 0, 0) output(i4, 'return false;\n') output('}\n') diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index 971ed0e721..6fe66d5f57 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # tool for querying VMX capabilities # @@ -275,5 +275,6 @@ controls = [ ), ] -for c in controls: - c.show() +if __name__ == '__main__': + for c in controls: + c.show() diff --git a/scripts/modules/module_block.py b/scripts/modules/module_block.py index f23191fac1..1109df827d 100644 --- a/scripts/modules/module_block.py +++ b/scripts/modules/module_block.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Module information generator # @@ -80,19 +80,20 @@ def print_bottom(fheader): #endif ''') -# First argument: output file -# All other arguments: modules source files (.c) -output_file = sys.argv[1] -with open(output_file, 'w') as fheader: - print_top(fheader) +if __name__ == '__main__': + # First argument: output file + # All other arguments: modules source files (.c) + output_file = sys.argv[1] + with open(output_file, 'w') as fheader: + print_top(fheader) - for filename in sys.argv[2:]: - if os.path.isfile(filename): - process_file(fheader, filename) - else: - print("File " + filename + " does not exist.", file=sys.stderr) - sys.exit(1) + for filename in sys.argv[2:]: + if os.path.isfile(filename): + process_file(fheader, filename) + else: + print("File " + filename + " does not exist.", file=sys.stderr) + sys.exit(1) - print_bottom(fheader) + print_bottom(fheader) -sys.exit(0) + sys.exit(0) diff --git a/scripts/oss-fuzz/build.sh b/scripts/oss-fuzz/build.sh new file mode 100755 index 0000000000..f5cee3d67e --- /dev/null +++ b/scripts/oss-fuzz/build.sh @@ -0,0 +1,105 @@ +#!/bin/sh -e +# +# OSS-Fuzz build script. See: +# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh +# +# The file is consumed by: +# https://github.com/google/oss-fuzz/blob/master/projects/qemu/Dockerfiles +# +# This code is licensed under the GPL version 2 or later. See +# the COPYING file in the top-level directory. +# + +# build project +# e.g. +# ./autogen.sh +# ./configure +# make -j$(nproc) all + +# build fuzzers +# e.g. +# $CXX $CXXFLAGS -std=c++11 -Iinclude \ +# /path/to/name_of_fuzzer.cc -o $OUT/name_of_fuzzer \ +# $LIB_FUZZING_ENGINE /path/to/library.a + +fatal () { + echo "Error : ${*}, exiting." + exit 1 +} + +OSS_FUZZ_BUILD_DIR="./build-oss-fuzz/" + +# There seems to be a bug in clang-11 (used for builds on oss-fuzz) : +# accel/tcg/cputlb.o: In function `load_memop': +# accel/tcg/cputlb.c:1505: undefined reference to `qemu_build_not_reached' +# +# When building with optimization, the compiler is expected to prove that the +# statement cannot be reached, and remove it. For some reason clang-11 doesn't +# remove it, resulting in an unresolved reference to qemu_build_not_reached +# Undefine the __OPTIMIZE__ macro which compiler.h relies on to choose whether +# to " #define qemu_build_not_reached() g_assert_not_reached() " +EXTRA_CFLAGS="$CFLAGS -U __OPTIMIZE__" + +if ! { [ -e "./COPYING" ] && + [ -e "./MAINTAINERS" ] && + [ -e "./Makefile" ] && + [ -e "./docs" ] && + [ -e "./VERSION" ] && + [ -e "./linux-user" ] && + [ -e "./softmmu" ];} ; then + fatal "Please run the script from the top of the QEMU tree" +fi + +mkdir -p $OSS_FUZZ_BUILD_DIR || fatal "mkdir $OSS_FUZZ_BUILD_DIR failed" +cd $OSS_FUZZ_BUILD_DIR || fatal "cd $OSS_FUZZ_BUILD_DIR failed" + + +if [ -z ${LIB_FUZZING_ENGINE+x} ]; then + LIB_FUZZING_ENGINE="-fsanitize=fuzzer" +fi + +if [ -z ${OUT+x} ]; then + DEST_DIR=$(realpath "./DEST_DIR") +else + DEST_DIR=$OUT +fi + +mkdir -p "$DEST_DIR/lib/" # Copy the shared libraries here + +# Build once to get the list of dynamic lib paths, and copy them over +../configure --disable-werror --cc="$CC" --cxx="$CXX" \ + --extra-cflags="$EXTRA_CFLAGS" + +if ! make CONFIG_FUZZ=y CFLAGS="$LIB_FUZZING_ENGINE" "-j$(nproc)" \ + i386-softmmu/fuzz; then + fatal "Build failed. Please specify a compiler with fuzzing support"\ + "using the \$CC and \$CXX environemnt variables, or specify a"\ + "\$LIB_FUZZING_ENGINE compatible with your compiler"\ + "\nFor example: CC=clang CXX=clang++ $0" +fi + +for i in $(ldd ./i386-softmmu/qemu-fuzz-i386 | cut -f3 -d' '); do + cp "$i" "$DEST_DIR/lib/" +done +rm ./i386-softmmu/qemu-fuzz-i386 + +# Build a second time to build the final binary with correct rpath +../configure --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" --disable-werror \ + --cc="$CC" --cxx="$CXX" --extra-cflags="$EXTRA_CFLAGS" \ + --extra-ldflags="-Wl,-rpath,'\$\$ORIGIN/lib'" +make CONFIG_FUZZ=y CFLAGS="$LIB_FUZZING_ENGINE" "-j$(nproc)" i386-softmmu/fuzz + +# Copy over the datadir +cp -r ../pc-bios/ "$DEST_DIR/pc-bios" + +# Run the fuzzer with no arguments, to print the help-string and get the list +# of available fuzz-targets. Copy over the qemu-fuzz-i386, naming it according +# to each available fuzz target (See 05509c8e6d fuzz: select fuzz target using +# executable name) +for target in $(./i386-softmmu/qemu-fuzz-i386 | awk '$1 ~ /\*/ {print $2}'); +do + cp ./i386-softmmu/qemu-fuzz-i386 "$DEST_DIR/qemu-fuzz-i386-target-$target" +done + +echo "Done. The fuzzers are located in $DEST_DIR" +exit 0 diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index bc30876c88..6809b0fb6e 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -104,6 +104,7 @@ def gen_marshal(name, arg_type, boxed, ret_type): %(proto)s { Error *err = NULL; + Visitor *v; ''', proto=build_marshal_proto(name)) @@ -114,44 +115,38 @@ def gen_marshal(name, arg_type, boxed, ret_type): c_type=ret_type.c_type()) if have_args: - visit_members = ('visit_type_%s_members(v, &arg, &err);' - % arg_type.c_name()) ret += mcgen(''' - Visitor *v; %(c_name)s arg = {0}; - ''', c_name=arg_type.c_name()) - else: - visit_members = '' - ret += mcgen(''' - Visitor *v = NULL; - - if (args) { -''') - push_indent() ret += mcgen(''' + v = qobject_input_visitor_new(QOBJECT(args)); visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out; } - %(visit_members)s +''') + + if have_args: + ret += mcgen(''' + visit_type_%(c_arg_type)s_members(v, &arg, &err); if (!err) { visit_check_struct(v, &err); } +''', + c_arg_type=arg_type.c_name()) + else: + ret += mcgen(''' + visit_check_struct(v, &err); +''') + + ret += mcgen(''' visit_end_struct(v, NULL); if (err) { goto out; } -''', - visit_members=visit_members) - - if not have_args: - pop_indent() - ret += mcgen(''' - } ''') ret += gen_call(name, arg_type, boxed, ret_type) @@ -163,29 +158,20 @@ out: visit_free(v); ''') + ret += mcgen(''' + v = qapi_dealloc_visitor_new(); + visit_start_struct(v, NULL, NULL, 0, NULL); +''') + if have_args: - visit_members = ('visit_type_%s_members(v, &arg, NULL);' - % arg_type.c_name()) - else: - visit_members = '' ret += mcgen(''' - if (args) { -''') - push_indent() + visit_type_%(c_arg_type)s_members(v, &arg, NULL); +''', + c_arg_type=arg_type.c_name()) ret += mcgen(''' - v = qapi_dealloc_visitor_new(); - visit_start_struct(v, NULL, NULL, 0, NULL); - %(visit_members)s visit_end_struct(v, NULL); visit_free(v); -''', - visit_members=visit_members) - - if not have_args: - pop_indent() - ret += mcgen(''' - } ''') ret += mcgen(''' diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 23d9194aa4..d5d7a1031f 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -189,6 +189,8 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error goto out; } if (!*obj) { + /* incomplete */ + assert(visit_is_dealloc(v)); goto out_obj; } switch ((*obj)->type) { @@ -230,8 +232,12 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error case QTYPE_NONE: abort(); default: + assert(visit_is_input(v)); error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "%(name)s"); + /* Avoid passing invalid *obj to qapi_free_%(c_name)s() */ + g_free(*obj); + *obj = NULL; } out_obj: visit_end_alternate(v, (void **)obj); @@ -260,6 +266,8 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error goto out; } if (!*obj) { + /* incomplete */ + assert(visit_is_dealloc(v)); goto out_obj; } visit_type_%(c_name)s_members(v, *obj, &err); diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index f2a305c42e..e0bfa7b5a4 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -1,5 +1,5 @@ -#!/usr/bin/python - +#!/usr/bin/env python3 +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates diff --git a/scripts/qemugdb/__init__.py b/scripts/qemugdb/__init__.py index 969f552b26..da8ff612e5 100644 --- a/scripts/qemugdb/__init__.py +++ b/scripts/qemugdb/__init__.py @@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright (c) 2015 Linaro Ltd diff --git a/scripts/qemugdb/aio.py b/scripts/qemugdb/aio.py index 2ba00c4444..d7c1ba0c28 100644 --- a/scripts/qemugdb/aio.py +++ b/scripts/qemugdb/aio.py @@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support: aio/iohandler debug # # Copyright (c) 2015 Red Hat, Inc. diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index 41e079d0e2..db61389022 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates diff --git a/scripts/qemugdb/mtree.py b/scripts/qemugdb/mtree.py index 3030a60d3f..8fe42c3c12 100644 --- a/scripts/qemugdb/mtree.py +++ b/scripts/qemugdb/mtree.py @@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates @@ -84,4 +83,3 @@ class MtreeCommand(gdb.Command): while not isnull(subregion): self.print_item(subregion, addr, level) subregion = subregion['subregions_link']['tqe_next'] - diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py index 18880fc9a7..16c03c06a9 100644 --- a/scripts/qemugdb/tcg.py +++ b/scripts/qemugdb/tcg.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # -*- coding: utf-8 -*- # # GDB debugging support, TCG status diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py index f0e132d27a..46537b27cf 100644 --- a/scripts/qemugdb/timers.py +++ b/scripts/qemugdb/timers.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # -*- coding: utf-8 -*- # GDB debugging support # diff --git a/scripts/qmp/qmp b/scripts/qmp/qmp index 0625fc2aba..8e52e4a54d 100755 --- a/scripts/qmp/qmp +++ b/scripts/qmp/qmp @@ -11,7 +11,9 @@ # See the COPYING file in the top-level directory. import sys, os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol def print_response(rsp, prefix=[]): if type(rsp) == list: diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index a01d31de1e..c5eef06f3f 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -77,9 +77,6 @@ import re sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import qmp -if sys.version_info[0] == 2: - input = raw_input - class QMPCompleter(list): def complete(self, text, state): for cmd in self: diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse index 6bada2c33d..5fa6b3bf64 100755 --- a/scripts/qmp/qom-fuse +++ b/scripts/qmp/qom-fuse @@ -15,7 +15,9 @@ import fuse, stat from fuse import Fuse import os, posix from errno import * -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol fuse.fuse_python_api = (0, 2) diff --git a/scripts/qmp/qom-get b/scripts/qmp/qom-get index 007b4cd442..666df71832 100755 --- a/scripts/qmp/qom-get +++ b/scripts/qmp/qom-get @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools # @@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None diff --git a/scripts/qmp/qom-list b/scripts/qmp/qom-list index 03bda3446b..5074fd939f 100755 --- a/scripts/qmp/qom-list +++ b/scripts/qmp/qom-list @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools # @@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None diff --git a/scripts/qmp/qom-set b/scripts/qmp/qom-set index c37fe78b00..240a78187f 100755 --- a/scripts/qmp/qom-set +++ b/scripts/qmp/qom-set @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools # @@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None diff --git a/scripts/qmp/qom-tree b/scripts/qmp/qom-tree index 1c8acf61e7..25b0781323 100755 --- a/scripts/qmp/qom-tree +++ b/scripts/qmp/qom-tree @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools # @@ -15,7 +15,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 264cc9eecc..31146242b7 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -10,7 +10,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" import sys diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 13d29f1e42..3ccfa1e116 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" import re diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 54cab2c4de..7bfcc86cc5 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -50,7 +50,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" import os diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py index 638990db79..5711892ba0 100644 --- a/scripts/tracetool/backend/dtrace.py +++ b/scripts/tracetool/backend/dtrace.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index 23b274c0fd..877222bbe9 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py index b650c262b5..a74d61fcd6 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py index a772a3b53b..6c0a5f8d68 100644 --- a/scripts/tracetool/backend/ust.py +++ b/scripts/tracetool/backend/ust.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py index aba2f7a441..2dc46f3dd9 100644 --- a/scripts/tracetool/format/__init__.py +++ b/scripts/tracetool/format/__init__.py @@ -32,7 +32,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" import os diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py index 78af8aff72..23d82ea861 100644 --- a/scripts/tracetool/format/c.py +++ b/scripts/tracetool/format/c.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py index d3980b914b..0afb5f3f47 100644 --- a/scripts/tracetool/format/d.py +++ b/scripts/tracetool/format/d.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index 83e1a2f355..e94f0be7da 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py index 8fc808f2ef..a218b0445c 100644 --- a/scripts/tracetool/format/stap.py +++ b/scripts/tracetool/format/stap.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index 0180e3d76c..33cf6a31b3 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out, Arguments diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py index 6527b69afd..2db6317f3c 100644 --- a/scripts/tracetool/format/tcg_helper_c.py +++ b/scripts/tracetool/format/tcg_helper_c.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import Arguments, out diff --git a/scripts/tracetool/format/tcg_helper_h.py b/scripts/tracetool/format/tcg_helper_h.py index 98ebe52f18..08554fbc85 100644 --- a/scripts/tracetool/format/tcg_helper_h.py +++ b/scripts/tracetool/format/tcg_helper_h.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/format/tcg_helper_wrapper_h.py b/scripts/tracetool/format/tcg_helper_wrapper_h.py index 6adeab74df..0c5a9797d1 100644 --- a/scripts/tracetool/format/tcg_helper_wrapper_h.py +++ b/scripts/tracetool/format/tcg_helper_wrapper_h.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import out diff --git a/scripts/tracetool/transform.py b/scripts/tracetool/transform.py index 8fd4dcf20d..ea8b27799d 100644 --- a/scripts/tracetool/transform.py +++ b/scripts/tracetool/transform.py @@ -9,7 +9,7 @@ __copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" def _transform_type(type_, trans): diff --git a/scripts/tracetool/vcpu.py b/scripts/tracetool/vcpu.py index 0b104e4f15..b54e4f4e7a 100644 --- a/scripts/tracetool/vcpu.py +++ b/scripts/tracetool/vcpu.py @@ -10,7 +10,7 @@ __copyright__ = "Copyright 2016, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" +__email__ = "stefanha@redhat.com" from tracetool import Arguments, try_import |