//! An eBPF object file parsing library with BTF and relocation support. //! //! # Status //! //! This crate includes code that started as internal API used by //! the [aya] crate. It has been split out so that it can be used by //! other projects that deal with eBPF object files. Unless you're writing //! low level eBPF plumbing tools, you should not need to use this crate //! but see the [aya] crate instead. //! //! The API as it is today has a few rough edges and is generally not as //! polished nor stable as the main [aya] crate API. As always, //! improvements welcome! //! //! [aya]: https://github.com/aya-rs/aya //! //! # Overview //! //! eBPF programs written with [libbpf] or [aya-bpf] are usually compiled //! into an ELF object file, using various sections to store information //! about the eBPF programs. //! //! `aya-obj` is a library for parsing such eBPF object files, with BTF and //! relocation support. //! //! [libbpf]: https://github.com/libbpf/libbpf //! [aya-bpf]: https://github.com/aya-rs/aya //! //! # Example //! //! This example loads a simple eBPF program and runs it with [rbpf]. //! //! ```no_run //! use aya_obj::{generated::bpf_insn, Object}; //! //! // Parse the object file //! let bytes = std::fs::read("program.o").unwrap(); //! let mut object = Object::parse(&bytes).unwrap(); //! // Relocate the programs //! #[cfg(feature = "std")] //! let text_sections = std::collections::HashSet::new(); //! #[cfg(not(feature = "std"))] //! let text_sections = hashbrown::HashSet::new(); //! object.relocate_calls(&text_sections).unwrap(); //! object.relocate_maps(std::iter::empty(), &text_sections).unwrap(); //! //! // Run with rbpf //! let function = object.functions.get(&object.programs["prog_name"].function_key()).unwrap(); //! let instructions = &function.instructions; //! let data = unsafe { //! core::slice::from_raw_parts( //! instructions.as_ptr() as *const u8, //! instructions.len() * core::mem::size_of::(), //! ) //! }; //! let vm = rbpf::EbpfVmNoData::new(Some(data)).unwrap(); //! let _return = vm.execute_program().unwrap(); //! ``` //! //! [rbpf]: https://github.com/qmonnet/rbpf #![no_std] #![doc( html_logo_url = "https://aya-rs.dev/assets/images/crabby.svg", html_favicon_url = "https://aya-rs.dev/assets/images/crabby.svg" )] #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(clippy::all, missing_docs)] #![allow(clippy::missing_safety_doc, clippy::len_without_is_empty)] extern crate alloc; #[cfg(feature = "std")] extern crate std; #[cfg(not(feature = "std"))] mod std { pub mod error { pub use core_error::Error; } pub use core::*; pub mod os { pub mod fd { pub type RawFd = core::ffi::c_int; } } } pub mod btf; pub mod generated; pub mod maps; pub mod obj; pub mod programs; pub mod relocation; mod util; pub use maps::Map; pub use obj::*; /// An error returned from the verifier. /// /// Provides a [`Debug`] implementation that doesn't escape newlines. pub struct VerifierLog(alloc::string::String); impl VerifierLog { /// Create a new verifier log. pub fn new(log: alloc::string::String) -> Self { Self(log) } } impl std::fmt::Debug for VerifierLog { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let Self(log) = self; f.write_str(log) } } impl std::fmt::Display for VerifierLog { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { ::fmt(self, f) } }