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

Merged
merged 3 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
64 changes: 64 additions & 0 deletions 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,13 @@ fn escape_reserved_keyword(identifier: Cow<'_, str>) -> Cow<'_, str> {
}
}

#[derive(Debug, Clone)]
pub struct BtfDependency {
pub name: Option<String>,
pub dep_id: i32,
pub 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 +385,70 @@ 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>>,

dependencies: RefCell<HashMap<TypeId, BtfDependency>>,
}

impl TypeMap {
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the name really fitting? Aren't you more registering a parent relationship rather than "deriving" anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assign_parent?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps register_parent would fit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

let mut deps = self.dependencies.borrow_mut();
if deps.get(&ty.type_id()).is_some() {
return;
}

let parent_dep = deps.get(&parent.type_id());
if let Some(pdep) = parent_dep {
let mut dep = pdep.clone();

if let Some(n) = parent.name() {
dep.name = Some(n.to_string_lossy().to_string());
}
if ty.name().is_some() {
dep.child_counter = Rc::new(RefCell::new(0));
}

let parent_counter = Rc::<RefCell<i32>>::clone(&pdep.child_counter);
*parent_counter.borrow_mut() += 1;
dep.dep_id = *parent_counter.borrow();

deps.insert(ty.type_id(), dep);
} else {
let mut dep = BtfDependency {
name: None,
dep_id: 0,
child_counter: Rc::new(RefCell::new(1)),
};
deps.insert(parent.type_id(), dep.clone());

if let Some(n) = parent.name() {
dep.name = Some(n.to_string_lossy().to_string());
}
if ty.name().is_some() {
dep.child_counter = Rc::new(RefCell::new(0));
}
dep.dep_id = 1;
deps.insert(ty.type_id(), dep);
}
}

pub fn lookup_parent<'s>(&self, ty: &BtfType<'s>) -> Option<BtfDependency> {
self.dependencies.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);

if let Some(parent) = self.lookup_parent(ty) {
if let Some(name) = parent.name {
if !name.is_empty() {
return format!("{ANON_PREFIX}{}_{}", name, parent.dep_id).into();
}
}
}
format!("{ANON_PREFIX}{anon_id}").into()
}
Some(n) => match self.names.borrow_mut().entry(ty.type_id()) {
Expand Down Expand Up @@ -726,6 +789,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
98 changes: 49 additions & 49 deletions libbpf-cargo/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2514,24 +2514,24 @@ struct Foo foo;
#[repr(C)]
pub struct Foo {
pub x: i32,
pub bar: __anon_1,
pub bar: __anon_Foo_1,
pub __pad_36: [u8; 4],
pub baz: __anon_2,
pub baz: __anon_Foo_2,
pub w: i32,
pub __pad_52: [u8; 4],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_1 {
pub union __anon_Foo_1 {
pub y: [u8; 10],
pub z: [u16; 16],
}
impl std::fmt::Debug for __anon_1 {
impl std::fmt::Debug for __anon_Foo_1 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_1 {
impl Default for __anon_Foo_1 {
fn default() -> Self {
Self {
y: [u8::default(); 10],
Expand All @@ -2540,16 +2540,16 @@ impl Default for __anon_1 {
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_2 {
pub union __anon_Foo_2 {
pub w: u32,
pub u: *mut u64,
}
impl std::fmt::Debug for __anon_2 {
impl std::fmt::Debug for __anon_Foo_2 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_2 {
impl Default for __anon_Foo_2 {
fn default() -> Self {
Self {
w: u32::default(),
Expand Down Expand Up @@ -2594,25 +2594,25 @@ struct Foo foo;
#[repr(C)]
pub struct Foo {
pub x: i32,
pub bar: __anon_1,
pub baz: __anon_2,
pub bar: __anon_Foo_1,
pub baz: __anon_Foo_2,
pub w: i32,
pub __pad_68: [u8; 4],
}
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct __anon_1 {
pub struct __anon_Foo_1 {
pub y: [u8; 10],
pub z: [u16; 16],
}
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct __anon_2 {
pub struct __anon_Foo_2 {
pub w: u32,
pub __pad_4: [u8; 4],
pub u: *mut u64,
}
impl Default for __anon_2 {
impl Default for __anon_Foo_2 {
fn default() -> Self {
Self {
w: u32::default(),
Expand Down Expand Up @@ -2667,31 +2667,31 @@ struct Foo foo;
#[repr(C)]
pub struct Foo {
pub x: i32,
pub bar: __anon_1,
pub zerg: __anon_2,
pub baz: __anon_3,
pub bar: __anon_Foo_1,
pub zerg: __anon_Foo_2,
pub baz: __anon_Foo_3,
pub w: i32,
pub __pad_76: [u8; 4],
pub flarg: __anon_4,
pub flarg: __anon_Foo_4,
}
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct __anon_1 {
pub struct __anon_Foo_1 {
pub y: [u8; 10],
pub z: [u16; 16],
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_2 {
pub union __anon_Foo_2 {
pub a: *mut i8,
pub b: i32,
}
impl std::fmt::Debug for __anon_2 {
impl std::fmt::Debug for __anon_Foo_2 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_2 {
impl Default for __anon_Foo_2 {
fn default() -> Self {
Self {
a: std::ptr::null_mut(),
Expand All @@ -2700,12 +2700,12 @@ impl Default for __anon_2 {
}
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct __anon_3 {
pub struct __anon_Foo_3 {
pub w: u32,
pub __pad_4: [u8; 4],
pub u: *mut u64,
}
impl Default for __anon_3 {
impl Default for __anon_Foo_3 {
fn default() -> Self {
Self {
w: u32::default(),
Expand All @@ -2716,16 +2716,16 @@ impl Default for __anon_3 {
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_4 {
pub union __anon_Foo_4 {
pub c: u8,
pub d: [u64; 5],
}
impl std::fmt::Debug for __anon_4 {
impl std::fmt::Debug for __anon_Foo_4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_4 {
impl Default for __anon_Foo_4 {
fn default() -> Self {
Self {
c: u8::default(),
Expand Down Expand Up @@ -2763,20 +2763,20 @@ struct Foo foo = {{0}};
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct Foo {
pub __anon_1: __anon_1,
pub __anon_Foo_1: __anon_Foo_1,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_1 {
pub union __anon_Foo_1 {
pub name: *mut i8,
pub tp: *mut std::ffi::c_void,
}
impl std::fmt::Debug for __anon_1 {
impl std::fmt::Debug for __anon_Foo_1 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_1 {
impl Default for __anon_Foo_1 {
fn default() -> Self {
Self {
name: std::ptr::null_mut(),
Expand Down Expand Up @@ -2811,17 +2811,17 @@ struct Foo foo;
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct Foo {
pub test: __anon_1,
pub test: __anon_Foo_1,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(transparent)]
pub struct __anon_1(pub u32);
pub struct __anon_Foo_1(pub u32);
#[allow(non_upper_case_globals)]
impl __anon_1 {
pub const FOO: __anon_1 = __anon_1(1);
impl __anon_Foo_1 {
pub const FOO: __anon_Foo_1 = __anon_Foo_1(1);
}
impl Default for __anon_1 {
fn default() -> Self { __anon_1::FOO }
impl Default for __anon_Foo_1 {
fn default() -> Self { __anon_Foo_1::FOO }
}
"#;

Expand Down Expand Up @@ -2918,40 +2918,40 @@ struct bpf_sock_tuple_5_15 tup;
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct bpf_sock_tuple_5_15 {
pub __anon_1: __anon_1,
pub __anon_bpf_sock_tuple_5_15_1: __anon_bpf_sock_tuple_5_15_1,
pub __pad_36: [u8; 4],
pub __anon_2: __anon_2,
pub __anon_bpf_sock_tuple_5_15_2: __anon_bpf_sock_tuple_5_15_2,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_1 {
pub ipv4: __anon_3,
pub ipv6: __anon_4,
pub union __anon_bpf_sock_tuple_5_15_1 {
pub ipv4: __anon_bpf_sock_tuple_5_15_3,
pub ipv6: __anon_bpf_sock_tuple_5_15_4,
}
impl std::fmt::Debug for __anon_1 {
impl std::fmt::Debug for __anon_bpf_sock_tuple_5_15_1 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_1 {
impl Default for __anon_bpf_sock_tuple_5_15_1 {
fn default() -> Self {
Self {
ipv4: __anon_3::default(),
ipv4: __anon_bpf_sock_tuple_5_15_3::default(),
}
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union __anon_2 {
pub union __anon_bpf_sock_tuple_5_15_2 {
pub a: i32,
pub b: *mut i8,
}
impl std::fmt::Debug for __anon_2 {
impl std::fmt::Debug for __anon_bpf_sock_tuple_5_15_2 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(???)")
}
}
impl Default for __anon_2 {
impl Default for __anon_bpf_sock_tuple_5_15_2 {
fn default() -> Self {
Self {
a: i32::default(),
Expand All @@ -2960,15 +2960,15 @@ impl Default for __anon_2 {
}
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct __anon_3 {
pub struct __anon_bpf_sock_tuple_5_15_3 {
pub saddr: u32,
pub daddr: u32,
pub sport: u16,
pub dport: u16,
}
#[derive(Debug, Default, Copy, Clone)]
#[repr(C)]
pub struct __anon_4 {
pub struct __anon_bpf_sock_tuple_5_15_4 {
pub saddr: [u32; 4],
pub daddr: [u32; 4],
pub sport: u16,
Expand Down