obj: Add Btf::to_bytes

This allows for parsed BTF to be re-encoded such that it could be loaded
in to the kernel. It moves bytes_of to the utils package. We could use
Object::bytes_of, but this requires the impl of the Pod trait on
generated code.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/126/head
Dave Tucker 3 years ago
parent c0f695c4b6
commit 7707fc3679

@ -7,12 +7,15 @@ use std::{
ptr, ptr,
}; };
use bytes::BufMut;
use object::Endianness; use object::Endianness;
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
generated::{btf_ext_header, btf_header}, generated::{btf_ext_header, btf_header},
obj::btf::{relocation::Relocation, BtfKind, BtfType}, obj::btf::{relocation::Relocation, BtfKind, BtfType},
util::bytes_of,
}; };
pub(crate) const MAX_RESOLVE_DEPTH: u8 = 32; pub(crate) const MAX_RESOLVE_DEPTH: u8 = 32;
@ -291,6 +294,18 @@ impl Btf {
type_id: root_type_id, type_id: root_type_id,
}) })
} }
pub(crate) fn to_bytes(&self) -> Vec<u8> {
let mut buf = bytes_of::<btf_header>(&self.header).to_vec();
for t in self.types() {
let b = unsafe { t.to_bytes() };
buf.put(b.as_slice())
}
for s in &self.strings {
buf.put_u8(*s);
}
buf
}
} }
unsafe fn read_btf_header(data: &[u8]) -> btf_header { unsafe fn read_btf_header(data: &[u8]) -> btf_header {
@ -472,4 +487,54 @@ mod tests {
assert_eq!(header.str_off, 0x2a5464); assert_eq!(header.str_off, 0x2a5464);
assert_eq!(header.str_len, 0x1c6410); assert_eq!(header.str_len, 0x1c6410);
} }
#[test]
fn test_parse_btf() {
let data: &[u8] = &[
0x9f, 0xeb, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01,
0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x04, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x01, 0x69, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x05, 0x00, 0x00, 0x00,
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xbc, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x00, 0x00, 0x00, 0x01, 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, 0x00, 0x78,
0x64, 0x70, 0x5f, 0x6d, 0x64, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x64, 0x61, 0x74,
0x61, 0x5f, 0x65, 0x6e, 0x64, 0x00, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x65, 0x74,
0x61, 0x00, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x66, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x00, 0x72, 0x78, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x00, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x66,
0x69, 0x6e, 0x64, 0x65, 0x78, 0x00, 0x5f, 0x5f, 0x75, 0x33, 0x32, 0x00, 0x75, 0x6e,
0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x63, 0x74, 0x78,
0x00, 0x69, 0x6e, 0x74, 0x00, 0x78, 0x64, 0x70, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x00,
0x78, 0x64, 0x70, 0x2f, 0x70, 0x61, 0x73, 0x73, 0x00, 0x2f, 0x68, 0x6f, 0x6d, 0x65,
0x2f, 0x64, 0x61, 0x76, 0x65, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x62, 0x70, 0x66, 0x64,
0x2f, 0x62, 0x70, 0x66, 0x2f, 0x78, 0x64, 0x70, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x2e,
0x62, 0x70, 0x66, 0x2e, 0x63, 0x00, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x58, 0x44, 0x50, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x3b, 0x00, 0x63,
0x68, 0x61, 0x72, 0x00, 0x5f, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x53, 0x49,
0x5a, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x5f, 0x00, 0x5f, 0x6c, 0x69, 0x63,
0x65, 0x6e, 0x73, 0x65, 0x00, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x00,
];
let got = Btf::parse(data, Endianness::default());
match got {
Ok(_) => {}
Err(e) => panic!("{}", e),
}
let data2 = got.unwrap().to_bytes();
assert_eq!(data, data2);
}
} }

@ -14,6 +14,7 @@ use crate::{
BTF_KIND_UNKN, BTF_KIND_VAR, BTF_KIND_VOLATILE, BTF_KIND_UNKN, BTF_KIND_VAR, BTF_KIND_VOLATILE,
}, },
obj::btf::{Btf, BtfError, MAX_RESOLVE_DEPTH}, obj::btf::{Btf, BtfError, MAX_RESOLVE_DEPTH},
util::bytes_of,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -149,6 +150,63 @@ impl BtfType {
}) })
} }
pub(crate) unsafe fn to_bytes(&self) -> Vec<u8> {
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>();
@ -406,7 +464,8 @@ 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!(nr_bits, 64); assert_eq!(nr_bits, 64);
@ -414,6 +473,8 @@ mod tests {
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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -422,11 +483,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -436,11 +500,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -450,11 +517,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -464,11 +534,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -478,11 +551,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -491,11 +567,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -504,11 +583,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -517,11 +599,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -530,11 +615,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -543,11 +631,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -556,11 +647,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -570,11 +664,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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -585,11 +682,14 @@ 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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -600,11 +700,14 @@ mod tests {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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::DataSec(_, _)) => {} Ok(BtfType::DataSec(_, _)) => {}
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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
#[test] #[test]
@ -613,10 +716,13 @@ 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 = unsafe { got.unwrap().to_bytes() };
assert_eq!(data, data2.as_slice())
} }
} }

@ -609,10 +609,9 @@ fn is_program_section(name: &str) -> bool {
mod tests { mod tests {
use matches::assert_matches; use matches::assert_matches;
use object::Endianness; use object::Endianness;
use std::slice;
use super::*; use super::*;
use crate::PinningType; use crate::{util::bytes_of, PinningType};
fn fake_section<'a>(name: &'a str, data: &'a [u8]) -> Section<'a> { fn fake_section<'a>(name: &'a str, data: &'a [u8]) -> Section<'a> {
Section { Section {
@ -635,11 +634,6 @@ mod tests {
} }
} }
fn bytes_of<T>(val: &T) -> &[u8] {
let size = mem::size_of::<T>();
unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) }
}
#[test] #[test]
fn test_parse_generic_error() { fn test_parse_generic_error() {
assert!(matches!( assert!(matches!(

@ -4,6 +4,7 @@ use std::{
ffi::CString, ffi::CString,
fs::{self, File}, fs::{self, File},
io::{self, BufReader}, io::{self, BufReader},
mem, slice,
str::FromStr, str::FromStr,
}; };
@ -143,6 +144,12 @@ macro_rules! include_bytes_aligned {
}}; }};
} }
// bytes of converts a <T> to raw bytes
pub(crate) fn bytes_of<T>(val: &T) -> &[u8] {
let size = mem::size_of::<T>();
unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) }
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

Loading…
Cancel
Save