ソースを参照

feat: Allow conversions to Program from ProgramInfo

Allow for a ProgramInfo to be converted into one of the program types
that we support. This allows for a user of Aya access to reattach,
pin or unload a program that was either, previously loaded, or was
loaded by another process.

Signed-off-by: Dave Tucker <[email protected]>
Dave Tucker 3 週間 前
コミット
2b0dcfbd09

+ 3 - 3
aya/src/bpf.rs

@@ -611,15 +611,15 @@ impl<'a> EbpfLoader<'a> {
                         }
                         ProgramSection::CgroupSkb => Program::CgroupSkb(CgroupSkb {
                             data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
-                            expected_attach_type: None,
+                            attach_type: None,
                         }),
                         ProgramSection::CgroupSkbIngress => Program::CgroupSkb(CgroupSkb {
                             data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
-                            expected_attach_type: Some(CgroupSkbAttachType::Ingress),
+                            attach_type: Some(CgroupSkbAttachType::Ingress),
                         }),
                         ProgramSection::CgroupSkbEgress => Program::CgroupSkb(CgroupSkb {
                             data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
-                            expected_attach_type: Some(CgroupSkbAttachType::Egress),
+                            attach_type: Some(CgroupSkbAttachType::Egress),
                         }),
                         ProgramSection::CgroupSockAddr { attach_type, .. } => {
                             Program::CgroupSockAddr(CgroupSockAddr {

+ 4 - 1
aya/src/programs/cgroup_device.rs

@@ -9,7 +9,7 @@ use aya_obj::generated::{
 use crate::{
     programs::{
         CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramFd,
-        bpf_prog_get_fd_by_id, define_link_wrapper, id_as_key, load_program, query,
+        ProgramType, bpf_prog_get_fd_by_id, define_link_wrapper, id_as_key, load_program, query,
     },
     sys::{LinkTarget, ProgQueryTarget, SyscallError, bpf_link_create},
     util::KernelVersion,
@@ -56,6 +56,9 @@ pub struct CgroupDevice {
 }
 
 impl CgroupDevice {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupDevice;
+
     /// Loads the program inside the kernel
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_CGROUP_DEVICE, &mut self.data)

+ 11 - 10
aya/src/programs/cgroup_skb.rs

@@ -10,7 +10,7 @@ use aya_obj::generated::{
 use crate::{
     VerifierLogLevel,
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -57,18 +57,19 @@ use crate::{
 #[doc(alias = "BPF_PROG_TYPE_CGROUP_SKB")]
 pub struct CgroupSkb {
     pub(crate) data: ProgramData<CgroupSkbLink>,
-    pub(crate) expected_attach_type: Option<CgroupSkbAttachType>,
+    pub(crate) attach_type: Option<CgroupSkbAttachType>,
 }
 
 impl CgroupSkb {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSkb;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
-        self.data.expected_attach_type =
-            self.expected_attach_type
-                .map(|attach_type| match attach_type {
-                    CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
-                    CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS,
-                });
+        self.data.expected_attach_type = self.attach_type.map(|attach_type| match attach_type {
+            CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
+            CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS,
+        });
         load_program(BPF_PROG_TYPE_CGROUP_SKB, &mut self.data)
     }
 
@@ -79,7 +80,7 @@ impl CgroupSkb {
     /// method returns `None` for programs defined with the generic section
     /// `cgroup/skb`.
     pub fn expected_attach_type(&self) -> &Option<CgroupSkbAttachType> {
-        &self.expected_attach_type
+        &self.attach_type
     }
 
     /// Attaches the program to the given cgroup.
@@ -138,7 +139,7 @@ impl CgroupSkb {
         let data = ProgramData::from_pinned_path(path, VerifierLogLevel::default())?;
         Ok(Self {
             data,
-            expected_attach_type: Some(expected_attach_type),
+            attach_type: Some(expected_attach_type),
         })
     }
 }

+ 4 - 1
aya/src/programs/cgroup_sock.rs

@@ -8,7 +8,7 @@ pub use aya_obj::programs::CgroupSockAttachType;
 use crate::{
     VerifierLogLevel,
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -58,6 +58,9 @@ pub struct CgroupSock {
 }
 
 impl CgroupSock {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSock;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(self.attach_type.into());

+ 4 - 1
aya/src/programs/cgroup_sock_addr.rs

@@ -8,7 +8,7 @@ pub use aya_obj::programs::CgroupSockAddrAttachType;
 use crate::{
     VerifierLogLevel,
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -59,6 +59,9 @@ pub struct CgroupSockAddr {
 }
 
 impl CgroupSockAddr {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSockAddr;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(self.attach_type.into());

+ 4 - 1
aya/src/programs/cgroup_sockopt.rs

@@ -8,7 +8,7 @@ pub use aya_obj::programs::CgroupSockoptAttachType;
 use crate::{
     VerifierLogLevel,
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -56,6 +56,9 @@ pub struct CgroupSockopt {
 }
 
 impl CgroupSockopt {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSockopt;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(self.attach_type.into());

+ 4 - 1
aya/src/programs/cgroup_sysctl.rs

@@ -8,7 +8,7 @@ use aya_obj::generated::{
 
 use crate::{
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -55,6 +55,9 @@ pub struct CgroupSysctl {
 }
 
 impl CgroupSysctl {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::CgroupSysctl;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_CGROUP_SYSCTL, &mut self.data)

+ 5 - 1
aya/src/programs/extension.rs

@@ -12,7 +12,8 @@ use thiserror::Error;
 use crate::{
     Btf,
     programs::{
-        FdLink, FdLinkId, ProgramData, ProgramError, ProgramFd, define_link_wrapper, load_program,
+        FdLink, FdLinkId, ProgramData, ProgramError, ProgramFd, ProgramType, define_link_wrapper,
+        load_program,
     },
     sys::{self, BpfLinkCreateArgs, LinkTarget, SyscallError, bpf_link_create},
 };
@@ -58,6 +59,9 @@ pub struct Extension {
 }
 
 impl Extension {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Extension;
+
     /// Loads the extension inside the kernel.
     ///
     /// Prepares the code included in the extension to replace the code of the function

+ 4 - 1
aya/src/programs/fentry.rs

@@ -6,7 +6,7 @@ use aya_obj::{
 };
 
 use crate::programs::{
-    FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program,
+    FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
     utils::attach_raw_tracepoint,
 };
 
@@ -51,6 +51,9 @@ pub struct FEntry {
 }
 
 impl FEntry {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Tracing;
+
     /// Loads the program inside the kernel.
     ///
     /// Loads the program so it's executed when the kernel function `fn_name`

+ 4 - 1
aya/src/programs/fexit.rs

@@ -6,7 +6,7 @@ use aya_obj::{
 };
 
 use crate::programs::{
-    FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program,
+    FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
     utils::attach_raw_tracepoint,
 };
 
@@ -51,6 +51,9 @@ pub struct FExit {
 }
 
 impl FExit {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Tracing;
+
     /// Loads the program inside the kernel.
     ///
     /// Loads the program so it's executed when the kernel function `fn_name`

+ 4 - 1
aya/src/programs/flow_dissector.rs

@@ -8,7 +8,7 @@ use aya_obj::generated::{
 
 use crate::{
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -65,6 +65,9 @@ pub struct FlowDissector {
 }
 
 impl FlowDissector {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::FlowDissector;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(BPF_FLOW_DISSECTOR);

+ 4 - 1
aya/src/programs/iter.rs

@@ -14,7 +14,7 @@ use aya_obj::{
 
 use crate::{
     programs::{
-        FdLink, LinkError, PerfLinkIdInner, PerfLinkInner, ProgramData, ProgramError,
+        FdLink, LinkError, PerfLinkIdInner, PerfLinkInner, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_create_iter, bpf_link_create, bpf_link_get_info_by_fd},
@@ -60,6 +60,9 @@ pub struct Iter {
 }
 
 impl Iter {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Tracing;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self, iter_type: &str, btf: &Btf) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(BPF_TRACE_ITER);

+ 5 - 1
aya/src/programs/kprobe.rs

@@ -12,7 +12,8 @@ use thiserror::Error;
 use crate::{
     VerifierLogLevel,
     programs::{
-        FdLink, LinkError, ProgramData, ProgramError, define_link_wrapper, load_program,
+        FdLink, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper,
+        load_program,
         perf_attach::{PerfLinkIdInner, PerfLinkInner},
         probe::{ProbeKind, attach},
     },
@@ -50,6 +51,9 @@ pub struct KProbe {
 }
 
 impl KProbe {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::KProbe;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_KPROBE, &mut self.data)

+ 5 - 2
aya/src/programs/lirc_mode2.rs

@@ -7,8 +7,8 @@ use aya_obj::generated::{
 
 use crate::{
     programs::{
-        CgroupAttachMode, Link, ProgramData, ProgramError, ProgramFd, ProgramInfo, id_as_key,
-        load_program, query,
+        CgroupAttachMode, Link, ProgramData, ProgramError, ProgramFd, ProgramInfo, ProgramType,
+        id_as_key, load_program, query,
     },
     sys::{ProgQueryTarget, bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id},
 };
@@ -56,6 +56,9 @@ pub struct LircMode2 {
 }
 
 impl LircMode2 {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::LircMode2;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_LIRC_MODE2, &mut self.data)

+ 4 - 1
aya/src/programs/lsm.rs

@@ -6,7 +6,7 @@ use aya_obj::{
 };
 
 use crate::programs::{
-    FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program,
+    FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
     utils::attach_raw_tracepoint,
 };
 
@@ -54,6 +54,9 @@ pub struct Lsm {
 }
 
 impl Lsm {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Lsm;
+
     /// Loads the program inside the kernel.
     ///
     /// # Arguments

+ 135 - 33
aya/src/programs/mod.rs

@@ -84,6 +84,7 @@ use aya_obj::{
     VerifierLog,
     btf::BtfError,
     generated::{bpf_attach_type, bpf_link_info, bpf_prog_info, bpf_prog_type},
+    programs::XdpAttachType,
 };
 use info::impl_info;
 pub use info::{ProgramInfo, ProgramType, loaded_programs};
@@ -331,39 +332,32 @@ impl Program {
     /// Returns the program type.
     pub fn prog_type(&self) -> ProgramType {
         match self {
-            Self::KProbe(_) | Self::UProbe(_) => ProgramType::KProbe,
-            Self::TracePoint(_) => ProgramType::TracePoint,
-            Self::SocketFilter(_) => ProgramType::SocketFilter,
-            Self::Xdp(_) => ProgramType::Xdp,
-            Self::SkMsg(_) => ProgramType::SkMsg,
-            Self::SkSkb(_) => ProgramType::SkSkb,
-            Self::SockOps(_) => ProgramType::SockOps,
-            Self::SchedClassifier(_) => ProgramType::SchedClassifier,
-            Self::CgroupSkb(_) => ProgramType::CgroupSkb,
-            Self::CgroupSysctl(_) => ProgramType::CgroupSysctl,
-            Self::CgroupSockopt(_) => ProgramType::CgroupSockopt,
-            Self::LircMode2(_) => ProgramType::LircMode2,
-            Self::PerfEvent(_) => ProgramType::PerfEvent,
-            Self::RawTracePoint(_) => ProgramType::RawTracePoint,
-            Self::Lsm(_) => ProgramType::Lsm,
-            // The following program types are a subset of `TRACING` programs:
-            //
-            // - `BPF_TRACE_RAW_TP` (`BtfTracePoint`)
-            // - `BTF_TRACE_FENTRY` (`FEntry`)
-            // - `BPF_MODIFY_RETURN` (not supported yet in Aya)
-            // - `BPF_TRACE_FEXIT` (`FExit`)
-            // - `BPF_TRACE_ITER` (`Iter`)
-            //
-            // https://github.com/torvalds/linux/blob/v6.12/kernel/bpf/syscall.c#L3935-L3940
-            Self::BtfTracePoint(_) | Self::FEntry(_) | Self::FExit(_) | Self::Iter(_) => {
-                ProgramType::Tracing
-            }
-            Self::Extension(_) => ProgramType::Extension,
-            Self::CgroupSockAddr(_) => ProgramType::CgroupSockAddr,
-            Self::SkLookup(_) => ProgramType::SkLookup,
-            Self::CgroupSock(_) => ProgramType::CgroupSock,
-            Self::CgroupDevice(_) => ProgramType::CgroupDevice,
-            Self::FlowDissector(_) => ProgramType::FlowDissector,
+            Self::KProbe(_) => KProbe::PROGRAM_TYPE,
+            Self::UProbe(_) => UProbe::PROGRAM_TYPE,
+            Self::TracePoint(_) => TracePoint::PROGRAM_TYPE,
+            Self::SocketFilter(_) => SocketFilter::PROGRAM_TYPE,
+            Self::Xdp(_) => Xdp::PROGRAM_TYPE,
+            Self::SkMsg(_) => SkMsg::PROGRAM_TYPE,
+            Self::SkSkb(_) => SkSkb::PROGRAM_TYPE,
+            Self::SockOps(_) => SockOps::PROGRAM_TYPE,
+            Self::SchedClassifier(_) => SchedClassifier::PROGRAM_TYPE,
+            Self::CgroupSkb(_) => CgroupSkb::PROGRAM_TYPE,
+            Self::CgroupSysctl(_) => CgroupSysctl::PROGRAM_TYPE,
+            Self::CgroupSockopt(_) => CgroupSockopt::PROGRAM_TYPE,
+            Self::LircMode2(_) => LircMode2::PROGRAM_TYPE,
+            Self::PerfEvent(_) => PerfEvent::PROGRAM_TYPE,
+            Self::RawTracePoint(_) => RawTracePoint::PROGRAM_TYPE,
+            Self::Lsm(_) => Lsm::PROGRAM_TYPE,
+            Self::BtfTracePoint(_) => BtfTracePoint::PROGRAM_TYPE,
+            Self::FEntry(_) => FEntry::PROGRAM_TYPE,
+            Self::FExit(_) => FExit::PROGRAM_TYPE,
+            Self::Extension(_) => Extension::PROGRAM_TYPE,
+            Self::CgroupSockAddr(_) => CgroupSockAddr::PROGRAM_TYPE,
+            Self::SkLookup(_) => SkLookup::PROGRAM_TYPE,
+            Self::CgroupSock(_) => CgroupSock::PROGRAM_TYPE,
+            Self::CgroupDevice(_) => CgroupDevice::PROGRAM_TYPE,
+            Self::Iter(_) => Iter::PROGRAM_TYPE,
+            Self::FlowDissector(_) => FlowDissector::PROGRAM_TYPE,
         }
     }
 
@@ -1004,6 +998,114 @@ impl_from_pin!(
     Iter,
 );
 
+macro_rules! impl_from_prog_info {
+    (
+        $(#[$doc:meta])*
+        @safety
+            [$($safety:tt)?]
+        @rest
+            $struct_name:ident $($var:ident : $var_ty:ty)?
+    ) => {
+        impl $struct_name {
+            /// Constructs an instance of a [`Self`] from a [`ProgramInfo`].
+            ///
+            /// This allows the caller to get a handle to an already loaded
+            /// program from the kernel without having to load it again.
+            ///
+            /// # Errors
+            ///
+            /// - If the program type reported by the kernel does not match
+            ///   [`Self::PROGRAM_TYPE`].
+            /// - If the file descriptor of the program cannot be cloned.
+            $(#[$doc])*
+            pub $($safety)?
+            fn from_program_info(
+                info: ProgramInfo,
+                name: Cow<'static, str>,
+                $($var: $var_ty,)?
+            ) -> Result<Self, ProgramError> {
+                if info.program_type()? != Self::PROGRAM_TYPE {
+                    return Err(ProgramError::UnexpectedProgramType {});
+                }
+                let ProgramInfo(bpf_progam_info) = info;
+                let fd = info.fd()?;
+                let fd = fd.as_fd().try_clone_to_owned()?;
+
+                Ok(Self {
+                    data: ProgramData::from_bpf_prog_info(
+                        Some(name),
+                        crate::MockableFd::from_fd(fd),
+                        Path::new(""),
+                        bpf_progam_info,
+                        VerifierLogLevel::default(),
+                    )?,
+                    $($var,)?
+                })
+            }
+        }
+    };
+
+    // Handle unsafe cases and pass a safety doc section
+    (
+        unsafe $struct_name:ident $($var:ident : $var_ty:ty)? $(, $($rest:tt)*)?
+    ) => {
+        impl_from_prog_info! {
+            ///
+            /// # Safety
+            ///
+            /// The runtime type of this program, as used by the kernel, is
+            /// overloaded. We assert the program type matches the runtime type
+            /// but we're unable to perform further checks. Therefore, the caller
+            /// must ensure that the program type is correct or the behavior is
+            /// undefined.
+            @safety [unsafe]
+            @rest $struct_name $($var : $var_ty)?
+        }
+        $( impl_from_prog_info!($($rest)*); )?
+    };
+
+    // Handle non-unsafe cases and omit safety doc section
+    (
+        $struct_name:ident $($var:ident : $var_ty:ty)? $(, $($rest:tt)*)?
+    ) => {
+        impl_from_prog_info! {
+            @safety []
+            @rest $struct_name $($var : $var_ty)?
+        }
+        $( impl_from_prog_info!($($rest)*); )?
+    };
+
+    // Handle trailing comma
+    (
+        $(,)?
+    ) => {};
+}
+
+impl_from_prog_info!(
+    unsafe KProbe kind : ProbeKind,
+    unsafe UProbe kind : ProbeKind,
+    TracePoint,
+    Xdp attach_type : XdpAttachType,
+    SkMsg,
+    SkSkb kind : SkSkbKind,
+    SockOps,
+    SchedClassifier,
+    CgroupSkb attach_type : Option<CgroupSkbAttachType>,
+    CgroupSysctl,
+    CgroupSockopt attach_type : CgroupSockoptAttachType,
+    LircMode2,
+    PerfEvent,
+    Lsm,
+    RawTracePoint,
+    unsafe BtfTracePoint,
+    unsafe FEntry,
+    unsafe FExit,
+    Extension,
+    SkLookup,
+    CgroupDevice,
+    Iter,
+);
+
 macro_rules! impl_try_from_program {
     ($($ty:ident),+ $(,)?) => {
         $(

+ 4 - 1
aya/src/programs/perf_event.rs

@@ -16,7 +16,7 @@ pub use aya_obj::generated::{
 
 use crate::{
     programs::{
-        FdLink, LinkError, ProgramData, ProgramError,
+        FdLink, LinkError, ProgramData, ProgramError, ProgramType,
         links::define_link_wrapper,
         load_program, perf_attach,
         perf_attach::{PerfLinkIdInner, PerfLinkInner},
@@ -127,6 +127,9 @@ pub struct PerfEvent {
 }
 
 impl PerfEvent {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::PerfEvent;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_PERF_EVENT, &mut self.data)

+ 4 - 1
aya/src/programs/raw_trace_point.rs

@@ -4,7 +4,7 @@ use std::ffi::CString;
 use aya_obj::generated::bpf_prog_type::BPF_PROG_TYPE_RAW_TRACEPOINT;
 
 use crate::programs::{
-    FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program,
+    FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
     utils::attach_raw_tracepoint,
 };
 
@@ -39,6 +39,9 @@ pub struct RawTracePoint {
 }
 
 impl RawTracePoint {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::RawTracePoint;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_RAW_TRACEPOINT, &mut self.data)

+ 6 - 1
aya/src/programs/sk_lookup.rs

@@ -5,7 +5,9 @@ use aya_obj::generated::{bpf_attach_type::BPF_SK_LOOKUP, bpf_prog_type::BPF_PROG
 
 use super::links::FdLink;
 use crate::{
-    programs::{FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program},
+    programs::{
+        FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
+    },
     sys::{LinkTarget, SyscallError, bpf_link_create},
 };
 
@@ -52,6 +54,9 @@ pub struct SkLookup {
 }
 
 impl SkLookup {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SkLookup;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(BPF_SK_LOOKUP);

+ 4 - 1
aya/src/programs/sk_msg.rs

@@ -9,7 +9,7 @@ use aya_obj::generated::{
 use crate::{
     maps::sock::SockMapFd,
     programs::{
-        CgroupAttachMode, ProgAttachLink, ProgAttachLinkId, ProgramData, ProgramError,
+        CgroupAttachMode, ProgAttachLink, ProgAttachLinkId, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, load_program,
     },
 };
@@ -72,6 +72,9 @@ pub struct SkMsg {
 }
 
 impl SkMsg {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SkLookup;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_SK_MSG, &mut self.data)

+ 4 - 1
aya/src/programs/sk_skb.rs

@@ -11,7 +11,7 @@ use crate::{
     VerifierLogLevel,
     maps::sock::SockMapFd,
     programs::{
-        CgroupAttachMode, ProgAttachLink, ProgAttachLinkId, ProgramData, ProgramError,
+        CgroupAttachMode, ProgAttachLink, ProgAttachLinkId, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, load_program,
     },
 };
@@ -74,6 +74,9 @@ pub struct SkSkb {
 }
 
 impl SkSkb {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SkSkb;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_SK_SKB, &mut self.data)

+ 4 - 1
aya/src/programs/sock_ops.rs

@@ -7,7 +7,7 @@ use aya_obj::generated::{
 
 use crate::{
     programs::{
-        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError,
+        CgroupAttachMode, FdLink, Link, ProgAttachLink, ProgramData, ProgramError, ProgramType,
         define_link_wrapper, id_as_key, load_program,
     },
     sys::{LinkTarget, SyscallError, bpf_link_create},
@@ -54,6 +54,9 @@ pub struct SockOps {
 }
 
 impl SockOps {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SkSkb;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_SOCK_OPS, &mut self.data)

+ 4 - 1
aya/src/programs/socket_filter.rs

@@ -10,7 +10,7 @@ use aya_obj::generated::{
 use libc::{SOL_SOCKET, setsockopt};
 use thiserror::Error;
 
-use crate::programs::{Link, ProgramData, ProgramError, id_as_key, load_program};
+use crate::programs::{Link, ProgramData, ProgramError, ProgramType, id_as_key, load_program};
 
 /// The type returned when attaching a [`SocketFilter`] fails.
 #[derive(Debug, Error)]
@@ -64,6 +64,9 @@ pub struct SocketFilter {
 }
 
 impl SocketFilter {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SocketFilter;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_SOCKET_FILTER, &mut self.data)

+ 5 - 2
aya/src/programs/tc.rs

@@ -18,8 +18,8 @@ use super::{FdLink, ProgramInfo};
 use crate::{
     VerifierLogLevel,
     programs::{
-        Link, LinkError, LinkOrder, ProgramData, ProgramError, define_link_wrapper, id_as_key,
-        load_program, query,
+        Link, LinkError, LinkOrder, ProgramData, ProgramError, ProgramType, define_link_wrapper,
+        id_as_key, load_program, query,
     },
     sys::{
         BpfLinkCreateArgs, LinkTarget, NetlinkError, ProgQueryTarget, SyscallError,
@@ -156,6 +156,9 @@ pub struct NlOptions {
 }
 
 impl SchedClassifier {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::SchedClassifier;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data)

+ 4 - 1
aya/src/programs/tp_btf.rs

@@ -6,7 +6,7 @@ use aya_obj::{
 };
 
 use crate::programs::{
-    FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program,
+    FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper, load_program,
     utils::attach_raw_tracepoint,
 };
 
@@ -52,6 +52,9 @@ pub struct BtfTracePoint {
 }
 
 impl BtfTracePoint {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Tracing;
+
     /// Loads the program inside the kernel.
     ///
     /// # Arguments

+ 5 - 1
aya/src/programs/trace_point.rs

@@ -10,7 +10,8 @@ use thiserror::Error;
 
 use crate::{
     programs::{
-        FdLink, LinkError, ProgramData, ProgramError, define_link_wrapper, load_program,
+        FdLink, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper,
+        load_program,
         perf_attach::{PerfLinkIdInner, PerfLinkInner, perf_attach},
         utils::find_tracefs_path,
     },
@@ -59,6 +60,9 @@ pub struct TracePoint {
 }
 
 impl TracePoint {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::TracePoint;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_TRACEPOINT, &mut self.data)

+ 5 - 1
aya/src/programs/uprobe.rs

@@ -18,7 +18,8 @@ use thiserror::Error;
 use crate::{
     VerifierLogLevel,
     programs::{
-        FdLink, LinkError, ProgramData, ProgramError, define_link_wrapper, load_program,
+        FdLink, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper,
+        load_program,
         perf_attach::{PerfLinkIdInner, PerfLinkInner},
         probe::{OsStringExt as _, ProbeKind, attach},
     },
@@ -71,6 +72,9 @@ impl From<u64> for UProbeAttachLocation<'static> {
 }
 
 impl UProbe {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::KProbe;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         load_program(BPF_PROG_TYPE_KPROBE, &mut self.data)

+ 5 - 2
aya/src/programs/xdp.rs

@@ -20,8 +20,8 @@ use thiserror::Error;
 use crate::{
     VerifierLogLevel,
     programs::{
-        FdLink, Link, LinkError, ProgramData, ProgramError, define_link_wrapper, id_as_key,
-        load_program,
+        FdLink, Link, LinkError, ProgramData, ProgramError, ProgramType, define_link_wrapper,
+        id_as_key, load_program,
     },
     sys::{
         LinkTarget, NetlinkError, SyscallError, bpf_link_create, bpf_link_get_info_by_fd,
@@ -84,6 +84,9 @@ pub struct Xdp {
 }
 
 impl Xdp {
+    /// The type of the program according to the kernel.
+    pub const PROGRAM_TYPE: ProgramType = ProgramType::Xdp;
+
     /// Loads the program inside the kernel.
     pub fn load(&mut self) -> Result<(), ProgramError> {
         self.data.expected_attach_type = Some(self.attach_type.into());

+ 22 - 3
test/integration-test/src/tests/info.rs

@@ -11,7 +11,7 @@ use std::{fs, panic, path::Path, time::SystemTime};
 use aya::{
     Ebpf,
     maps::{Array, HashMap, IterableMap as _, MapError, MapType, loaded_maps},
-    programs::{ProgramError, ProgramType, SocketFilter, TracePoint, loaded_programs},
+    programs::{ProgramError, ProgramType, SocketFilter, TracePoint, UProbe, loaded_programs},
     util::KernelVersion,
 };
 use libc::EINVAL;
@@ -22,8 +22,8 @@ use crate::utils::{kernel_assert, kernel_assert_eq};
 fn test_loaded_programs() {
     // Load a program.
     // Since we are only testing the programs for their metadata, there is no need to "attach" them.
-    let mut bpf = Ebpf::load(crate::SIMPLE_PROG).unwrap();
-    let prog: &mut SocketFilter = bpf.program_mut("simple_prog").unwrap().try_into().unwrap();
+    let mut bpf = Ebpf::load(crate::TEST).unwrap();
+    let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap();
     prog.load().unwrap();
     let test_prog = prog.info().unwrap();
 
@@ -48,6 +48,25 @@ fn test_loaded_programs() {
         programs.any(|prog| prog.id() == test_prog.id()),
         KernelVersion::new(4, 13, 0)
     );
+
+    // Use loaded programs to find our test program and exercise `from_program_info()`.
+    let info = loaded_programs()
+        .filter_map(|prog| prog.ok())
+        .find(|prog| prog.id() == test_prog.id())
+        .unwrap();
+
+    let mut p: UProbe = unsafe {
+        UProbe::from_program_info(info, "test_uprobe".into(), aya::programs::ProbeKind::UProbe)
+            .unwrap()
+    };
+
+    // Ensure we can perform basic operations on the re-created program.
+    let res = p
+        .attach("uprobe_function", "/proc/self/exe", None, None)
+        .unwrap();
+
+    // Ensure the program can be detached.
+    p.detach(res).unwrap();
 }
 
 #[test]

+ 140 - 0
xtask/public-api/aya.txt

@@ -2528,6 +2528,7 @@ pub use aya::programs::CgroupSockoptAttachType
 pub mod aya::programs::cgroup_device
 pub struct aya::programs::cgroup_device::CgroupDevice
 impl aya::programs::cgroup_device::CgroupDevice
+pub const aya::programs::cgroup_device::CgroupDevice::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_device::CgroupDevice::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_device::CgroupDeviceLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_device::CgroupDevice::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::cgroup_device::CgroupDevice::query<T: std::os::fd::owned::AsFd>(target_fd: T) -> core::result::Result<alloc::vec::Vec<aya::programs::cgroup_device::CgroupDeviceLink>, aya::programs::ProgramError>
@@ -2539,6 +2540,8 @@ pub fn aya::programs::cgroup_device::CgroupDevice::fd(&self) -> core::result::Re
 impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::cgroup_device::CgroupDevice
+pub fn aya::programs::cgroup_device::CgroupDevice::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -2691,6 +2694,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_skb::CgroupSkbAttachTyp
 pub fn aya::programs::cgroup_skb::CgroupSkbAttachType::from(t: T) -> T
 pub struct aya::programs::cgroup_skb::CgroupSkb
 impl aya::programs::cgroup_skb::CgroupSkb
+pub const aya::programs::cgroup_skb::CgroupSkb::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_skb::CgroupSkb::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, attach_type: aya::programs::cgroup_skb::CgroupSkbAttachType, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_skb::CgroupSkbLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_skb::CgroupSkb::expected_attach_type(&self) -> &core::option::Option<aya::programs::cgroup_skb::CgroupSkbAttachType>
 pub fn aya::programs::cgroup_skb::CgroupSkb::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, expected_attach_type: aya::programs::cgroup_skb::CgroupSkbAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
@@ -2701,6 +2705,8 @@ pub fn aya::programs::cgroup_skb::CgroupSkb::take_link(&mut self, link_id: aya::
 impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::cgroup_skb::CgroupSkb
+pub fn aya::programs::cgroup_skb::CgroupSkb::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: core::option::Option<aya::programs::cgroup_skb::CgroupSkbAttachType>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -2818,6 +2824,7 @@ pub mod aya::programs::cgroup_sock
 pub use aya::programs::cgroup_sock::CgroupSockAttachType
 pub struct aya::programs::cgroup_sock::CgroupSock
 impl aya::programs::cgroup_sock::CgroupSock
+pub const aya::programs::cgroup_sock::CgroupSock::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sock::CgroupSock::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sock::CgroupSockLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock::CgroupSock::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sock::CgroupSockAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock::CgroupSock::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -2944,6 +2951,7 @@ pub mod aya::programs::cgroup_sock_addr
 pub use aya::programs::cgroup_sock_addr::CgroupSockAddrAttachType
 pub struct aya::programs::cgroup_sock_addr::CgroupSockAddr
 impl aya::programs::cgroup_sock_addr::CgroupSockAddr
+pub const aya::programs::cgroup_sock_addr::CgroupSockAddr::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sock_addr::CgroupSockAddrAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -3070,6 +3078,7 @@ pub mod aya::programs::cgroup_sockopt
 pub use aya::programs::cgroup_sockopt::CgroupSockoptAttachType
 pub struct aya::programs::cgroup_sockopt::CgroupSockopt
 impl aya::programs::cgroup_sockopt::CgroupSockopt
+pub const aya::programs::cgroup_sockopt::CgroupSockopt::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sockopt::CgroupSockoptLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -3079,6 +3088,8 @@ pub fn aya::programs::cgroup_sockopt::CgroupSockopt::take_link(&mut self, link_i
 impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::cgroup_sockopt::CgroupSockopt
+pub fn aya::programs::cgroup_sockopt::CgroupSockopt::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -3195,6 +3206,7 @@ pub fn aya::programs::cgroup_sockopt::CgroupSockoptLinkId::from(t: T) -> T
 pub mod aya::programs::cgroup_sysctl
 pub struct aya::programs::cgroup_sysctl::CgroupSysctl
 impl aya::programs::cgroup_sysctl::CgroupSysctl
+pub const aya::programs::cgroup_sysctl::CgroupSysctl::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sysctl::CgroupSysctlLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
@@ -3205,6 +3217,8 @@ pub fn aya::programs::cgroup_sysctl::CgroupSysctl::fd(&self) -> core::result::Re
 impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
+pub fn aya::programs::cgroup_sysctl::CgroupSysctl::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -3354,6 +3368,7 @@ impl<T> core::convert::From<T> for aya::programs::extension::ExtensionError
 pub fn aya::programs::extension::ExtensionError::from(t: T) -> T
 pub struct aya::programs::extension::Extension
 impl aya::programs::extension::Extension
+pub const aya::programs::extension::Extension::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::extension::Extension::attach(&mut self) -> core::result::Result<aya::programs::extension::ExtensionLinkId, aya::programs::ProgramError>
 pub fn aya::programs::extension::Extension::attach_to_program(&mut self, program: &aya::programs::ProgramFd, func_name: &str) -> core::result::Result<aya::programs::extension::ExtensionLinkId, aya::programs::ProgramError>
 pub fn aya::programs::extension::Extension::load(&mut self, program: aya::programs::ProgramFd, func_name: &str) -> core::result::Result<(), aya::programs::ProgramError>
@@ -3365,6 +3380,8 @@ pub fn aya::programs::extension::Extension::fd(&self) -> core::result::Result<&a
 impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::extension::Extension
+pub fn aya::programs::extension::Extension::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -3485,6 +3502,7 @@ pub fn aya::programs::extension::ExtensionLinkId::from(t: T) -> T
 pub mod aya::programs::fentry
 pub struct aya::programs::fentry::FEntry
 impl aya::programs::fentry::FEntry
+pub const aya::programs::fentry::FEntry::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::fentry::FEntry::attach(&mut self) -> core::result::Result<aya::programs::fentry::FEntryLinkId, aya::programs::ProgramError>
 pub fn aya::programs::fentry::FEntry::load(&mut self, fn_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
@@ -3495,6 +3513,8 @@ pub fn aya::programs::fentry::FEntry::fd(&self) -> core::result::Result<&aya::pr
 impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
+pub unsafe fn aya::programs::fentry::FEntry::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -3615,6 +3635,7 @@ pub fn aya::programs::fentry::FEntryLinkId::from(t: T) -> T
 pub mod aya::programs::fexit
 pub struct aya::programs::fexit::FExit
 impl aya::programs::fexit::FExit
+pub const aya::programs::fexit::FExit::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::fexit::FExit::attach(&mut self) -> core::result::Result<aya::programs::fexit::FExitLinkId, aya::programs::ProgramError>
 pub fn aya::programs::fexit::FExit::load(&mut self, fn_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
@@ -3625,6 +3646,8 @@ pub fn aya::programs::fexit::FExit::fd(&self) -> core::result::Result<&aya::prog
 impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
+pub unsafe fn aya::programs::fexit::FExit::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -3745,6 +3768,7 @@ pub fn aya::programs::fexit::FExitLinkId::from(t: T) -> T
 pub mod aya::programs::flow_dissector
 pub struct aya::programs::flow_dissector::FlowDissector
 impl aya::programs::flow_dissector::FlowDissector
+pub const aya::programs::flow_dissector::FlowDissector::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::flow_dissector::FlowDissector::attach<T: std::os::fd::owned::AsFd>(&mut self, netns: T) -> core::result::Result<aya::programs::flow_dissector::FlowDissectorLinkId, aya::programs::ProgramError>
 pub fn aya::programs::flow_dissector::FlowDissector::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::flow_dissector::FlowDissector
@@ -3871,6 +3895,7 @@ pub fn aya::programs::flow_dissector::FlowDissectorLinkId::from(t: T) -> T
 pub mod aya::programs::iter
 pub struct aya::programs::iter::Iter
 impl aya::programs::iter::Iter
+pub const aya::programs::iter::Iter::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::iter::Iter::attach(&mut self) -> core::result::Result<aya::programs::iter::IterLinkId, aya::programs::ProgramError>
 pub fn aya::programs::iter::Iter::load(&mut self, iter_type: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::iter::Iter
@@ -3881,6 +3906,8 @@ pub fn aya::programs::iter::Iter::fd(&self) -> core::result::Result<&aya::progra
 impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::iter::Iter
+pub fn aya::programs::iter::Iter::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -4068,6 +4095,7 @@ impl<T> core::convert::From<T> for aya::programs::kprobe::KProbeError
 pub fn aya::programs::kprobe::KProbeError::from(t: T) -> T
 pub struct aya::programs::kprobe::KProbe
 impl aya::programs::kprobe::KProbe
+pub const aya::programs::kprobe::KProbe::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::kprobe::KProbe::attach<T: core::convert::AsRef<std::ffi::os_str::OsStr>>(&mut self, fn_name: T, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::kind(&self) -> aya::programs::ProbeKind
@@ -4078,6 +4106,8 @@ pub fn aya::programs::kprobe::KProbe::take_link(&mut self, link_id: aya::program
 impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::kprobe::KProbe
+pub unsafe fn aya::programs::kprobe::KProbe::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -4769,6 +4799,7 @@ impl<T> core::convert::From<T> for aya::programs::lirc_mode2::LircLinkId
 pub fn aya::programs::lirc_mode2::LircLinkId::from(t: T) -> T
 pub struct aya::programs::lirc_mode2::LircMode2
 impl aya::programs::lirc_mode2::LircMode2
+pub const aya::programs::lirc_mode2::LircMode2::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::lirc_mode2::LircMode2::attach<T: std::os::fd::owned::AsFd>(&mut self, lircdev: T) -> core::result::Result<aya::programs::lirc_mode2::LircLinkId, aya::programs::ProgramError>
 pub fn aya::programs::lirc_mode2::LircMode2::detach(&mut self, link_id: aya::programs::lirc_mode2::LircLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::lirc_mode2::LircMode2::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -4779,6 +4810,8 @@ pub fn aya::programs::lirc_mode2::LircMode2::fd(&self) -> core::result::Result<&
 impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::lirc_mode2::LircMode2
+pub fn aya::programs::lirc_mode2::LircMode2::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -4820,6 +4853,7 @@ pub fn aya::programs::lirc_mode2::LircMode2::from(t: T) -> T
 pub mod aya::programs::lsm
 pub struct aya::programs::lsm::Lsm
 impl aya::programs::lsm::Lsm
+pub const aya::programs::lsm::Lsm::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::lsm::Lsm::attach(&mut self) -> core::result::Result<aya::programs::lsm::LsmLinkId, aya::programs::ProgramError>
 pub fn aya::programs::lsm::Lsm::load(&mut self, lsm_hook_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
@@ -4830,6 +4864,8 @@ pub fn aya::programs::lsm::Lsm::fd(&self) -> core::result::Result<&aya::programs
 impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
+pub fn aya::programs::lsm::Lsm::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5146,6 +5182,7 @@ impl<T> core::convert::From<T> for aya::programs::perf_event::SamplePolicy
 pub fn aya::programs::perf_event::SamplePolicy::from(t: T) -> T
 pub struct aya::programs::perf_event::PerfEvent
 impl aya::programs::perf_event::PerfEvent
+pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
@@ -5156,6 +5193,8 @@ pub fn aya::programs::perf_event::PerfEvent::fd(&self) -> core::result::Result<&
 impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
+pub fn aya::programs::perf_event::PerfEvent::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5278,6 +5317,7 @@ pub fn aya::programs::perf_event::PerfEventLinkId::from(t: T) -> T
 pub mod aya::programs::raw_trace_point
 pub struct aya::programs::raw_trace_point::RawTracePoint
 impl aya::programs::raw_trace_point::RawTracePoint
+pub const aya::programs::raw_trace_point::RawTracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::raw_trace_point::RawTracePoint::attach(&mut self, tp_name: &str) -> core::result::Result<aya::programs::raw_trace_point::RawTracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::raw_trace_point::RawTracePoint::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
@@ -5288,6 +5328,8 @@ pub fn aya::programs::raw_trace_point::RawTracePoint::fd(&self) -> core::result:
 impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
+pub fn aya::programs::raw_trace_point::RawTracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5408,6 +5450,7 @@ pub fn aya::programs::raw_trace_point::RawTracePointLinkId::from(t: T) -> T
 pub mod aya::programs::sk_lookup
 pub struct aya::programs::sk_lookup::SkLookup
 impl aya::programs::sk_lookup::SkLookup
+pub const aya::programs::sk_lookup::SkLookup::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_lookup::SkLookup::attach<T: std::os::fd::owned::AsFd>(&mut self, netns: T) -> core::result::Result<aya::programs::sk_lookup::SkLookupLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_lookup::SkLookup::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
@@ -5418,6 +5461,8 @@ pub fn aya::programs::sk_lookup::SkLookup::fd(&self) -> core::result::Result<&ay
 impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
+pub fn aya::programs::sk_lookup::SkLookup::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5538,6 +5583,7 @@ pub fn aya::programs::sk_lookup::SkLookupLinkId::from(t: T) -> T
 pub mod aya::programs::sk_msg
 pub struct aya::programs::sk_msg::SkMsg
 impl aya::programs::sk_msg::SkMsg
+pub const aya::programs::sk_msg::SkMsg::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_msg::SkMsg::attach(&mut self, map: &aya::maps::sock::SockMapFd) -> core::result::Result<aya::programs::sk_msg::SkMsgLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_msg::SkMsg::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
@@ -5548,6 +5594,8 @@ pub fn aya::programs::sk_msg::SkMsg::fd(&self) -> core::result::Result<&aya::pro
 impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
+pub fn aya::programs::sk_msg::SkMsg::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5704,6 +5752,7 @@ impl<T> core::convert::From<T> for aya::programs::sk_skb::SkSkbKind
 pub fn aya::programs::sk_skb::SkSkbKind::from(t: T) -> T
 pub struct aya::programs::sk_skb::SkSkb
 impl aya::programs::sk_skb::SkSkb
+pub const aya::programs::sk_skb::SkSkb::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_skb::SkSkb::attach(&mut self, map: &aya::maps::sock::SockMapFd) -> core::result::Result<aya::programs::sk_skb::SkSkbLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_skb::SkSkb::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::sk_skb::SkSkbKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::sk_skb::SkSkb::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -5713,6 +5762,8 @@ pub fn aya::programs::sk_skb::SkSkb::take_link(&mut self, link_id: aya::programs
 impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::sk_skb::SkSkb
+pub fn aya::programs::sk_skb::SkSkb::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::sk_skb::SkSkbKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5833,6 +5884,7 @@ pub fn aya::programs::sk_skb::SkSkbLinkId::from(t: T) -> T
 pub mod aya::programs::sock_ops
 pub struct aya::programs::sock_ops::SockOps
 impl aya::programs::sock_ops::SockOps
+pub const aya::programs::sock_ops::SockOps::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sock_ops::SockOps::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::sock_ops::SockOpsLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sock_ops::SockOps::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
@@ -5843,6 +5895,8 @@ pub fn aya::programs::sock_ops::SockOps::fd(&self) -> core::result::Result<&aya:
 impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
+pub fn aya::programs::sock_ops::SockOps::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -5994,6 +6048,7 @@ impl<T> core::convert::From<T> for aya::programs::socket_filter::SocketFilterErr
 pub fn aya::programs::socket_filter::SocketFilterError::from(t: T) -> T
 pub struct aya::programs::socket_filter::SocketFilter
 impl aya::programs::socket_filter::SocketFilter
+pub const aya::programs::socket_filter::SocketFilter::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::socket_filter::SocketFilter::attach<T: std::os::fd::owned::AsFd>(&mut self, socket: T) -> core::result::Result<aya::programs::socket_filter::SocketFilterLinkId, aya::programs::ProgramError>
 pub fn aya::programs::socket_filter::SocketFilter::detach(&mut self, link_id: aya::programs::socket_filter::SocketFilterLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::socket_filter::SocketFilter::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -6269,6 +6324,7 @@ impl<T> core::convert::From<T> for aya::programs::tc::NlOptions
 pub fn aya::programs::tc::NlOptions::from(t: T) -> T
 pub struct aya::programs::tc::SchedClassifier
 impl aya::programs::tc::SchedClassifier
+pub const aya::programs::tc::SchedClassifier::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::tc::SchedClassifier::attach(&mut self, interface: &str, attach_type: aya::programs::tc::TcAttachType) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tc::SchedClassifier::attach_to_link(&mut self, link: aya::programs::tc::SchedClassifierLink) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tc::SchedClassifier::attach_with_options(&mut self, interface: &str, attach_type: aya::programs::tc::TcAttachType, options: aya::programs::tc::TcAttachOptions) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
@@ -6281,6 +6337,8 @@ pub fn aya::programs::tc::SchedClassifier::take_link(&mut self, link_id: aya::pr
 impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::tc::SchedClassifier
+pub fn aya::programs::tc::SchedClassifier::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -6417,6 +6475,7 @@ pub fn aya::programs::tc::qdisc_detach_program(if_name: &str, attach_type: aya::
 pub mod aya::programs::tp_btf
 pub struct aya::programs::tp_btf::BtfTracePoint
 impl aya::programs::tp_btf::BtfTracePoint
+pub const aya::programs::tp_btf::BtfTracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::tp_btf::BtfTracePoint::attach(&mut self) -> core::result::Result<aya::programs::tp_btf::BtfTracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tp_btf::BtfTracePoint::load(&mut self, tracepoint: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
@@ -6427,6 +6486,8 @@ pub fn aya::programs::tp_btf::BtfTracePoint::fd(&self) -> core::result::Result<&
 impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
+pub unsafe fn aya::programs::tp_btf::BtfTracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -6583,6 +6644,7 @@ impl<T> core::convert::From<T> for aya::programs::trace_point::TracePointError
 pub fn aya::programs::trace_point::TracePointError::from(t: T) -> T
 pub struct aya::programs::trace_point::TracePoint
 impl aya::programs::trace_point::TracePoint
+pub const aya::programs::trace_point::TracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::trace_point::TracePoint::attach(&mut self, category: &str, name: &str) -> core::result::Result<aya::programs::trace_point::TracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::trace_point::TracePoint::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
@@ -6593,6 +6655,8 @@ pub fn aya::programs::trace_point::TracePoint::fd(&self) -> core::result::Result
 impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
+pub fn aya::programs::trace_point::TracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -6827,6 +6891,7 @@ impl<T> core::convert::From<T> for aya::programs::uprobe::UProbeError
 pub fn aya::programs::uprobe::UProbeError::from(t: T) -> T
 pub struct aya::programs::uprobe::UProbe
 impl aya::programs::uprobe::UProbe
+pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Loc: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'loc>>>(&mut self, location: Loc, target: T, pid: core::option::Option<libc::unix::pid_t>, cookie: core::option::Option<u64>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::uprobe::UProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind
@@ -6837,6 +6902,8 @@ pub fn aya::programs::uprobe::UProbe::take_link(&mut self, link_id: aya::program
 impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::uprobe::UProbe
+pub unsafe fn aya::programs::uprobe::UProbe::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -6993,6 +7060,7 @@ impl<T> core::convert::From<T> for aya::programs::xdp::XdpError
 pub fn aya::programs::xdp::XdpError::from(t: T) -> T
 pub struct aya::programs::xdp::Xdp
 impl aya::programs::xdp::Xdp
+pub const aya::programs::xdp::Xdp::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::xdp::Xdp::attach(&mut self, interface: &str, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
 pub fn aya::programs::xdp::Xdp::attach_to_if_index(&mut self, if_index: u32, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
 pub fn aya::programs::xdp::Xdp::attach_to_link(&mut self, link: aya::programs::xdp::XdpLink) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
@@ -7004,6 +7072,8 @@ pub fn aya::programs::xdp::Xdp::take_link(&mut self, link_id: aya::programs::xdp
 impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::xdp::Xdp
+pub fn aya::programs::xdp::Xdp::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: aya_obj::programs::xdp::XdpAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8180,6 +8250,7 @@ impl<T> core::convert::From<T> for aya::programs::xdp::XdpError
 pub fn aya::programs::xdp::XdpError::from(t: T) -> T
 pub struct aya::programs::BtfTracePoint
 impl aya::programs::tp_btf::BtfTracePoint
+pub const aya::programs::tp_btf::BtfTracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::tp_btf::BtfTracePoint::attach(&mut self) -> core::result::Result<aya::programs::tp_btf::BtfTracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tp_btf::BtfTracePoint::load(&mut self, tracepoint: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
@@ -8190,6 +8261,8 @@ pub fn aya::programs::tp_btf::BtfTracePoint::fd(&self) -> core::result::Result<&
 impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
+pub unsafe fn aya::programs::tp_btf::BtfTracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8230,6 +8303,7 @@ impl<T> core::convert::From<T> for aya::programs::tp_btf::BtfTracePoint
 pub fn aya::programs::tp_btf::BtfTracePoint::from(t: T) -> T
 pub struct aya::programs::CgroupDevice
 impl aya::programs::cgroup_device::CgroupDevice
+pub const aya::programs::cgroup_device::CgroupDevice::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_device::CgroupDevice::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_device::CgroupDeviceLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_device::CgroupDevice::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::cgroup_device::CgroupDevice::query<T: std::os::fd::owned::AsFd>(target_fd: T) -> core::result::Result<alloc::vec::Vec<aya::programs::cgroup_device::CgroupDeviceLink>, aya::programs::ProgramError>
@@ -8241,6 +8315,8 @@ pub fn aya::programs::cgroup_device::CgroupDevice::fd(&self) -> core::result::Re
 impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::cgroup_device::CgroupDevice
+pub fn aya::programs::cgroup_device::CgroupDevice::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8281,6 +8357,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_device::CgroupDevice
 pub fn aya::programs::cgroup_device::CgroupDevice::from(t: T) -> T
 pub struct aya::programs::CgroupSkb
 impl aya::programs::cgroup_skb::CgroupSkb
+pub const aya::programs::cgroup_skb::CgroupSkb::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_skb::CgroupSkb::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, attach_type: aya::programs::cgroup_skb::CgroupSkbAttachType, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_skb::CgroupSkbLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_skb::CgroupSkb::expected_attach_type(&self) -> &core::option::Option<aya::programs::cgroup_skb::CgroupSkbAttachType>
 pub fn aya::programs::cgroup_skb::CgroupSkb::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, expected_attach_type: aya::programs::cgroup_skb::CgroupSkbAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
@@ -8291,6 +8368,8 @@ pub fn aya::programs::cgroup_skb::CgroupSkb::take_link(&mut self, link_id: aya::
 impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::cgroup_skb::CgroupSkb
+pub fn aya::programs::cgroup_skb::CgroupSkb::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: core::option::Option<aya::programs::cgroup_skb::CgroupSkbAttachType>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8331,6 +8410,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_skb::CgroupSkb
 pub fn aya::programs::cgroup_skb::CgroupSkb::from(t: T) -> T
 pub struct aya::programs::CgroupSock
 impl aya::programs::cgroup_sock::CgroupSock
+pub const aya::programs::cgroup_sock::CgroupSock::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sock::CgroupSock::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sock::CgroupSockLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock::CgroupSock::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sock::CgroupSockAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock::CgroupSock::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -8380,6 +8460,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_sock::CgroupSock
 pub fn aya::programs::cgroup_sock::CgroupSock::from(t: T) -> T
 pub struct aya::programs::CgroupSockAddr
 impl aya::programs::cgroup_sock_addr::CgroupSockAddr
+pub const aya::programs::cgroup_sock_addr::CgroupSockAddr::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sock_addr::CgroupSockAddrLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sock_addr::CgroupSockAddrAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -8429,6 +8510,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_sock_addr::CgroupSockAd
 pub fn aya::programs::cgroup_sock_addr::CgroupSockAddr::from(t: T) -> T
 pub struct aya::programs::CgroupSockopt
 impl aya::programs::cgroup_sockopt::CgroupSockopt
+pub const aya::programs::cgroup_sockopt::CgroupSockopt::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sockopt::CgroupSockoptLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -8438,6 +8520,8 @@ pub fn aya::programs::cgroup_sockopt::CgroupSockopt::take_link(&mut self, link_i
 impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::cgroup_sockopt::CgroupSockopt
+pub fn aya::programs::cgroup_sockopt::CgroupSockopt::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8478,6 +8562,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_sockopt::CgroupSockopt
 pub fn aya::programs::cgroup_sockopt::CgroupSockopt::from(t: T) -> T
 pub struct aya::programs::CgroupSysctl
 impl aya::programs::cgroup_sysctl::CgroupSysctl
+pub const aya::programs::cgroup_sysctl::CgroupSysctl::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::cgroup_sysctl::CgroupSysctlLinkId, aya::programs::ProgramError>
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
@@ -8488,6 +8573,8 @@ pub fn aya::programs::cgroup_sysctl::CgroupSysctl::fd(&self) -> core::result::Re
 impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
+pub fn aya::programs::cgroup_sysctl::CgroupSysctl::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8528,6 +8615,7 @@ impl<T> core::convert::From<T> for aya::programs::cgroup_sysctl::CgroupSysctl
 pub fn aya::programs::cgroup_sysctl::CgroupSysctl::from(t: T) -> T
 pub struct aya::programs::Extension
 impl aya::programs::extension::Extension
+pub const aya::programs::extension::Extension::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::extension::Extension::attach(&mut self) -> core::result::Result<aya::programs::extension::ExtensionLinkId, aya::programs::ProgramError>
 pub fn aya::programs::extension::Extension::attach_to_program(&mut self, program: &aya::programs::ProgramFd, func_name: &str) -> core::result::Result<aya::programs::extension::ExtensionLinkId, aya::programs::ProgramError>
 pub fn aya::programs::extension::Extension::load(&mut self, program: aya::programs::ProgramFd, func_name: &str) -> core::result::Result<(), aya::programs::ProgramError>
@@ -8539,6 +8627,8 @@ pub fn aya::programs::extension::Extension::fd(&self) -> core::result::Result<&a
 impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::extension::Extension
+pub fn aya::programs::extension::Extension::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8579,6 +8669,7 @@ impl<T> core::convert::From<T> for aya::programs::extension::Extension
 pub fn aya::programs::extension::Extension::from(t: T) -> T
 pub struct aya::programs::FEntry
 impl aya::programs::fentry::FEntry
+pub const aya::programs::fentry::FEntry::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::fentry::FEntry::attach(&mut self) -> core::result::Result<aya::programs::fentry::FEntryLinkId, aya::programs::ProgramError>
 pub fn aya::programs::fentry::FEntry::load(&mut self, fn_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
@@ -8589,6 +8680,8 @@ pub fn aya::programs::fentry::FEntry::fd(&self) -> core::result::Result<&aya::pr
 impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
+pub unsafe fn aya::programs::fentry::FEntry::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8629,6 +8722,7 @@ impl<T> core::convert::From<T> for aya::programs::fentry::FEntry
 pub fn aya::programs::fentry::FEntry::from(t: T) -> T
 pub struct aya::programs::FExit
 impl aya::programs::fexit::FExit
+pub const aya::programs::fexit::FExit::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::fexit::FExit::attach(&mut self) -> core::result::Result<aya::programs::fexit::FExitLinkId, aya::programs::ProgramError>
 pub fn aya::programs::fexit::FExit::load(&mut self, fn_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
@@ -8639,6 +8733,8 @@ pub fn aya::programs::fexit::FExit::fd(&self) -> core::result::Result<&aya::prog
 impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
+pub unsafe fn aya::programs::fexit::FExit::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8679,6 +8775,7 @@ impl<T> core::convert::From<T> for aya::programs::fexit::FExit
 pub fn aya::programs::fexit::FExit::from(t: T) -> T
 pub struct aya::programs::FlowDissector
 impl aya::programs::flow_dissector::FlowDissector
+pub const aya::programs::flow_dissector::FlowDissector::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::flow_dissector::FlowDissector::attach<T: std::os::fd::owned::AsFd>(&mut self, netns: T) -> core::result::Result<aya::programs::flow_dissector::FlowDissectorLinkId, aya::programs::ProgramError>
 pub fn aya::programs::flow_dissector::FlowDissector::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::flow_dissector::FlowDissector
@@ -8729,6 +8826,7 @@ impl<T> core::convert::From<T> for aya::programs::flow_dissector::FlowDissector
 pub fn aya::programs::flow_dissector::FlowDissector::from(t: T) -> T
 pub struct aya::programs::Iter
 impl aya::programs::iter::Iter
+pub const aya::programs::iter::Iter::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::iter::Iter::attach(&mut self) -> core::result::Result<aya::programs::iter::IterLinkId, aya::programs::ProgramError>
 pub fn aya::programs::iter::Iter::load(&mut self, iter_type: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::iter::Iter
@@ -8739,6 +8837,8 @@ pub fn aya::programs::iter::Iter::fd(&self) -> core::result::Result<&aya::progra
 impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::iter::Iter
+pub fn aya::programs::iter::Iter::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8779,6 +8879,7 @@ impl<T> core::convert::From<T> for aya::programs::iter::Iter
 pub fn aya::programs::iter::Iter::from(t: T) -> T
 pub struct aya::programs::KProbe
 impl aya::programs::kprobe::KProbe
+pub const aya::programs::kprobe::KProbe::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::kprobe::KProbe::attach<T: core::convert::AsRef<std::ffi::os_str::OsStr>>(&mut self, fn_name: T, offset: u64) -> core::result::Result<aya::programs::kprobe::KProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::kprobe::KProbe::kind(&self) -> aya::programs::ProbeKind
@@ -8789,6 +8890,8 @@ pub fn aya::programs::kprobe::KProbe::take_link(&mut self, link_id: aya::program
 impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::kprobe::KProbe
+pub unsafe fn aya::programs::kprobe::KProbe::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::kprobe::KProbe
 pub fn aya::programs::kprobe::KProbe::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8865,6 +8968,7 @@ impl<T> core::convert::From<T> for aya::programs::links::LinkOrder
 pub fn aya::programs::links::LinkOrder::from(t: T) -> T
 pub struct aya::programs::LircMode2
 impl aya::programs::lirc_mode2::LircMode2
+pub const aya::programs::lirc_mode2::LircMode2::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::lirc_mode2::LircMode2::attach<T: std::os::fd::owned::AsFd>(&mut self, lircdev: T) -> core::result::Result<aya::programs::lirc_mode2::LircLinkId, aya::programs::ProgramError>
 pub fn aya::programs::lirc_mode2::LircMode2::detach(&mut self, link_id: aya::programs::lirc_mode2::LircLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::lirc_mode2::LircMode2::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -8875,6 +8979,8 @@ pub fn aya::programs::lirc_mode2::LircMode2::fd(&self) -> core::result::Result<&
 impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::lirc_mode2::LircMode2
+pub fn aya::programs::lirc_mode2::LircMode2::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8915,6 +9021,7 @@ impl<T> core::convert::From<T> for aya::programs::lirc_mode2::LircMode2
 pub fn aya::programs::lirc_mode2::LircMode2::from(t: T) -> T
 pub struct aya::programs::Lsm
 impl aya::programs::lsm::Lsm
+pub const aya::programs::lsm::Lsm::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::lsm::Lsm::attach(&mut self) -> core::result::Result<aya::programs::lsm::LsmLinkId, aya::programs::ProgramError>
 pub fn aya::programs::lsm::Lsm::load(&mut self, lsm_hook_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
@@ -8925,6 +9032,8 @@ pub fn aya::programs::lsm::Lsm::fd(&self) -> core::result::Result<&aya::programs
 impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
+pub fn aya::programs::lsm::Lsm::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -8965,6 +9074,7 @@ impl<T> core::convert::From<T> for aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::from(t: T) -> T
 pub struct aya::programs::PerfEvent
 impl aya::programs::perf_event::PerfEvent
+pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
@@ -8975,6 +9085,8 @@ pub fn aya::programs::perf_event::PerfEvent::fd(&self) -> core::result::Result<&
 impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
+pub fn aya::programs::perf_event::PerfEvent::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::perf_event::PerfEvent
 pub fn aya::programs::perf_event::PerfEvent::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9113,6 +9225,7 @@ impl<T> core::convert::From<T> for aya::programs::ProgramInfo
 pub fn aya::programs::ProgramInfo::from(t: T) -> T
 pub struct aya::programs::RawTracePoint
 impl aya::programs::raw_trace_point::RawTracePoint
+pub const aya::programs::raw_trace_point::RawTracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::raw_trace_point::RawTracePoint::attach(&mut self, tp_name: &str) -> core::result::Result<aya::programs::raw_trace_point::RawTracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::raw_trace_point::RawTracePoint::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
@@ -9123,6 +9236,8 @@ pub fn aya::programs::raw_trace_point::RawTracePoint::fd(&self) -> core::result:
 impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
+pub fn aya::programs::raw_trace_point::RawTracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9163,6 +9278,7 @@ impl<T> core::convert::From<T> for aya::programs::raw_trace_point::RawTracePoint
 pub fn aya::programs::raw_trace_point::RawTracePoint::from(t: T) -> T
 pub struct aya::programs::SchedClassifier
 impl aya::programs::tc::SchedClassifier
+pub const aya::programs::tc::SchedClassifier::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::tc::SchedClassifier::attach(&mut self, interface: &str, attach_type: aya::programs::tc::TcAttachType) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tc::SchedClassifier::attach_to_link(&mut self, link: aya::programs::tc::SchedClassifierLink) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
 pub fn aya::programs::tc::SchedClassifier::attach_with_options(&mut self, interface: &str, attach_type: aya::programs::tc::TcAttachType, options: aya::programs::tc::TcAttachOptions) -> core::result::Result<aya::programs::tc::SchedClassifierLinkId, aya::programs::ProgramError>
@@ -9175,6 +9291,8 @@ pub fn aya::programs::tc::SchedClassifier::take_link(&mut self, link_id: aya::pr
 impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::tc::SchedClassifier
+pub fn aya::programs::tc::SchedClassifier::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9217,6 +9335,7 @@ impl<T> core::convert::From<T> for aya::programs::tc::SchedClassifier
 pub fn aya::programs::tc::SchedClassifier::from(t: T) -> T
 pub struct aya::programs::SkLookup
 impl aya::programs::sk_lookup::SkLookup
+pub const aya::programs::sk_lookup::SkLookup::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_lookup::SkLookup::attach<T: std::os::fd::owned::AsFd>(&mut self, netns: T) -> core::result::Result<aya::programs::sk_lookup::SkLookupLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_lookup::SkLookup::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
@@ -9227,6 +9346,8 @@ pub fn aya::programs::sk_lookup::SkLookup::fd(&self) -> core::result::Result<&ay
 impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
+pub fn aya::programs::sk_lookup::SkLookup::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9267,6 +9388,7 @@ impl<T> core::convert::From<T> for aya::programs::sk_lookup::SkLookup
 pub fn aya::programs::sk_lookup::SkLookup::from(t: T) -> T
 pub struct aya::programs::SkMsg
 impl aya::programs::sk_msg::SkMsg
+pub const aya::programs::sk_msg::SkMsg::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_msg::SkMsg::attach(&mut self, map: &aya::maps::sock::SockMapFd) -> core::result::Result<aya::programs::sk_msg::SkMsgLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_msg::SkMsg::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
@@ -9277,6 +9399,8 @@ pub fn aya::programs::sk_msg::SkMsg::fd(&self) -> core::result::Result<&aya::pro
 impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
+pub fn aya::programs::sk_msg::SkMsg::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9317,6 +9441,7 @@ impl<T> core::convert::From<T> for aya::programs::sk_msg::SkMsg
 pub fn aya::programs::sk_msg::SkMsg::from(t: T) -> T
 pub struct aya::programs::SkSkb
 impl aya::programs::sk_skb::SkSkb
+pub const aya::programs::sk_skb::SkSkb::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sk_skb::SkSkb::attach(&mut self, map: &aya::maps::sock::SockMapFd) -> core::result::Result<aya::programs::sk_skb::SkSkbLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sk_skb::SkSkb::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::sk_skb::SkSkbKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::sk_skb::SkSkb::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -9326,6 +9451,8 @@ pub fn aya::programs::sk_skb::SkSkb::take_link(&mut self, link_id: aya::programs
 impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::sk_skb::SkSkb
+pub fn aya::programs::sk_skb::SkSkb::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::sk_skb::SkSkbKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9366,6 +9493,7 @@ impl<T> core::convert::From<T> for aya::programs::sk_skb::SkSkb
 pub fn aya::programs::sk_skb::SkSkb::from(t: T) -> T
 pub struct aya::programs::SockOps
 impl aya::programs::sock_ops::SockOps
+pub const aya::programs::sock_ops::SockOps::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::sock_ops::SockOps::attach<T: std::os::fd::owned::AsFd>(&mut self, cgroup: T, mode: aya::programs::links::CgroupAttachMode) -> core::result::Result<aya::programs::sock_ops::SockOpsLinkId, aya::programs::ProgramError>
 pub fn aya::programs::sock_ops::SockOps::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
@@ -9376,6 +9504,8 @@ pub fn aya::programs::sock_ops::SockOps::fd(&self) -> core::result::Result<&aya:
 impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
+pub fn aya::programs::sock_ops::SockOps::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9416,6 +9546,7 @@ impl<T> core::convert::From<T> for aya::programs::sock_ops::SockOps
 pub fn aya::programs::sock_ops::SockOps::from(t: T) -> T
 pub struct aya::programs::SocketFilter
 impl aya::programs::socket_filter::SocketFilter
+pub const aya::programs::socket_filter::SocketFilter::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::socket_filter::SocketFilter::attach<T: std::os::fd::owned::AsFd>(&mut self, socket: T) -> core::result::Result<aya::programs::socket_filter::SocketFilterLinkId, aya::programs::ProgramError>
 pub fn aya::programs::socket_filter::SocketFilter::detach(&mut self, link_id: aya::programs::socket_filter::SocketFilterLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::socket_filter::SocketFilter::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@@ -9465,6 +9596,7 @@ impl<T> core::convert::From<T> for aya::programs::socket_filter::SocketFilter
 pub fn aya::programs::socket_filter::SocketFilter::from(t: T) -> T
 pub struct aya::programs::TracePoint
 impl aya::programs::trace_point::TracePoint
+pub const aya::programs::trace_point::TracePoint::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::trace_point::TracePoint::attach(&mut self, category: &str, name: &str) -> core::result::Result<aya::programs::trace_point::TracePointLinkId, aya::programs::ProgramError>
 pub fn aya::programs::trace_point::TracePoint::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
@@ -9475,6 +9607,8 @@ pub fn aya::programs::trace_point::TracePoint::fd(&self) -> core::result::Result
 impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
+pub fn aya::programs::trace_point::TracePoint::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9515,6 +9649,7 @@ impl<T> core::convert::From<T> for aya::programs::trace_point::TracePoint
 pub fn aya::programs::trace_point::TracePoint::from(t: T) -> T
 pub struct aya::programs::UProbe
 impl aya::programs::uprobe::UProbe
+pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Loc: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'loc>>>(&mut self, location: Loc, target: T, pid: core::option::Option<libc::unix::pid_t>, cookie: core::option::Option<u64>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
 pub fn aya::programs::uprobe::UProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
 pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind
@@ -9525,6 +9660,8 @@ pub fn aya::programs::uprobe::UProbe::take_link(&mut self, link_id: aya::program
 impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::uprobe::UProbe
+pub unsafe fn aya::programs::uprobe::UProbe::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@@ -9565,6 +9702,7 @@ impl<T> core::convert::From<T> for aya::programs::uprobe::UProbe
 pub fn aya::programs::uprobe::UProbe::from(t: T) -> T
 pub struct aya::programs::Xdp
 impl aya::programs::xdp::Xdp
+pub const aya::programs::xdp::Xdp::PROGRAM_TYPE: aya::programs::ProgramType
 pub fn aya::programs::xdp::Xdp::attach(&mut self, interface: &str, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
 pub fn aya::programs::xdp::Xdp::attach_to_if_index(&mut self, if_index: u32, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
 pub fn aya::programs::xdp::Xdp::attach_to_link(&mut self, link: aya::programs::xdp::XdpLink) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
@@ -9576,6 +9714,8 @@ pub fn aya::programs::xdp::Xdp::take_link(&mut self, link_id: aya::programs::xdp
 impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
 impl aya::programs::xdp::Xdp
+pub fn aya::programs::xdp::Xdp::from_program_info(info: aya::programs::ProgramInfo, name: alloc::borrow::Cow<'static, str>, attach_type: aya_obj::programs::xdp::XdpAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
+impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
 impl aya::programs::xdp::Xdp
 pub fn aya::programs::xdp::Xdp::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>