libfdt: Move pack(), unpack(), apply_overlay()

Fix the lifetime of overlay in Fdt::apply_overlay() as there is no need
for it to share the lifetime of the Fdt (only that the reference is
valid during the execution of the function call) and fix the Safety
comment to clarify that overlay always gets corrupted.

Add FFI for fdt_open_into(), fdt_pack(), and fdt_overlay_apply().

Note that Rust does not allow aliasing mutable and const references so,
to properly expose the fdt_open_into() API to clients, provide it
through distinct read-only and read-write functions: Libfdt::open_into()
and LibfdtMut::open_into_self().

Test: m pvmfw
Test: atest liblibfdt.integration_test
Change-Id: Ib95154317fcba22f8ce2f89032f2859ea62e9c6e
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index ab3c83f..925c473 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -637,40 +637,30 @@
 
     /// Unpacks the DT to cover the whole slice it is contained in.
     pub fn unpack(&mut self) -> Result<()> {
-        // SAFETY: "Opens" the DT in-place (supported use-case) by updating its header and
-        // internal structures to make use of the whole self.fdt slice but performs no accesses
-        // outside of it and leaves the DT in a state that will be detected by other functions.
-        let ret = unsafe {
-            libfdt_bindgen::fdt_open_into(
-                self.as_ptr(),
-                self.as_mut_ptr(),
-                self.capacity().try_into().map_err(|_| FdtError::Internal)?,
-            )
-        };
-        fdt_err_expect_zero(ret)
+        self.open_into_self()
     }
 
     /// Packs the DT to take a minimum amount of memory.
     ///
     /// Doesn't shrink the underlying memory slice.
     pub fn pack(&mut self) -> Result<()> {
-        // SAFETY: "Closes" the DT in-place by updating its header and relocating its structs.
-        let ret = unsafe { libfdt_bindgen::fdt_pack(self.as_mut_ptr()) };
-        fdt_err_expect_zero(ret)
+        LibfdtMut::pack(self)
     }
 
     /// Applies a DT overlay on the base DT.
     ///
     /// # Safety
     ///
-    /// On failure, the library corrupts the DT and overlay so both must be discarded.
-    pub unsafe fn apply_overlay<'a>(&'a mut self, overlay: &'a mut Fdt) -> Result<&'a mut Self> {
-        let ret =
-        // SAFETY: Both pointers are valid because they come from references, and fdt_overlay_apply
-        // doesn't keep them after it returns. It may corrupt their contents if there is an error,
-        // but that's our caller's responsibility.
-            unsafe { libfdt_bindgen::fdt_overlay_apply(self.as_mut_ptr(), overlay.as_mut_ptr()) };
-        fdt_err_expect_zero(ret)?;
+    /// As libfdt corrupts the input DT on failure, `self` should be discarded on error:
+    ///
+    ///     let fdt = fdt.apply_overlay(overlay)?;
+    ///
+    /// Furthermore, `overlay` is _always_ corrupted by libfdt and will never refer to a valid
+    /// `Fdt` after this function returns and must therefore be discarded by the caller.
+    pub unsafe fn apply_overlay<'a>(&'a mut self, overlay: &mut Fdt) -> Result<&'a mut Self> {
+        // SAFETY: Our caller will properly discard overlay and/or self as needed.
+        unsafe { self.overlay_apply(overlay) }?;
+
         Ok(self)
     }
 
@@ -785,14 +775,6 @@
         self.buffer.as_ptr().cast()
     }
 
-    fn as_mut_ptr(&mut self) -> *mut c_void {
-        self.buffer.as_mut_ptr().cast::<_>()
-    }
-
-    fn capacity(&self) -> usize {
-        self.buffer.len()
-    }
-
     fn header(&self) -> &libfdt_bindgen::fdt_header {
         let p = self.as_ptr().cast();
         // SAFETY: A valid FDT (verified by constructor) must contain a valid fdt_header.