libfdt: Add FdtNode::name()
This is the initial step for supporting iteration over FdtNodes.
Bug: 277993056
Test: atest liblibfdt.integration_test
Change-Id: I19ee85b9ee195f27cc776c8277f88797a6eba97e
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index a305e03..43eadae 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -251,6 +251,18 @@
}
}
+ /// Returns the node name.
+ pub fn name(&self) -> Result<&'a CStr> {
+ let mut len: c_int = 0;
+ // SAFETY: Accesses are constrained to the DT totalsize (validated by ctor). On success, the
+ // function returns valid null terminating string and otherwise returned values are dropped.
+ let name = unsafe { libfdt_bindgen::fdt_get_name(self.fdt.as_ptr(), self.offset, &mut len) }
+ as *const c_void;
+ let len = usize::try_from(fdt_err(len)?).unwrap();
+ let name = self.fdt.get_from_ptr(name, len + 1)?;
+ CStr::from_bytes_with_nul(name).map_err(|_| FdtError::Internal)
+ }
+
/// Retrieve the value of a given <string> property.
pub fn getprop_str(&self, name: &CStr) -> Result<Option<&CStr>> {
let value = if let Some(bytes) = self.getprop(name)? {
@@ -293,11 +305,7 @@
/// Retrieve the value of a given property.
pub fn getprop(&self, name: &CStr) -> Result<Option<&'a [u8]>> {
if let Some((prop, len)) = Self::getprop_internal(self.fdt, self.offset, name)? {
- let offset = (prop as usize)
- .checked_sub(self.fdt.as_ptr() as usize)
- .ok_or(FdtError::Internal)?;
-
- Ok(Some(self.fdt.buffer.get(offset..(offset + len)).ok_or(FdtError::Internal)?))
+ Ok(Some(self.fdt.get_from_ptr(prop, len)?))
} else {
Ok(None) // property was not found
}
@@ -327,7 +335,7 @@
let Some(len) = fdt_err_or_option(len)? else {
return Ok(None); // Property was not found.
};
- let len = usize::try_from(len).map_err(|_| FdtError::Internal)?;
+ let len = usize::try_from(len).unwrap();
if prop.is_null() {
// We expected an error code in len but still received a valid value?!
@@ -806,6 +814,12 @@
fdt_err_expect_zero(ret)
}
+ fn get_from_ptr(&self, ptr: *const c_void, len: usize) -> Result<&[u8]> {
+ let ptr = ptr as usize;
+ let offset = ptr.checked_sub(self.as_ptr() as usize).ok_or(FdtError::Internal)?;
+ self.buffer.get(offset..(offset + len)).ok_or(FdtError::Internal)
+ }
+
/// Return a shared pointer to the device tree.
pub fn as_ptr(&self) -> *const c_void {
self.buffer.as_ptr().cast::<_>()