diff --git a/aya/Cargo.toml b/aya/Cargo.toml index d0bd3bd0..a69aec84 100644 --- a/aya/Cargo.toml +++ b/aya/Cargo.toml @@ -21,7 +21,7 @@ bytes = { workspace = true } lazy_static = { workspace = true } libc = { workspace = true } log = { workspace = true } -object = { workspace = true, features = ["elf", "read_core", "std"] } +object = { workspace = true, features = ["elf", "read_core", "std", "write"] } thiserror = { workspace = true } tokio = { workspace = true, features = ["rt"], optional = true } diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index 1c0a0ce0..74298219 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -6,13 +6,13 @@ use std::{ fs, io::{self, BufRead, Cursor, Read}, mem, - os::{fd::AsFd as _, raw::c_char}, + os::{fd::AsFd as _, raw::c_char, unix::ffi::OsStrExt}, path::{Path, PathBuf}, sync::Arc, }; use libc::pid_t; -use object::{Object, ObjectSection, ObjectSymbol}; +use object::{Object, ObjectSection, ObjectSymbol, Symbol}; use thiserror::Error; use crate::{ @@ -432,17 +432,103 @@ enum ResolveSymbolError { #[error("symbol `{0}` in section `{1:?}` which has no offset")] SectionFileRangeNone(String, Result), + + #[error("failed to access debuglink file `{0}`: `{1}`")] + DebuglinkAccessError(String, io::Error), + + #[error("symbol `{0}` not found, mismatched build IDs in main and debug files")] + BuildIdMismatch(String), +} + +fn construct_debuglink_path( + filename: &[u8], + main_path: &Path, +) -> Result { + let filename_str = OsStr::from_bytes(filename); + let debuglink_path = Path::new(filename_str); + + let resolved_path = if debuglink_path.is_relative() { + // If the debug path is relative, resolve it against the parent of the main path + main_path.parent().map_or_else( + || PathBuf::from(debuglink_path), // Use original if no parent + |parent| parent.join(debuglink_path), + ) + } else { + // If the path is not relative, just use original + PathBuf::from(debuglink_path) + }; + + Ok(resolved_path) +} + +fn verify_build_ids<'a>( + main_obj: &'a object::File<'a>, + debug_obj: &'a object::File<'a>, + symbol_name: &str, +) -> Result<(), ResolveSymbolError> { + let main_build_id = main_obj.build_id().ok().flatten(); + let debug_build_id = debug_obj.build_id().ok().flatten(); + + match (debug_build_id, main_build_id) { + (Some(debug_build_id), Some(main_build_id)) => { + // Only perform a comparison if both build IDs are present + if debug_build_id != main_build_id { + return Err(ResolveSymbolError::BuildIdMismatch(symbol_name.to_owned())); + } + Ok(()) + } + _ => Ok(()), + } +} + +fn find_debug_path_in_object<'a>( + obj: &'a object::File<'a>, + main_path: &Path, + symbol: &str, +) -> Result { + match obj.gnu_debuglink() { + Ok(Some((filename, _))) => construct_debuglink_path(filename, main_path), + Ok(None) => Err(ResolveSymbolError::Unknown(symbol.to_string())), + Err(err) => Err(ResolveSymbolError::Object(err)), + } +} + +fn find_symbol_in_object<'a>(obj: &'a object::File<'a>, symbol: &str) -> Option> { + obj.dynamic_symbols() + .chain(obj.symbols()) + .find(|sym| sym.name().map(|name| name == symbol).unwrap_or(false)) } fn resolve_symbol(path: &Path, symbol: &str) -> Result { let data = fs::read(path)?; let obj = object::read::File::parse(&*data)?; - let sym = obj - .dynamic_symbols() - .chain(obj.symbols()) - .find(|sym| sym.name().map(|name| name == symbol).unwrap_or(false)) - .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string()))?; + let mut debug_data = Vec::default(); + let mut debug_obj_keeper = None; + + let sym = find_symbol_in_object(&obj, symbol).map_or_else( + || { + // Only search in the debug object if the symbol was not found in the main object + let debug_path = find_debug_path_in_object(&obj, path, symbol)?; + debug_data = fs::read(&debug_path).map_err(|e| { + ResolveSymbolError::DebuglinkAccessError( + debug_path + .to_str() + .unwrap_or("Debuglink path missing") + .to_string(), + e, + ) + })?; + let debug_obj = object::read::File::parse(&*debug_data)?; + + verify_build_ids(&obj, &debug_obj, symbol)?; + + debug_obj_keeper = Some(debug_obj); + find_symbol_in_object(debug_obj_keeper.as_ref().unwrap(), symbol) + .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string())) + }, + Ok, + )?; let needs_addr_translation = matches!( obj.kind(), @@ -464,3 +550,174 @@ fn resolve_symbol(path: &Path, symbol: &str) -> Result Ok(sym.address() - section.address() + offset) } } + +#[cfg(test)] +mod tests { + + use object::{write::SectionKind, Architecture, BinaryFormat, Endianness}; + + use super::*; + + #[test] + fn test_relative_path_with_parent() { + let filename = b"debug_info"; + let main_path = Path::new("/usr/lib/main_binary"); + let expected = Path::new("/usr/lib/debug_info"); + + let result = construct_debuglink_path(filename, main_path).unwrap(); + assert_eq!( + result, expected, + "The debug path should resolve relative to the main path's parent" + ); + } + + #[test] + fn test_relative_path_without_parent() { + let filename = b"debug_info"; + let main_path = Path::new("main_binary"); + let expected = Path::new("debug_info"); + + let result = construct_debuglink_path(filename, main_path).unwrap(); + assert_eq!( + result, expected, + "The debug path should be the original path as there is no parent" + ); + } + + #[test] + fn test_absolute_path() { + let filename = b"/absolute/path/to/debug_info"; + let main_path = Path::new("/usr/lib/main_binary"); + let expected = Path::new("/absolute/path/to/debug_info"); + + let result = construct_debuglink_path(filename, main_path).unwrap(); + assert_eq!( + result, expected, + "The debug path should be the same as the input absolute path" + ); + } + + fn create_elf_with_debuglink( + debug_filename: &[u8], + crc: u32, + ) -> Result, object::write::Error> { + let mut obj = + object::write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little); + + let section_name = b".gnu_debuglink"; + + let section_id = obj.add_section(vec![], section_name.to_vec(), SectionKind::Note); + + let mut debuglink_data = Vec::new(); + + debuglink_data.extend_from_slice(debug_filename); + debuglink_data.push(0); // Null terminator + + while debuglink_data.len() % 4 != 0 { + debuglink_data.push(0); + } + + debuglink_data.extend(&crc.to_le_bytes()); + + obj.append_section_data(section_id, &debuglink_data, 4 /* align */); + + obj.write() + } + + fn create_elf_with_build_id(build_id: &[u8]) -> Result, object::write::Error> { + let mut obj = + object::write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little); + + let section_name = b".note.gnu.build-id"; + + let section_id = obj.add_section(vec![], section_name.to_vec(), SectionKind::Note); + + let mut note_data = Vec::new(); + let build_id_name = b"GNU"; + + note_data.extend(&(build_id_name.len() as u32 + 1).to_le_bytes()); + note_data.extend(&(build_id.len() as u32).to_le_bytes()); + note_data.extend(&3u32.to_le_bytes()); + + note_data.extend_from_slice(build_id_name); + note_data.push(0); // Null terminator + note_data.extend_from_slice(build_id); + + obj.append_section_data(section_id, ¬e_data, 4 /* align */); + + obj.write() + } + + fn aligned_slice(vec: &mut Vec) -> &mut [u8] { + let alignment = 8; + + let original_size = vec.len(); + let total_size = original_size + alignment - 1; + + if vec.capacity() < total_size { + vec.reserve(total_size - vec.capacity()); + } + + if vec.len() < total_size { + vec.resize(total_size, 0); + } + + let ptr = vec.as_ptr() as usize; + + let aligned_ptr = (ptr + alignment - 1) & !(alignment - 1); + + let offset = aligned_ptr - ptr; + + if offset > 0 { + let tmp = vec.len(); + vec.copy_within(0..tmp - offset, offset); + } + + &mut vec[offset..offset + original_size] + } + + #[test] + fn test_find_debug_path_success() { + let debug_filepath = b"main.debug"; + let mut main_bytes = create_elf_with_debuglink(debug_filepath, 0x123 /* fake CRC */) + .expect("got main_bytes"); + let align_bytes = aligned_slice(&mut main_bytes); + let main_obj = object::File::parse(&*align_bytes).expect("got main obj"); + + let main_path = Path::new("/path/to/main"); + let result = find_debug_path_in_object(&main_obj, main_path, "symbol"); + + assert_eq!(result.unwrap(), Path::new("/path/to/main.debug")); + } + + #[test] + fn test_verify_build_ids_same() { + let build_id = b"test_build_id"; + let mut main_bytes = create_elf_with_build_id(build_id).expect("got main_bytes"); + let align_bytes = aligned_slice(&mut main_bytes); + let main_obj = object::File::parse(&*align_bytes).expect("got main obj"); + let debug_build_id = b"test_build_id"; + let mut debug_bytes = create_elf_with_build_id(debug_build_id).expect("got debug bytes"); + let align_bytes = aligned_slice(&mut debug_bytes); + let debug_obj = object::File::parse(&*align_bytes).expect("got debug obj"); + + assert!(verify_build_ids(&main_obj, &debug_obj, "symbol_name").is_ok()); + } + + #[test] + fn test_verify_build_ids_different() { + let build_id = b"main_build_id"; + let mut main_bytes = create_elf_with_build_id(build_id).expect("got main_bytes"); + let align_bytes = aligned_slice(&mut main_bytes); + let main_obj = object::File::parse(&*align_bytes).expect("got main obj"); + let debug_build_id = b"debug_build_id"; + let mut debug_bytes = create_elf_with_build_id(debug_build_id).expect("got debug bytes"); + let align_bytes = aligned_slice(&mut debug_bytes); + let debug_obj = object::File::parse(&*align_bytes).expect("got debug obj"); + + assert!(matches!( + verify_build_ids(&main_obj, &debug_obj, "symbol_name"), + Err(ResolveSymbolError::BuildIdMismatch(_)) + )); + } +} diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 2496b411..dfb86b0a 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -469,6 +469,10 @@ impl core::marker::Sync for aya::maps::perf::Events impl core::marker::Unpin for aya::maps::perf::Events impl core::panic::unwind_safe::RefUnwindSafe for aya::maps::perf::Events impl core::panic::unwind_safe::UnwindSafe for aya::maps::perf::Events +impl equivalent::Equivalent for aya::maps::perf::Events where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::maps::perf::Events::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::maps::perf::Events where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::maps::perf::Events::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::maps::perf::Events where U: core::convert::From pub fn aya::maps::perf::Events::into(self) -> U impl core::convert::TryFrom for aya::maps::perf::Events where U: core::convert::Into @@ -2531,6 +2535,10 @@ impl core::marker::Sync for aya::programs::cgroup_device::CgroupDeviceLinkId impl core::marker::Unpin for aya::programs::cgroup_device::CgroupDeviceLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_device::CgroupDeviceLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_device::CgroupDeviceLinkId +impl equivalent::Equivalent for aya::programs::cgroup_device::CgroupDeviceLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_device::CgroupDeviceLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_device::CgroupDeviceLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_device::CgroupDeviceLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_device::CgroupDeviceLinkId where U: core::convert::From pub fn aya::programs::cgroup_device::CgroupDeviceLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_device::CgroupDeviceLinkId where U: core::convert::Into @@ -2677,6 +2685,10 @@ impl core::marker::Sync for aya::programs::cgroup_skb::CgroupSkbLinkId impl core::marker::Unpin for aya::programs::cgroup_skb::CgroupSkbLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_skb::CgroupSkbLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_skb::CgroupSkbLinkId +impl equivalent::Equivalent for aya::programs::cgroup_skb::CgroupSkbLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_skb::CgroupSkbLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_skb::CgroupSkbLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_skb::CgroupSkbLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_skb::CgroupSkbLinkId where U: core::convert::From pub fn aya::programs::cgroup_skb::CgroupSkbLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_skb::CgroupSkbLinkId where U: core::convert::Into @@ -2789,6 +2801,10 @@ impl core::marker::Sync for aya::programs::cgroup_sock::CgroupSockLinkId impl core::marker::Unpin for aya::programs::cgroup_sock::CgroupSockLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_sock::CgroupSockLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_sock::CgroupSockLinkId +impl equivalent::Equivalent for aya::programs::cgroup_sock::CgroupSockLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sock::CgroupSockLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_sock::CgroupSockLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sock::CgroupSockLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_sock::CgroupSockLinkId where U: core::convert::From pub fn aya::programs::cgroup_sock::CgroupSockLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_sock::CgroupSockLinkId where U: core::convert::Into @@ -2901,6 +2917,10 @@ impl core::marker::Sync for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkI impl core::marker::Unpin for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId +impl equivalent::Equivalent for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId where U: core::convert::From pub fn aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId where U: core::convert::Into @@ -3013,6 +3033,10 @@ impl core::marker::Sync for aya::programs::cgroup_sockopt::CgroupSockoptLinkId impl core::marker::Unpin for aya::programs::cgroup_sockopt::CgroupSockoptLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_sockopt::CgroupSockoptLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_sockopt::CgroupSockoptLinkId +impl equivalent::Equivalent for aya::programs::cgroup_sockopt::CgroupSockoptLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sockopt::CgroupSockoptLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_sockopt::CgroupSockoptLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sockopt::CgroupSockoptLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_sockopt::CgroupSockoptLinkId where U: core::convert::From pub fn aya::programs::cgroup_sockopt::CgroupSockoptLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_sockopt::CgroupSockoptLinkId where U: core::convert::Into @@ -3125,6 +3149,10 @@ impl core::marker::Sync for aya::programs::cgroup_sysctl::CgroupSysctlLinkId impl core::marker::Unpin for aya::programs::cgroup_sysctl::CgroupSysctlLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::cgroup_sysctl::CgroupSysctlLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::cgroup_sysctl::CgroupSysctlLinkId +impl equivalent::Equivalent for aya::programs::cgroup_sysctl::CgroupSysctlLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sysctl::CgroupSysctlLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::cgroup_sysctl::CgroupSysctlLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::cgroup_sysctl::CgroupSysctlLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::cgroup_sysctl::CgroupSysctlLinkId where U: core::convert::From pub fn aya::programs::cgroup_sysctl::CgroupSysctlLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::cgroup_sysctl::CgroupSysctlLinkId where U: core::convert::Into @@ -3275,6 +3303,10 @@ impl core::marker::Sync for aya::programs::extension::ExtensionLinkId impl core::marker::Unpin for aya::programs::extension::ExtensionLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::extension::ExtensionLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::extension::ExtensionLinkId +impl equivalent::Equivalent for aya::programs::extension::ExtensionLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::extension::ExtensionLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::extension::ExtensionLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::extension::ExtensionLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::extension::ExtensionLinkId where U: core::convert::From pub fn aya::programs::extension::ExtensionLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::extension::ExtensionLinkId where U: core::convert::Into @@ -3391,6 +3423,10 @@ impl core::marker::Sync for aya::programs::fentry::FEntryLinkId impl core::marker::Unpin for aya::programs::fentry::FEntryLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::fentry::FEntryLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::fentry::FEntryLinkId +impl equivalent::Equivalent for aya::programs::fentry::FEntryLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::fentry::FEntryLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::fentry::FEntryLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::fentry::FEntryLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::fentry::FEntryLinkId where U: core::convert::From pub fn aya::programs::fentry::FEntryLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::fentry::FEntryLinkId where U: core::convert::Into @@ -3507,6 +3543,10 @@ impl core::marker::Sync for aya::programs::fexit::FExitLinkId impl core::marker::Unpin for aya::programs::fexit::FExitLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::fexit::FExitLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::fexit::FExitLinkId +impl equivalent::Equivalent for aya::programs::fexit::FExitLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::fexit::FExitLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::fexit::FExitLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::fexit::FExitLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::fexit::FExitLinkId where U: core::convert::From pub fn aya::programs::fexit::FExitLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::fexit::FExitLinkId where U: core::convert::Into @@ -3661,6 +3701,10 @@ impl core::marker::Sync for aya::programs::kprobe::KProbeLinkId impl core::marker::Unpin for aya::programs::kprobe::KProbeLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::kprobe::KProbeLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::kprobe::KProbeLinkId +impl equivalent::Equivalent for aya::programs::kprobe::KProbeLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::kprobe::KProbeLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::kprobe::KProbeLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::kprobe::KProbeLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::kprobe::KProbeLinkId where U: core::convert::From pub fn aya::programs::kprobe::KProbeLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::kprobe::KProbeLinkId where U: core::convert::Into @@ -3817,6 +3861,10 @@ impl core::marker::Sync for aya::programs::links::FdLinkId impl core::marker::Unpin for aya::programs::links::FdLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::links::FdLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::links::FdLinkId +impl equivalent::Equivalent for aya::programs::links::FdLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::links::FdLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::links::FdLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::links::FdLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::links::FdLinkId where U: core::convert::From pub fn aya::programs::links::FdLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::links::FdLinkId where U: core::convert::Into @@ -3919,6 +3967,10 @@ impl core::marker::Sync for aya::programs::links::ProgAttachLinkId impl core::marker::Unpin for aya::programs::links::ProgAttachLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::links::ProgAttachLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::links::ProgAttachLinkId +impl equivalent::Equivalent for aya::programs::links::ProgAttachLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::links::ProgAttachLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::links::ProgAttachLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::links::ProgAttachLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::links::ProgAttachLinkId where U: core::convert::From pub fn aya::programs::links::ProgAttachLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::links::ProgAttachLinkId where U: core::convert::Into @@ -4094,6 +4146,10 @@ impl core::marker::Sync for aya::programs::lirc_mode2::LircLinkId impl core::marker::Unpin for aya::programs::lirc_mode2::LircLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lirc_mode2::LircLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::lirc_mode2::LircLinkId +impl equivalent::Equivalent for aya::programs::lirc_mode2::LircLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::lirc_mode2::LircLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::lirc_mode2::LircLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::lirc_mode2::LircLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::lirc_mode2::LircLinkId where U: core::convert::From pub fn aya::programs::lirc_mode2::LircLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::lirc_mode2::LircLinkId where U: core::convert::Into @@ -4260,6 +4316,10 @@ impl core::marker::Sync for aya::programs::lsm::LsmLinkId impl core::marker::Unpin for aya::programs::lsm::LsmLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lsm::LsmLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::lsm::LsmLinkId +impl equivalent::Equivalent for aya::programs::lsm::LsmLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::lsm::LsmLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::lsm::LsmLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::lsm::LsmLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::lsm::LsmLinkId where U: core::convert::From pub fn aya::programs::lsm::LsmLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::lsm::LsmLinkId where U: core::convert::Into @@ -4321,6 +4381,10 @@ impl core::marker::Sync for aya::programs::perf_attach::PerfLinkId impl core::marker::Unpin for aya::programs::perf_attach::PerfLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_attach::PerfLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_attach::PerfLinkId +impl equivalent::Equivalent for aya::programs::perf_attach::PerfLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::perf_attach::PerfLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::perf_attach::PerfLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::perf_attach::PerfLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::perf_attach::PerfLinkId where U: core::convert::From pub fn aya::programs::perf_attach::PerfLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::perf_attach::PerfLinkId where U: core::convert::Into @@ -4555,6 +4619,10 @@ impl core::marker::Sync for aya::programs::perf_event::PerfEventLinkId impl core::marker::Unpin for aya::programs::perf_event::PerfEventLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfEventLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfEventLinkId +impl equivalent::Equivalent for aya::programs::perf_event::PerfEventLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::perf_event::PerfEventLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::perf_event::PerfEventLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::perf_event::PerfEventLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::perf_event::PerfEventLinkId where U: core::convert::From pub fn aya::programs::perf_event::PerfEventLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::perf_event::PerfEventLinkId where U: core::convert::Into @@ -4671,6 +4739,10 @@ impl core::marker::Sync for aya::programs::raw_trace_point::RawTracePointLinkId impl core::marker::Unpin for aya::programs::raw_trace_point::RawTracePointLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::raw_trace_point::RawTracePointLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::raw_trace_point::RawTracePointLinkId +impl equivalent::Equivalent for aya::programs::raw_trace_point::RawTracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::raw_trace_point::RawTracePointLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::raw_trace_point::RawTracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::raw_trace_point::RawTracePointLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::raw_trace_point::RawTracePointLinkId where U: core::convert::From pub fn aya::programs::raw_trace_point::RawTracePointLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::raw_trace_point::RawTracePointLinkId where U: core::convert::Into @@ -4787,6 +4859,10 @@ impl core::marker::Sync for aya::programs::sk_lookup::SkLookupLinkId impl core::marker::Unpin for aya::programs::sk_lookup::SkLookupLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::sk_lookup::SkLookupLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::sk_lookup::SkLookupLinkId +impl equivalent::Equivalent for aya::programs::sk_lookup::SkLookupLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_lookup::SkLookupLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::sk_lookup::SkLookupLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_lookup::SkLookupLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::sk_lookup::SkLookupLinkId where U: core::convert::From pub fn aya::programs::sk_lookup::SkLookupLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::sk_lookup::SkLookupLinkId where U: core::convert::Into @@ -4903,6 +4979,10 @@ impl core::marker::Sync for aya::programs::sk_msg::SkMsgLinkId impl core::marker::Unpin for aya::programs::sk_msg::SkMsgLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::sk_msg::SkMsgLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::sk_msg::SkMsgLinkId +impl equivalent::Equivalent for aya::programs::sk_msg::SkMsgLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_msg::SkMsgLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::sk_msg::SkMsgLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_msg::SkMsgLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::sk_msg::SkMsgLinkId where U: core::convert::From pub fn aya::programs::sk_msg::SkMsgLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::sk_msg::SkMsgLinkId where U: core::convert::Into @@ -5052,6 +5132,10 @@ impl core::marker::Sync for aya::programs::sk_skb::SkSkbLinkId impl core::marker::Unpin for aya::programs::sk_skb::SkSkbLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::sk_skb::SkSkbLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::sk_skb::SkSkbLinkId +impl equivalent::Equivalent for aya::programs::sk_skb::SkSkbLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_skb::SkSkbLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::sk_skb::SkSkbLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sk_skb::SkSkbLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::sk_skb::SkSkbLinkId where U: core::convert::From pub fn aya::programs::sk_skb::SkSkbLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::sk_skb::SkSkbLinkId where U: core::convert::Into @@ -5168,6 +5252,10 @@ impl core::marker::Sync for aya::programs::sock_ops::SockOpsLinkId impl core::marker::Unpin for aya::programs::sock_ops::SockOpsLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::sock_ops::SockOpsLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::sock_ops::SockOpsLinkId +impl equivalent::Equivalent for aya::programs::sock_ops::SockOpsLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sock_ops::SockOpsLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::sock_ops::SockOpsLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::sock_ops::SockOpsLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::sock_ops::SockOpsLinkId where U: core::convert::From pub fn aya::programs::sock_ops::SockOpsLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::sock_ops::SockOpsLinkId where U: core::convert::Into @@ -5313,6 +5401,10 @@ impl core::marker::Sync for aya::programs::socket_filter::SocketFilterLinkId impl core::marker::Unpin for aya::programs::socket_filter::SocketFilterLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::socket_filter::SocketFilterLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::socket_filter::SocketFilterLinkId +impl equivalent::Equivalent for aya::programs::socket_filter::SocketFilterLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::socket_filter::SocketFilterLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::socket_filter::SocketFilterLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::socket_filter::SocketFilterLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::socket_filter::SocketFilterLinkId where U: core::convert::From pub fn aya::programs::socket_filter::SocketFilterLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::socket_filter::SocketFilterLinkId where U: core::convert::Into @@ -5351,6 +5443,10 @@ impl core::marker::Sync for aya::programs::tc::TcAttachType impl core::marker::Unpin for aya::programs::tc::TcAttachType impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::tc::TcAttachType impl core::panic::unwind_safe::UnwindSafe for aya::programs::tc::TcAttachType +impl equivalent::Equivalent for aya::programs::tc::TcAttachType where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::TcAttachType::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::tc::TcAttachType where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::TcAttachType::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::tc::TcAttachType where U: core::convert::From pub fn aya::programs::tc::TcAttachType::into(self) -> U impl core::convert::TryFrom for aya::programs::tc::TcAttachType where U: core::convert::Into @@ -5508,6 +5604,10 @@ impl core::marker::Sync for aya::programs::tc::SchedClassifierLinkId impl core::marker::Unpin for aya::programs::tc::SchedClassifierLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::tc::SchedClassifierLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::tc::SchedClassifierLinkId +impl equivalent::Equivalent for aya::programs::tc::SchedClassifierLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::SchedClassifierLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::tc::SchedClassifierLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::SchedClassifierLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::tc::SchedClassifierLinkId where U: core::convert::From pub fn aya::programs::tc::SchedClassifierLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::tc::SchedClassifierLinkId where U: core::convert::Into @@ -5653,6 +5753,10 @@ impl core::marker::Sync for aya::programs::tp_btf::BtfTracePointLinkId impl core::marker::Unpin for aya::programs::tp_btf::BtfTracePointLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::tp_btf::BtfTracePointLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::tp_btf::BtfTracePointLinkId +impl equivalent::Equivalent for aya::programs::tp_btf::BtfTracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tp_btf::BtfTracePointLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::tp_btf::BtfTracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tp_btf::BtfTracePointLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::tp_btf::BtfTracePointLinkId where U: core::convert::From pub fn aya::programs::tp_btf::BtfTracePointLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::tp_btf::BtfTracePointLinkId where U: core::convert::Into @@ -5807,6 +5911,10 @@ impl core::marker::Sync for aya::programs::trace_point::TracePointLinkId impl core::marker::Unpin for aya::programs::trace_point::TracePointLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::trace_point::TracePointLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::trace_point::TracePointLinkId +impl equivalent::Equivalent for aya::programs::trace_point::TracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::trace_point::TracePointLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::trace_point::TracePointLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::trace_point::TracePointLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::trace_point::TracePointLinkId where U: core::convert::From pub fn aya::programs::trace_point::TracePointLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::trace_point::TracePointLinkId where U: core::convert::Into @@ -5968,6 +6076,10 @@ impl core::marker::Sync for aya::programs::uprobe::UProbeLinkId impl core::marker::Unpin for aya::programs::uprobe::UProbeLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::uprobe::UProbeLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::uprobe::UProbeLinkId +impl equivalent::Equivalent for aya::programs::uprobe::UProbeLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::uprobe::UProbeLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::uprobe::UProbeLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::uprobe::UProbeLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::uprobe::UProbeLinkId where U: core::convert::From pub fn aya::programs::uprobe::UProbeLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::uprobe::UProbeLinkId where U: core::convert::Into @@ -6233,6 +6345,10 @@ impl core::marker::Sync for aya::programs::xdp::XdpLinkId impl core::marker::Unpin for aya::programs::xdp::XdpLinkId impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::xdp::XdpLinkId impl core::panic::unwind_safe::UnwindSafe for aya::programs::xdp::XdpLinkId +impl equivalent::Equivalent for aya::programs::xdp::XdpLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::xdp::XdpLinkId::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::xdp::XdpLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::xdp::XdpLinkId::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::xdp::XdpLinkId where U: core::convert::From pub fn aya::programs::xdp::XdpLinkId::into(self) -> U impl core::convert::TryFrom for aya::programs::xdp::XdpLinkId where U: core::convert::Into @@ -6864,6 +6980,10 @@ impl core::marker::Sync for aya::programs::tc::TcAttachType impl core::marker::Unpin for aya::programs::tc::TcAttachType impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::tc::TcAttachType impl core::panic::unwind_safe::UnwindSafe for aya::programs::tc::TcAttachType +impl equivalent::Equivalent for aya::programs::tc::TcAttachType where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::TcAttachType::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::programs::tc::TcAttachType where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::tc::TcAttachType::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::programs::tc::TcAttachType where U: core::convert::From pub fn aya::programs::tc::TcAttachType::into(self) -> U impl core::convert::TryFrom for aya::programs::tc::TcAttachType where U: core::convert::Into @@ -8528,6 +8648,10 @@ impl core::marker::Sync for aya::util::KernelVersion impl core::marker::Unpin for aya::util::KernelVersion impl core::panic::unwind_safe::RefUnwindSafe for aya::util::KernelVersion impl core::panic::unwind_safe::UnwindSafe for aya::util::KernelVersion +impl equivalent::Equivalent for aya::util::KernelVersion where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::util::KernelVersion::equivalent(&self, key: &K) -> bool +impl hashbrown::Equivalent for aya::util::KernelVersion where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::util::KernelVersion::equivalent(&self, key: &K) -> bool impl core::convert::Into for aya::util::KernelVersion where U: core::convert::From pub fn aya::util::KernelVersion::into(self) -> U impl core::convert::TryFrom for aya::util::KernelVersion where U: core::convert::Into