1
1
use core:: ffi:: c_void;
2
2
use std:: collections:: HashMap ;
3
3
use std:: ffi:: CStr ;
4
+ use std:: ffi:: CString ;
4
5
use std:: mem;
5
- use std:: os:: raw:: c_char;
6
6
use std:: path:: Path ;
7
7
use std:: ptr:: NonNull ;
8
8
use std:: ptr:: { self } ;
@@ -20,22 +20,42 @@ use crate::Program;
20
20
use crate :: Result ;
21
21
22
22
/// Builder for creating an [`OpenObject`]. Typically the entry point into libbpf-rs.
23
- #[ derive( Default , Debug ) ]
23
+ #[ derive( Debug ) ]
24
24
pub struct ObjectBuilder {
25
- name : String ,
26
- relaxed_maps : bool ,
25
+ name : Option < CString > ,
26
+
27
+ opts : libbpf_sys:: bpf_object_open_opts ,
28
+ }
29
+
30
+ impl Default for ObjectBuilder {
31
+ fn default ( ) -> Self {
32
+ let opts = libbpf_sys:: bpf_object_open_opts {
33
+ sz : mem:: size_of :: < libbpf_sys:: bpf_object_open_opts > ( ) as libbpf_sys:: size_t ,
34
+ object_name : ptr:: null ( ) ,
35
+ relaxed_maps : false ,
36
+ pin_root_path : ptr:: null ( ) ,
37
+ kconfig : ptr:: null ( ) ,
38
+ btf_custom_path : ptr:: null ( ) ,
39
+ kernel_log_buf : ptr:: null_mut ( ) ,
40
+ kernel_log_size : 0 ,
41
+ kernel_log_level : 0 ,
42
+ ..Default :: default ( )
43
+ } ;
44
+ Self { name : None , opts }
45
+ }
27
46
}
28
47
29
48
impl ObjectBuilder {
30
49
/// Override the generated name that would have been inferred from the constructor.
31
- pub fn name < T : AsRef < str > > ( & mut self , name : T ) -> & mut Self {
32
- self . name = name. as_ref ( ) . to_string ( ) ;
33
- self
50
+ pub fn name < T : AsRef < str > > ( & mut self , name : T ) -> Result < & mut Self > {
51
+ self . name = Some ( util:: str_to_cstring ( name. as_ref ( ) ) ?) ;
52
+ self . opts . object_name = self . name . as_ref ( ) . map_or ( ptr:: null ( ) , |p| p. as_ptr ( ) ) ;
53
+ Ok ( self )
34
54
}
35
55
36
56
/// Option to parse map definitions non-strictly, allowing extra attributes/data
37
57
pub fn relaxed_maps ( & mut self , relaxed_maps : bool ) -> & mut Self {
38
- self . relaxed_maps = relaxed_maps;
58
+ self . opts . relaxed_maps = relaxed_maps;
39
59
self
40
60
}
41
61
@@ -52,20 +72,13 @@ impl ObjectBuilder {
52
72
self
53
73
}
54
74
55
- /// Get an instance of libbpf_sys::bpf_object_open_opts.
56
- pub fn opts ( & mut self , name : * const c_char ) -> libbpf_sys:: bpf_object_open_opts {
57
- libbpf_sys:: bpf_object_open_opts {
58
- sz : mem:: size_of :: < libbpf_sys:: bpf_object_open_opts > ( ) as libbpf_sys:: size_t ,
59
- object_name : name,
60
- relaxed_maps : self . relaxed_maps ,
61
- pin_root_path : ptr:: null ( ) ,
62
- kconfig : ptr:: null ( ) ,
63
- btf_custom_path : ptr:: null ( ) ,
64
- kernel_log_buf : ptr:: null_mut ( ) ,
65
- kernel_log_size : 0 ,
66
- kernel_log_level : 0 ,
67
- ..Default :: default ( )
68
- }
75
+ /// Get the raw libbpf_sys::bpf_object_open_opts.
76
+ ///
77
+ /// The internal pointers are tied to the lifetime of the
78
+ /// ObjectBuilder, so be wary when copying the struct or otherwise
79
+ /// handing the lifetime over to C.
80
+ pub fn opts ( & self ) -> & libbpf_sys:: bpf_object_open_opts {
81
+ & self . opts
69
82
}
70
83
71
84
/// Open an object using the provided path on the file system.
@@ -77,43 +90,23 @@ impl ObjectBuilder {
77
90
let path_c = util:: str_to_cstring ( path_str) ?;
78
91
let path_ptr = path_c. as_ptr ( ) ;
79
92
80
- // Convert name to a C style pointer
81
- //
82
- // NB: we must hold onto a CString otherwise our pointer dangles
83
- let name = util:: str_to_cstring ( & self . name ) ?;
84
- let name_ptr = if !self . name . is_empty ( ) {
85
- name. as_ptr ( )
86
- } else {
87
- ptr:: null ( )
88
- } ;
89
-
90
- let opts = self . opts ( name_ptr) ;
93
+ let opts = self . opts ( ) ;
91
94
92
95
util:: create_bpf_entity_checked ( || unsafe {
93
- libbpf_sys:: bpf_object__open_file ( path_ptr, & opts)
96
+ libbpf_sys:: bpf_object__open_file ( path_ptr, opts)
94
97
} )
95
98
. and_then ( |ptr| unsafe { OpenObject :: new ( ptr) } )
96
99
}
97
100
98
101
/// Open an object from memory.
99
- pub fn open_memory < T : AsRef < str > > ( & mut self , name : T , mem : & [ u8 ] ) -> Result < OpenObject > {
100
- // Convert name to a C style pointer
101
- //
102
- // NB: we must hold onto a CString otherwise our pointer dangles
103
- let name = util:: str_to_cstring ( name. as_ref ( ) ) ?;
104
- let name_ptr = if !name. to_bytes ( ) . is_empty ( ) {
105
- name. as_ptr ( )
106
- } else {
107
- ptr:: null ( )
108
- } ;
109
-
110
- let opts = self . opts ( name_ptr) ;
102
+ pub fn open_memory ( & mut self , mem : & [ u8 ] ) -> Result < OpenObject > {
103
+ let opts = self . opts ( ) ;
111
104
112
105
util:: create_bpf_entity_checked ( || unsafe {
113
106
libbpf_sys:: bpf_object__open_mem (
114
107
mem. as_ptr ( ) as * const c_void ,
115
108
mem. len ( ) as libbpf_sys:: size_t ,
116
- & opts,
109
+ opts,
117
110
)
118
111
} )
119
112
. and_then ( |ptr| unsafe { OpenObject :: new ( ptr) } )
0 commit comments