rust/zerocopy/src/layout.rs
Source file repositories/reference/linux-study-clean/rust/zerocopy/src/layout.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/zerocopy/src/layout.rs- Extension
.rs- Size
- 100893 bytes
- Lines
- 2226
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
struct MacroArgsstruct FooAlignenum CastParamsInnerfunction pubfunction pubfunction pubfunction pubfunction Somefunction pubfunction test_dst_layout_for_slicefunction test_dst_layout_extend_sized_with_sizedfunction test_dst_layout_extend_sized_with_dstfunction test_dst_layout_pad_to_align_with_sizedfunction test_dst_layout_pad_to_align_with_dstfunction test_validate_cast_and_convert_metadatafunction validate_behaviorfunction test_validate_rust_layoutfunction prove_requires_dynamic_paddingfunction prove_dst_layout_extendfunction Okfunction Okfunction prove_dst_layout_extend_dst_panicsfunction prove_dst_layout_pad_to_align
Annotated Snippet
struct MacroArgs {
offset: usize,
align: NonZeroUsize,
elem_size: Option<usize>,
}
/// # Safety
///
/// `test` promises to only call `addr_of_slice_field` on a `NonNull<T>`
/// which points to a valid `T`.
///
/// `with_elems` must produce a pointer which points to a valid `T`.
fn test<T: ?Sized, W: Fn(usize) -> NonNull<T>>(
args: MacroArgs,
with_elems: W,
addr_of_slice_field: Option<fn(NonNull<T>) -> NonNull<u8>>,
) {
let dst = args.elem_size.is_some();
let layout = {
let size_info = match args.elem_size {
Some(elem_size) => {
SizeInfo::SliceDst(TrailingSliceLayout { offset: args.offset, elem_size })
}
None => SizeInfo::Sized {
// Rust only supports types whose sizes are a multiple
// of their alignment. If the macro created a type like
// this:
//
// #[repr(C, align(2))]
// struct Foo([u8; 1]);
//
// ...then Rust will automatically round the type's size
// up to 2.
size: args.offset + util::padding_needed_for(args.offset, args.align),
},
};
DstLayout { size_info, align: args.align, statically_shallow_unpadded: false }
};
for elems in 0..128 {
let ptr = with_elems(elems);
if let Some(addr_of_slice_field) = addr_of_slice_field {
let slc_field_ptr = addr_of_slice_field(ptr).as_ptr();
// SAFETY: Both `slc_field_ptr` and `ptr` are pointers to
// the same valid Rust object.
// Work around https://github.com/rust-lang/rust-clippy/issues/12280
let offset: usize =
unsafe { slc_field_ptr.byte_offset_from(ptr.as_ptr()).try_into().unwrap() };
assert_eq!(offset, args.offset);
}
// SAFETY: `ptr` points to a valid `T`.
#[allow(clippy::multiple_unsafe_ops_per_block)]
let (size, align) = unsafe {
(mem::size_of_val_raw(ptr.as_ptr()), mem::align_of_val_raw(ptr.as_ptr()))
};
// Avoid expensive allocation when running under Miri.
let assert_msg = if !cfg!(miri) {
format!("\n{:?}\nsize:{}, align:{}", args, size, align)
} else {
String::new()
};
let without_padding =
args.offset + args.elem_size.map(|elem_size| elems * elem_size).unwrap_or(0);
assert!(size >= without_padding, "{}", assert_msg);
assert_eq!(align, args.align.get(), "{}", assert_msg);
// This encodes the most important part of the test: our
// understanding of how Rust determines the layout of repr(C)
// types. Sized repr(C) types are trivial, but DST types have
// some subtlety. Note that:
// - For sized types, `without_padding` is just the size of the
// type that we constructed for `Foo`. Since we may have
// requested a larger alignment, `Foo` may actually be larger
// than this, hence `padding_needed_for`.
// - For unsized types, `without_padding` is dynamically
// computed from the offset, the element size, and element
// count. We expect that the size of the object should be
// `offset + elem_size * elems` rounded up to the next
// alignment.
let expected_size =
without_padding + util::padding_needed_for(without_padding, args.align);
assert_eq!(expected_size, size, "{}", assert_msg);
// For zero-sized element types,
// `validate_cast_and_convert_metadata` just panics, so we skip
// testing those types.
Annotation
- Detected declarations: `struct MacroArgs`, `struct FooAlign`, `enum CastParamsInner`, `function pub`, `function pub`, `function pub`, `function pub`, `function Some`, `function pub`, `function test_dst_layout_for_slice`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.