diff --git a/.github/scripts/download_kernel_images.sh b/.github/scripts/download_kernel_images.sh index c86c6ca7..eab4e8a3 100755 --- a/.github/scripts/download_kernel_images.sh +++ b/.github/scripts/download_kernel_images.sh @@ -27,20 +27,22 @@ for VERSION in "${VERSIONS[@]}"; do FILES+=("$match") # The debug package contains the actual System.map. Debian has transitioned - # between -dbg and -dbgsym suffixes, so try both. - DEBUG_REGEX_BASE="linux-image-${VERSION//./\\.}\\.[0-9]+(-[0-9]+)?(\+bpo|\+deb[0-9]+)?-cloud-${ARCHITECTURE}-" - debug_match="" - for debug_suffix in dbg dbgsym; do - regex="${DEBUG_REGEX_BASE}${debug_suffix}_.*\\.deb" - debug_match=$(printf '%s\n' "$URLS" | grep -E "$regex" | sort -V | tail -n1 || true) - if [[ -n "$debug_match" ]]; then - break - fi - done - if [[ -z "$debug_match" ]]; then - printf 'Failed to locate debug package for VERSION=%s (tried dbg/dbgsym)\n' "$VERSION" >&2 + # between -dbg and -dbgsym suffixes, so match either for the specific kernel + # we just selected. + kernel_basename=$(basename "$match") + kernel_prefix=${kernel_basename%%_*} + kernel_suffix=${kernel_basename#${kernel_prefix}_} + base_prefix=${kernel_prefix%-unsigned} + + base_prefix_regex=$(printf '%s\n' "$base_prefix" | sed 's/[][(){}.^$*+?|\\-]/\\&/g') + kernel_suffix_regex=$(printf '%s\n' "$kernel_suffix" | sed 's/[][(){}.^$*+?|\\-]/\\&/g') + + DEBUG_REGEX="${base_prefix_regex}-dbg(sym)?_${kernel_suffix_regex}" + debug_match=$(printf '%s\n' "$URLS" | grep -E "$DEBUG_REGEX" | sort -V | tail -n1) || { + printf 'Failed to locate debug package matching %s\n%s\nVERSION=%s\nREGEX=%s\n' \ + "$kernel_basename" "$URLS" "$VERSION" "$DEBUG_REGEX" >&2 exit 1 - fi + } FILES+=("$debug_match") done diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index ddcc0f25..ec7d1520 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -236,10 +236,6 @@ pub enum ProgramError { /// An error occurred while working with Netlink. #[error(transparent)] NetlinkError(#[from] NetlinkError), - - /// The perf event breakpoint is underspecified - #[error("the breakpoint description is missing or incomplete")] - IncompleteBreakpoint, } /// A [`Program`] file descriptor. diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index ec581dc9..2e2160b3 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -3,10 +3,8 @@ use std::os::fd::AsFd as _; use aya_obj::generated::{ - HW_BREAKPOINT_EMPTY, HW_BREAKPOINT_INVALID, HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, - HW_BREAKPOINT_LEN_3, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_5, HW_BREAKPOINT_LEN_6, - HW_BREAKPOINT_LEN_7, HW_BREAKPOINT_LEN_8, HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W, - HW_BREAKPOINT_X, bpf_link_type, + HW_BREAKPOINT_LEN_1, HW_BREAKPOINT_LEN_2, HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_LEN_8, + bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT, perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, perf_type_id, @@ -21,7 +19,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, ProgramType, impl_try_into_fdlink, links::define_link_wrapper, load_program, - perf_attach::{PerfLinkIdInner, PerfLinkInner}, + perf_attach::{PerfLinkIdInner, PerfLinkInner, perf_attach}, }, sys::{SyscallError, bpf_link_get_info_by_fd, perf_event_open}, }; @@ -62,16 +60,7 @@ pub enum PerfEventConfig { }, /// A hardware breakpoint. #[doc(alias = "PERF_TYPE_BREAKPOINT")] - Breakpoint { - /// The address to set the breakpoint on - address: u64, - /// The breakpoint size. For HwBreakpointX this must be sizeof(long). For - /// all other types it should be one of HwBreakpointLen1, HwBreakpointLen2,, - /// HwBreakpointLen4 or HwBreakpointLen8. - length: PerfBreakpointSize, - /// The breakpoint type, one of HW_BREAKPOINT_{R,W,RW,X} - type_: PerfBreakpointType, - }, + Breakpoint(BreakpointConfig), /// The dynamic PMU (Performance Monitor Unit) event to report. /// /// Available PMU's may be found under `/sys/bus/event_source/devices`. @@ -290,38 +279,51 @@ impl HwCacheResult { } } -/// Type of hardware breakpoint, determines if we break on read, write, or execute. -#[repr(u32)] +/// Type of hardware breakpoint, determines if we break on read, write, or +/// execute, or if there should be no breakpoint on the given address. #[derive(Debug, Clone, Copy)] -pub enum PerfBreakpointType { - /// HW_BREAKPOINT_EMPTY +pub enum BreakpointConfig { + /// HW_BREAKPOINT_EMPTY, no breakpoint. #[doc(alias = "HW_BREAKPOINT_EMPTY")] - HwBreakpointEmpty = HW_BREAKPOINT_EMPTY, - /// HW_BREAKPOINT_R + Empty { + /// The size of the breakpoint being measured. + size: PerfBreakpointSize, + /// The address of the breakpoint. + address: u64, + }, + /// HW_BREAKPOINT_R, count when we read the memory location. #[doc(alias = "HW_BREAKPOINT_R")] - HwBreakpointR = HW_BREAKPOINT_R, - /// HW_BREAKPOINT_W + Read { + /// The size of the breakpoint being measured. + size: PerfBreakpointSize, + /// The address of the breakpoint. + address: u64, + }, + /// HW_BREAKPOINT_W, count when we write the memory location. #[doc(alias = "HW_BREAKPOINT_W")] - HwBreakpointW = HW_BREAKPOINT_W, - /// HW_BREAKPOINT_RW + Write { + /// The size of the breakpoint being measured. + size: PerfBreakpointSize, + /// The address of the breakpoint. + address: u64, + }, + /// HW_BREAKPOINT_RW, count when we read or write the memory location. #[doc(alias = "HW_BREAKPOINT_RW")] - HwBreakpointRW = HW_BREAKPOINT_RW, - /// HW_BREAKPOINT_X + ReadWrite { + /// The size of the breakpoint being measured. + size: PerfBreakpointSize, + /// The address of the breakpoint. + address: u64, + }, + /// HW_BREAKPOINT_X, count when we execute code at the memory location. #[doc(alias = "HW_BREAKPOINT_X")] - HwBreakpointX = HW_BREAKPOINT_X, - /// HW_BREAKPOINT_INVALID - #[doc(alias = "HW_BREAKPOINT_INVALID")] - HwBreakpointInvalid = HW_BREAKPOINT_INVALID, -} - -impl PerfBreakpointType { - pub(crate) const fn into_primitive(self) -> u32 { - const _: [(); 4] = [(); std::mem::size_of::()]; - self as u32 - } + Execute { + /// The address of the breakpoint. + address: u64, + }, } -/// The size of the breakpoint being measured +/// The size of the breakpoint being observed in bytes. #[repr(u64)] #[derive(Debug, Clone, Copy)] pub enum PerfBreakpointSize { @@ -331,21 +333,9 @@ pub enum PerfBreakpointSize { /// HW_BREAKPOINT_LEN_2 #[doc(alias = "HW_BREAKPOINT_LEN_2")] HwBreakpointLen2 = HW_BREAKPOINT_LEN_2 as u64, - /// HW_BREAKPOINT_LEN_3 - #[doc(alias = "HW_BREAKPOINT_LEN_3")] - HwBreakpointLen3 = HW_BREAKPOINT_LEN_3 as u64, /// HW_BREAKPOINT_LEN_4 #[doc(alias = "HW_BREAKPOINT_LEN_4")] HwBreakpointLen4 = HW_BREAKPOINT_LEN_4 as u64, - /// HW_BREAKPOINT_LEN_5 - #[doc(alias = "HW_BREAKPOINT_LEN_5")] - HwBreakpointLen5 = HW_BREAKPOINT_LEN_5 as u64, - /// HW_BREAKPOINT_LEN_6 - #[doc(alias = "HW_BREAKPOINT_LEN_6")] - HwBreakpointLen6 = HW_BREAKPOINT_LEN_6 as u64, - /// HW_BREAKPOINT_LEN_7 - #[doc(alias = "HW_BREAKPOINT_LEN_7")] - HwBreakpointLen7 = HW_BREAKPOINT_LEN_7 as u64, /// HW_BREAKPOINT_LEN_8 #[doc(alias = "HW_BREAKPOINT_LEN_8")] HwBreakpointLen8 = HW_BREAKPOINT_LEN_8 as u64, @@ -356,6 +346,16 @@ impl PerfBreakpointSize { const _: [(); 8] = [(); std::mem::size_of::()]; self as u64 } + + pub(crate) const fn from_primitive(size: u64) -> Self { + match size { + n if n == Self::HwBreakpointLen1.into_primitive() => Self::HwBreakpointLen1, + n if n == Self::HwBreakpointLen2.into_primitive() => Self::HwBreakpointLen2, + n if n == Self::HwBreakpointLen4.into_primitive() => Self::HwBreakpointLen4, + n if n == Self::HwBreakpointLen8.into_primitive() => Self::HwBreakpointLen8, + _ => panic!("invalid hardware breakpoint size"), + } + } } /// Sample Policy @@ -473,6 +473,7 @@ impl PerfEvent { let prog_fd = self.fd()?; let prog_fd = prog_fd.as_fd(); + let mut breakpoint = None; let (perf_type, config) = match perf_config { PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config), PerfEventConfig::Hardware(hw_event) => ( @@ -497,11 +498,10 @@ impl PerfEvent { | (u64::from(result.into_primitive()) << 16), ), PerfEventConfig::Raw { event_id } => (perf_type_id_to_u32(PERF_TYPE_RAW), event_id), - PerfEventConfig::Breakpoint { - address: _, - length: _, - type_: _, - } => (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0), + PerfEventConfig::Breakpoint(config) => { + breakpoint = Some(config); + (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0) + } }; let (sample_period, sample_frequency) = match sample_policy { SamplePolicy::Period(period) => (period, None), @@ -521,18 +521,16 @@ impl PerfEvent { cpu, sample_period, sample_frequency, - // wakeup=true for breakpoints, false for all other types - perf_type == perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), inherit, 0, - Some(perf_config), + breakpoint, ) .map_err(|io_error| SyscallError { call: "perf_event_open", io_error, })?; - let link = crate::programs::perf_attach(prog_fd, fd, None /* cookie */)?; + let link = perf_attach(prog_fd, fd, None /* cookie */)?; self.data.links.insert(PerfEventLink::new(link)) } } diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs index 33941598..b907f6aa 100644 --- a/aya/src/sys/perf_event.rs +++ b/aya/src/sys/perf_event.rs @@ -5,6 +5,7 @@ use std::{ }; use aya_obj::generated::{ + HW_BREAKPOINT_EMPTY, HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W, HW_BREAKPOINT_X, PERF_FLAG_FD_CLOEXEC, perf_event_attr, perf_event_sample_format::PERF_SAMPLE_RAW, perf_sw_ids::PERF_COUNT_SW_BPF_OUTPUT, @@ -13,7 +14,7 @@ use aya_obj::generated::{ use libc::pid_t; use super::{PerfEventIoctlRequest, Syscall, syscall}; -use crate::programs::perf_event::PerfEventConfig; +use crate::programs::perf_event::{BreakpointConfig, PerfBreakpointSize}; #[expect(clippy::too_many_arguments)] pub(crate) fn perf_event_open( @@ -23,10 +24,9 @@ pub(crate) fn perf_event_open( cpu: c_int, sample_period: u64, sample_frequency: Option, - wakeup: bool, inherit: bool, flags: u32, - perf_config: Option, + breakpoint: Option, ) -> io::Result { let mut attr = unsafe { mem::zeroed::() }; @@ -35,7 +35,6 @@ pub(crate) fn perf_event_open( attr.type_ = perf_type; attr.sample_type = PERF_SAMPLE_RAW as u64; attr.set_inherit(if inherit { 1 } else { 0 }); - attr.__bindgen_anon_2.wakeup_events = u32::from(wakeup); if let Some(frequency) = sample_frequency { attr.set_freq(1); @@ -44,16 +43,25 @@ pub(crate) fn perf_event_open( attr.__bindgen_anon_1.sample_period = sample_period; } - if let Some(PerfEventConfig::Breakpoint { - address, - length, - type_, - }) = perf_config - { - attr.bp_type = type_.into_primitive(); + if let Some(bp) = breakpoint { + let (type_, length, address) = match bp { + BreakpointConfig::Empty { size, address } => (HW_BREAKPOINT_EMPTY, size, address), + BreakpointConfig::Read { size, address } => (HW_BREAKPOINT_R, size, address), + BreakpointConfig::Write { size, address } => (HW_BREAKPOINT_W, size, address), + BreakpointConfig::ReadWrite { size, address } => (HW_BREAKPOINT_RW, size, address), + BreakpointConfig::Execute { address } => ( + HW_BREAKPOINT_X, + PerfBreakpointSize::from_primitive(std::mem::size_of::() as u64), + address, + ), + }; + attr.bp_type = type_; attr.__bindgen_anon_3.bp_addr = address; attr.__bindgen_anon_4.bp_len = length.into_primitive(); attr.set_precise_ip(2); + attr.__bindgen_anon_2.wakeup_events = u32::from(true); + } else { + attr.__bindgen_anon_2.wakeup_events = u32::from(false); } perf_event_sys(attr, pid, cpu, flags) @@ -68,7 +76,6 @@ pub(crate) fn perf_event_open_bpf(cpu: c_int) -> io::Result { 1, None, true, - false, PERF_FLAG_FD_CLOEXEC, None, ) diff --git a/test/integration-test/src/tests/perf_event_bp.rs b/test/integration-test/src/tests/perf_event_bp.rs index bbeb86f2..d9f56410 100644 --- a/test/integration-test/src/tests/perf_event_bp.rs +++ b/test/integration-test/src/tests/perf_event_bp.rs @@ -7,10 +7,7 @@ use aya::{ Ebpf, programs::{ PerfEventScope, SamplePolicy, - perf_event::{ - PerfBreakpointSize::HwBreakpointLen1, PerfBreakpointType::HwBreakpointRW, - PerfEventConfig, - }, + perf_event::{BreakpointConfig, PerfBreakpointSize::HwBreakpointLen1, PerfEventConfig}, }, util::online_cpus, }; @@ -72,6 +69,10 @@ fn find_kallsyms_symbol(sym: &str) -> Option { #[test_log::test] fn perf_event_bp() { let mut bpf = Ebpf::load(crate::PERF_EVENT_BP).unwrap(); + + // Search for the address of modprobe_path. Prefer to grab it directly from + // kallsyms, but if it's not there we can grab it from System.map and apply + // the kaslr offset. let attach_addr = if let Some(addr) = find_kallsyms_symbol("modprobe_path") { addr } else { @@ -91,15 +92,13 @@ fn perf_event_bp() { .unwrap(); prog.load().unwrap(); - // attach hardware breakpoint to modprobe_path global for cpu in online_cpus().unwrap() { info!("attaching to cpu {cpu}"); prog.attach( - PerfEventConfig::Breakpoint { + PerfEventConfig::Breakpoint(BreakpointConfig::ReadWrite { address: attach_addr, - length: HwBreakpointLen1, - type_: HwBreakpointRW, - }, + size: HwBreakpointLen1, + }), PerfEventScope::AllProcessesOneCpu { cpu }, SamplePolicy::Period(1), true, @@ -107,10 +106,14 @@ fn perf_event_bp() { .unwrap(); } - // trigger hardware breakpoint by reading modprobe_path via procfs - let _ = fs::read_to_string("/proc/sys/kernel/modprobe"); + // Trigger the hardware breakpoint by reading /proc/sys/kernel/modprobe, the + // sysctl connected to modprobe_path. + // + // See: https://elixir.bootlin.com/linux/v6.1.155/source/kernel/sysctl.c#L1770 + fs::read_to_string("/proc/sys/kernel/modprobe").expect("failed to read modprobe"); - // assert that the map contains an entry for this process + // Assert that the map contains an entry for this process, and that we read + // the address we expected to. let map: aya::maps::HashMap<_, u32, u64> = aya::maps::HashMap::try_from(bpf.map_mut("READERS").unwrap()).unwrap(); let tgid = std::process::id(); diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 57a32141..e6c6ba0c 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -5299,6 +5299,54 @@ pub fn aya::programs::perf_attach::PerfLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLinkId::from(t: T) -> T pub mod aya::programs::perf_event +pub enum aya::programs::perf_event::BreakpointConfig +pub aya::programs::perf_event::BreakpointConfig::Empty +pub aya::programs::perf_event::BreakpointConfig::Empty::address: u64 +pub aya::programs::perf_event::BreakpointConfig::Empty::size: aya::programs::perf_event::PerfBreakpointSize +pub aya::programs::perf_event::BreakpointConfig::Execute +pub aya::programs::perf_event::BreakpointConfig::Execute::address: u64 +pub aya::programs::perf_event::BreakpointConfig::Read +pub aya::programs::perf_event::BreakpointConfig::Read::address: u64 +pub aya::programs::perf_event::BreakpointConfig::Read::size: aya::programs::perf_event::PerfBreakpointSize +pub aya::programs::perf_event::BreakpointConfig::ReadWrite +pub aya::programs::perf_event::BreakpointConfig::ReadWrite::address: u64 +pub aya::programs::perf_event::BreakpointConfig::ReadWrite::size: aya::programs::perf_event::PerfBreakpointSize +pub aya::programs::perf_event::BreakpointConfig::Write +pub aya::programs::perf_event::BreakpointConfig::Write::address: u64 +pub aya::programs::perf_event::BreakpointConfig::Write::size: aya::programs::perf_event::PerfBreakpointSize +impl core::clone::Clone for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::clone(&self) -> aya::programs::perf_event::BreakpointConfig +impl core::fmt::Debug for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::BreakpointConfig +impl core::marker::Freeze for aya::programs::perf_event::BreakpointConfig +impl core::marker::Send for aya::programs::perf_event::BreakpointConfig +impl core::marker::Sync for aya::programs::perf_event::BreakpointConfig +impl core::marker::Unpin for aya::programs::perf_event::BreakpointConfig +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::BreakpointConfig +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::BreakpointConfig +impl core::convert::Into for aya::programs::perf_event::BreakpointConfig where U: core::convert::From +pub fn aya::programs::perf_event::BreakpointConfig::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::BreakpointConfig where U: core::convert::Into +pub type aya::programs::perf_event::BreakpointConfig::Error = core::convert::Infallible +pub fn aya::programs::perf_event::BreakpointConfig::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::BreakpointConfig where U: core::convert::TryFrom +pub type aya::programs::perf_event::BreakpointConfig::Error = >::Error +pub fn aya::programs::perf_event::BreakpointConfig::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone +pub type aya::programs::perf_event::BreakpointConfig::Owned = T +pub fn aya::programs::perf_event::BreakpointConfig::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::BreakpointConfig::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::BreakpointConfig where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::BreakpointConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::BreakpointConfig::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::BreakpointConfig where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::BreakpointConfig::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::BreakpointConfig +pub fn aya::programs::perf_event::BreakpointConfig::from(t: T) -> T #[repr(u32)] pub enum aya::programs::perf_event::HardwareEvent pub aya::programs::perf_event::HardwareEvent::BranchInstructions = 4 pub aya::programs::perf_event::HardwareEvent::BranchMisses = 5 @@ -5460,11 +5508,7 @@ pub fn aya::programs::perf_event::HwCacheResult::from(t: T) -> T #[repr(u64)] pub enum aya::programs::perf_event::PerfBreakpointSize pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen1 = 1 pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen2 = 2 -pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen3 = 3 pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen4 = 4 -pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen5 = 5 -pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen6 = 6 -pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen7 = 7 pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen8 = 8 impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointSize pub fn aya::programs::perf_event::PerfBreakpointSize::clone(&self) -> aya::programs::perf_event::PerfBreakpointSize @@ -5499,51 +5543,8 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpoint pub unsafe fn aya::programs::perf_event::PerfBreakpointSize::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::PerfBreakpointSize pub fn aya::programs::perf_event::PerfBreakpointSize::from(t: T) -> T -#[repr(u32)] pub enum aya::programs::perf_event::PerfBreakpointType -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointEmpty = 0 -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointInvalid = 7 -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointR = 1 -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointRW = 3 -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointW = 2 -pub aya::programs::perf_event::PerfBreakpointType::HwBreakpointX = 4 -impl core::clone::Clone for aya::programs::perf_event::PerfBreakpointType -pub fn aya::programs::perf_event::PerfBreakpointType::clone(&self) -> aya::programs::perf_event::PerfBreakpointType -impl core::fmt::Debug for aya::programs::perf_event::PerfBreakpointType -pub fn aya::programs::perf_event::PerfBreakpointType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Copy for aya::programs::perf_event::PerfBreakpointType -impl core::marker::Freeze for aya::programs::perf_event::PerfBreakpointType -impl core::marker::Send for aya::programs::perf_event::PerfBreakpointType -impl core::marker::Sync for aya::programs::perf_event::PerfBreakpointType -impl core::marker::Unpin for aya::programs::perf_event::PerfBreakpointType -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfBreakpointType -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfBreakpointType -impl core::convert::Into for aya::programs::perf_event::PerfBreakpointType where U: core::convert::From -pub fn aya::programs::perf_event::PerfBreakpointType::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::PerfBreakpointType where U: core::convert::Into -pub type aya::programs::perf_event::PerfBreakpointType::Error = core::convert::Infallible -pub fn aya::programs::perf_event::PerfBreakpointType::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::PerfBreakpointType where U: core::convert::TryFrom -pub type aya::programs::perf_event::PerfBreakpointType::Error = >::Error -pub fn aya::programs::perf_event::PerfBreakpointType::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone -pub type aya::programs::perf_event::PerfBreakpointType::Owned = T -pub fn aya::programs::perf_event::PerfBreakpointType::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::PerfBreakpointType::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::PerfBreakpointType where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpointType::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpointType::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::PerfBreakpointType where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpointType::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpointType where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::PerfBreakpointType::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::PerfBreakpointType -pub fn aya::programs::perf_event::PerfBreakpointType::from(t: T) -> T pub enum aya::programs::perf_event::PerfEventConfig -pub aya::programs::perf_event::PerfEventConfig::Breakpoint -pub aya::programs::perf_event::PerfEventConfig::Breakpoint::address: u64 -pub aya::programs::perf_event::PerfEventConfig::Breakpoint::length: aya::programs::perf_event::PerfBreakpointSize -pub aya::programs::perf_event::PerfEventConfig::Breakpoint::type_: aya::programs::perf_event::PerfBreakpointType +pub aya::programs::perf_event::PerfEventConfig::Breakpoint(aya::programs::perf_event::BreakpointConfig) pub aya::programs::perf_event::PerfEventConfig::Hardware(aya::programs::perf_event::HardwareEvent) pub aya::programs::perf_event::PerfEventConfig::HwCache pub aya::programs::perf_event::PerfEventConfig::HwCache::event: aya::programs::perf_event::HwCacheEvent @@ -8297,7 +8298,6 @@ pub aya::programs::ProgramError::AttachCookieNotSupported pub aya::programs::ProgramError::Btf(aya_obj::btf::btf::BtfError) pub aya::programs::ProgramError::ExtensionError(aya::programs::extension::ExtensionError) pub aya::programs::ProgramError::IOError(std::io::error::Error) -pub aya::programs::ProgramError::IncompleteBreakpoint pub aya::programs::ProgramError::InvalidName pub aya::programs::ProgramError::InvalidName::name: alloc::string::String pub aya::programs::ProgramError::KProbeError(aya::programs::kprobe::KProbeError)