Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: bpftool but with aya #902

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions aya-obj/src/btf/btf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ pub enum BtfError {
#[error("error parsing BTF header")]
InvalidHeader,

/// Invalid ELF data
#[cfg(feature = "std")]
#[error("error parsing ELF")]
Elf,

/// invalid BTF type info segment
#[error("invalid BTF type info segment")]
InvalidTypeInfo,
Expand Down Expand Up @@ -276,7 +281,8 @@ impl Btf {
self.types.types.len() < 2
}

pub(crate) fn types(&self) -> impl Iterator<Item = &BtfType> {
/// Iterates over the BTF types.
pub fn types(&self) -> impl Iterator<Item = &BtfType> {
self.types.types.iter()
}

Expand Down Expand Up @@ -307,7 +313,7 @@ impl Btf {

/// Loads BTF metadata from the given `path`.
#[cfg(feature = "std")]
pub fn parse_file<P: AsRef<std::path::Path>>(
pub(crate) fn parse_file<P: AsRef<std::path::Path>>(
path: P,
endianness: Endianness,
) -> Result<Btf, BtfError> {
Expand All @@ -322,6 +328,26 @@ impl Btf {
)
}

/// Loads BTF metadata from an ELF section.
#[cfg(feature = "std")]
pub fn parse_elf_file<P: AsRef<std::path::Path>>(
path: P,
endianness: Endianness,
) -> Result<Btf, BtfError> {
use object::{Object, ObjectSection};
let path = path.as_ref();
let bin_data = std::fs::read(path).map_err(|e| BtfError::FileError {
path: path.to_owned(),
error: e,
})?;
let obj_file = object::File::parse(&*bin_data).map_err(|_| BtfError::Elf)?;
let section = obj_file
.section_by_name(".BTF")
.ok_or_else(|| BtfError::InvalidHeader)?;
let data = section.data().map_err(|_| BtfError::InvalidHeader)?;
Btf::parse(data, endianness)
}

/// Parses BTF from binary data of the given endianness
pub fn parse(data: &[u8], endianness: Endianness) -> Result<Btf, BtfError> {
if data.len() < mem::size_of::<btf_header>() {
Expand Down Expand Up @@ -374,7 +400,8 @@ impl Btf {
Ok(types)
}

pub(crate) fn string_at(&self, offset: u32) -> Result<Cow<'_, str>, BtfError> {
/// Returns the string at the given offset within the BTF metadata.
pub fn string_at(&self, offset: u32) -> Result<Cow<'_, str>, BtfError> {
let btf_header {
hdr_len,
mut str_off,
Expand All @@ -400,7 +427,8 @@ impl Btf {
Ok(s.to_string_lossy())
}

pub(crate) fn type_by_id(&self, type_id: u32) -> Result<&BtfType, BtfError> {
/// Returns the BtfType at the given type id.
pub fn type_by_id(&self, type_id: u32) -> Result<&BtfType, BtfError> {
self.types.type_by_id(type_id)
}

Expand Down
172 changes: 157 additions & 15 deletions aya-obj/src/btf/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ impl Const {
btf_type,
}
}
/// The target type of the const.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand All @@ -104,6 +108,11 @@ impl Volatile {
pub(crate) fn type_info_size(&self) -> usize {
mem::size_of::<Self>()
}

/// The target type of the volatile.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[derive(Clone, Debug)]
Expand All @@ -125,6 +134,11 @@ impl Restrict {
pub(crate) fn type_info_size(&self) -> usize {
mem::size_of::<Self>()
}

/// The target type of the restrict.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand Down Expand Up @@ -156,6 +170,11 @@ impl Ptr {
btf_type,
}
}

/// The target type of the pointer.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand Down Expand Up @@ -187,6 +206,11 @@ impl Typedef {
btf_type,
}
}

/// The target type of the typedef.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand Down Expand Up @@ -276,6 +300,11 @@ impl Func {
pub(crate) fn set_linkage(&mut self, linkage: FuncLinkage) {
self.info = (self.info & 0xFFFF0000) | (linkage as u32) & 0xFFFF;
}

/// The target type of the func.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand Down Expand Up @@ -378,17 +407,23 @@ impl Int {
}
}

pub(crate) fn encoding(&self) -> IntEncoding {
/// The integer size.
pub fn size(&self) -> u32 {
self.size
}

/// The integer encoding.
pub fn encoding(&self) -> IntEncoding {
((self.data & 0x0f000000) >> 24).into()
}

pub(crate) fn offset(&self) -> u32 {
/// The offset of the integer.
pub fn offset(&self) -> u32 {
(self.data & 0x00ff0000) >> 16
}

// TODO: Remove directive this when this crate is pub
#[cfg(test)]
pub(crate) fn bits(&self) -> u32 {
/// The size of the integer in bits.
pub fn bits(&self) -> u32 {
self.data & 0x000000ff
}
}
Expand Down Expand Up @@ -563,15 +598,27 @@ impl Enum64 {
}
}
}

/// A member of a struct or union.
#[repr(C)]
#[derive(Clone, Debug)]
pub(crate) struct BtfMember {
pub struct BtfMember {
pub(crate) name_offset: u32,
pub(crate) btf_type: u32,
pub(crate) offset: u32,
}

impl BtfMember {
/// The offset of the members name in the BTF string section.
pub fn name_offset(&self) -> u32 {
self.name_offset
}

/// The type of the member.
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
#[derive(Clone, Debug)]
pub struct Struct {
Expand Down Expand Up @@ -632,7 +679,8 @@ impl Struct {
}
}

pub(crate) fn member_bit_offset(&self, member: &BtfMember) -> usize {
/// The offset of the member within the struct or union.
pub fn member_bit_offset(&self, member: &BtfMember) -> usize {
let k_flag = self.info >> 31 == 1;
let bit_offset = if k_flag {
member.offset & 0xFFFFFF
Expand All @@ -649,6 +697,21 @@ impl Struct {

size as usize
}

/// The size of the struct.
pub fn size(&self) -> u32 {
self.size
}

/// Vlen
pub fn vlen(&self) -> usize {
type_vlen(self.info)
}

/// The members of the struct.
pub fn members(&self) -> &[BtfMember] {
&self.members
}
}

#[repr(C)]
Expand Down Expand Up @@ -771,6 +834,14 @@ impl Array {
mem::size_of::<Self>()
}

pub fn index_type(&self) -> u32 {
self.array.index_type
}

pub fn len(&self) -> u32 {
self.array.len
}

#[cfg(test)]
pub(crate) fn new(name_offset: u32, element_type: u32, index_type: u32, len: u32) -> Self {
let info = (BtfKind::Array as u32) << 24;
Expand All @@ -790,8 +861,24 @@ impl Array {
#[repr(C)]
#[derive(Clone, Debug)]
pub struct BtfParam {
pub name_offset: u32,
pub btf_type: u32,
pub(crate) name_offset: u32,
pub(crate) btf_type: u32,
}

impl BtfParam {
pub fn new(name_offset: u32, btf_type: u32) -> Self {
Self {
name_offset,
btf_type,
}
}

pub fn name_offset(&self) -> u32 {
self.name_offset
}
pub fn btf_type(&self) -> u32 {
self.btf_type
}
}

#[repr(C)]
Expand Down Expand Up @@ -836,6 +923,18 @@ impl FuncProto {
mem::size_of::<Fwd>() + mem::size_of::<BtfParam>() * self.params.len()
}

pub fn return_type(&self) -> u32 {
self.return_type
}

pub fn vlen(&self) -> usize {
type_vlen(self.info)
}

pub fn params(&self) -> &[BtfParam] {
&self.params
}

pub fn new(params: Vec<BtfParam>, return_type: u32) -> Self {
let mut info = (BtfKind::FuncProto as u32) << 24;
info |= (params.len() as u32) & 0xFFFF;
Expand Down Expand Up @@ -911,14 +1010,43 @@ impl Var {
linkage,
}
}

pub fn btf_type(&self) -> u32 {
self.btf_type
}

pub fn linkage(&self) -> &VarLinkage {
&self.linkage
}
}

#[repr(C)]
#[derive(Clone, Debug)]
pub struct DataSecEntry {
pub btf_type: u32,
pub offset: u32,
pub size: u32,
pub(crate) btf_type: u32,
pub(crate) offset: u32,
pub(crate) size: u32,
}

impl DataSecEntry {
pub fn new(btf_type: u32, offset: u32, size: u32) -> Self {
Self {
btf_type,
offset,
size,
}
}
pub fn btf_type(&self) -> u32 {
self.btf_type
}

pub fn offset(&self) -> u32 {
self.offset
}

pub fn size(&self) -> u32 {
self.size
}
}

#[repr(C)]
Expand Down Expand Up @@ -980,6 +1108,18 @@ impl DataSec {
entries,
}
}

pub fn size(&self) -> u32 {
self.size
}

pub fn vlen(&self) -> usize {
type_vlen(self.info)
}

pub fn entries(&self) -> &[DataSecEntry] {
&self.entries
}
}

#[repr(C)]
Expand Down Expand Up @@ -1337,7 +1477,8 @@ impl BtfType {
}
}

pub(crate) fn name_offset(&self) -> u32 {
/// Returns the name offset of the BTF type.
pub fn name_offset(&self) -> u32 {
match self {
BtfType::Unknown => 0,
BtfType::Fwd(t) => t.name_offset,
Expand All @@ -1362,7 +1503,8 @@ impl BtfType {
}
}

pub(crate) fn kind(&self) -> BtfKind {
/// Returns the kind of the BTF type.
pub fn kind(&self) -> BtfKind {
match self {
BtfType::Unknown => BtfKind::Unknown,
BtfType::Fwd(t) => t.kind(),
Expand Down
2 changes: 2 additions & 0 deletions aya-tool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ homepage.workspace = true
edition.workspace = true

[dependencies]
aya-obj = { version = "0.1.0", path = "../aya-obj", features = ["std"] }
bindgen = { workspace = true, default-features = true }
clap = { workspace = true, default-features = true, features = ["derive"] }
anyhow = { workspace = true, default-features = true }
thiserror = { workspace = true }
tempfile = { workspace = true }
object = { workspace = true }
Loading
Loading