|
@@ -394,6 +394,20 @@ impl BtfType {
|
|
|
btf_type.__bindgen_anon_1.type_ = type_;
|
|
|
BtfType::Typedef(btf_type)
|
|
|
}
|
|
|
+
|
|
|
+ #[cfg(test)]
|
|
|
+ pub(crate) fn new_array(name_off: u32, type_: u32, index_type: u32, nelems: u32) -> BtfType {
|
|
|
+ let info = (BTF_KIND_ARRAY) << 24;
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
+ btf_type.name_off = name_off;
|
|
|
+ btf_type.info = info;
|
|
|
+ let btf_array = btf_array {
|
|
|
+ type_,
|
|
|
+ index_type,
|
|
|
+ nelems,
|
|
|
+ };
|
|
|
+ BtfType::Array(btf_type, btf_array)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
fn type_kind(ty: &btf_type) -> Result<BtfKind, BtfError> {
|
|
@@ -453,8 +467,10 @@ pub(crate) fn types_are_compatible(
|
|
|
return Ok(true)
|
|
|
}
|
|
|
Int(_, local_off) => {
|
|
|
+ let local_off = (local_off >> 16) & 0xFF;
|
|
|
if let Int(_, target_off) = target_ty {
|
|
|
- return Ok(*local_off == 0 && *target_off == 0);
|
|
|
+ let target_off = (target_off >> 16) & 0xFF;
|
|
|
+ return Ok(local_off == 0 && target_off == 0);
|
|
|
}
|
|
|
}
|
|
|
Ptr(l_ty) => {
|
|
@@ -467,13 +483,10 @@ pub(crate) fn types_are_compatible(
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- Array(l_ty, _) => {
|
|
|
- if let Array(t_ty, _) = target_ty {
|
|
|
- // Safety: union
|
|
|
- unsafe {
|
|
|
- local_id = l_ty.__bindgen_anon_1.type_;
|
|
|
- target_id = t_ty.__bindgen_anon_1.type_;
|
|
|
- }
|
|
|
+ Array(_, l_ty) => {
|
|
|
+ if let Array(_, t_ty) = target_ty {
|
|
|
+ local_id = l_ty.type_;
|
|
|
+ target_id = t_ty.type_;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
@@ -546,13 +559,11 @@ pub(crate) fn fields_are_compatible(
|
|
|
}
|
|
|
Float(_) => return Ok(true),
|
|
|
Ptr(_) => return Ok(true),
|
|
|
- Array(l_ty, _) => {
|
|
|
- if let Array(t_ty, _) = target_ty {
|
|
|
- // Safety: union
|
|
|
- unsafe {
|
|
|
- local_id = l_ty.__bindgen_anon_1.type_;
|
|
|
- target_id = t_ty.__bindgen_anon_1.type_;
|
|
|
- }
|
|
|
+ Array(_, l_ty) => {
|
|
|
+ if let Array(_, t_ty) = target_ty {
|
|
|
+ local_id = l_ty.type_;
|
|
|
+ target_id = t_ty.type_;
|
|
|
+
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
@@ -918,4 +929,20 @@ mod tests {
|
|
|
Err(_) => panic!("unexpected error"),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_types_are_compatible() {
|
|
|
+ let mut btf = Btf::new();
|
|
|
+ let name_offset = btf.add_string("u32".to_string());
|
|
|
+ let u32t = btf.add_type(BtfType::new_int(name_offset, 4, 0, 0));
|
|
|
+ let name_offset = btf.add_string("u64".to_string());
|
|
|
+ let u64t = btf.add_type(BtfType::new_int(name_offset, 8, 0, 0));
|
|
|
+ let name_offset = btf.add_string("widgets".to_string());
|
|
|
+ let array_type = btf.add_type(BtfType::new_array(name_offset, u64t, u32t, 16));
|
|
|
+
|
|
|
+ assert!(types_are_compatible(&btf, u32t, &btf, u32t).unwrap());
|
|
|
+ // int types are compatible if offsets match. size and encoding aren't compared
|
|
|
+ assert!(types_are_compatible(&btf, u32t, &btf, u64t).unwrap());
|
|
|
+ assert!(types_are_compatible(&btf, array_type, &btf, array_type).unwrap());
|
|
|
+ }
|
|
|
}
|