Merge pull request #704 from aya-rs/better-panic

all: better panic messages
reviewable/pr706/r1
Tamir Duberstein 1 year ago committed by GitHub
commit 868a9b00b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1054,11 +1054,11 @@ pub(crate) struct SecInfo<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::btf::{ use crate::btf::{
BtfParam, DataSec, DataSecEntry, DeclTag, Float, Func, FuncProto, Ptr, TypeTag, Var, BtfParam, DataSec, DataSecEntry, DeclTag, Float, Func, FuncProto, Ptr, TypeTag, Var,
}; };
use assert_matches::assert_matches;
use super::*;
#[test] #[test]
fn test_parse_header() { fn test_parse_header() {
@ -1121,12 +1121,7 @@ mod tests {
0x65, 0x6e, 0x73, 0x65, 0x00, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x00, 0x65, 0x6e, 0x73, 0x65, 0x00, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x00,
]; ];
assert_eq!(data.len(), 517); assert_eq!(data.len(), 517);
let got = Btf::parse(data, Endianness::default()); let btf = Btf::parse(data, Endianness::default()).unwrap_or_else(|e| panic!("{}", e));
match got {
Ok(_) => {}
Err(e) => panic!("{}", e),
}
let btf = got.unwrap();
let data2 = btf.to_bytes(); let data2 = btf.to_bytes();
assert_eq!(data2.len(), 517); assert_eq!(data2.len(), 517);
assert_eq!(data, data2); assert_eq!(data, data2);
@ -1141,10 +1136,8 @@ mod tests {
]; ];
assert_eq!(ext_data.len(), 80); assert_eq!(ext_data.len(), 80);
let got = BtfExt::parse(ext_data, Endianness::default(), &btf); let _: BtfExt = BtfExt::parse(ext_data, Endianness::default(), &btf)
if let Err(e) = got { .unwrap_or_else(|e| panic!("{}", e));
panic!("{}", e)
}
} }
#[test] #[test]
@ -1176,17 +1169,10 @@ mod tests {
let btf_bytes = btf.to_bytes(); let btf_bytes = btf.to_bytes();
let raw_btf = btf_bytes.as_slice(); let raw_btf = btf_bytes.as_slice();
let parsed = Btf::parse(raw_btf, Endianness::default()); let btf = Btf::parse(raw_btf, Endianness::default()).unwrap_or_else(|e| panic!("{}", e));
match parsed {
Ok(btf) => {
assert_eq!(btf.string_at(1).unwrap(), "int"); assert_eq!(btf.string_at(1).unwrap(), "int");
assert_eq!(btf.string_at(5).unwrap(), "widget"); assert_eq!(btf.string_at(5).unwrap(), "widget");
} }
Err(e) => {
panic!("{}", e)
}
}
}
#[test] #[test]
fn test_fixup_ptr() { fn test_fixup_ptr() {
@ -1206,15 +1192,9 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Ptr(fixed) = btf.type_by_id(ptr_type_id).unwrap() { assert_matches!(btf.type_by_id(ptr_type_id).unwrap(), BtfType::Ptr(fixed) => {
assert!( assert_eq!(fixed.name_offset, 0);
fixed.name_offset == 0, });
"expected offset 0, got {}",
fixed.name_offset
)
} else {
panic!("not a ptr")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1245,11 +1225,9 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Int(fixed) = btf.type_by_id(var_type_id).unwrap() { assert_matches!(btf.type_by_id(var_type_id).unwrap(), BtfType::Int(fixed) => {
assert!(fixed.name_offset == name_offset) assert_eq!(fixed.name_offset, name_offset);
} else { });
panic!("not an int")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1289,14 +1267,16 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Struct(fixed) = btf.type_by_id(datasec_type_id).unwrap() { assert_matches!(btf.type_by_id(datasec_type_id).unwrap(), BtfType::Struct(fixed) => {
assert!(fixed.name_offset == name_offset); assert_eq!(fixed.name_offset , name_offset);
assert!(fixed.members.len() == 1); assert_matches!(*fixed.members, [
assert!(fixed.members[0].btf_type == var_type_id); BtfMember {
assert!(fixed.members[0].offset == 0) name_offset: _,
} else { btf_type,
panic!("not a struct") offset: 0,
} },
] => assert_eq!(btf_type, var_type_id));
});
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1341,20 +1321,23 @@ mod tests {
) )
.unwrap(); .unwrap();
if let BtfType::DataSec(fixed) = btf.type_by_id(datasec_type_id).unwrap() { assert_matches!(btf.type_by_id(datasec_type_id).unwrap(), BtfType::DataSec(fixed) => {
assert!(fixed.name_offset != name_offset); assert_ne!(fixed.name_offset, name_offset);
assert!(fixed.size == 32); assert_eq!(fixed.size, 32);
assert!(fixed.entries.len() == 1); assert_matches!(*fixed.entries, [
assert!(fixed.entries[0].btf_type == var_type_id); DataSecEntry {
assert!( btf_type,
fixed.entries[0].offset == 64, offset,
"expected 64, got {}", size,
fixed.entries[0].offset },
); ] => {
assert!(btf.string_at(fixed.name_offset).unwrap() == ".data.foo") assert_eq!(btf_type, var_type_id);
} else { assert_eq!(offset, 64);
panic!("not a datasec") assert_eq!(size, 4);
} }
);
assert_eq!(btf.string_at(fixed.name_offset).unwrap(), ".data.foo");
});
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1397,23 +1380,31 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Enum(fixed) = btf.type_by_id(func_proto_type_id).unwrap() { assert_matches!(btf.type_by_id(func_proto_type_id).unwrap(), BtfType::Enum(fixed) => {
assert!(fixed.name_offset == 0); assert_eq!(fixed.name_offset, 0);
assert!(fixed.variants.len() == 2); assert_matches!(*fixed.variants, [
assert!(btf.string_at(fixed.variants[0].name_offset).unwrap() == "a"); BtfEnum {
assert!(fixed.variants[0].value == int_type_id); name_offset: name_offset1,
assert!(btf.string_at(fixed.variants[1].name_offset).unwrap() == "b"); value: value1,
assert!(fixed.variants[1].value == int_type_id); },
} else { BtfEnum {
panic!("not an emum") name_offset: name_offset2,
value: value2,
},
] => {
assert_eq!(btf.string_at(name_offset1).unwrap(), "a");
assert_eq!(value1, int_type_id);
assert_eq!(btf.string_at(name_offset2).unwrap(), "b");
assert_eq!(value2, int_type_id);
} }
);
});
assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Typedef(fixed) => {
assert_eq!(fixed.name_offset, inc);
assert_eq!(fixed.btf_type, func_proto_type_id);
});
if let BtfType::Typedef(fixed) = btf.type_by_id(func_type_id).unwrap() {
assert!(fixed.name_offset == inc);
assert!(fixed.btf_type == func_proto_type_id);
} else {
panic!("not a typedef")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1447,12 +1438,25 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::FuncProto(fixed) = btf.type_by_id(func_proto_type_id).unwrap() { assert_matches!(btf.type_by_id(func_proto_type_id).unwrap(), BtfType::FuncProto(fixed) => {
assert!(btf.string_at(fixed.params[0].name_offset).unwrap() == "param0"); assert_matches!(*fixed.params, [
assert!(btf.string_at(fixed.params[1].name_offset).unwrap() == "param1"); BtfParam {
} else { name_offset: name_offset1,
panic!("not a func_proto") btf_type: btf_type1,
},
BtfParam {
name_offset: name_offset2,
btf_type: btf_type2,
},
] => {
assert_eq!(btf.string_at(name_offset1).unwrap(), "param0");
assert_eq!(btf_type1, int_type_id);
assert_eq!(btf.string_at(name_offset2).unwrap(), "param1");
assert_eq!(btf_type2, int_type_id);
} }
);
});
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1497,11 +1501,10 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Func(fixed) = btf.type_by_id(func_type_id).unwrap() { assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Func(fixed) => {
assert!(fixed.linkage() == FuncLinkage::Static); assert_eq!(fixed.linkage(), FuncLinkage::Static);
} else { });
panic!("not a func")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1549,11 +1552,9 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Func(fixed) = btf.type_by_id(func_type_id).unwrap() { assert_matches!(btf.type_by_id(func_type_id).unwrap(), BtfType::Func(fixed) => {
assert!(fixed.linkage() == FuncLinkage::Static); assert_eq!(fixed.linkage(), FuncLinkage::Static);
} else { });
panic!("not a func")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
@ -1574,12 +1575,11 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Struct(fixed) = btf.type_by_id(float_type_id).unwrap() { assert_matches!(btf.type_by_id(float_type_id).unwrap(), BtfType::Struct(fixed) => {
assert!(fixed.name_offset == 0); assert_eq!(fixed.name_offset, 0);
assert!(fixed.size == 16); assert_eq!(fixed.size, 16);
} else { });
panic!("not a struct")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1614,12 +1614,11 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Int(fixed) = btf.type_by_id(decl_tag_type_id).unwrap() { assert_matches!(btf.type_by_id(decl_tag_type_id).unwrap(), BtfType::Int(fixed) => {
assert!(fixed.name_offset == name_offset); assert_eq!(fixed.name_offset, name_offset);
assert!(fixed.size == 1); assert_eq!(fixed.size, 1);
} else { });
panic!("not an int")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();
@ -1642,11 +1641,10 @@ mod tests {
btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features) btf.fixup_and_sanitize(&HashMap::new(), &HashMap::new(), &features)
.unwrap(); .unwrap();
if let BtfType::Const(fixed) = btf.type_by_id(type_tag_type).unwrap() { assert_matches!(btf.type_by_id(type_tag_type).unwrap(), BtfType::Const(fixed) => {
assert!(fixed.btf_type == int_type_id); assert_eq!(fixed.btf_type, int_type_id);
} else { });
panic!("not a const")
}
// Ensure we can convert to bytes and back again // Ensure we can convert to bytes and back again
let raw = btf.to_bytes(); let raw = btf.to_bytes();
Btf::parse(&raw, Endianness::default()).unwrap(); Btf::parse(&raw, Endianness::default()).unwrap();

@ -580,7 +580,7 @@ fn match_member<'target>(
// this won't panic, bounds are checked when local_spec is built in AccessSpec::new // this won't panic, bounds are checked when local_spec is built in AccessSpec::new
BtfType::Struct(s) => s.members.get(local_accessor.index).unwrap(), BtfType::Struct(s) => s.members.get(local_accessor.index).unwrap(),
BtfType::Union(u) => u.members.get(local_accessor.index).unwrap(), BtfType::Union(u) => u.members.get(local_accessor.index).unwrap(),
_ => panic!("bug! this should only be called for structs and unions"), local_ty => panic!("unexpected type {:?}", local_ty),
}; };
let local_name = &*local_btf.string_at(local_member.name_offset)?; let local_name = &*local_btf.string_at(local_member.name_offset)?;
@ -1210,8 +1210,10 @@ impl ComputedRelocation {
FieldRShift64 => { FieldRShift64 => {
value.value = 64 - bit_size as u64; value.value = 64 - bit_size as u64;
} }
FieldExists // this is handled at the start of the function kind @ (FieldExists | TypeIdLocal | TypeIdTarget | TypeExists | TypeSize
| _ => panic!("bug! this should not be reached"), | EnumVariantExists | EnumVariantValue) => {
panic!("unexpected relocation kind {:?}", kind)
}
} }
Ok(value) Ok(value)

@ -1327,7 +1327,7 @@ pub(crate) fn types_are_compatible(
continue; continue;
} }
} }
_ => panic!("this shouldn't be reached"), local_ty => panic!("unexpected type {:?}", local_ty),
} }
} }
@ -1378,7 +1378,7 @@ pub(crate) fn fields_are_compatible(
continue; continue;
} }
} }
_ => panic!("this shouldn't be reached"), local_ty => panic!("unexpected type {:?}", local_ty),
} }
} }
@ -1392,6 +1392,7 @@ fn bytes_of<T>(val: &T) -> &[u8] {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use assert_matches::assert_matches;
#[test] #[test]
fn test_read_btf_type_int() { fn test_read_btf_type_int() {
@ -1400,18 +1401,17 @@ mod tests {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Int(new @ Int {
match got { name_offset,
Ok(BtfType::Int(new)) => { info: _,
assert_eq!(new.name_offset, 1); size,
assert_eq!(new.size, 8); data: _,
}) => {
assert_eq!(name_offset, 1);
assert_eq!(size, 8);
assert_eq!(new.bits(), 64); assert_eq!(new.bits(), 64);
let data2 = new.to_bytes(); assert_eq!(new.to_bytes(), data);
assert_eq!(data, data2); });
}
Ok(t) => panic!("expected int type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
} }
#[test] #[test]
@ -1450,14 +1450,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Ptr(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Ptr(_)) => {} });
Ok(t) => panic!("expected ptr type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1467,14 +1462,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Array(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Array(_)) => {} });
Ok(t) => panic!("expected array type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1484,14 +1474,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x47, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x47, 0x02,
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Struct(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Struct(_)) => {} });
Ok(t) => panic!("expected struct type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1501,14 +1486,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x0d, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x0d, 0x04,
0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Union(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Union(_)) => {} });
Ok(t) => panic!("expected union type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1518,14 +1498,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0xc9, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Enum(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Enum(_)) => {} });
Ok(t) => panic!("expected enum type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1534,14 +1509,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x0b, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Fwd(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Fwd(_)) => {} });
Ok(t) => panic!("expected fwd type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1550,14 +1520,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Typedef(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Typedef(_)) => {} });
Ok(t) => panic!("expected typedef type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1566,14 +1531,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x24, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Volatile(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Volatile(_)) => {} });
Ok(t) => panic!("expected volatile type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1582,14 +1542,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Const(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Const(_)) => {} });
Ok(t) => panic!("expected const type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1598,14 +1553,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Restrict(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Restrict(_)) => {} });
Ok(t) => panic!("expected restrict type gpt {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1614,14 +1564,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x17, 0x8b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xe4, 0x00, 0x00, 0x17, 0x8b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xe4, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Func(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Func(_)) => {} });
Ok(t) => panic!("expected func type gpt {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1631,14 +1576,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::FuncProto(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::FuncProto(_)) => {} });
Ok(t) => panic!("expected func_proto type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1649,14 +1589,9 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Var(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Var(_)) => {} });
Ok(t) => panic!("expected var type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
};
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1666,19 +1601,22 @@ mod tests {
0xd9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::DataSec(DataSec {
match &got { name_offset: _,
Ok(BtfType::DataSec(ty)) => { info: _,
assert_eq!(0, ty.size); size,
assert_eq!(11, ty.entries[0].btf_type); entries,
assert_eq!(0, ty.entries[0].offset); }) => {
assert_eq!(4, ty.entries[0].size); assert_eq!(size, 0);
assert_matches!(*entries, [
DataSecEntry {
btf_type: 11,
offset: 0,
size: 4,
} }
Ok(t) => panic!("expected datasec type, got {t:#?}"), ]);
Err(_) => panic!("unexpected error"),
} }
let data2 = got.unwrap().to_bytes(); );
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1687,14 +1625,9 @@ mod tests {
let data: &[u8] = &[ let data: &[u8] = &[
0x78, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x78, 0xfd, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00,
]; ];
let got = unsafe { BtfType::read(data, endianness) }; assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Float(got) => {
match got { assert_eq!(got.to_bytes(), data);
Ok(BtfType::Float(_)) => {} });
Ok(t) => panic!("expected float type, got {t:#?}"),
Err(_) => panic!("unexpected error"),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2)
} }
#[test] #[test]
@ -1711,14 +1644,17 @@ mod tests {
]; ];
let func_proto = FuncProto::new(params, 2); let func_proto = FuncProto::new(params, 2);
let data = func_proto.to_bytes(); let data = func_proto.to_bytes();
let got = unsafe { BtfType::read(&data, Endianness::default()) }; assert_matches!(unsafe { BtfType::read(&data, Endianness::default()) }.unwrap(), BtfType::FuncProto(FuncProto {
match got { name_offset: _,
Ok(BtfType::FuncProto(fp)) => { info: _,
assert_eq!(fp.params.len(), 2); return_type: _,
} params,
Ok(t) => panic!("expected func proto type, got {t:#?}"), }) => {
Err(_) => panic!("unexpected error"), assert_matches!(*params, [
} _,
_,
])
});
} }
#[test] #[test]

@ -1771,11 +1771,9 @@ mod tests {
assert!(obj.maps.get("bar").is_some()); assert!(obj.maps.get("bar").is_some());
assert!(obj.maps.get("baz").is_some()); assert!(obj.maps.get("baz").is_some());
for map in obj.maps.values() { for map in obj.maps.values() {
if let Map::Legacy(m) = map { assert_matches!(map, Map::Legacy(m) => {
assert_eq!(&m.def, def); assert_eq!(&m.def, def);
} else { })
panic!("expected a BTF map")
}
} }
} }
@ -2462,12 +2460,10 @@ mod tests {
obj.parse_section(map_section).unwrap(); obj.parse_section(map_section).unwrap();
let map = obj.maps.get("map_1").unwrap(); let map = obj.maps.get("map_1").unwrap();
if let Map::Btf(m) = map { assert_matches!(map, Map::Btf(m) => {
assert_eq!(m.def.key_size, 4); assert_eq!(m.def.key_size, 4);
assert_eq!(m.def.value_size, 8); assert_eq!(m.def.value_size, 8);
assert_eq!(m.def.max_entries, 1); assert_eq!(m.def.max_entries, 1);
} else { });
panic!("expected a BTF map")
}
} }
} }

