Browse Source
Tanish Desai and Paolo Bonzini's tracing Rust support. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmjdSSIACgkQnKSrs4Gr c8h8hwf/RXawMzImGn3I2kTOUWAQ97+yY0UgtyO010K71gypBa2EBcPIVH0ZOsy0 oT5pF2w7k0g83DXqupXiZO3yjSSmeGBXlOw8QS6D+FN0VpsdxrYJnvzVMqCckOrR 6wwM+fYYfCk/LwQFvjcMDdd6BSB/wUyMuBnh+fa8X9vxRL6CgMY7RpQd7YZ9JNtL PFQscu/K6zUARxwQ/DZTx5jYlW4rE5O4mq80CW2l1pgnyOH5vH/TySTKp0yX8eDO 5eoF7ttieOxxt6YobFak7EfWFvFuyp1j5NlWlyWKzhce1oSOAbaXnB1I61admRb3 7XrsTU0RjH6kp8ki4SZEoAh/HMw+4w== =myWt -----END PGP SIGNATURE----- Merge tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu into staging Pull request Tanish Desai and Paolo Bonzini's tracing Rust support. # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmjdSSIACgkQnKSrs4Gr # c8h8hwf/RXawMzImGn3I2kTOUWAQ97+yY0UgtyO010K71gypBa2EBcPIVH0ZOsy0 # oT5pF2w7k0g83DXqupXiZO3yjSSmeGBXlOw8QS6D+FN0VpsdxrYJnvzVMqCckOrR # 6wwM+fYYfCk/LwQFvjcMDdd6BSB/wUyMuBnh+fa8X9vxRL6CgMY7RpQd7YZ9JNtL # PFQscu/K6zUARxwQ/DZTx5jYlW4rE5O4mq80CW2l1pgnyOH5vH/TySTKp0yX8eDO # 5eoF7ttieOxxt6YobFak7EfWFvFuyp1j5NlWlyWKzhce1oSOAbaXnB1I61admRb3 # 7XrsTU0RjH6kp8ki4SZEoAh/HMw+4w== # =myWt # -----END PGP SIGNATURE----- # gpg: Signature made Wed 01 Oct 2025 08:30:42 AM PDT # gpg: using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [unknown] # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu: tracetool/syslog: add Rust support tracetool/ftrace: add Rust support tracetool/log: add Rust support log: change qemu_loglevel to unsigned tracetool/simple: add Rust support rust: pl011: add tracepoints rust: qdev: add minimal clock bindings rust: add trace crate tracetool: Add Rust format support tracetool/backend: remove redundant trace event checks tracetool: add CHECK_TRACE_EVENT_GET_STATE trace/ftrace: move snprintf+write from tracepoints to ftrace.c tracetool: add SPDX headers treewide: remove unnessary "coding" header tracetool: remove dead code tracetool: fix usage of try_import() Signed-off-by: Richard Henderson <richard.henderson@linaro.org>pull/305/head
62 changed files with 721 additions and 224 deletions
@ -0,0 +1,19 @@ |
|||
[package] |
|||
name = "trace" |
|||
version = "0.1.0" |
|||
authors = ["Tanish Desai <tanishdesai37@gmail.com>"] |
|||
description = "QEMU tracing infrastructure support" |
|||
resolver = "2" |
|||
publish = false |
|||
|
|||
edition.workspace = true |
|||
homepage.workspace = true |
|||
license.workspace = true |
|||
repository.workspace = true |
|||
rust-version.workspace = true |
|||
|
|||
[dependencies] |
|||
libc = { workspace = true } |
|||
|
|||
[lints] |
|||
workspace = true |
|||
@ -0,0 +1,19 @@ |
|||
rust = import('rust') |
|||
|
|||
lib_rs = configure_file( |
|||
input: 'src/lib.rs', |
|||
output: 'lib.rs', |
|||
configuration: { |
|||
'MESON_BUILD_ROOT': meson.project_build_root(), |
|||
}) |
|||
|
|||
_trace_rs = static_library( |
|||
'trace', # Library name, |
|||
lib_rs, |
|||
trace_rs_targets, # List of generated `.rs` custom targets |
|||
override_options: ['rust_std=2021', 'build.rust_std=2021'], |
|||
dependencies: [libc_rs], |
|||
rust_abi: 'rust', |
|||
) |
|||
|
|||
trace_rs = declare_dependency(link_with: _trace_rs) |
|||
@ -0,0 +1,39 @@ |
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
//! This crate provides macros that aid in using QEMU's tracepoint
|
|||
//! functionality.
|
|||
|
|||
#[doc(hidden)] |
|||
/// Re-exported item to avoid adding libc as a dependency everywhere.
|
|||
pub use libc::{syslog, LOG_INFO}; |
|||
|
|||
#[macro_export] |
|||
/// Define the trace-points from the named directory (which should have slashes
|
|||
/// replaced by underscore characters) as functions in a module called `trace`.
|
|||
///
|
|||
/// ```ignore
|
|||
/// ::trace::include_trace!("hw_char");
|
|||
/// // ...
|
|||
/// trace::trace_pl011_read_fifo_rx_full();
|
|||
/// ```
|
|||
macro_rules! include_trace { |
|||
($name:literal) => { |
|||
#[allow(
|
|||
clippy::ptr_as_ptr, |
|||
clippy::cast_lossless, |
|||
clippy::used_underscore_binding |
|||
)] |
|||
mod trace { |
|||
#[cfg(not(MESON))] |
|||
include!(concat!( |
|||
env!("MESON_BUILD_ROOT"), |
|||
"/trace/trace-", |
|||
$name, |
|||
".rs" |
|||
)); |
|||
|
|||
#[cfg(MESON)] |
|||
include!(concat!("@MESON_BUILD_ROOT@/trace/trace-", $name, ".rs")); |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
# SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
""" |
|||
trace-DIR.rs |
|||
""" |
|||
|
|||
__author__ = "Tanish Desai <tanishdesai37@gmail.com>" |
|||
__copyright__ = "Copyright 2025, Tanish Desai <tanishdesai37@gmail.com>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@redhat.com" |
|||
|
|||
|
|||
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;', |
|||
'', |
|||
'#[inline(always)]', |
|||
'fn trace_event_state_is_enabled(dstate: u16) -> bool {', |
|||
' (unsafe { trace_events_enabled_count }) != 0 && dstate != 0', |
|||
'}', |
|||
'', |
|||
'extern "C" {', |
|||
' static mut trace_events_enabled_count: u32;', |
|||
'}',) |
|||
|
|||
out('extern "C" {') |
|||
|
|||
for e in events: |
|||
out(' 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(%(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,40 @@ |
|||
// 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; |
|||
|
|||
#[inline(always)] |
|||
fn trace_event_state_is_enabled(dstate: u16) -> bool { |
|||
(unsafe { trace_events_enabled_count }) != 0 && dstate != 0 |
|||
} |
|||
|
|||
extern "C" { |
|||
static mut trace_events_enabled_count: u32; |
|||
} |
|||
extern "C" { |
|||
static mut _TRACE_TEST_BLAH_DSTATE: u16; |
|||
static mut _TRACE_TEST_WIBBLE_DSTATE: u16; |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { |
|||
let format_string = c"Blah context=%p filename=%s"; |
|||
unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} |
|||
} |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { |
|||
let format_string = c"Wibble context=%p value=%d"; |
|||
unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
// 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; |
|||
|
|||
#[inline(always)] |
|||
fn trace_event_state_is_enabled(dstate: u16) -> bool { |
|||
(unsafe { trace_events_enabled_count }) != 0 && dstate != 0 |
|||
} |
|||
|
|||
extern "C" { |
|||
static mut trace_events_enabled_count: u32; |
|||
} |
|||
extern "C" { |
|||
static mut _TRACE_TEST_BLAH_DSTATE: u16; |
|||
static mut _TRACE_TEST_WIBBLE_DSTATE: u16; |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { |
|||
let format_string = c"test_blah Blah context=%p filename=%s\n"; |
|||
if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 { |
|||
unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} |
|||
} |
|||
} |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { |
|||
let format_string = c"test_wibble Wibble context=%p value=%d\n"; |
|||
if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 { |
|||
unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
// 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; |
|||
|
|||
#[inline(always)] |
|||
fn trace_event_state_is_enabled(dstate: u16) -> bool { |
|||
(unsafe { trace_events_enabled_count }) != 0 && dstate != 0 |
|||
} |
|||
|
|||
extern "C" { |
|||
static mut trace_events_enabled_count: u32; |
|||
} |
|||
extern "C" { |
|||
static mut _TRACE_TEST_BLAH_DSTATE: u16; |
|||
static mut _TRACE_TEST_WIBBLE_DSTATE: u16; |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { |
|||
extern "C" { fn _simple_trace_test_blah(_context: *mut (), _filename: *const std::ffi::c_char); } |
|||
unsafe { _simple_trace_test_blah(_context, _filename.as_ptr()); } |
|||
} |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { |
|||
extern "C" { fn _simple_trace_test_wibble(_context: *mut (), _value: std::ffi::c_int); } |
|||
unsafe { _simple_trace_test_wibble(_context, _value); } |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
// 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; |
|||
|
|||
#[inline(always)] |
|||
fn trace_event_state_is_enabled(dstate: u16) -> bool { |
|||
(unsafe { trace_events_enabled_count }) != 0 && dstate != 0 |
|||
} |
|||
|
|||
extern "C" { |
|||
static mut trace_events_enabled_count: u32; |
|||
} |
|||
extern "C" { |
|||
static mut _TRACE_TEST_BLAH_DSTATE: u16; |
|||
static mut _TRACE_TEST_WIBBLE_DSTATE: u16; |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) { |
|||
let format_string = c"Blah context=%p filename=%s"; |
|||
unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());} |
|||
} |
|||
} |
|||
|
|||
#[inline(always)] |
|||
#[allow(dead_code)] |
|||
pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) |
|||
{ |
|||
if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) { |
|||
let format_string = c"Wibble context=%p value=%d"; |
|||
unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue