Skip to content

Commit

Permalink
utils: add an elf module and an helper to read a .BTF section from an…
Browse files Browse the repository at this point in the history
… ELF file

This helpers is useful to extract .BTF ELF sections from kernel
binaries, e.g. vmlinux and .ko files.

Signed-off-by: Antoine Tenart <[email protected]>
  • Loading branch information
atenart committed Sep 17, 2024
1 parent fce8b48 commit 380e663
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test_task:
- rustup component add rustfmt
- rustup component add clippy
build_script: cargo build --verbose
test_script: cargo test --verbose
test_script: cargo test --verbose -F elf
check_script:
- cargo fmt --check
- cargo clippy -- -D warnings
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ maintenance = { status = "actively-developed" }
[dependencies]
anyhow = "1.0"
byteorder = "1.5"
elf = { version = "0.7", optional = true }

[dev-dependencies]
test-case = "3.2"

[features]
elf = ["dep:elf"]
test_runtime = []
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
//!
//! ### Feature flags
//!
//! - elf: Enable helpers parsing the .BTF section of ELF files in
//! `utils::elf`.
//! - test_runtime: Use the system's runtime BTF files to perform extra
//! integration tests.
Expand Down
30 changes: 30 additions & 0 deletions src/utils/elf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::{
fs::{self, File},
path::Path,
};

use anyhow::{anyhow, bail, Result};
use elf::{endian::AnyEndian, ElfStream};

/// Extract raw BTF data from the .BTF elf section of the given file. Output can
/// be used to fed `from_bytes` constructors in this library.
pub fn extract_btf_from_file<P: AsRef<Path>>(path: P) -> Result<Vec<u8>> {
let file = File::open(&path)
.map_err(|e| anyhow!("Could not open {}: {e}", path.as_ref().display()))?;
let mut elf = ElfStream::<AnyEndian, _>::open_stream(file)?;

let btf_hdr = match elf.section_header_by_name(".BTF")? {
Some(hdr) => *hdr,
None => bail!("No BTF section in {}", path.as_ref().display()),
};

let (btf, chdr) = elf.section_data(&btf_hdr)?;
if chdr.is_some() {
bail!(
"Compressed BTF sections are not supported ({})",
path.as_ref().display()
);
}

Ok(btf.to_vec())
}
2 changes: 2 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
//! use cases.
pub mod collection;
#[cfg(feature = "elf")]
pub mod elf;

0 comments on commit 380e663

Please sign in to comment.