copy with `copy_from_slice`, use `assert_eq!` where appropriate

*  Replace the bytewise copy loop with a `copy_from_slice` call.
*  Where `..Default::default()` is used in creating `bpf_map_def`,
replace `assert!(matches!())` with `assert_eq!()`; where it is more
appropriate or convenient to use `assert!(matches!())`, set the `id`
and `pinning` fields instead of using `..Default::default()`.

Refs: #10, #14
pull/14/head
Rafael Ortiz 4 years ago
parent ff6d7b8b0a
commit 86b639bd2e

@ -48,7 +48,7 @@ unsafe_impl_pod!(i8, u8, i16, u16, i32, u32, i64, u64);
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default, PartialEq)]
pub(crate) struct bpf_map_def { pub(crate) struct bpf_map_def {
// minimum features required by old BPF programs // minimum features required by old BPF programs
pub(crate) map_type: u32, pub(crate) map_type: u32,

@ -22,6 +22,7 @@ use crate::{
obj::btf::{Btf, BtfError, BtfExt}, obj::btf::{Btf, BtfError, BtfExt},
BpfError, BpfError,
}; };
use std::slice::from_raw_parts_mut;
const KERNEL_VERSION_ANY: u32 = 0xFFFF_FFFE; const KERNEL_VERSION_ANY: u32 = 0xFFFF_FFFE;
/// The first five __u32 of `bpf_map_def` must be defined. /// The first five __u32 of `bpf_map_def` must be defined.
@ -520,13 +521,9 @@ fn parse_map_def(name: &str, data: &[u8]) -> Result<bpf_map_def, ParseError> {
if data.len() < mem::size_of::<bpf_map_def>() { if data.len() < mem::size_of::<bpf_map_def>() {
let mut map_def = bpf_map_def::default(); let mut map_def = bpf_map_def::default();
unsafe { unsafe {
let mut data_ptr = data.as_ptr(); let map_def_ptr =
let mut map_def_ptr = &mut map_def as *mut bpf_map_def as *mut u8; from_raw_parts_mut(&mut map_def as *mut bpf_map_def as *mut u8, data.len());
for _ in 0..=data.len() { map_def_ptr.copy_from_slice(data);
*map_def_ptr = *data_ptr;
map_def_ptr = map_def_ptr.add(1);
data_ptr = data_ptr.add(1);
}
} }
Ok(map_def) Ok(map_def)
} else { } else {
@ -672,39 +669,38 @@ mod tests {
#[test] #[test]
fn test_parse_map_def() { fn test_parse_map_def() {
#![allow(unused_variables)] // map_def is used by the assertion
assert!(matches!( assert!(matches!(
parse_map_def("foo", &[]), parse_map_def("foo", &[]),
Err(ParseError::InvalidMapDefinition { .. }) Err(ParseError::InvalidMapDefinition { .. })
)); ));
assert!(matches!( assert!(matches!(
parse_map_def("foo", &[0u8; std::mem::size_of::<bpf_map_def>() + 10]), parse_map_def("foo", &[0u8; std::mem::size_of::<bpf_map_def>() + 1]),
Err(ParseError::InvalidMapDefinition { .. }) Err(ParseError::InvalidMapDefinition { .. })
)); ));
let def = bpf_map_def { assert_eq!(
parse_map_def(
"foo",
bytes_of(&bpf_map_def {
map_type: 1, map_type: 1,
key_size: 2, key_size: 2,
value_size: 3, value_size: 3,
max_entries: 4, max_entries: 4,
map_flags: 5, map_flags: 5,
..Default::default() ..Default::default()
}; })
assert!(matches!( )
parse_map_def( .unwrap(),
"foo", bpf_map_def {
bytes_of(&bpf_map_def {
map_type: 1, map_type: 1,
key_size: 2, key_size: 2,
value_size: 3, value_size: 3,
max_entries: 4, max_entries: 4,
map_flags: 5, map_flags: 5,
..Default::default() ..Default::default()
}) }
), );
Ok(def)
));
assert!(matches!( assert_eq!(
parse_map_def( parse_map_def(
"foo", "foo",
&bytes_of(&bpf_map_def { &bytes_of(&bpf_map_def {
@ -715,9 +711,17 @@ mod tests {
map_flags: 5, map_flags: 5,
..Default::default() ..Default::default()
})[..(mem::size_of::<u32>() * 5)] })[..(mem::size_of::<u32>() * 5)]
), )
Ok(map_def) .unwrap(),
)); bpf_map_def {
map_type: 1,
key_size: 2,
value_size: 3,
max_entries: 4,
map_flags: 5,
..Default::default()
}
);
let map = parse_map_def( let map = parse_map_def(
"foo", "foo",
&bytes_of(&bpf_map_def { &bytes_of(&bpf_map_def {
@ -741,7 +745,7 @@ mod tests {
)); ));
assert!(matches!( assert!(matches!(
parse_map( parse_map(
&fake_section("maps/foo", &[0u8; std::mem::size_of::<bpf_map_def>() + 10]), &fake_section("maps/foo", &[0u8; std::mem::size_of::<bpf_map_def>() + 1]),
"foo" "foo"
), ),
Err(ParseError::InvalidMapDefinition { .. }) Err(ParseError::InvalidMapDefinition { .. })
@ -750,15 +754,6 @@ mod tests {
#[test] #[test]
fn test_parse_map() { fn test_parse_map() {
#![allow(unused_variables)] // def is used by the assertion
let def = bpf_map_def {
map_type: 1,
key_size: 2,
value_size: 3,
max_entries: 4,
map_flags: 5,
..Default::default()
};
assert!(matches!( assert!(matches!(
parse_map( parse_map(
&fake_section( &fake_section(
@ -769,7 +764,8 @@ mod tests {
value_size: 3, value_size: 3,
max_entries: 4, max_entries: 4,
map_flags: 5, map_flags: 5,
..Default::default() id: 0,
pinning: 0
}) })
), ),
"foo" "foo"
@ -777,7 +773,15 @@ mod tests {
Ok(Map { Ok(Map {
section_index: 0, section_index: 0,
name, name,
def, def: bpf_map_def {
map_type: 1,
key_size: 2,
value_size: 3,
max_entries: 4,
map_flags: 5,
id: 0,
pinning: 0
},
data data
}) if name == "foo" && data.is_empty() }) if name == "foo" && data.is_empty()
)) ))
@ -785,18 +789,7 @@ mod tests {
#[test] #[test]
fn test_parse_map_data() { fn test_parse_map_data() {
#![allow(unused_variables)] // def is used by the assertion
let map_data = b"map data"; let map_data = b"map data";
let _map_type = BPF_MAP_TYPE_ARRAY;
let value_size = map_data.len() as u32;
let def = bpf_map_def {
map_type: _map_type as u32,
key_size: 4,
value_size,
max_entries: 1,
map_flags: 0,
..Default::default()
};
assert!(matches!( assert!(matches!(
parse_map( parse_map(
&fake_section( &fake_section(
@ -808,7 +801,15 @@ mod tests {
Ok(Map { Ok(Map {
section_index: 0, section_index: 0,
name, name,
def, def: bpf_map_def {
map_type: _map_type,
key_size: 4,
value_size,
max_entries: 1,
map_flags: 0,
id: 0,
pinning: 0,
},
data data
}) if name == ".bss" && data == map_data && value_size == map_data.len() as u32 }) if name == ".bss" && data == map_data && value_size == map_data.len() as u32
)) ))

Loading…
Cancel
Save