forked from libbpf/blazesym
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
248 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use std::ffi::CStr; | ||
use std::ffi::OsStr; | ||
use std::io; | ||
use std::os::fd::AsRawFd as _; | ||
use std::os::unix::ffi::OsStrExt as _; | ||
use std::slice; | ||
|
||
use super::sys; | ||
|
||
|
||
/// A type encapsulating kernel provided BPF type information. | ||
/// | ||
/// <https://www.kernel.org/doc/html/latest/bpf/btf.html> | ||
pub(crate) struct Btf { | ||
/// The complete BTF data, including the "raw" header bytes. | ||
data: Vec<u8>, | ||
/// The extracted BTF header. | ||
header: sys::btf_header, | ||
} | ||
|
||
impl Btf { | ||
/// Load BTF information with the given ID from the kernel. | ||
pub fn load_from_id(btf_id: u32) -> io::Result<Btf> { | ||
// TODO: Better error chaining would be nice. | ||
let btf_fd = sys::bpf_btf_get_fd_from_id(btf_id)?; | ||
|
||
// Do a first call to retrieve the BTF size we need. | ||
let mut btf_info = sys::bpf_btf_info::default(); | ||
let () = sys::bpf_btf_get_info_from_fd(btf_fd.as_raw_fd(), &mut btf_info)?; | ||
|
||
// Now call again to retrieve the actual data. | ||
let mut btf_data = Vec::<u8>::with_capacity(btf_info.btf_size as _); | ||
let mut btf_info = sys::bpf_btf_info { | ||
btf: btf_data.as_mut_ptr() as _, | ||
btf_size: btf_data.capacity() as _, | ||
..Default::default() | ||
}; | ||
let () = sys::bpf_btf_get_info_from_fd(btf_fd.as_raw_fd(), &mut btf_info)?; | ||
let header = unsafe { | ||
btf_data | ||
.as_mut_ptr() | ||
.cast::<sys::btf_header>() | ||
.read_unaligned() | ||
}; | ||
|
||
let slf = Self { | ||
data: btf_data, | ||
header, | ||
}; | ||
Ok(slf) | ||
} | ||
|
||
/// Retrieve a slice representing the BTF string data. | ||
fn raw_strs(&self) -> &[u8] { | ||
let start = self.header.hdr_len as usize + self.header.str_off as usize; | ||
let end = start + self.header.str_len as usize; | ||
// SANITY: Sub-slice calculation is based on data provided by the | ||
// kernel, which is trusted. | ||
self.data.get(start..end).unwrap() | ||
} | ||
|
||
/// Retrieve the "name" at the given offset. | ||
pub fn name(&self, offset: u32) -> Option<&OsStr> { | ||
let name = self.raw_strs().get(offset as _..)?; | ||
// SANITY: The strings are trusted and laid out by the kernel; | ||
// each entry has to be valid or it's a bug. | ||
let name = CStr::from_bytes_until_nul(name).unwrap(); | ||
Some(OsStr::from_bytes(name.to_bytes())) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
mod btf; | ||
mod prog; | ||
mod sys; | ||
|
||
use btf::Btf; | ||
|
||
pub(super) use prog::BpfProg; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters