Skip to content

libbpf-cargo: Relative anonymous type naming for struct fields #1178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion libbpf-cargo/src/gen/btf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::fmt::Write;
use std::mem::size_of;
use std::num::NonZeroUsize;
use std::ops::Deref;
use std::rc::Rc;

use anyhow::anyhow;
use anyhow::bail;
Expand Down Expand Up @@ -367,6 +368,20 @@ fn escape_reserved_keyword(identifier: Cow<'_, str>) -> Cow<'_, str> {
}
}

#[derive(Debug, Clone)]
struct BtfDependency {
/// Name of the dependency parent
parent_name: Option<String>,

/// Dependency id relative to the parent's `child_counter`
dep_id: i32,

/// The `child_counter` for the dependency if it is intended to be
/// a parent itself.
/// For an anonymous unit this should be a pointer to the parent's `child_counter`
child_counter: Rc<RefCell<i32>>,
}

#[derive(Debug, Default)]
pub(crate) struct TypeMap {
/// A mapping from type to number, allowing us to assign numbers to
Expand All @@ -377,15 +392,75 @@ pub(crate) struct TypeMap {
/// Mapping from type name to the number of times we have seen this
/// name already.
names_count: RefCell<HashMap<String, u8>>,

/// Mapping from type to it's parent. Used in anonymous members naming
dependency_tree: RefCell<HashMap<TypeId, BtfDependency>>,
}

impl TypeMap {
fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
let mut deps = self.dependency_tree.borrow_mut();
if deps.get(&ty.type_id()).is_some() {
return;
}

let pdep = deps.entry(parent.type_id()).or_insert(BtfDependency {
parent_name: None,
dep_id: 0,
child_counter: Rc::new(RefCell::new(0)),
});

let mut dep = pdep.clone();

// If parent is named, derive it.
// Otherwise derive parent's parent
if let Some(n) = parent.name() {
dep.parent_name = Some(n.to_string_lossy().to_string());
}

// If the current unit is named, self-assign the child_counter.
// Otherwise derive a parent's one
if ty.name().is_some() {
dep.child_counter = Rc::new(RefCell::new(0));
}

// Increment parent's `child_counter` and assign the new value to dep_id
let parent_counter = Rc::clone(&pdep.child_counter);
*parent_counter.borrow_mut() += 1;
dep.dep_id = *parent_counter.borrow();

deps.insert(ty.type_id(), dep);
}

fn lookup_parent<'s>(&self, ty: &BtfType<'s>) -> Option<BtfDependency> {
self.dependency_tree.borrow().get(&ty.type_id()).cloned()
}

pub fn type_name_or_anon<'s>(&self, ty: &BtfType<'s>) -> Cow<'s, str> {
match ty.name() {
None => {
let mut anon_table = self.types.borrow_mut();
let len = anon_table.len() + 1; // use 1 index anon ids for backwards compat
let anon_id = anon_table.entry(ty.type_id()).or_insert(len);

let anon_id = match anon_table.entry(ty.type_id()) {
Entry::Occupied(anon_id) => {
let anon_id = anon_id.get();
*anon_id
}
Entry::Vacant(anon_id) => {
if let Some(dep) = self.lookup_parent(ty) {
if let Some(name) = dep.parent_name {
if !name.is_empty() {
return format!("{ANON_PREFIX}{}_{}", name, dep.dep_id).into();
}
}
}

let anon_id = anon_id.insert(len);
*anon_id
}
};

format!("{ANON_PREFIX}{anon_id}").into()
}
Some(n) => match self.names.borrow_mut().entry(ty.type_id()) {
Expand Down Expand Up @@ -726,6 +801,7 @@ impl<'s> GenBtf<'s> {
}

if let Some(next_ty_id) = next_type(field_ty)? {
self.type_map.derive_parent(&next_ty_id, &t);
dependent_types.push(next_ty_id);
}
let field_name = if let Some(name) = member.name {
Expand Down
Loading
Loading