[fbl][rust] Use bindgen Rather than hard-coding the size of alignment of various structures, use bindgen to generate that information from the C++ structures. Bug: 512840182 Change-Id: I78da718cfadae00f2163710788344a8de5b20f58 Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1656781 Commit-Queue: Adam Barth <abarth@google.com> Reviewed-by: Adrian Danis <adanis@google.com> Fuchsia-Auto-Submit: Adam Barth <abarth@google.com> Reviewed-by: Erick Tryzelaar <etryzelaar@google.com>
diff --git a/zircon/system/ulib/fbl/rust/BUILD.gn b/zircon/system/ulib/fbl/rust/BUILD.gn index 0250fa3..23c83a0 100644 --- a/zircon/system/ulib/fbl/rust/BUILD.gn +++ b/zircon/system/ulib/fbl/rust/BUILD.gn
@@ -5,12 +5,15 @@ # https://opensource.org/licenses/MIT import("//build/components.gni") +import("//build/rust/rustc_bindgen.gni") import("//build/rust/rustc_library.gni") rustc_library("fbl") { edition = "2024" + validations = [ ":fbl_bindgen_golden" ] sources = [ "src/array.rs", + "src/bindings.rs", "src/canary.rs", "src/conditional_select_nospec.rs", "src/confine_array_index.rs", @@ -80,3 +83,41 @@ testonly = true deps = [ ":fbl-rust-test-pkg" ] } + +rustc_bindgen_golden("fbl_bindgen_golden") { + headers = [ "bindgen.h" ] + checked_in_source = "src/bindings.rs" + + type_allowlist = [ "fbl_bindgen::.*" ] + + include_dirs = [ + "//prebuilt/third_party/clang/${host_os}-${host_cpu}/include/x86_64-unknown-linux-gnu/c++/v1", + "//prebuilt/third_party/clang/${host_os}-${host_cpu}/include/c++/v1", + "//sdk/lib/stdcompat/include", + "//sdk/lib/zircon-assert", + "//zircon/system/public", + "//zircon/system/ulib/fbl/include", + ] + + additional_clang_flags = [ + "-x", + "c++", + "-std=c++20", + "-stdlib=libc++", + "--sysroot=" + rebase_path("//prebuilt/third_party/sysroot/linux", "//"), + ] + + additional_bindgen_flags = [ + "--rust-edition", + "2021", + ] + + notice_year = 2026 + use_core = true + + expect_lints = [ + "dead_code", + "non_camel_case_types", + "non_upper_case_globals", + ] +}
diff --git a/zircon/system/ulib/fbl/rust/bindgen.h b/zircon/system/ulib/fbl/rust/bindgen.h new file mode 100644 index 0000000..7933586 --- /dev/null +++ b/zircon/system/ulib/fbl/rust/bindgen.h
@@ -0,0 +1,44 @@ +// Copyright 2026 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ZIRCON_SYSTEM_ULIB_FBL_RUST_BINDGEN_H_ +#define ZIRCON_SYSTEM_ULIB_FBL_RUST_BINDGEN_H_ + +#include <stddef.h> + +#include <fbl/canary.h> +#include <fbl/intrusive_double_list.h> +#include <fbl/intrusive_single_list.h> +#include <fbl/intrusive_wavl_tree.h> +#include <fbl/ref_counted.h> + +namespace fbl_bindgen { + +struct DummyObject; + +using Canary32 = fbl::Canary<0x12345678>; + +struct CanaryContainer { + fbl::Canary<0x12345678> canary; +}; + +struct SinglyNodeWrapper { + fbl::SinglyLinkedListNodeState<DummyObject*> state; +}; + +struct DoublyNodeWrapper { + fbl::DoublyLinkedListNodeState<DummyObject*> state; +}; + +struct WAVLNodeWrapper { + fbl::WAVLTreeNodeState<DummyObject*> state; +}; + +struct RefCountedObject : public fbl::RefCounted<RefCountedObject> { + int value; +}; + +} // namespace fbl_bindgen + +#endif // ZIRCON_SYSTEM_ULIB_FBL_RUST_BINDGEN_H_
diff --git a/zircon/system/ulib/fbl/rust/src/bindings.rs b/zircon/system/ulib/fbl/rust/src/bindings.rs new file mode 100644 index 0000000..c81b552 --- /dev/null +++ b/zircon/system/ulib/fbl/rust/src/bindings.rs
@@ -0,0 +1,78 @@ +// Copyright 2026 The Fuchsia Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is automatically generated by //zircon/system/ulib/fbl/rust:fbl_bindgen_golden. + +#![expect(dead_code)] +#![expect(non_camel_case_types)] +#![expect(non_upper_case_globals)] + +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8<T>(pub T); +impl<T: Copy + Default, const N: usize> Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([<T as Default>::default(); N]) + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fbl_internal_ContainerPtrTraits { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug)] +pub struct fbl_internal_CommonNodeStateBase { + pub _address: u8, +} +pub const fbl_NodeOptions_None: fbl_NodeOptions = 0; +pub const fbl_NodeOptions_AllowCopy: fbl_NodeOptions = 1; +pub const fbl_NodeOptions_AllowCopyFromContainer: fbl_NodeOptions = 2; +pub const fbl_NodeOptions_AllowMove: fbl_NodeOptions = 4; +pub const fbl_NodeOptions_AllowMoveFromContainer: fbl_NodeOptions = 8; +pub const fbl_NodeOptions_AllowCopyMove: fbl_NodeOptions = 5; +pub const fbl_NodeOptions_AllowCopyMoveFromContainer: fbl_NodeOptions = 10; +pub const fbl_NodeOptions_AllowMultiContainerUptr: fbl_NodeOptions = 16; +pub const fbl_NodeOptions_AllowRemoveFromContainer: fbl_NodeOptions = 32; +pub const fbl_NodeOptions_AllowClearUnsafe: fbl_NodeOptions = 64; +pub const fbl_NodeOptions_ReservedBits: fbl_NodeOptions = 17293822569102704640; +pub type fbl_NodeOptions = u64; +pub type fbl_DoublyLinkedListNodeState_Base = fbl_internal_CommonNodeStateBase; +pub type fbl_DoublyLinkedListNodeState_PtrType<PtrType_> = PtrType_; +pub type fbl_DoublyLinkedListNodeState_PtrTraits = fbl_internal_ContainerPtrTraits; +pub type fbl_SinglyLinkedListNodeState_Base = fbl_internal_CommonNodeStateBase; +pub type fbl_SinglyLinkedListNodeState_PtrType<PtrType_> = PtrType_; +pub type fbl_SinglyLinkedListNodeState_PtrTraits = fbl_internal_ContainerPtrTraits; +#[repr(C)] +#[derive(Debug)] +pub struct fbl_bindgen_DummyObject { + _unused: [u8; 0], +} +pub type fbl_bindgen_Canary32 = u32; +#[repr(C)] +#[derive(Debug)] +pub struct fbl_bindgen_CanaryContainer { + pub canary: u32, +} +#[repr(C)] +#[derive(Debug)] +pub struct fbl_bindgen_SinglyNodeWrapper { + pub state: __BindgenOpaqueArray8<[u8; 8usize]>, +} +#[repr(C)] +#[derive(Debug)] +pub struct fbl_bindgen_DoublyNodeWrapper { + pub state: __BindgenOpaqueArray8<[u8; 16usize]>, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fbl_bindgen_WAVLNodeWrapper { + pub state: __BindgenOpaqueArray8<[u8; 32usize]>, +} +#[repr(C)] +#[derive(Debug)] +pub struct fbl_bindgen_RefCountedObject { + pub _base: u32, + pub value: ::core::ffi::c_int, +}
diff --git a/zircon/system/ulib/fbl/rust/src/canary.rs b/zircon/system/ulib/fbl/rust/src/canary.rs index 61e8621..ae547b1 100644 --- a/zircon/system/ulib/fbl/rust/src/canary.rs +++ b/zircon/system/ulib/fbl/rust/src/canary.rs
@@ -45,9 +45,6 @@ magic: u32, } -zr::static_assert!(core::mem::size_of::<Canary<{ magic(b"test") }>>() == 4); -zr::static_assert!(core::mem::align_of::<Canary<{ magic(b"test") }>>() == 4); - impl<const MAGIC: u32> Canary<MAGIC> { /// Create a new Canary with the specified magic value. pub const fn new() -> Self {
diff --git a/zircon/system/ulib/fbl/rust/src/doubly_linked_list.rs b/zircon/system/ulib/fbl/rust/src/doubly_linked_list.rs index 070ec58..99ae530 100644 --- a/zircon/system/ulib/fbl/rust/src/doubly_linked_list.rs +++ b/zircon/system/ulib/fbl/rust/src/doubly_linked_list.rs
@@ -74,14 +74,6 @@ } } -// Static asserts for layout verification. -::zr::static_assert!( - core::mem::size_of::<DoublyLinkedListNode<()>>() == 2 * core::mem::size_of::<*mut ()>() -); -::zr::static_assert!( - core::mem::align_of::<DoublyLinkedListNode<()>>() == core::mem::align_of::<*mut ()>() -); - impl<T> Drop for DoublyLinkedListNode<T> { fn drop(&mut self) { debug_assert!(!self.in_container(), "Object destroyed while still in container");
diff --git a/zircon/system/ulib/fbl/rust/src/intrusive_container_test_support.rs b/zircon/system/ulib/fbl/rust/src/intrusive_container_test_support.rs index bd7cd5c..dfa5609 100644 --- a/zircon/system/ulib/fbl/rust/src/intrusive_container_test_support.rs +++ b/zircon/system/ulib/fbl/rust/src/intrusive_container_test_support.rs
@@ -311,3 +311,57 @@ ::zr::static_assert!(core::mem::offset_of!(SharedRefObject, allocated_in_rust) == 64); ::zr::static_assert!(core::mem::offset_of!(SharedRefObject, destruction_flag) == 72); ::zr::static_assert!(core::mem::size_of::<SharedRefObject>() == 80); + +// Bindgen layout asserts for production library types +type BindgenCanaryContainer = crate::bindings::fbl_bindgen_CanaryContainer; +#[allow(dead_code)] +struct RustCanaryContainer { + canary: crate::Canary<0x12345678>, +} +::zr::static_assert!( + core::mem::size_of::<RustCanaryContainer>() == core::mem::size_of::<BindgenCanaryContainer>() +); +::zr::static_assert!( + core::mem::align_of::<RustCanaryContainer>() == core::mem::align_of::<BindgenCanaryContainer>() +); + +type BindgenRefCountedObject = crate::bindings::fbl_bindgen_RefCountedObject; +#[allow(dead_code)] +struct RustRefCountedObject { + _base: crate::RefCounted, + value: i32, +} +::zr::static_assert!( + core::mem::size_of::<RustRefCountedObject>() == core::mem::size_of::<BindgenRefCountedObject>() +); +::zr::static_assert!( + core::mem::align_of::<RustRefCountedObject>() + == core::mem::align_of::<BindgenRefCountedObject>() +); + +::zr::static_assert!( + core::mem::size_of::<crate::SinglyLinkedListNode<()>>() + == core::mem::size_of::<crate::bindings::fbl_bindgen_SinglyNodeWrapper>() +); +::zr::static_assert!( + core::mem::align_of::<crate::SinglyLinkedListNode<()>>() + == core::mem::align_of::<crate::bindings::fbl_bindgen_SinglyNodeWrapper>() +); + +::zr::static_assert!( + core::mem::size_of::<crate::DoublyLinkedListNode<()>>() + == core::mem::size_of::<crate::bindings::fbl_bindgen_DoublyNodeWrapper>() +); +::zr::static_assert!( + core::mem::align_of::<crate::DoublyLinkedListNode<()>>() + == core::mem::align_of::<crate::bindings::fbl_bindgen_DoublyNodeWrapper>() +); + +::zr::static_assert!( + core::mem::size_of::<crate::WavlTreeNode<()>>() + == core::mem::size_of::<crate::bindings::fbl_bindgen_WAVLNodeWrapper>() +); +::zr::static_assert!( + core::mem::align_of::<crate::WavlTreeNode<()>>() + == core::mem::align_of::<crate::bindings::fbl_bindgen_WAVLNodeWrapper>() +);
diff --git a/zircon/system/ulib/fbl/rust/src/lib.rs b/zircon/system/ulib/fbl/rust/src/lib.rs index c342fd3..351ee88 100644 --- a/zircon/system/ulib/fbl/rust/src/lib.rs +++ b/zircon/system/ulib/fbl/rust/src/lib.rs
@@ -8,6 +8,9 @@ extern crate self as fbl; +#[cfg(test)] +mod bindings; + mod array; mod canary; mod conditional_select_nospec;
diff --git a/zircon/system/ulib/fbl/rust/src/singly_linked_list.rs b/zircon/system/ulib/fbl/rust/src/singly_linked_list.rs index f4559e9..4e50c90 100644 --- a/zircon/system/ulib/fbl/rust/src/singly_linked_list.rs +++ b/zircon/system/ulib/fbl/rust/src/singly_linked_list.rs
@@ -765,13 +765,6 @@ } zr::static_assert!( - core::mem::size_of::<SinglyLinkedListNode<()>>() == core::mem::size_of::<*mut ()>() - ); - zr::static_assert!( - core::mem::align_of::<SinglyLinkedListNode<()>>() == core::mem::align_of::<*mut ()>() - ); - - zr::static_assert!( core::mem::size_of::<SinglyLinkedList<*mut DummyTarget>>() == core::mem::size_of::<*mut DummyTarget>() );
diff --git a/zircon/system/ulib/fbl/rust/src/wavl_tree.rs b/zircon/system/ulib/fbl/rust/src/wavl_tree.rs index cdf0565..8da637f 100644 --- a/zircon/system/ulib/fbl/rust/src/wavl_tree.rs +++ b/zircon/system/ulib/fbl/rust/src/wavl_tree.rs
@@ -338,12 +338,6 @@ } } -// Static asserts for layout verification. -::zr::static_assert!(core::mem::size_of::<WavlTreeNode<()>>() == 32); -::zr::static_assert!(core::mem::align_of::<WavlTreeNode<()>>() == 8); -::zr::static_assert!(core::mem::size_of::<WavlTreeNode<(), i32>>() == 32); -::zr::static_assert!(core::mem::align_of::<WavlTreeNode<(), i32>>() == 8); - impl<T, R: WavlTreeRank> Drop for WavlTreeNode<T, R> { fn drop(&mut self) { debug_assert!(!self.in_container(), "Object destroyed while still in container");