@ -623,7 +623,7 @@ mod tests {
Some(10) => set_next_key(attr, 20), Some(10) => set_next_key(attr, 20),
Some(20) => return sys_error(EFAULT), Some(20) => return sys_error(EFAULT),
Some(30) => return sys_error(ENOENT), Some(30) => return sys_error(ENOENT),
Some(_) => panic!(), Some(i) => panic!("invalid key {}", i),
}; };
Ok(1) Ok(1)

@ -331,7 +331,7 @@ mod tests {
fn fake_mmap(buf: &MMappedBuf) { fn fake_mmap(buf: &MMappedBuf) {
override_syscall(|call| match call { override_syscall(|call| match call {
Syscall::PerfEventOpen { .. } | Syscall::PerfEventIoctl { .. } => Ok(42), Syscall::PerfEventOpen { .. } | Syscall::PerfEventIoctl { .. } => Ok(42),
_ => panic!(), call => panic!("unexpected syscall: {:?}", call),
}); });
TEST_MMAP_RET.with(|ret| *ret.borrow_mut() = buf as *const _ as *mut _); TEST_MMAP_RET.with(|ret| *ret.borrow_mut() = buf as *const _ as *mut _);
} }

@ -40,6 +40,38 @@ pub(crate) enum Syscall<'a> {
}, },
} }
impl std::fmt::Debug for Syscall<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Bpf { cmd, attr: _ } => f
.debug_struct("Syscall::Bpf")
.field("cmd", cmd)
.field("attr", &format_args!("_"))
.finish(),
Self::PerfEventOpen {
attr: _,
pid,
cpu,
group,
flags,
} => f
.debug_struct("Syscall::PerfEventOpen")
.field("attr", &format_args!("_"))
.field("pid", pid)
.field("cpu", cpu)
.field("group", group)
.field("flags", flags)
.finish(),
Self::PerfEventIoctl { fd, request, arg } => f
.debug_struct("Syscall::PerfEventIoctl")
.field("fd", fd)
.field("request", request)
.field("arg", arg)
.finish(),
}
}
}
fn syscall(call: Syscall) -> SysResult<c_long> { fn syscall(call: Syscall) -> SysResult<c_long> {
#[cfg(test)] #[cfg(test)]
return TEST_SYSCALL.with(|test_impl| unsafe { test_impl.borrow()(call) }); return TEST_SYSCALL.with(|test_impl| unsafe { test_impl.borrow()(call) });

@ -3,19 +3,6 @@ use object::{Object, ObjectSymbol};
#[test] #[test]
fn test_maps() { fn test_maps() {
let obj_file = object::File::parse(crate::MAP_TEST).unwrap(); let obj_file = object::File::parse(crate::MAP_TEST).unwrap();
if obj_file.section_by_name("maps").is_none() { assert!(obj_file.section_by_name("maps").is_some());
panic!("No 'maps' ELF section"); assert!(obj_file.symbols().any(|sym| sym.name() == Ok("BAR")));
}
let mut found = false;
for sym in obj_file.symbols() {
if let Ok(name) = sym.name() {
if name == "BAR" {
found = true;
break;
}
}
}
if !found {
panic!("No symbol 'BAR' in ELF file")
}
} }

Loading…
Cancel
Save