mirror of https://github.com/aya-rs/aya
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.9 KiB
Rust
120 lines
4.9 KiB
Rust
use aya_obj::btf::{Btf, BtfType, IntEncoding, VarLinkage};
|
|
use object::Endianness;
|
|
|
|
use std::{fmt::Write, path::Path};
|
|
|
|
pub fn print_btf<P: AsRef<Path>>(path: P) -> anyhow::Result<()> {
|
|
let btf = Btf::parse_elf_file(path, Endianness::default())?;
|
|
for (i, t) in btf.types().enumerate().skip(1) {
|
|
let kind = t.kind();
|
|
let name = if t.name_offset() > 0 {
|
|
format!(
|
|
"'{}'",
|
|
btf.string_at(t.name_offset())
|
|
.unwrap_or(std::borrow::Cow::Borrowed(""))
|
|
)
|
|
} else {
|
|
"''".to_owned()
|
|
};
|
|
let info = match t {
|
|
BtfType::Unknown => "".to_string(),
|
|
BtfType::Fwd(_) => "type_id=0".to_string(),
|
|
BtfType::Const(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Volatile(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Restrict(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Ptr(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Typedef(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Func(ty) => format!("type_id={}", ty.btf_type()),
|
|
BtfType::Int(i) => {
|
|
let encoding = match i.encoding() {
|
|
IntEncoding::Signed => "(signed)",
|
|
IntEncoding::Char => "(char)",
|
|
IntEncoding::Bool => "(bool)",
|
|
IntEncoding::None => "(none)",
|
|
IntEncoding::Unknown => "(unknown)",
|
|
};
|
|
format!(
|
|
"size={} bits_offset={} nr_bits={} encoding={}",
|
|
i.size(),
|
|
i.offset(),
|
|
i.bits(),
|
|
encoding,
|
|
)
|
|
}
|
|
BtfType::Float(_) => todo!(),
|
|
BtfType::Enum(_) => todo!(),
|
|
BtfType::Array(ty) => {
|
|
format!(
|
|
"type_id=0 index_type_id={} nr_elems={}",
|
|
ty.index_type(),
|
|
ty.len()
|
|
)
|
|
}
|
|
BtfType::Struct(ty) => {
|
|
let size = ty.size();
|
|
let vlen = ty.vlen();
|
|
let mut out = format!("size={} vlen={}", size, vlen,);
|
|
for m in ty.members() {
|
|
let name = btf
|
|
.string_at(m.name_offset())
|
|
.unwrap_or(std::borrow::Cow::Borrowed(""));
|
|
let type_id = m.btf_type();
|
|
let offset = ty.member_bit_offset(m);
|
|
write!(out, "\n\t'{name}' type_id={type_id} bits_offset={offset}")?;
|
|
}
|
|
out
|
|
}
|
|
BtfType::Union(_) => todo!(),
|
|
BtfType::FuncProto(ty) => {
|
|
let ret_type_id = ty.return_type();
|
|
let vlen = ty.vlen();
|
|
let mut out = format!("ret_type_id={ret_type_id} vlen={vlen}");
|
|
for p in ty.params() {
|
|
let name = btf
|
|
.string_at(p.name_offset())
|
|
.unwrap_or(std::borrow::Cow::Borrowed(""));
|
|
let type_id = p.btf_type();
|
|
write!(out, "\n\t'{name}' type_id={type_id}")?;
|
|
}
|
|
out
|
|
}
|
|
BtfType::Var(ty) => {
|
|
let type_id = ty.btf_type();
|
|
let linkage = match ty.linkage() {
|
|
VarLinkage::Static => "static".to_owned(),
|
|
VarLinkage::Global => "global".to_owned(),
|
|
VarLinkage::Extern => "extern".to_owned(),
|
|
VarLinkage::Unknown => "unknown".to_owned(),
|
|
};
|
|
format!("type_id={type_id} linkage={linkage}")
|
|
}
|
|
BtfType::DataSec(ty) => {
|
|
let size = ty.size();
|
|
let vlen = ty.vlen();
|
|
let mut out = format!("size={size} vlen={vlen}");
|
|
for entry in ty.entries() {
|
|
let points_to = btf.type_by_id(entry.btf_type()).unwrap();
|
|
let name = btf
|
|
.string_at(points_to.name_offset())
|
|
.unwrap_or(std::borrow::Cow::Borrowed(""));
|
|
write!(
|
|
out,
|
|
"\n\ttype_id={} offset={} size={} ({} '{}')",
|
|
entry.btf_type(),
|
|
entry.offset(),
|
|
entry.size(),
|
|
points_to.kind(),
|
|
name
|
|
)?;
|
|
}
|
|
out
|
|
}
|
|
BtfType::DeclTag(_) => unimplemented!("decl tag formatting not implemented"),
|
|
BtfType::TypeTag(_) => unimplemented!("type tag formatting not implemented"),
|
|
BtfType::Enum64(_) => unimplemented!("enum64 formatting not implemented"),
|
|
};
|
|
println!("[{i}] {kind} {name} {info}");
|
|
}
|
|
Ok(())
|
|
}
|