|
@@ -1,5 +1,6 @@
|
|
use std::{
|
|
use std::{
|
|
convert::{TryFrom, TryInto},
|
|
convert::{TryFrom, TryInto},
|
|
|
|
+ fmt::Display,
|
|
mem, ptr,
|
|
mem, ptr,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -7,11 +8,11 @@ use object::Endianness;
|
|
|
|
|
|
use crate::{
|
|
use crate::{
|
|
generated::{
|
|
generated::{
|
|
- btf_array, btf_enum, btf_member, btf_param, btf_type, btf_type__bindgen_ty_1, btf_var,
|
|
|
|
- btf_var_secinfo, BTF_KIND_ARRAY, BTF_KIND_CONST, BTF_KIND_DATASEC, BTF_KIND_ENUM,
|
|
|
|
- BTF_KIND_FLOAT, BTF_KIND_FUNC, BTF_KIND_FUNC_PROTO, BTF_KIND_FWD, BTF_KIND_INT,
|
|
|
|
- BTF_KIND_PTR, BTF_KIND_RESTRICT, BTF_KIND_STRUCT, BTF_KIND_TYPEDEF, BTF_KIND_UNION,
|
|
|
|
- BTF_KIND_UNKN, BTF_KIND_VAR, BTF_KIND_VOLATILE,
|
|
|
|
|
|
+ btf_array, btf_enum, btf_func_linkage, btf_member, btf_param, btf_type,
|
|
|
|
+ btf_type__bindgen_ty_1, btf_var, btf_var_secinfo, BTF_KIND_ARRAY, BTF_KIND_CONST,
|
|
|
|
+ BTF_KIND_DATASEC, BTF_KIND_ENUM, BTF_KIND_FLOAT, BTF_KIND_FUNC, BTF_KIND_FUNC_PROTO,
|
|
|
|
+ BTF_KIND_FWD, BTF_KIND_INT, BTF_KIND_PTR, BTF_KIND_RESTRICT, BTF_KIND_STRUCT,
|
|
|
|
+ BTF_KIND_TYPEDEF, BTF_KIND_UNION, BTF_KIND_UNKN, BTF_KIND_VAR, BTF_KIND_VOLATILE,
|
|
},
|
|
},
|
|
obj::btf::{Btf, BtfError, MAX_RESOLVE_DEPTH},
|
|
obj::btf::{Btf, BtfError, MAX_RESOLVE_DEPTH},
|
|
};
|
|
};
|
|
@@ -87,6 +88,36 @@ impl TryFrom<u32> for BtfKind {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+impl Display for BtfKind {
|
|
|
|
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
+ match self {
|
|
|
|
+ BtfKind::Unknown => write!(f, "[UNKNOWN]"),
|
|
|
|
+ BtfKind::Int => write!(f, "[INT]"),
|
|
|
|
+ BtfKind::Float => write!(f, "[FLOAT]"),
|
|
|
|
+ BtfKind::Ptr => write!(f, "[PTR]"),
|
|
|
|
+ BtfKind::Array => write!(f, "[ARRAY]"),
|
|
|
|
+ BtfKind::Struct => write!(f, "[STRUCT]"),
|
|
|
|
+ BtfKind::Union => write!(f, "[UNION]"),
|
|
|
|
+ BtfKind::Enum => write!(f, "[ENUM]"),
|
|
|
|
+ BtfKind::Fwd => write!(f, "[FWD]"),
|
|
|
|
+ BtfKind::Typedef => write!(f, "[TYPEDEF]"),
|
|
|
|
+ BtfKind::Volatile => write!(f, "[VOLATILE]"),
|
|
|
|
+ BtfKind::Const => write!(f, "[CONST]"),
|
|
|
|
+ BtfKind::Restrict => write!(f, "[RESTRICT]"),
|
|
|
|
+ BtfKind::Func => write!(f, "[FUNC]"),
|
|
|
|
+ BtfKind::FuncProto => write!(f, "[FUNC_PROTO]"),
|
|
|
|
+ BtfKind::Var => write!(f, "[VAR]"),
|
|
|
|
+ BtfKind::DataSec => write!(f, "[DATASEC]"),
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl Default for BtfKind {
|
|
|
|
+ fn default() -> Self {
|
|
|
|
+ BtfKind::Unknown
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
unsafe fn read<T>(data: &[u8]) -> Result<T, BtfError> {
|
|
unsafe fn read<T>(data: &[u8]) -> Result<T, BtfError> {
|
|
if mem::size_of::<T>() > data.len() {
|
|
if mem::size_of::<T>() > data.len() {
|
|
return Err(BtfError::InvalidTypeInfo);
|
|
return Err(BtfError::InvalidTypeInfo);
|
|
@@ -149,6 +180,67 @@ impl BtfType {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ pub(crate) fn to_bytes(&self) -> Vec<u8> {
|
|
|
|
+ fn bytes_of<T>(val: &T) -> &[u8] {
|
|
|
|
+ // Safety: all btf types are POD
|
|
|
|
+ unsafe { crate::util::bytes_of(val) }
|
|
|
|
+ }
|
|
|
|
+ match self {
|
|
|
|
+ BtfType::Fwd(btf_type)
|
|
|
|
+ | BtfType::Const(btf_type)
|
|
|
|
+ | BtfType::Volatile(btf_type)
|
|
|
|
+ | BtfType::Restrict(btf_type)
|
|
|
|
+ | BtfType::Ptr(btf_type)
|
|
|
|
+ | BtfType::Typedef(btf_type)
|
|
|
|
+ | BtfType::Func(btf_type)
|
|
|
|
+ | BtfType::Float(btf_type) => bytes_of::<btf_type>(btf_type).to_vec(),
|
|
|
|
+ BtfType::Int(btf_type, len) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ buf.append(&mut len.to_ne_bytes().to_vec());
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::Enum(btf_type, enums) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ for en in enums {
|
|
|
|
+ buf.append(&mut bytes_of::<btf_enum>(en).to_vec());
|
|
|
|
+ }
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::Array(btf_type, btf_array) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ buf.append(&mut bytes_of::<btf_array>(btf_array).to_vec());
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::Struct(btf_type, btf_members) | BtfType::Union(btf_type, btf_members) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ for m in btf_members {
|
|
|
|
+ buf.append(&mut bytes_of::<btf_member>(m).to_vec());
|
|
|
|
+ }
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::FuncProto(btf_type, btf_params) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ for p in btf_params {
|
|
|
|
+ buf.append(&mut bytes_of::<btf_param>(p).to_vec());
|
|
|
|
+ }
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::Var(btf_type, btf_var) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ buf.append(&mut bytes_of::<btf_var>(btf_var).to_vec());
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::DataSec(btf_type, btf_var_secinfo) => {
|
|
|
|
+ let mut buf = bytes_of::<btf_type>(btf_type).to_vec();
|
|
|
|
+ for s in btf_var_secinfo {
|
|
|
|
+ buf.append(&mut bytes_of::<btf_var_secinfo>(s).to_vec());
|
|
|
|
+ }
|
|
|
|
+ buf
|
|
|
|
+ }
|
|
|
|
+ BtfType::Unknown => vec![],
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
pub(crate) fn type_info_size(&self) -> usize {
|
|
pub(crate) fn type_info_size(&self) -> usize {
|
|
let ty_size = mem::size_of::<btf_type>();
|
|
let ty_size = mem::size_of::<btf_type>();
|
|
|
|
|
|
@@ -206,13 +298,109 @@ impl BtfType {
|
|
pub(crate) fn is_composite(&self) -> bool {
|
|
pub(crate) fn is_composite(&self) -> bool {
|
|
matches!(self, BtfType::Struct(_, _) | BtfType::Union(_, _))
|
|
matches!(self, BtfType::Struct(_, _) | BtfType::Union(_, _))
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_int(name_off: u32, size: u32, encoding: u32, offset: u32) -> BtfType {
|
|
|
|
+ let info = (BTF_KIND_INT) << 24;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.size = size;
|
|
|
|
+
|
|
|
|
+ let mut data = 0u32;
|
|
|
|
+ data |= (encoding & 0x0f) << 24;
|
|
|
|
+ data |= (offset & 0xff) << 16;
|
|
|
|
+ data |= (size * 8) & 0xff;
|
|
|
|
+ BtfType::Int(btf_type, data)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_func(name_off: u32, proto: u32, linkage: btf_func_linkage) -> BtfType {
|
|
|
|
+ let mut info = (BTF_KIND_FUNC) << 24;
|
|
|
|
+ info |= (linkage as u32) & 0xFFFF;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.type_ = proto;
|
|
|
|
+ BtfType::Func(btf_type)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_func_proto(params: Vec<btf_param>, return_type: u32) -> BtfType {
|
|
|
|
+ let mut info = (BTF_KIND_FUNC_PROTO) << 24;
|
|
|
|
+ info |= (params.len() as u32) & 0xFFFF;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = 0;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.type_ = return_type;
|
|
|
|
+ BtfType::FuncProto(btf_type, params)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_var(name_off: u32, type_: u32, linkage: u32) -> BtfType {
|
|
|
|
+ let info = (BTF_KIND_VAR) << 24;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.type_ = type_;
|
|
|
|
+ let var = btf_var { linkage };
|
|
|
|
+ BtfType::Var(btf_type, var)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_datasec(
|
|
|
|
+ name_off: u32,
|
|
|
|
+ variables: Vec<btf_var_secinfo>,
|
|
|
|
+ size: u32,
|
|
|
|
+ ) -> BtfType {
|
|
|
|
+ let mut info = (BTF_KIND_DATASEC) << 24;
|
|
|
|
+ info |= (variables.len() as u32) & 0xFFFF;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.size = size;
|
|
|
|
+ BtfType::DataSec(btf_type, variables)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_float(name_off: u32, size: u32) -> BtfType {
|
|
|
|
+ let info = (BTF_KIND_FLOAT) << 24;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.size = size;
|
|
|
|
+ BtfType::Float(btf_type)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_struct(name_off: u32, members: Vec<btf_member>, size: u32) -> BtfType {
|
|
|
|
+ let mut info = (BTF_KIND_STRUCT) << 24;
|
|
|
|
+ info |= (members.len() as u32) & 0xFFFF;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.size = size;
|
|
|
|
+ BtfType::Struct(btf_type, members)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_enum(name_off: u32, members: Vec<btf_enum>) -> BtfType {
|
|
|
|
+ let mut info = (BTF_KIND_ENUM) << 24;
|
|
|
|
+ info |= (members.len() as u32) & 0xFFFF;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.size = 4;
|
|
|
|
+ BtfType::Enum(btf_type, members)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub(crate) fn new_typedef(name_off: u32, type_: u32) -> BtfType {
|
|
|
|
+ let info = (BTF_KIND_TYPEDEF) << 24;
|
|
|
|
+ let mut btf_type = unsafe { std::mem::zeroed::<btf_type>() };
|
|
|
|
+ btf_type.name_off = name_off;
|
|
|
|
+ btf_type.info = info;
|
|
|
|
+ btf_type.__bindgen_anon_1.type_ = type_;
|
|
|
|
+ BtfType::Typedef(btf_type)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
fn type_kind(ty: &btf_type) -> Result<BtfKind, BtfError> {
|
|
fn type_kind(ty: &btf_type) -> Result<BtfKind, BtfError> {
|
|
((ty.info >> 24) & 0x1F).try_into()
|
|
((ty.info >> 24) & 0x1F).try_into()
|
|
}
|
|
}
|
|
|
|
|
|
-fn type_vlen(ty: &btf_type) -> usize {
|
|
|
|
|
|
+pub(crate) fn type_vlen(ty: &btf_type) -> usize {
|
|
(ty.info & 0xFFFF) as usize
|
|
(ty.info & 0xFFFF) as usize
|
|
}
|
|
}
|
|
|
|
|
|
@@ -397,6 +585,8 @@ impl std::fmt::Debug for btf_type__bindgen_ty_1 {
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|
|
mod tests {
|
|
mod tests {
|
|
|
|
+ use crate::generated::BTF_INT_SIGNED;
|
|
|
|
+
|
|
use super::*;
|
|
use super::*;
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -406,14 +596,48 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Int(ty, nr_bits)) => {
|
|
Ok(BtfType::Int(ty, nr_bits)) => {
|
|
assert_eq!(ty.name_off, 1);
|
|
assert_eq!(ty.name_off, 1);
|
|
|
|
+ assert_eq!(unsafe { ty.__bindgen_anon_1.size }, 8);
|
|
assert_eq!(nr_bits, 64);
|
|
assert_eq!(nr_bits, 64);
|
|
}
|
|
}
|
|
Ok(t) => panic!("expected int type, got {:#?}", t),
|
|
Ok(t) => panic!("expected int type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_write_btf_long_unsigned_int() {
|
|
|
|
+ let data: &[u8] = &[
|
|
|
|
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00,
|
|
|
|
+ 0x00, 0x00,
|
|
|
|
+ ];
|
|
|
|
+ let int = BtfType::new_int(1, 8, 0, 0);
|
|
|
|
+ assert_eq!(int.to_bytes(), data);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_write_btf_uchar() {
|
|
|
|
+ let data: &[u8] = &[
|
|
|
|
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
|
|
|
|
+ 0x00, 0x00,
|
|
|
|
+ ];
|
|
|
|
+ let int = BtfType::new_int(0x13, 1, 0, 0);
|
|
|
|
+ assert_eq!(int.to_bytes(), data);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_write_btf_signed_short_int() {
|
|
|
|
+ let data: &[u8] = &[
|
|
|
|
+ 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00,
|
|
|
|
+ 0x00, 0x01,
|
|
|
|
+ ];
|
|
|
|
+ let int = BtfType::new_int(0x4a, 2, BTF_INT_SIGNED, 0);
|
|
|
|
+ assert_eq!(int.to_bytes(), data);
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -422,11 +646,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Ptr(_)) => {}
|
|
Ok(BtfType::Ptr(_)) => {}
|
|
Ok(t) => panic!("expected ptr type, got {:#?}", t),
|
|
Ok(t) => panic!("expected ptr type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -436,11 +663,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Array(_, _)) => {}
|
|
Ok(BtfType::Array(_, _)) => {}
|
|
Ok(t) => panic!("expected array type, got {:#?}", t),
|
|
Ok(t) => panic!("expected array type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -450,11 +680,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Struct(_, _)) => {}
|
|
Ok(BtfType::Struct(_, _)) => {}
|
|
Ok(t) => panic!("expected struct type, got {:#?}", t),
|
|
Ok(t) => panic!("expected struct type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -464,11 +697,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Union(_, _)) => {}
|
|
Ok(BtfType::Union(_, _)) => {}
|
|
Ok(t) => panic!("expected union type, got {:#?}", t),
|
|
Ok(t) => panic!("expected union type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -478,11 +714,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Enum(_, _)) => {}
|
|
Ok(BtfType::Enum(_, _)) => {}
|
|
Ok(t) => panic!("expected enum type, got {:#?}", t),
|
|
Ok(t) => panic!("expected enum type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -491,11 +730,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Fwd(_)) => {}
|
|
Ok(BtfType::Fwd(_)) => {}
|
|
Ok(t) => panic!("expected fwd type, got {:#?}", t),
|
|
Ok(t) => panic!("expected fwd type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -504,11 +746,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Typedef(_)) => {}
|
|
Ok(BtfType::Typedef(_)) => {}
|
|
Ok(t) => panic!("expected typedef type, got {:#?}", t),
|
|
Ok(t) => panic!("expected typedef type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -517,11 +762,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Volatile(_)) => {}
|
|
Ok(BtfType::Volatile(_)) => {}
|
|
Ok(t) => panic!("expected volatile type, got {:#?}", t),
|
|
Ok(t) => panic!("expected volatile type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -530,11 +778,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Const(_)) => {}
|
|
Ok(BtfType::Const(_)) => {}
|
|
Ok(t) => panic!("expected const type, got {:#?}", t),
|
|
Ok(t) => panic!("expected const type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -543,11 +794,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Restrict(_)) => {}
|
|
Ok(BtfType::Restrict(_)) => {}
|
|
Ok(t) => panic!("expected restrict type gpt {:#?}", t),
|
|
Ok(t) => panic!("expected restrict type gpt {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -556,11 +810,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Func(_)) => {}
|
|
Ok(BtfType::Func(_)) => {}
|
|
Ok(t) => panic!("expected func type gpt {:#?}", t),
|
|
Ok(t) => panic!("expected func type gpt {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -570,11 +827,14 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::FuncProto(_, _)) => {}
|
|
Ok(BtfType::FuncProto(_, _)) => {}
|
|
Ok(t) => panic!("expected func_proto type, got {:#?}", t),
|
|
Ok(t) => panic!("expected func_proto type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -585,26 +845,38 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Var(_, _)) => {}
|
|
Ok(BtfType::Var(_, _)) => {}
|
|
Ok(t) => panic!("expected var type, got {:#?}", t),
|
|
Ok(t) => panic!("expected var type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
- }
|
|
|
|
|
|
+ };
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
fn test_read_btf_type_func_datasec() {
|
|
fn test_read_btf_type_func_datasec() {
|
|
let endianness = Endianness::default();
|
|
let endianness = Endianness::default();
|
|
- // NOTE: There was no data in /sys/kernell/btf/vmlinux for this type
|
|
|
|
let data: &[u8] = &[
|
|
let data: &[u8] = &[
|
|
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
- Ok(BtfType::DataSec(_, _)) => {}
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match &got {
|
|
|
|
+ Ok(BtfType::DataSec(ty, info)) => {
|
|
|
|
+ assert_eq!(0, unsafe { ty.__bindgen_anon_1.size } as usize);
|
|
|
|
+ assert_eq!(1, type_vlen(ty) as usize);
|
|
|
|
+ assert_eq!(1, info.len());
|
|
|
|
+ assert_eq!(11, info[0].type_);
|
|
|
|
+ assert_eq!(0, info[0].offset);
|
|
|
|
+ assert_eq!(4, info[0].size);
|
|
|
|
+ }
|
|
Ok(t) => panic!("expected datasec type, got {:#?}", t),
|
|
Ok(t) => panic!("expected datasec type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
}
|
|
}
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
@@ -613,10 +885,37 @@ 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,
|
|
];
|
|
];
|
|
- match unsafe { BtfType::read(data, endianness) } {
|
|
|
|
|
|
+ let got = unsafe { BtfType::read(data, endianness) };
|
|
|
|
+ match got {
|
|
Ok(BtfType::Float(_)) => {}
|
|
Ok(BtfType::Float(_)) => {}
|
|
Ok(t) => panic!("expected float type, got {:#?}", t),
|
|
Ok(t) => panic!("expected float type, got {:#?}", t),
|
|
Err(_) => panic!("unexpected error"),
|
|
Err(_) => panic!("unexpected error"),
|
|
}
|
|
}
|
|
|
|
+ let data2 = got.unwrap().to_bytes();
|
|
|
|
+ assert_eq!(data, data2.as_slice())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[test]
|
|
|
|
+ fn test_write_btf_func_proto() {
|
|
|
|
+ let params = vec![
|
|
|
|
+ btf_param {
|
|
|
|
+ name_off: 1,
|
|
|
|
+ type_: 1,
|
|
|
|
+ },
|
|
|
|
+ btf_param {
|
|
|
|
+ name_off: 3,
|
|
|
|
+ type_: 1,
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ let func_proto = BtfType::new_func_proto(params, 2);
|
|
|
|
+ let data = func_proto.to_bytes();
|
|
|
|
+ let got = unsafe { BtfType::read(&data, Endianness::default()) };
|
|
|
|
+ match got {
|
|
|
|
+ Ok(BtfType::FuncProto(btf_type, _params)) => {
|
|
|
|
+ assert_eq!(type_vlen(&btf_type), 2);
|
|
|
|
+ }
|
|
|
|
+ Ok(t) => panic!("expected func proto type, got {:#?}", t),
|
|
|
|
+ Err(_) => panic!("unexpected error"),
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|