1use std::path::Path;
2use std::ptr::null_mut;
3use std::ptr::NonNull;
4
5use crate::util::path_to_cstring;
6use crate::util::validate_bpf_ret;
7use crate::AsRawLibbpf;
8use crate::Error;
9use crate::ErrorExt as _;
10use crate::Result;
11
12#[derive(Debug)]
18#[doc(alias = "bpf_linker")]
19pub struct Linker {
20 linker: NonNull<libbpf_sys::bpf_linker>,
22}
23
24impl Linker {
25 #[doc(alias = "bpf_linker__new")]
27 pub fn new<P>(output: P) -> Result<Self>
28 where
29 P: AsRef<Path>,
30 {
31 let output = path_to_cstring(output)?;
32 let opts = null_mut();
33 let ptr = unsafe { libbpf_sys::bpf_linker__new(output.as_ptr(), opts) };
35 let ptr = validate_bpf_ret(ptr).context("failed to attach iterator")?;
36 let slf = Self { linker: ptr };
37 Ok(slf)
38 }
39
40 #[doc(alias = "bpf_linker__add_file")]
42 pub fn add_file<P>(&mut self, file: P) -> Result<()>
43 where
44 P: AsRef<Path>,
45 {
46 let file = path_to_cstring(file)?;
47 let opts = null_mut();
48 let err =
50 unsafe { libbpf_sys::bpf_linker__add_file(self.linker.as_ptr(), file.as_ptr(), opts) };
51 if err != 0 {
52 Err(Error::from_raw_os_error(err)).context("bpf_linker__add_file failed")
53 } else {
54 Ok(())
55 }
56 }
57
58 #[doc(alias = "bpf_linker__add_buf")]
60 pub fn add_buf(&mut self, buf: &[u8]) -> Result<()> {
61 let opts = null_mut();
62 let err = unsafe {
64 libbpf_sys::bpf_linker__add_buf(
65 self.linker.as_ptr(),
66 buf.as_ptr().cast_mut().cast(),
67 buf.len() as _,
68 opts,
69 )
70 };
71 if err != 0 {
72 Err(Error::from_raw_os_error(err)).context("bpf_linker__add_buf failed")
73 } else {
74 Ok(())
75 }
76 }
77
78 #[doc(alias = "bpf_linker__finalize")]
81 pub fn link(&self) -> Result<()> {
82 let err = unsafe { libbpf_sys::bpf_linker__finalize(self.linker.as_ptr()) };
84 if err != 0 {
85 return Err(Error::from_raw_os_error(err)).context("bpf_linker__finalize failed");
86 }
87 Ok(())
88 }
89}
90
91impl AsRawLibbpf for Linker {
92 type LibbpfType = libbpf_sys::bpf_linker;
93
94 fn as_libbpf_object(&self) -> NonNull<Self::LibbpfType> {
96 self.linker
97 }
98}
99
100unsafe impl Send for Linker {}
102
103impl Drop for Linker {
104 #[doc(alias = "bpf_linker__free")]
105 fn drop(&mut self) {
106 unsafe { libbpf_sys::bpf_linker__free(self.linker.as_ptr()) }
108 }
109}
110
111#[cfg(test)]
112mod test {
113 use super::*;
114
115 #[test]
117 fn linker_is_send() {
118 fn test<T>()
119 where
120 T: Send,
121 {
122 }
123
124 test::<Linker>();
125 }
126}