diff --git a/aya-obj/src/btf/btf.rs b/aya-obj/src/btf/btf.rs index ef7217ad..52b04daa 100644 --- a/aya-obj/src/btf/btf.rs +++ b/aya-obj/src/btf/btf.rs @@ -416,6 +416,20 @@ impl Btf { self.string_at(ty.name_offset()).ok().map(String::from) } + /// Returns a type id matching the type name + pub fn id_by_type_name(&self, name: &str) -> Result { + for (type_id, ty) in self.types().enumerate() { + if self.type_name(ty)? == name { + return Ok(type_id as u32); + } + continue; + } + + Err(BtfError::UnknownBtfTypeName { + type_name: name.to_owned(), + }) + } + /// Returns a type id matching the type name and [BtfKind] pub fn id_by_type_name_kind(&self, name: &str, kind: BtfKind) -> Result { for (type_id, ty) in self.types().enumerate() { diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index f6f4fc8b..50cb9fed 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -8,6 +8,7 @@ use alloc::{ vec::Vec, }; use core::{ffi::CStr, mem, ptr, slice::from_raw_parts_mut, str::FromStr}; +use std::println; use log::debug; use object::{ diff --git a/aya-obj/src/relocation.rs b/aya-obj/src/relocation.rs index b05648ba..46639bab 100644 --- a/aya-obj/src/relocation.rs +++ b/aya-obj/src/relocation.rs @@ -2,6 +2,7 @@ use alloc::{borrow::ToOwned, collections::BTreeMap, string::String}; use core::mem; +use std::println; use log::debug; use object::{SectionIndex, SymbolKind}; @@ -108,9 +109,20 @@ impl Object { &mut self, maps: I, text_sections: &HashSet, + ignored_maps: &HashMap, ) -> Result<(), EbpfRelocationError> { let mut maps_by_section = HashMap::new(); let mut maps_by_symbol = HashMap::new(); + let mut ignored_by_section = HashSet::new(); + let mut ignored_by_symbol = HashSet::new(); + + for (name, map) in ignored_maps { + ignored_by_section.insert(map.section_index()); + if let Some(index) = map.symbol_index() { + ignored_by_symbol.insert(index); + } + } + for (name, fd, map) in maps { maps_by_section.insert(map.section_index(), (name, fd, map)); if let Some(index) = map.symbol_index() { @@ -127,6 +139,8 @@ impl Object { &maps_by_symbol, &self.symbol_table, text_sections, + &ignored_by_section, + &ignored_by_symbol, ) .map_err(|error| EbpfRelocationError { function: function.name.clone(), @@ -176,6 +190,7 @@ impl Object { } } +#[allow(clippy::too_many_arguments)] fn relocate_maps<'a, I: Iterator>( fun: &mut Function, relocations: I, @@ -183,6 +198,8 @@ fn relocate_maps<'a, I: Iterator>( maps_by_symbol: &HashMap, symbol_table: &HashMap, text_sections: &HashSet, + ignored_by_section: &HashSet, + ignored_by_symbol: &HashSet, ) -> Result<(), RelocationError> { let section_offset = fun.section_offset; let instructions = &mut fun.instructions; @@ -212,6 +229,7 @@ fn relocate_maps<'a, I: Iterator>( index: rel.symbol_index, })?; + let Some(section_index) = sym.section_index else { // this is not a map relocation continue; @@ -222,7 +240,9 @@ fn relocate_maps<'a, I: Iterator>( continue; } - let (_name, fd, map) = if let Some(m) = maps_by_symbol.get(&rel.symbol_index) { + let (_name, fd, map) = if ignored_by_symbol.contains(&rel.symbol_index) { + continue + } else if let Some(m) = maps_by_symbol.get(&rel.symbol_index) { let map = &m.2; debug!( "relocating map by symbol index {:?}, kind {:?} at insn {ins_index} in section {}", @@ -232,6 +252,8 @@ fn relocate_maps<'a, I: Iterator>( ); debug_assert_eq!(map.symbol_index().unwrap(), rel.symbol_index); m + } else if ignored_by_section.contains(§ion_index) { + continue } else { let Some(m) = maps_by_section.get(§ion_index) else { debug!("failed relocating map by section index {}", section_index); @@ -580,6 +602,8 @@ mod test { &maps_by_symbol, &symbol_table, &HashSet::new(), + &HashSet::new(), + &HashSet::new(), ) .unwrap(); @@ -636,6 +660,8 @@ mod test { &maps_by_symbol, &symbol_table, &HashSet::new(), + &HashSet::new(), + &HashSet::new(), ) .unwrap(); @@ -675,6 +701,8 @@ mod test { &maps_by_symbol, &symbol_table, &HashSet::new(), + &HashSet::new(), + &HashSet::new(), ) .unwrap(); @@ -731,6 +759,8 @@ mod test { &maps_by_symbol, &symbol_table, &HashSet::new(), + &HashSet::new(), + &HashSet::new(), ) .unwrap(); diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 42a9a489..977fff96 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -3,7 +3,7 @@ use std::{ collections::{HashMap, HashSet}, fs, io, os::{ - fd::{AsFd as _, AsRawFd as _, OwnedFd}, + fd::{AsFd as _, AsRawFd as _, FromRawFd, OwnedFd}, raw::c_int, }, path::{Path, PathBuf}, @@ -21,10 +21,10 @@ use thiserror::Error; use crate::{ generated::{ - bpf_map_type, bpf_map_type::*, AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE, + bpf_map_type::{self, *}, AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE, AYA_PERF_EVENT_IOC_SET_BPF, }, - maps::{Map, MapData, MapError}, + maps::{Map, MapData, MapError, MapFd}, obj::{ btf::{Btf, BtfError}, Object, ParseError, ProgramSection, @@ -137,6 +137,7 @@ pub struct EbpfLoader<'a> { extensions: HashSet<&'a str>, verifier_log_level: VerifierLogLevel, allow_unsupported_maps: bool, + deactivate_maps: HashSet, } /// Builder style API for advanced loading of eBPF programs. @@ -175,6 +176,7 @@ impl<'a> EbpfLoader<'a> { extensions: HashSet::new(), verifier_log_level: VerifierLogLevel::default(), allow_unsupported_maps: false, + deactivate_maps: HashSet::new(), } } @@ -224,6 +226,12 @@ impl<'a> EbpfLoader<'a> { self } + /// Documentaaaaaaaaaaaaation + pub fn deactivate_maps(&mut self, set: HashSet) -> &mut Self { + self.deactivate_maps = set; + self + } + /// Sets the base directory path for pinned maps. /// /// Pinned maps will be loaded from `path/MAP_NAME`. @@ -394,9 +402,9 @@ impl<'a> EbpfLoader<'a> { extensions, verifier_log_level, allow_unsupported_maps, + deactivate_maps, } = self; let mut obj = Object::parse(data)?; - obj.patch_map_data(globals.clone())?; let btf_fd = if let Some(features) = &FEATURES.btf() { if let Some(btf) = obj.fixup_and_sanitize_btf(features)? { @@ -459,12 +467,20 @@ impl<'a> EbpfLoader<'a> { obj.relocate_btf(btf)?; } let mut maps = HashMap::new(); + let mut ignored_maps = HashMap::new(); + for (name, mut obj) in obj.maps.drain() { if let (false, EbpfSectionKind::Bss | EbpfSectionKind::Data | EbpfSectionKind::Rodata) = (FEATURES.bpf_global_data(), obj.section_kind()) { continue; } + + if deactivate_maps.contains(&obj.map_type().try_into().map_err(|_| EbpfError::MapError(MapError::InvalidMapType { map_type: obj.map_type() }))?) { + ignored_maps.insert(name, obj); + continue; + } + let num_cpus = || -> Result { Ok(possible_cpus() .map_err(|error| EbpfError::FileError { @@ -498,17 +514,16 @@ impl<'a> EbpfLoader<'a> { PinningType::ByName => { // pin maps in /sys/fs/bpf by default to align with libbpf // behavior https://github.com/libbpf/libbpf/blob/v1.2.2/src/libbpf.c#L2161. - let path = map_pin_path - .as_deref() - .unwrap_or_else(|| Path::new("/sys/fs/bpf")); + let path: &Path = map_pin_path + .as_deref() + .unwrap_or_else(|| Path::new("/sys/fs/bpf")); - MapData::create_pinned_by_name(path, obj, &name, btf_fd)? + MapData::create_pinned_by_name(path, obj, &name, btf_fd)? } }; map.finalize()?; maps.insert(name, map); } - let text_sections = obj .functions .keys() @@ -519,6 +534,7 @@ impl<'a> EbpfLoader<'a> { maps.iter() .map(|(s, data)| (s.as_str(), data.fd().as_fd().as_raw_fd(), data.obj())), &text_sections, + &ignored_maps, )?; obj.relocate_calls(&text_sections)?; obj.sanitize_functions(&FEATURES);