From 8ef00c4c637bb3f86f6cabb86f44d5e9a40d6506 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Sat, 25 Mar 2023 18:10:17 +1100 Subject: [PATCH] Revert "aya: make it possible to use set_global() with slices of Pod(s)" This reverts commit b614ffd603f4a276fd060659e14e5794bb26381f. --- aya/src/bpf.rs | 56 +++++++++++-------------------------------------- aya/src/util.rs | 16 ++------------ 2 files changed, 14 insertions(+), 58 deletions(-) diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index e94b2f6c..719f1195 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -38,7 +38,7 @@ use crate::{ is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported, is_prog_name_supported, retry_with_verifier_logs, }, - util::{bytes_of, bytes_of_slice, possible_cpus, VerifierLog, POSSIBLE_CPUS}, + util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS}, }; pub(crate) const BPF_OBJ_NAME_LEN: usize = 16; @@ -210,17 +210,15 @@ impl<'a> BpfLoader<'a> { self } - /// Sets the value of a global variable. - /// - /// From Rust eBPF, a global variable can be defined as follows: + /// Sets the value of a global variable /// + /// From Rust eBPF, a global variable would be constructed as follows: /// ```no_run /// #[no_mangle] /// static VERSION: i32 = 0; /// ``` - /// - /// Then it can be accessed using `core::ptr::read_volatile`: - /// + /// Then it would be accessed with `core::ptr::read_volatile` inside + /// functions: /// ```no_run /// # #[no_mangle] /// # static VERSION: i32 = 0; @@ -228,12 +226,10 @@ impl<'a> BpfLoader<'a> { /// let version = core::ptr::read_volatile(&VERSION); /// # } /// ``` + /// If using a struct, ensure that it is `#[repr(C)]` to ensure the size will + /// match that of the corresponding ELF symbol. /// - /// The type of a global variable must be `Pod` (plain old data), for instance `u8`, `u32` and - /// all other primitive types. You may use custom types as well, but you must ensure that those - /// types are `#[repr(C)]` and only contain other `Pod` types. - /// - /// From C eBPF, you would annotate a global variable as `volatile const`. + /// From C eBPF, you would annotate a variable as `volatile const` /// /// # Example /// @@ -242,17 +238,14 @@ impl<'a> BpfLoader<'a> { /// /// let bpf = BpfLoader::new() /// .set_global("VERSION", &2) - /// .set_global("PIDS", &[1234u16, 5678]) /// .load_file("file.o")?; /// # Ok::<(), aya::BpfError>(()) /// ``` /// - pub fn set_global>>( - &mut self, - name: &'a str, - value: T, - ) -> &mut BpfLoader<'a> { - self.globals.insert(name, value.into().bytes); + pub fn set_global(&mut self, name: &'a str, value: &'a V) -> &mut BpfLoader<'a> { + // Safety: value is POD + let data = unsafe { bytes_of(value) }; + self.globals.insert(name, data); self } @@ -904,28 +897,3 @@ fn load_btf(raw_btf: Vec) -> Result { } } } - -/// Global data that can be exported to eBPF programs before they are loaded. -/// -/// Valid global data includes `Pod` types and slices of `Pod` types. See also -/// [BpfLoader::set_global]. -pub struct GlobalData<'a> { - bytes: &'a [u8], -} - -impl<'a, T: Pod> From<&'a [T]> for GlobalData<'a> { - fn from(s: &'a [T]) -> Self { - GlobalData { - bytes: bytes_of_slice(s), - } - } -} - -impl<'a, T: Pod> From<&'a T> for GlobalData<'a> { - fn from(v: &'a T) -> Self { - GlobalData { - // Safety: v is Pod - bytes: unsafe { bytes_of(v) }, - } - } -} diff --git a/aya/src/util.rs b/aya/src/util.rs index 9584e820..34a82681 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -8,10 +8,7 @@ use std::{ str::FromStr, }; -use crate::{ - generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}, - Pod, -}; +use crate::generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}; use libc::{if_nametoindex, sysconf, _SC_PAGESIZE}; @@ -153,20 +150,11 @@ pub(crate) fn page_size() -> usize { } // bytes_of converts a to a byte slice -pub(crate) unsafe fn bytes_of(val: &T) -> &[u8] { +pub(crate) unsafe fn bytes_of(val: &T) -> &[u8] { let size = mem::size_of::(); slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) } -pub(crate) fn bytes_of_slice(val: &[T]) -> &[u8] { - let size = val.len().wrapping_mul(mem::size_of::()); - // Safety: - // Any alignment is allowed. - // The size is determined in this function. - // The Pod trait ensures the type is valid to cast to bytes. - unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) } -} - const MIN_LOG_BUF_SIZE: usize = 1024 * 10; const MAX_LOG_BUF_SIZE: usize = (std::u32::MAX >> 8) as usize;