#![doc = include_str!("../examples/input-struct-init.c")]
#![allow(non_camel_case_types, clippy::manual_non_exhaustive)]
#![deny(unsafe_op_in_unsafe_fn)]
macro_rules! input_zeroed {
($container_ptr:ident, $container_ty:ty) => {{
let user_size = unsafe { $container_ptr.cast::<usize>().read() };
if user_size < std::mem::size_of_val(&user_size) {
false
} else {
let effective_size = memoffset::offset_of!($container_ty, reserved);
unsafe {
crate::util::is_mem_zero(
$container_ptr.cast::<u8>().add(effective_size),
user_size.saturating_sub(effective_size),
)
}
}
}};
}
macro_rules! input_sanitize {
($container_ptr:ident, $container_ty:ty) => {
unsafe {
let user_type_size = (*$container_ptr).type_size;
if (user_type_size < std::mem::size_of::<$container_ty>()) {
let mut obj = std::mem::MaybeUninit::<$container_ty>::uninit();
let buf = obj.as_mut_ptr().cast::<u8>();
let () =
std::ptr::copy_nonoverlapping($container_ptr.cast::<u8>(), buf, user_type_size);
let () = std::ptr::write_bytes(
buf.add(user_type_size),
0,
std::mem::size_of::<$container_ty>() - user_type_size,
);
obj.assume_init()
} else {
$container_ptr.read()
}
}
};
}
mod error;
mod helper;
mod inspect;
mod normalize;
mod symbolize;
mod trace;
mod util;
pub use error::*;
pub use helper::*;
pub use inspect::*;
pub use normalize::*;
pub use symbolize::*;
pub use trace::*;
#[cfg(test)]
mod tests {
use std::io;
use std::path::Path;
#[test]
fn no_padding_bytes() {
let header = Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("include")
.join("blazesym.h");
let mut data = Vec::new();
let bindings = Box::new(&mut data);
let () = bindgen::builder()
.allowlist_type("blaze.+")
.explicit_padding(true)
.header(header.to_string_lossy())
.generate()
.unwrap()
.write(bindings as Box<dyn io::Write>)
.unwrap();
let contents = String::from_utf8(data).unwrap();
assert!(!contents.contains("padding"), "{contents}");
}
}