Import QEMU upstream snapshot d2e570c
Upstream: https://gitlab.com/qemu-project/qemu.git Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
commit
cf256aa081
11315 files changed
+3598369
No files matched your search
@@ -0,0 +1,140 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Backend management.
|
||||
|
||||
|
||||
Creating new backends
|
||||
---------------------
|
||||
|
||||
A new backend named 'foo-bar' corresponds to Python module
|
||||
'tracetool/backend/foo_bar.py'.
|
||||
|
||||
A backend module should provide a docstring, whose first non-empty line will be
|
||||
considered its short description.
|
||||
|
||||
All backends must generate their contents through the 'tracetool.out' routine.
|
||||
|
||||
|
||||
Backend attributes
|
||||
------------------
|
||||
|
||||
=========================== ====================================================
|
||||
Attribute Description
|
||||
=========================== ====================================================
|
||||
PUBLIC If exists and is set to 'True', the backend is
|
||||
considered "public".
|
||||
CHECK_TRACE_EVENT_GET_STATE If exists and is set to 'True', the backend-specific
|
||||
code inside the tracepoint is emitted within an
|
||||
``if trace_event_get_state()`` conditional.
|
||||
=========================== ====================================================
|
||||
|
||||
|
||||
Backend functions
|
||||
-----------------
|
||||
|
||||
All the following functions are optional, and no output will be generated if
|
||||
they do not exist.
|
||||
|
||||
=============================== ==============================================
|
||||
Function Description
|
||||
=============================== ==============================================
|
||||
generate_<format>_begin(events) Generate backend- and format-specific file
|
||||
header contents.
|
||||
generate_<format>_end(events) Generate backend- and format-specific file
|
||||
footer contents.
|
||||
generate_<format>(event) Generate backend- and format-specific contents
|
||||
for the given event.
|
||||
=============================== ==============================================
|
||||
|
||||
"""
|
||||
|
||||
__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(only_public = False):
|
||||
"""Get a list of (name, description) pairs."""
|
||||
res = [("nop", "Tracing disabled.")]
|
||||
modnames = []
|
||||
for filename in os.listdir(tracetool.backend.__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.backend." + modname)
|
||||
|
||||
# just in case; should never fail unless non-module files are put there
|
||||
if not module[0]:
|
||||
continue
|
||||
module = module[1]
|
||||
|
||||
public = getattr(module, "PUBLIC", False)
|
||||
if only_public and not public:
|
||||
continue
|
||||
|
||||
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 backend exists."""
|
||||
if len(name) == 0:
|
||||
return False
|
||||
if name == "nop":
|
||||
return True
|
||||
name = name.replace("-", "_")
|
||||
return tracetool.try_import("tracetool.backend." + name)[0]
|
||||
|
||||
|
||||
class Wrapper:
|
||||
def __init__(self, backends, format):
|
||||
self._backends = [backend.replace("-", "_") for backend in backends]
|
||||
self._format = format.replace("-", "_")
|
||||
self.check_trace_event_get_state = False
|
||||
for backend in self._backends:
|
||||
assert exists(backend)
|
||||
assert tracetool.format.exists(self._format)
|
||||
for backend in self.backend_modules():
|
||||
check_trace_event_get_state = getattr(backend, "CHECK_TRACE_EVENT_GET_STATE", False)
|
||||
self.check_trace_event_get_state = self.check_trace_event_get_state or check_trace_event_get_state
|
||||
|
||||
def backend_modules(self):
|
||||
for backend in self._backends:
|
||||
module = tracetool.try_import("tracetool.backend." + backend)[1]
|
||||
if module is not None:
|
||||
yield module
|
||||
|
||||
def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs):
|
||||
for backend in self.backend_modules():
|
||||
func = getattr(backend, name % self._format, None)
|
||||
if func is not None and \
|
||||
(check_trace_event_get_state is None or
|
||||
check_trace_event_get_state == getattr(backend, 'CHECK_TRACE_EVENT_GET_STATE', False)):
|
||||
func(*args, **kwargs)
|
||||
|
||||
def generate_begin(self, events, group):
|
||||
self._run_function("generate_%s_begin", events, group)
|
||||
|
||||
def generate(self, event, group, check_trace_event_get_state=None):
|
||||
self._run_function("generate_%s", event, group, check_trace_event_get_state=check_trace_event_get_state)
|
||||
|
||||
def generate_backend_dstate(self, event, group):
|
||||
self._run_function("generate_%s_backend_dstate", event, group)
|
||||
|
||||
def generate_end(self, events, group):
|
||||
self._run_function("generate_%s_end", events, group)
|
||||
@@ -0,0 +1,103 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
DTrace/SystemTAP backend.
|
||||
"""
|
||||
|
||||
__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
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
|
||||
|
||||
PROBEPREFIX = None
|
||||
|
||||
def probeprefix():
|
||||
if PROBEPREFIX is None:
|
||||
raise ValueError("you must set PROBEPREFIX")
|
||||
return PROBEPREFIX
|
||||
|
||||
|
||||
BINARY = None
|
||||
|
||||
def binary():
|
||||
if BINARY is None:
|
||||
raise ValueError("you must set BINARY")
|
||||
return BINARY
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
if group == "root":
|
||||
header = "trace-dtrace-root.h"
|
||||
else:
|
||||
header = "trace-dtrace-%s.h" % group
|
||||
|
||||
# Workaround for ust backend, which also includes <sys/sdt.h> and may
|
||||
# require SDT_USE_VARIADIC to be defined. If dtrace includes <sys/sdt.h>
|
||||
# first without defining SDT_USE_VARIADIC then ust breaks because the
|
||||
# STAP_PROBEV() macro is not defined.
|
||||
out('#ifndef SDT_USE_VARIADIC')
|
||||
out('#define SDT_USE_VARIADIC 1')
|
||||
out('#endif')
|
||||
|
||||
out('#include "%s"' % header,
|
||||
'')
|
||||
|
||||
out('#undef SDT_USE_VARIADIC')
|
||||
|
||||
# SystemTap defines <provider>_<name>_ENABLED() but other DTrace
|
||||
# implementations might not.
|
||||
for e in events:
|
||||
out('#ifndef QEMU_%(uppername)s_ENABLED',
|
||||
'#define QEMU_%(uppername)s_ENABLED() true',
|
||||
'#endif',
|
||||
uppername=e.name.upper())
|
||||
|
||||
def generate_h(event, group):
|
||||
out(' QEMU_%(uppername)s(%(argnames)s);',
|
||||
uppername=event.name.upper(),
|
||||
argnames=", ".join(event.args.names()))
|
||||
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' QEMU_%(uppername)s_ENABLED() || \\',
|
||||
uppername=event.name.upper())
|
||||
|
||||
|
||||
def generate_rs_begin(events, group):
|
||||
out('use std::cell::UnsafeCell;',
|
||||
'',
|
||||
'extern "C" {')
|
||||
# These are the Rust declarations of the .probes section semaphores
|
||||
# generated by dtrace(1) in its .o file output.
|
||||
for e in events:
|
||||
if 'disable' in e.properties:
|
||||
continue
|
||||
out(' #[allow(dead_code)]',
|
||||
f' static qemu_{e.name}_semaphore: UnsafeCell<u16>;')
|
||||
out('}',
|
||||
'')
|
||||
|
||||
|
||||
def generate_rs(event, group):
|
||||
args = event.args.rust_call_extern()
|
||||
if args:
|
||||
args = ', ' + args
|
||||
|
||||
out(f' ::trace::probe!(qemu, {event.name}{args});')
|
||||
|
||||
|
||||
def generate_rs_backend_dstate(event, group):
|
||||
# Rust does not have access to the <provider>_<name>_ENABLED() macro from
|
||||
# the dtrace(1) generated .h file. Use the matching semaphore declarations
|
||||
# generated by generate_rs_begin() instead.
|
||||
out(' (unsafe {qemu_%(n)s_semaphore.get().read_volatile()}) != 0 ||',
|
||||
n=event.name)
|
||||
@@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Ftrace built-in backend.
|
||||
"""
|
||||
|
||||
__author__ = "Eiichi Tsukata <[email protected]>"
|
||||
__copyright__ = "Copyright (C) 2013 Hitachi, Ltd."
|
||||
__license__ = "GPL version 2 or (at your option) any later version"
|
||||
|
||||
__maintainer__ = "Stefan Hajnoczi"
|
||||
__email__ = "[email protected]"
|
||||
|
||||
|
||||
from tracetool import out, expand_format_string
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
CHECK_TRACE_EVENT_GET_STATE = True
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
out('#include "trace/ftrace.h"',
|
||||
'')
|
||||
|
||||
|
||||
def generate_h(event, group):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out('#line %(event_lineno)d "%(event_filename)s"',
|
||||
' ftrace_write("%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||
'#line %(out_next_lineno)d "%(out_filename)s"',
|
||||
name=event.name,
|
||||
args=event.args,
|
||||
event_lineno=event.lineno,
|
||||
event_filename=event.filename,
|
||||
fmt=event.fmt.rstrip("\n"),
|
||||
argnames=argnames)
|
||||
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
|
||||
event_id="TRACE_" + event.name.upper())
|
||||
|
||||
def generate_rs(event, group):
|
||||
out(' let format_string = c"%(fmt)s";',
|
||||
' unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, %(args)s);}',
|
||||
fmt=expand_format_string(event.fmt),
|
||||
args=event.args.rust_call_varargs())
|
||||
@@ -0,0 +1,54 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Stderr built-in backend.
|
||||
"""
|
||||
|
||||
__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, expand_format_string
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
CHECK_TRACE_EVENT_GET_STATE = True
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
out('#include "qemu/log-for-trace.h"',
|
||||
'')
|
||||
|
||||
|
||||
def generate_h(event, group):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out(' if (qemu_loglevel_mask(LOG_TRACE)) {',
|
||||
'#line %(event_lineno)d "%(event_filename)s"',
|
||||
' qemu_log("%(name)s " %(fmt)s "\\n"%(argnames)s);',
|
||||
'#line %(out_next_lineno)d "%(out_filename)s"',
|
||||
' }',
|
||||
event_lineno=event.lineno,
|
||||
event_filename=event.filename,
|
||||
name=event.name,
|
||||
fmt=event.fmt.rstrip("\n"),
|
||||
argnames=argnames)
|
||||
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
|
||||
event_id="TRACE_" + event.name.upper())
|
||||
|
||||
def generate_rs(event, group):
|
||||
out(' let format_string = c"%(fmt)s\\n";',
|
||||
' if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {',
|
||||
' unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, %(args)s);}',
|
||||
' }',
|
||||
fmt=expand_format_string(event.fmt, event.name + " "),
|
||||
args=event.args.rust_call_varargs())
|
||||
@@ -0,0 +1,107 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Simple built-in backend.
|
||||
"""
|
||||
|
||||
__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
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
CHECK_TRACE_EVENT_GET_STATE = True
|
||||
|
||||
|
||||
def is_string(arg):
|
||||
strtype = ('const char*', 'char*', 'const char *', 'char *')
|
||||
arg_strip = arg.lstrip()
|
||||
if arg_strip.startswith(strtype) and arg_strip.count('*') == 1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
for event in events:
|
||||
out('void _simple_%(api)s(%(args)s);',
|
||||
api=event.api(),
|
||||
args=event.args)
|
||||
out('')
|
||||
|
||||
|
||||
def generate_h(event, group):
|
||||
out(' _simple_%(api)s(%(args)s);',
|
||||
api=event.api(),
|
||||
args=", ".join(event.args.names()))
|
||||
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
|
||||
event_id="TRACE_" + event.name.upper())
|
||||
|
||||
|
||||
def generate_c_begin(events, group):
|
||||
out('#include "qemu/osdep.h"',
|
||||
'#include "trace/control.h"',
|
||||
'#include "trace/simple.h"',
|
||||
'')
|
||||
|
||||
|
||||
def generate_c(event, group):
|
||||
out('void _simple_%(api)s(%(args)s)',
|
||||
'{',
|
||||
' TraceBufferRecord rec;',
|
||||
api=event.api(),
|
||||
args=event.args)
|
||||
sizes = []
|
||||
for type_, name in event.args:
|
||||
if is_string(type_):
|
||||
out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
|
||||
name=name)
|
||||
strsizeinfo = "4 + arg%s_len" % name
|
||||
sizes.append(strsizeinfo)
|
||||
else:
|
||||
sizes.append("8")
|
||||
sizestr = " + ".join(sizes)
|
||||
if len(event.args) == 0:
|
||||
sizestr = '0'
|
||||
|
||||
out('',
|
||||
' if (trace_record_start(&rec, %(event_obj)s.id, %(size_str)s)) {',
|
||||
' return; /* Trace Buffer Full, Event Dropped ! */',
|
||||
' }',
|
||||
event_obj=event.api(event.QEMU_EVENT),
|
||||
size_str=sizestr)
|
||||
|
||||
if len(event.args) > 0:
|
||||
for type_, name in event.args:
|
||||
# string
|
||||
if is_string(type_):
|
||||
out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
|
||||
name=name)
|
||||
# pointer var (not string)
|
||||
elif type_.endswith('*'):
|
||||
out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
|
||||
name=name)
|
||||
# primitive data type
|
||||
else:
|
||||
out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
|
||||
name=name)
|
||||
|
||||
out(' trace_record_finish(&rec);',
|
||||
'}',
|
||||
'')
|
||||
|
||||
def generate_rs(event, group):
|
||||
out(' extern "C" { fn _simple_%(api)s(%(rust_args)s); }',
|
||||
' unsafe { _simple_%(api)s(%(args)s); }',
|
||||
api=event.api(),
|
||||
rust_args=event.args.rust_decl_extern(),
|
||||
args=event.args.rust_call_extern())
|
||||
@@ -0,0 +1,49 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Syslog built-in backend.
|
||||
"""
|
||||
|
||||
__author__ = "Paul Durrant <[email protected]>"
|
||||
__copyright__ = "Copyright 2016, Citrix Systems Inc."
|
||||
__license__ = "GPL version 2 or (at your option) any later version"
|
||||
|
||||
__maintainer__ = "Stefan Hajnoczi"
|
||||
__email__ = "[email protected]"
|
||||
|
||||
|
||||
from tracetool import out, expand_format_string
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
CHECK_TRACE_EVENT_GET_STATE = True
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
out('#include <syslog.h>',
|
||||
'')
|
||||
|
||||
|
||||
def generate_h(event, group):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out('#line %(event_lineno)d "%(event_filename)s"',
|
||||
' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);',
|
||||
'#line %(out_next_lineno)d "%(out_filename)s"',
|
||||
event_lineno=event.lineno,
|
||||
event_filename=event.filename,
|
||||
name=event.name,
|
||||
fmt=event.fmt.rstrip("\n"),
|
||||
argnames=argnames)
|
||||
|
||||
def generate_rs(event, group):
|
||||
out(' let format_string = c"%(fmt)s";',
|
||||
' unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, %(args)s);}',
|
||||
fmt=expand_format_string(event.fmt),
|
||||
args=event.args.rust_call_varargs())
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
|
||||
event_id="TRACE_" + event.name.upper())
|
||||
@@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
LTTng User Space Tracing backend.
|
||||
"""
|
||||
|
||||
__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
|
||||
|
||||
|
||||
PUBLIC = True
|
||||
|
||||
|
||||
def generate_h_begin(events, group):
|
||||
header = 'trace-ust-' + group + '.h'
|
||||
out('#include <lttng/tracepoint.h>',
|
||||
'#include "%s"' % header,
|
||||
'',
|
||||
'/* tracepoint_enabled() was introduced in LTTng UST 2.7 */',
|
||||
'#ifndef tracepoint_enabled',
|
||||
'#define tracepoint_enabled(a, b) true',
|
||||
'#endif',
|
||||
'')
|
||||
|
||||
|
||||
def generate_h(event, group):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out(' tracepoint(qemu, %(name)s%(tp_args)s);',
|
||||
name=event.name,
|
||||
tp_args=argnames)
|
||||
|
||||
|
||||
def generate_h_backend_dstate(event, group):
|
||||
out(' tracepoint_enabled(qemu, %(name)s) || \\',
|
||||
name=event.name)
|
||||
Reference in new issue
Block a user