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
5 changed files
with
287 additions
and
3 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,93 @@ | ||
use std::ffi::CStr; | ||
use std::ffi::OsStr; | ||
use std::os::fd::AsRawFd as _; | ||
use std::os::unix::ffi::OsStrExt as _; | ||
|
||
use crate::Error; | ||
use crate::ErrorExt as _; | ||
use crate::Result; | ||
|
||
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) -> Result<Btf> { | ||
let btf_fd = sys::bpf_btf_get_fd_from_id(btf_id) | ||
.with_context(|| format!("failed to retrieve BTF file descriptor for 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) | ||
.with_context(|| format!("failed to retrieve BTF information for ID {btf_id}"))?; | ||
|
||
// Now call again to retrieve the actual data. | ||
let mut btf_data = Vec::<u8>::with_capacity(btf_info.btf_size as _); | ||
// SAFETY: `btf_data` is valid for any bit pattern, so we can | ||
// adjust the vector's length to its capacity. | ||
let () = unsafe { btf_data.set_len(btf_data.capacity()) }; | ||
|
||
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) | ||
.with_context(|| format!("failed to retrieve BTF information for ID {btf_id}"))?; | ||
|
||
let header = unsafe { | ||
btf_data | ||
.as_mut_ptr() | ||
.cast::<sys::btf_header>() | ||
.read_unaligned() | ||
}; | ||
|
||
if header.magic != 0xeb9f { | ||
return Err(Error::with_unsupported(format!( | ||
"encountered unsupported BTF magic number ({:#x})", | ||
header.magic | ||
))) | ||
} | ||
|
||
if header.version != 1 { | ||
return Err(Error::with_unsupported(format!( | ||
"encountered unsupported BTF version ({})", | ||
header.version | ||
))) | ||
} | ||
|
||
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
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