Skip to content

Commit

Permalink
libbpf-cargo: Move generated struct_ops type out of types module
Browse files Browse the repository at this point in the history
The struct_ops type is basically a libbpf-cargo construct -- there is no
corresponding C type to be found in the BTF information (there is
something similar in the C skeleton, but that is entirely orthogonal).
However, because we generate this type inside the types module, which is
the dumping ground for all Rust types with C equivalents, there is the
potential for conflicts. For example, the kernel actually does have a
type called struct_ops itself. That is not currently a problem, but it
may become one once we generate Rust types for more of the C ones
present in BTF.
To fix this issue, move the generated struct_ops type out of the types
module and into the "global" (from the skeleton's view) namespace. Also
rename it to StructOps as an indication that this is a Rust construct
without a C direct equivalent, similar to other generated types such as
Open*Maps, Open*Progs, etc.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o authored and danielocfb committed Jul 24, 2024
1 parent 0e65531 commit 95ad476
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 51 deletions.
2 changes: 2 additions & 0 deletions libbpf-cargo/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Unreleased
- Adjusted skeleton creation logic to generate Rust types for types used in BPF
maps
- Renamed module for generated Rust types from `<project>_types` to just `types`
- Renamed generated `struct_ops` type to `StructOps` and moved it out of `types`
module


0.23.3
Expand Down
14 changes: 7 additions & 7 deletions libbpf-cargo/src/gen/btf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,21 @@ impl<'btf> GenStructOps<'btf> {
}

pub fn gen_struct_ops_def(&self, def: &mut String) -> Result<()> {
// Emit a single struct_ops definition containing all variables
// discovered earlier.
// Emit a single struct_ops type definition containing all
// variables discovered earlier.
write!(
def,
r#"
#[derive(Debug, Clone)]
#[repr(C)]
pub struct struct_ops {{
pub struct StructOps {{
"#
)?;

for var in self.vars.iter() {
writeln!(
def,
r#" pub {var_name}: *mut {var_type},"#,
r#" pub {var_name}: *mut types::{var_type},"#,
var_name = var.name().unwrap().to_string_lossy(),
var_type = self.btf.type_declaration(**var)?
)?;
Expand All @@ -358,21 +358,21 @@ pub struct struct_ops {{
write!(
def,
r#"
impl struct_ops {{
impl StructOps {{
"#
)?;

for var in self.vars.iter() {
write!(
def,
r#"
pub fn {var_name}(&self) -> &{var_type} {{
pub fn {var_name}(&self) -> &types::{var_type} {{
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe {{ self.{var_name}.as_ref() }}.unwrap()
}}
pub fn {var_name}_mut(&mut self) -> &mut {var_type} {{
pub fn {var_name}_mut(&mut self) -> &mut types::{var_type} {{
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe {{ self.{var_name}.as_mut() }}.unwrap()
Expand Down
72 changes: 36 additions & 36 deletions libbpf-cargo/src/gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,28 +730,6 @@ fn gen_skel_prog_defs(skel: &mut String, progs: &ProgsData, raw_obj_name: &str)
}


fn gen_skel_struct_ops_types(
skel: &mut String,
btf: Option<&GenBtf<'_>>,
processed: &mut HashSet<TypeId>,
) -> Result<()> {
if let Some(btf) = btf {
let gen = GenStructOps::new(btf)?;
let () = gen.gen_struct_ops_def(skel)?;
let () = gen.gen_dependent_types(processed, skel)?;
} else {
write!(
skel,
"
#[derive(Debug, Clone)]
#[repr(C)]
pub struct struct_ops {{}}
"
)?;
}
Ok(())
}

fn gen_skel_datasec_types(
skel: &mut String,
btf: Option<&GenBtf<'_>>,
Expand Down Expand Up @@ -825,11 +803,11 @@ fn gen_skel_struct_ops_getters(skel: &mut String, object: &Object) -> Result<()>
write!(
skel,
"\
pub fn struct_ops_raw(&self) -> *const types::struct_ops {{
pub fn struct_ops_raw(&self) -> *const StructOps {{
&self.struct_ops
}}
pub fn struct_ops(&self) -> &types::struct_ops {{
pub fn struct_ops(&self) -> &StructOps {{
&self.struct_ops
}}
",
Expand Down Expand Up @@ -1077,19 +1055,41 @@ fn gen_skel_contents(_debug: bool, raw_obj_name: &str, obj_file_path: &Path) ->
struct_ops_init = gen_skel_struct_ops_init(&object)?,
)?;

write!(
skel,
"\
pub mod types {{
#[allow(unused_imports)]
use super::*;
"
)?;

let mut processed = HashSet::new();
// Generate struct_ops types before anything else, as they are slightly
// modified compared to the dumb structure contained in BTF.
gen_skel_struct_ops_types(&mut skel, btf.as_ref(), &mut processed)?;
if let Some(btf) = &btf {
let gen = GenStructOps::new(btf)?;
let () = gen.gen_struct_ops_def(&mut skel)?;
write!(
skel,
"\
pub mod types {{
#[allow(unused_imports)]
use super::*;
"
)?;

let () = gen.gen_dependent_types(&mut processed, &mut skel)?;
} else {
write!(
skel,
"
#[derive(Debug, Clone)]
#[repr(C)]
pub struct StructOps {{}}
"
)?;
write!(
skel,
"\
pub mod types {{
#[allow(unused_imports)]
use super::*;
"
)?;
}

gen_skel_datasec_types(&mut skel, btf.as_ref(), &mut processed)?;
gen_skel_map_types(&mut skel, &object, btf.as_ref(), &mut processed)?;
writeln!(skel, "}}")?;
Expand All @@ -1101,7 +1101,7 @@ fn gen_skel_contents(_debug: bool, raw_obj_name: &str, obj_file_path: &Path) ->
pub obj: &'obj mut libbpf_rs::OpenObject,
pub maps: Open{name}Maps<'obj>,
pub progs: Open{name}Progs<'obj>,
pub struct_ops: types::struct_ops,
pub struct_ops: StructOps,
skel_config: libbpf_rs::__internal_skel::ObjectSkeletonConfig<'obj>,
}}
Expand Down Expand Up @@ -1168,7 +1168,7 @@ fn gen_skel_contents(_debug: bool, raw_obj_name: &str, obj_file_path: &Path) ->
pub obj: &'obj mut libbpf_rs::Object,
pub maps: {name}Maps<'obj>,
pub progs: {name}Progs<'obj>,
struct_ops: types::struct_ops,
struct_ops: StructOps,
skel_config: libbpf_rs::__internal_skel::ObjectSkeletonConfig<'obj>,
",
name = &obj_name,
Expand Down
16 changes: 8 additions & 8 deletions libbpf-cargo/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2999,32 +2999,32 @@ struct bpf_dummy_ops dummy_2 = {
let expected_output = r#"
#[derive(Debug, Clone)]
#[repr(C)]
pub struct struct_ops {
pub dummy_1: *mut bpf_dummy_ops,
pub dummy_2: *mut bpf_dummy_ops,
pub struct StructOps {
pub dummy_1: *mut types::bpf_dummy_ops,
pub dummy_2: *mut types::bpf_dummy_ops,
}
impl struct_ops {
impl StructOps {
pub fn dummy_1(&self) -> &bpf_dummy_ops {
pub fn dummy_1(&self) -> &types::bpf_dummy_ops {
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe { self.dummy_1.as_ref() }.unwrap()
}
pub fn dummy_1_mut(&mut self) -> &mut bpf_dummy_ops {
pub fn dummy_1_mut(&mut self) -> &mut types::bpf_dummy_ops {
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe { self.dummy_1.as_mut() }.unwrap()
}
pub fn dummy_2(&self) -> &bpf_dummy_ops {
pub fn dummy_2(&self) -> &types::bpf_dummy_ops {
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe { self.dummy_2.as_ref() }.unwrap()
}
pub fn dummy_2_mut(&mut self) -> &mut bpf_dummy_ops {
pub fn dummy_2_mut(&mut self) -> &mut types::bpf_dummy_ops {
// SAFETY: The library ensures that the member is pointing to
// valid data.
unsafe { self.dummy_2.as_mut() }.unwrap()
Expand Down

0 comments on commit 95ad476

Please sign in to comment.