# SPDX-License-Identifier: GPL-2.0-or-later """ DTrace/SystemTAP backend. """ __author__ = "Lluís Vilanova " __copyright__ = "Copyright 2012-2017, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@redhat.com" 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 and may # require SDT_USE_VARIADIC to be defined. If dtrace includes # 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 __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;') 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 __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)