summary refs log tree commit diff
path: root/data_model
diff options
context:
space:
mode:
authorGurchetan Singh <gurchetansingh@chromium.org>2018-10-31 17:31:46 -0700
committerCommit Bot <commit-bot@chromium.org>2019-12-11 00:34:36 +0000
commitbf433ea9f6b5f3717b23700b50f996edd527e17d (patch)
tree7853dbffb71a0f76e00e60ac9685b09a4d3906db /data_model
parent65b98f1ccc2ce1d52c12f75a224a259fd399e555 (diff)
downloadcrosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.gz
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.bz2
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.lz
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.xz
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.tar.zst
crosvm-bf433ea9f6b5f3717b23700b50f996edd527e17d.zip
crosvm: move vec_with_array_field to data_model
Move it to the newly created flexible array file.

BUG=chromium:892806
TEST=compiles

Change-Id: I6c423a885cec17e376b0da87a4adbd17c71ff6f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1325510
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'data_model')
-rw-r--r--data_model/src/flexible_array.rs39
-rw-r--r--data_model/src/lib.rs3
2 files changed, 42 insertions, 0 deletions
diff --git a/data_model/src/flexible_array.rs b/data_model/src/flexible_array.rs
new file mode 100644
index 0000000..35ac15a
--- /dev/null
+++ b/data_model/src/flexible_array.rs
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! A wrapper for structures that contain flexible arrays.
+
+use std::mem::size_of;
+
+// Returns a `Vec<T>` with a size in bytes at least as large as `size_in_bytes`.
+fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> {
+    let rounded_size = (size_in_bytes + size_of::<T>() - 1) / size_of::<T>();
+    let mut v = Vec::with_capacity(rounded_size);
+    for _ in 0..rounded_size {
+        v.push(T::default())
+    }
+    v
+}
+
+/// The kernel API has many structs that resemble the following `Foo` structure:
+///
+/// ```ignore
+/// #[repr(C)]
+/// struct Foo {
+///    some_data: u32,
+///    entries: __IncompleteArrayField<__u32>,
+/// }
+/// ```
+///
+/// In order to allocate such a structure, `size_of::<Foo>()` would be too small because it would
+/// not include any space for `entries`. To make the allocation large enough while still being
+/// aligned for `Foo`, a `Vec<Foo>` is created. Only the first element of `Vec<Foo>` would actually
+/// be used as a `Foo`. The remaining memory in the `Vec<Foo>` is for `entries`, which must be
+/// contiguous with `Foo`. This function is used to make the `Vec<Foo>` with enough space for
+/// `count` entries.
+pub fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> {
+    let element_space = count * size_of::<F>();
+    let vec_size_bytes = size_of::<T>() + element_space;
+    vec_with_size_in_bytes(vec_size_bytes)
+}
diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs
index dcca108..3f75377 100644
--- a/data_model/src/lib.rs
+++ b/data_model/src/lib.rs
@@ -180,3 +180,6 @@ pub use crate::endian::*;
 
 pub mod volatile_memory;
 pub use crate::volatile_memory::*;
+
+mod flexible_array;
+pub use flexible_array::vec_with_array_field;