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
+84
View File
@@ -0,0 +1,84 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Format management.
Creating new formats
--------------------
A new format named 'foo-bar' corresponds to Python module
'tracetool/format/foo_bar.py'.
A format module should provide a docstring, whose first non-empty line will be
considered its short description.
All formats must generate their contents through the 'tracetool.out' routine.
Format functions
----------------
======== ==================================================================
Function Description
======== ==================================================================
generate Called to generate a format-specific file.
======== ==================================================================
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
import os
import tracetool
def get_list():
"""Get a list of (name, description) pairs."""
res = []
modnames = []
for filename in os.listdir(tracetool.format.__path__[0]):
if filename.endswith('.py') and filename != '__init__.py':
modnames.append(filename.rsplit('.', 1)[0])
for modname in sorted(modnames):
module = tracetool.try_import("tracetool.format." + modname)
# just in case; should never fail unless non-module files are put there
if not module[0]:
continue
module = module[1]
doc = module.__doc__
if doc is None:
doc = ""
doc = doc.strip().split("\n")[0]
name = modname.replace("_", "-")
res.append((name, doc))
return res
def exists(name):
"""Return whether the given format exists."""
if len(name) == 0:
return False
name = name.replace("-", "_")
return tracetool.try_import("tracetool.format." + name)[0]
def generate(events, format, backend, group):
if not exists(format):
raise ValueError("unknown format: %s" % format)
format = format.replace("-", "_")
func = tracetool.try_import("tracetool.format." + format,
"generate")[1]
if func is None:
raise AttributeError("format has no 'generate': %s" % format)
func(events, backend, group)
+67
View File
@@ -0,0 +1,67 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace/generated-tracers.c
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
def generate(events, backend, group):
active_events = [e for e in events
if "disable" not in e.properties]
header = "trace-" + group + ".h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#include "qemu/osdep.h"',
'#include "qemu/module.h"',
'#include "%s"' % header,
'')
for e in events:
out('uint16_t %s;' % e.api(e.QEMU_DSTATE))
for e in events:
out('TraceEvent %(event)s = {',
' .id = 0,',
' .name = \"%(name)s\",',
' .sstate = %(sstate)s,',
' .dstate = &%(dstate)s',
'};',
event = e.api(e.QEMU_EVENT),
name = e.name,
sstate = "TRACE_%s_ENABLED" % e.name.upper(),
dstate = e.api(e.QEMU_DSTATE))
out('TraceEvent *%(group)s_trace_events[] = {',
group = group.lower())
for e in events:
out(' &%(event)s,', event = e.api(e.QEMU_EVENT))
out(' NULL,',
'};',
'')
out('static void trace_%(group)s_register_events(void)',
'{',
' trace_event_register_group(%(group)s_trace_events);',
'}',
'trace_init(trace_%(group)s_register_events)',
group = group.lower())
backend.generate_begin(active_events, group)
for event in active_events:
backend.generate(event, group)
backend.generate_end(active_events, group)
+78
View File
@@ -0,0 +1,78 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace/generated-tracers.dtrace (DTrace only).
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
from sys import platform
# Reserved keywords from
# https://wikis.oracle.com/display/DTrace/Types,+Operators+and+Expressions
RESERVED_WORDS = (
'auto', 'goto', 'sizeof', 'break', 'if', 'static', 'case', 'import',
'string', 'char', 'inline', 'stringof', 'const', 'int', 'struct',
'continue', 'long', 'switch', 'counter', 'offsetof', 'this',
'default', 'probe', 'translator', 'do', 'provider', 'typedef',
'double', 'register', 'union', 'else', 'restrict', 'unsigned',
'enum', 'return', 'void', 'extern', 'self', 'volatile', 'float',
'short', 'while', 'for', 'signed', 'xlate',
)
def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
# SystemTap's dtrace(1) warns about empty "provider qemu {}" but is happy
# with an empty file. Avoid the warning.
# But dtrace on macOS can't deal with empty files.
if not events and platform != "darwin":
return
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'provider qemu {')
for e in events:
args = []
for type_, name in e.args:
if platform == "darwin":
# macOS dtrace accepts only C99 _Bool
if type_ == 'bool':
type_ = '_Bool'
if type_ == 'bool *':
type_ = '_Bool *'
# It converts int8_t * in probe points to char * in header
# files and introduces [-Wpointer-sign] warning.
# Avoid it by changing probe type to signed char * beforehand.
if type_ == 'int8_t *':
type_ = 'signed char *'
# SystemTap dtrace(1) emits a warning when long long is used
type_ = type_.replace('unsigned long long', 'uint64_t')
type_ = type_.replace('signed long long', 'int64_t')
type_ = type_.replace('long long', 'int64_t')
if name in RESERVED_WORDS:
name += '_'
args.append(type_ + ' ' + name)
# Define prototype for probe arguments
out('',
'probe %(name)s(%(args)s);',
name=e.name,
args=','.join(args))
out('',
'};')
+78
View File
@@ -0,0 +1,78 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace/generated-tracers.h
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2017, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
def generate(events, backend, group):
header = "trace/control.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#ifndef TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
'#define TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
'',
'#include "%s"' % header,
'')
for e in events:
out('extern TraceEvent %(event)s;',
event = e.api(e.QEMU_EVENT))
for e in events:
out('extern uint16_t %s;' % e.api(e.QEMU_DSTATE))
# static state
for e in events:
if 'disable' in e.properties:
enabled = 0
else:
enabled = 1
out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled))
backend.generate_begin(events, group)
for e in events:
# tracer-specific dstate
out('',
'#define %(api)s() ( \\',
api=e.api(e.QEMU_BACKEND_DSTATE))
if "disable" not in e.properties:
backend.generate_backend_dstate(e, group)
out(' false)')
out('',
'static inline void %(api)s(%(args)s)',
'{',
api=e.api(),
args=e.args)
if "disable" not in e.properties:
backend.generate(e, group, check_trace_event_get_state=False)
if backend.check_trace_event_get_state:
event_id = 'TRACE_' + e.name.upper()
cond = "trace_event_get_state(%s)" % event_id
out(' if (%(cond)s) {',
cond=cond)
backend.generate(e, group, check_trace_event_get_state=True)
out(' }')
out('}')
backend.generate_end(events, group)
out('#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper())
+128
View File
@@ -0,0 +1,128 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Generate .stp file that printfs log messages (DTrace with SystemTAP only).
"""
__author__ = "Daniel P. Berrange <[email protected]>"
__copyright__ = "Copyright (C) 2014-2019, Red Hat, Inc."
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Daniel Berrange"
__email__ = "[email protected]"
import re
from tracetool import out
from tracetool.backend.dtrace import binary, probeprefix
from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape
STATE_SKIP = 0
STATE_LITERAL = 1
STATE_MACRO = 2
def c_macro_to_format(macro):
if macro.startswith("PRI"):
return macro[3]
raise Exception("Unhandled macro '%s'" % macro)
def c_fmt_to_stap(fmt):
state = 0
bits = []
literal = ""
macro = ""
escape = 0;
for i in range(len(fmt)):
if fmt[i] == '\\':
if escape:
escape = 0
else:
escape = 1
if state != STATE_LITERAL:
raise Exception("Unexpected escape outside string literal")
literal = literal + fmt[i]
elif fmt[i] == '"' and not escape:
if state == STATE_LITERAL:
state = STATE_SKIP
bits.append(literal)
literal = ""
else:
if state == STATE_MACRO:
bits.append(c_macro_to_format(macro))
macro = ""
state = STATE_LITERAL
elif fmt[i] == ' ' or fmt[i] == '\t':
if state == STATE_MACRO:
bits.append(c_macro_to_format(macro))
macro = ""
state = STATE_SKIP
elif state == STATE_LITERAL:
literal = literal + fmt[i]
else:
escape = 0
if state == STATE_SKIP:
state = STATE_MACRO
if state == STATE_LITERAL:
literal = literal + fmt[i]
else:
macro = macro + fmt[i]
if state == STATE_MACRO:
bits.append(c_macro_to_format(macro))
elif state == STATE_LITERAL:
bits.append(literal)
# All variables in systemtap are 64-bit in size
# The "%l" integer size qualifier is thus redundant
# and "%ll" is not valid at all. Similarly the size_t
# based "%z" size qualifier is not valid. We just
# strip all size qualifiers for sanity.
fmt = re.sub(r"%(\d*)(l+|z)(x|u|d)", r"%\1\3", "".join(bits))
return fmt
def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for event_id, e in enumerate(events):
if 'disable' in e.properties:
continue
out('probe %(probeprefix)s.log.%(name)s = %(probeprefix)s.%(name)s ?',
'{',
probeprefix=probeprefix(),
name=e.name)
# Get references to userspace strings
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
out(' try {',
' arg%(name)s_str = %(name)s ? ' +
'user_string_n(%(name)s, 512) : "<null>"',
' } catch {}',
name=name)
# Determine systemtap's view of variable names
fields = ["pid()", "gettimeofday_ns()"]
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
fields.append("arg" + name + "_str")
else:
fields.append(name)
# Emit the entire record in a single SystemTap printf()
arg_str = ', '.join(arg for arg in fields)
fmt_str = "%d@%d " + e.name + " " + c_fmt_to_stap(e.fmt) + "\\n"
out(' printf("%(fmt_str)s", %(arg_str)s)',
fmt_str=fmt_str, arg_str=arg_str)
out('}')
out()
+83
View File
@@ -0,0 +1,83 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace-DIR.rs
"""
__author__ = "Tanish Desai <[email protected]>"
__copyright__ = "Copyright 2025, Tanish Desai <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
def generate(events, backend, group):
out('// SPDX-License-Identifier: GPL-2.0-or-later',
'// This file is @generated by tracetool, do not edit.',
'',
'#[allow(unused_imports)]',
'use std::ffi::c_char;',
'#[allow(unused_imports)]',
'use util::bindings;',
'',
'#[allow(dead_code)]',
'#[inline(always)]',
'fn trace_event_state_is_enabled(dstate: u16) -> bool {',
' (unsafe { trace_events_enabled_count }) != 0 && dstate != 0',
'}',
'',
'extern "C" {',
' #[allow(dead_code)]',
' static mut trace_events_enabled_count: u32;',
'}',)
out('extern "C" {')
for e in events:
out(' #[allow(dead_code)]',
' static mut %s: u16;' % e.api(e.QEMU_DSTATE))
out('}',
'')
backend.generate_begin(events, group)
for e in events:
out('#[inline(always)]',
'#[allow(dead_code)]',
'pub fn %(api)s() -> bool',
'{',
api=e.api(e.QEMU_RUST_DSTATE))
if "disable" not in e.properties:
backend.generate_backend_dstate(e, group)
if backend.check_trace_event_get_state:
out(' trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) ||',
event_id = 'TRACE_' + e.name.upper())
out(' false',
'}',
'',
'#[inline(always)]',
'#[allow(dead_code)]',
'pub fn %(api)s(%(args)s)',
'{',
api=e.api(e.QEMU_TRACE),
args=e.args.rust_decl())
if "disable" not in e.properties:
backend.generate(e, group, check_trace_event_get_state=False)
if backend.check_trace_event_get_state:
event_id = 'TRACE_' + e.name.upper()
out(' if trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) {',
event_id = event_id,
api=e.api())
backend.generate(e, group, check_trace_event_get_state=True)
out(' }')
out('}',
'')
backend.generate_end(events, group)
@@ -0,0 +1,71 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only).
"""
__author__ = "Stefan Hajnoczi <redhat.com>"
__copyright__ = "Copyright (C) 2014, Red Hat, Inc."
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
from tracetool.backend.dtrace import probeprefix
from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape
def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for event_id, e in enumerate(events):
if 'disable' in e.properties:
continue
out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?',
'{',
probeprefix=probeprefix(),
name=e.name)
# Calculate record size
sizes = ['24'] # sizeof(TraceRecord)
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
out(' try {',
' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"',
' } catch {}',
' arg%(name)s_len = strlen(arg%(name)s_str)',
name=name)
sizes.append('4 + arg%s_len' % name)
else:
sizes.append('8')
sizestr = ' + '.join(sizes)
# Generate format string and value pairs for record header and arguments
fields = [('8b', str(event_id)),
('8b', 'gettimeofday_ns()'),
('4b', sizestr),
('4b', 'pid()')]
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
fields.extend([('4b', 'arg%s_len' % name),
('.*s', 'arg%s_len, arg%s_str' % (name, name))])
else:
fields.append(('8b', name))
# Emit the entire record in a single SystemTap printf()
fmt_str = '%'.join(fmt for fmt, _ in fields)
arg_str = ', '.join(arg for _, arg in fields)
out(' printf("%%8b%%%(fmt_str)s", 1, %(arg_str)s)',
fmt_str=fmt_str, arg_str=arg_str)
out('}')
out()
+61
View File
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Generate .stp file (DTrace with SystemTAP only).
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
from tracetool.backend.dtrace import binary, probeprefix
# Technically 'self' is not used by systemtap yet, but
# they recommended we keep it in the reserved list anyway
RESERVED_WORDS = (
'break', 'catch', 'continue', 'delete', 'else', 'for',
'foreach', 'function', 'global', 'if', 'in', 'limit',
'long', 'next', 'probe', 'return', 'self', 'string',
'try', 'while'
)
def stap_escape(identifier):
# Append underscore to reserved keywords
if identifier in RESERVED_WORDS:
return identifier + '_'
return identifier
def generate(events, backend, group):
events = [e for e in events
if "disable" not in e.properties]
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for e in events:
# Define prototype for probe arguments
out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
'{',
probeprefix=probeprefix(),
name=e.name,
binary=binary())
i = 1
if len(e.args) > 0:
for name in e.args.names():
name = stap_escape(name)
out(' %s = $arg%d;' % (name, i))
i += 1
out('}')
out()
+35
View File
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace/generated-ust.c
"""
__author__ = "Mohamad Gebai <[email protected]>"
__copyright__ = "Copyright 2012, Mohamad Gebai <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
def generate(events, backend, group):
events = [e for e in events
if "disabled" not in e.properties]
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#include "qemu/osdep.h"',
'',
'#define TRACEPOINT_DEFINE',
'#define TRACEPOINT_CREATE_PROBES',
'',
'/* If gcc version 4.7 or older is used, LTTng ust gives a warning when compiling with',
' -Wredundant-decls.',
' */',
'#pragma GCC diagnostic ignored "-Wredundant-decls"',
'',
'#include "trace-ust-all.h"')
+106
View File
@@ -0,0 +1,106 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace/generated-ust-provider.h
"""
__author__ = "Mohamad Gebai <[email protected]>"
__copyright__ = "Copyright 2012, Mohamad Gebai <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
def generate(events, backend, group):
events = [e for e in events
if "disabled" not in e.properties]
if group == "all":
include = "trace-ust-all.h"
else:
include = "trace-ust.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#undef TRACEPOINT_PROVIDER',
'#define TRACEPOINT_PROVIDER qemu',
'',
'#undef TRACEPOINT_INCLUDE',
'#define TRACEPOINT_INCLUDE "./%s"' % include,
'',
'#if !defined (TRACE_%s_GENERATED_UST_H) || \\' % group.upper(),
' defined(TRACEPOINT_HEADER_MULTI_READ)',
'#define TRACE_%s_GENERATED_UST_H' % group.upper(),
'',
'#include <lttng/tracepoint.h>',
'',
'/*',
' * LTTng ust 2.0 does not allow you to use TP_ARGS(void) for tracepoints',
' * requiring no arguments. We define these macros introduced in more recent'
' * versions of LTTng ust as a workaround',
' */',
'#ifndef _TP_EXPROTO1',
'#define _TP_EXPROTO1(a) void',
'#endif',
'#ifndef _TP_EXDATA_PROTO1',
'#define _TP_EXDATA_PROTO1(a) void *__tp_data',
'#endif',
'#ifndef _TP_EXDATA_VAR1',
'#define _TP_EXDATA_VAR1(a) __tp_data',
'#endif',
'#ifndef _TP_EXVAR1',
'#define _TP_EXVAR1(a)',
'#endif',
'')
for e in events:
if len(e.args) > 0:
out('TRACEPOINT_EVENT(',
' qemu,',
' %(name)s,',
' TP_ARGS(%(args)s),',
' TP_FIELDS(',
name=e.name,
args=", ".join(", ".join(i) for i in e.args))
types = e.args.types()
names = e.args.names()
fmts = e.formats()
for t,n,f in zip(types, names, fmts):
if ('char *' in t) or ('char*' in t):
out(' ctf_string(' + n + ', ' + n + ')')
elif ("%p" in f) or ("x" in f) or ("PRIx" in f):
out(' ctf_integer_hex('+ t + ', ' + n + ', ' + n + ')')
elif ("ptr" in t) or ("*" in t):
out(' ctf_integer_hex('+ t + ', ' + n + ', ' + n + ')')
elif ('int' in t) or ('long' in t) or ('unsigned' in t) \
or ('size_t' in t) or ('bool' in t):
out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
elif ('double' in t) or ('float' in t):
out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
elif ('void *' in t) or ('void*' in t):
out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
out(' )',
')',
'')
else:
out('TRACEPOINT_EVENT(',
' qemu,',
' %(name)s,',
' TP_ARGS(void),',
' TP_FIELDS()',
')',
'',
name=e.name)
out('#endif /* TRACE_%s_GENERATED_UST_H */' % group.upper(),
'',
'/* This part must be outside ifdef protection */',
'#include <lttng/tracepoint-event.h>')