libfdt: Use zerocopy for safe fdt_header wrapper
Provide a way to get a safe &(mut) fdt_header from any <T: Libfdt(Mut)>.
Instead of manually doing the conversion from the BE-encoded DT fields,
use zerocopy to implement a zero-cost wrapper where each field has a
getter and setter function that transparently handles the endianness.
Combine those to remove the need for unsafe code in Fdt.
Test: m pvmfw
Test: atest liblibfdt.integration_test
Change-Id: I5ccaf49b48c13855d80ad386d41be3abbf3fdfe8
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 1961232..6328f4c 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -27,7 +27,7 @@
PropertyIterator, RangesIterator, Reg, RegIterator, SubnodeIterator,
};
pub use result::{FdtError, Result};
-pub use safe_types::{NodeOffset, Phandle, PropOffset, StringOffset};
+pub use safe_types::{FdtHeader, NodeOffset, Phandle, PropOffset, StringOffset};
use core::ffi::{c_void, CStr};
use core::ops::Range;
@@ -778,13 +778,14 @@
self.buffer.as_ptr().cast()
}
- fn header(&self) -> &libfdt_bindgen::fdt_header {
- let p = self.as_ptr().cast();
+ fn header(&self) -> &FdtHeader {
+ let p = self.as_ptr().cast::<libfdt_bindgen::fdt_header>();
// SAFETY: A valid FDT (verified by constructor) must contain a valid fdt_header.
- unsafe { &*p }
+ let header = unsafe { &*p };
+ header.as_ref()
}
fn totalsize(&self) -> usize {
- u32::from_be(self.header().totalsize) as usize
+ self.header().totalsize.get().try_into().unwrap()
}
}