libfdt: Add setprop_placeholder & Improve trimprop
Add a wrapper for the previously unsupported fdt_setprop_placeholder().
As fdt_setprop() internally calls fdt_setprop_placeholder()+memcpy(),
the previous implementation of trimprop() was effectively resulting in
fdt_setprop_placeholder(..., len, ...);
memcpy(data, data, len);
for which it needed to use getprop_internal() to play some tricks around
the borrow checker to make that memcpy have no effect. Instead, simply
implement it by calling fdt_setprop_placeholder() directly, making the C
calls more efficient and the Rust code simpler and safer.
Test: m pvmfw
Test: atest liblibfdt.integration_test
Change-Id: I4b847dd51c230d4c6c9b6b2efd6c45087544c955
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index d81c0c1..299b1d3 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -528,27 +528,13 @@
/// Trims the size of the given property to new_size.
pub fn trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()> {
- let (prop, len) =
- FdtNode::getprop_internal(self.fdt, self.offset, name)?.ok_or(FdtError::NotFound)?;
- if len == new_size {
- return Ok(());
- }
- if new_size > len {
- return Err(FdtError::NoSpace);
- }
+ let prop = self.as_node().getprop(name)?.ok_or(FdtError::NotFound)?;
- // SAFETY: new_size is smaller than the old size
- let ret = unsafe {
- libfdt_bindgen::fdt_setprop(
- self.fdt.as_mut_ptr(),
- self.offset,
- name.as_ptr(),
- prop.cast::<c_void>(),
- new_size.try_into().map_err(|_| FdtError::BadValue)?,
- )
- };
-
- fdt_err_expect_zero(ret)
+ match prop.len() {
+ x if x == new_size => Ok(()),
+ x if x < new_size => Err(FdtError::NoSpace),
+ _ => self.fdt.setprop_placeholder(self.offset, name, new_size).map(|_| ()),
+ }
}
/// Returns reference to the containing device tree.