Skip to content

Commit 19d5ff4

Browse files
committed
libbpf-cargo: Relative anonymous type naming
1 parent 4f4c5f9 commit 19d5ff4

File tree

2 files changed

+185
-45
lines changed

2 files changed

+185
-45
lines changed

libbpf-cargo/src/gen/btf.rs

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,17 @@ fn escape_reserved_keyword(identifier: Cow<'_, str>) -> Cow<'_, str> {
369369
}
370370

371371
#[derive(Debug, Clone)]
372-
pub struct BtfDependency {
373-
pub name: Option<String>,
374-
pub dep_id: i32,
375-
pub child_counter: Rc<RefCell<i32>>,
372+
struct BtfDependency {
373+
/// Name of the dependency parent
374+
parent_name: Option<String>,
375+
376+
/// Dependency id relative to the parent's `child_counter`
377+
dep_id: i32,
378+
379+
/// The `child_counter` for the dependency if it is intended to be
380+
/// a parent itself.
381+
/// For an anonymous unit this should be a pointer to the parent's `child_counter`
382+
child_counter: Rc<RefCell<i32>>,
376383
}
377384

378385
#[derive(Debug, Default)]
@@ -386,69 +393,74 @@ pub(crate) struct TypeMap {
386393
/// name already.
387394
names_count: RefCell<HashMap<String, u8>>,
388395

389-
dependencies: RefCell<HashMap<TypeId, BtfDependency>>,
396+
/// Mapping from type to it's parent. Used in anonymous members naming
397+
dependency_tree: RefCell<HashMap<TypeId, BtfDependency>>,
390398
}
391399

392400
impl TypeMap {
393-
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
394-
let mut deps = self.dependencies.borrow_mut();
401+
fn register_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) {
402+
let mut deps = self.dependency_tree.borrow_mut();
395403
if deps.get(&ty.type_id()).is_some() {
396404
return;
397405
}
398406

399-
let parent_dep = deps.get(&parent.type_id());
400-
if let Some(pdep) = parent_dep {
401-
let mut dep = pdep.clone();
402-
403-
if let Some(n) = parent.name() {
404-
dep.name = Some(n.to_string_lossy().to_string());
405-
}
406-
if ty.name().is_some() {
407-
dep.child_counter = Rc::new(RefCell::new(0));
408-
}
407+
let pdep = deps.entry(parent.type_id()).or_insert(BtfDependency {
408+
parent_name: None,
409+
dep_id: 0,
410+
child_counter: Rc::new(RefCell::new(0)),
411+
});
409412

410-
let parent_counter = Rc::<RefCell<i32>>::clone(&pdep.child_counter);
411-
*parent_counter.borrow_mut() += 1;
412-
dep.dep_id = *parent_counter.borrow();
413+
let mut dep = pdep.clone();
413414

414-
deps.insert(ty.type_id(), dep);
415-
} else {
416-
let mut dep = BtfDependency {
417-
name: None,
418-
dep_id: 0,
419-
child_counter: Rc::new(RefCell::new(1)),
420-
};
421-
deps.insert(parent.type_id(), dep.clone());
415+
// If parent is named, derive it.
416+
// Otherwise derive parent's parent
417+
if let Some(n) = parent.name() {
418+
dep.parent_name = Some(n.to_string_lossy().to_string());
419+
}
422420

423-
if let Some(n) = parent.name() {
424-
dep.name = Some(n.to_string_lossy().to_string());
425-
}
426-
if ty.name().is_some() {
427-
dep.child_counter = Rc::new(RefCell::new(0));
428-
}
429-
dep.dep_id = 1;
430-
deps.insert(ty.type_id(), dep);
421+
// If the current unit is named, self-assign the child_counter.
422+
// Otherwise derive a parent's one
423+
if ty.name().is_some() {
424+
dep.child_counter = Rc::new(RefCell::new(0));
431425
}
426+
427+
// Increment parent's `child_counter` and assign the new value to dep_id
428+
let parent_counter = Rc::clone(&pdep.child_counter);
429+
*parent_counter.borrow_mut() += 1;
430+
dep.dep_id = *parent_counter.borrow();
431+
432+
deps.insert(ty.type_id(), dep);
432433
}
433434

434-
pub fn lookup_parent<'s>(&self, ty: &BtfType<'s>) -> Option<BtfDependency> {
435-
self.dependencies.borrow().get(&ty.type_id()).cloned()
435+
fn lookup_parent<'s>(&self, ty: &BtfType<'s>) -> Option<BtfDependency> {
436+
self.dependency_tree.borrow().get(&ty.type_id()).cloned()
436437
}
437438

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

445-
if let Some(parent) = self.lookup_parent(ty) {
446-
if let Some(name) = parent.name {
447-
if !name.is_empty() {
448-
return format!("{ANON_PREFIX}{}_{}", name, parent.dep_id).into();
445+
let anon_id = match anon_table.entry(ty.type_id()) {
446+
Entry::Occupied(anon_id) => {
447+
let anon_id = anon_id.get();
448+
*anon_id
449+
}
450+
Entry::Vacant(anon_id) => {
451+
if let Some(dep) = self.lookup_parent(ty) {
452+
if let Some(name) = dep.parent_name {
453+
if !name.is_empty() {
454+
return format!("{ANON_PREFIX}{}_{}", name, dep.dep_id).into();
455+
}
456+
}
449457
}
458+
459+
let anon_id = anon_id.insert(len);
460+
*anon_id
450461
}
451-
}
462+
};
463+
452464
format!("{ANON_PREFIX}{anon_id}").into()
453465
}
454466
Some(n) => match self.names.borrow_mut().entry(ty.type_id()) {
@@ -789,7 +801,7 @@ impl<'s> GenBtf<'s> {
789801
}
790802

791803
if let Some(next_ty_id) = next_type(field_ty)? {
792-
self.type_map.derive_parent(&next_ty_id, &t);
804+
self.type_map.register_parent(&next_ty_id, &t);
793805
dependent_types.push(next_ty_id);
794806
}
795807
let field_name = if let Some(name) = member.name {

libbpf-cargo/src/test.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,6 +2792,134 @@ impl Default for __anon_Foo_1 {
27922792
assert_definition(&btf, &struct_foo, expected_output);
27932793
}
27942794

2795+
#[test]
2796+
fn test_btf_dump_anon_member_tree() {
2797+
let prog_text = r#"
2798+
#include "vmlinux.h"
2799+
#include <bpf/bpf_helpers.h>
2800+
2801+
struct Foo {
2802+
union {
2803+
struct {
2804+
char *name;
2805+
void *tp;
2806+
};
2807+
struct Bar {
2808+
union {
2809+
struct {
2810+
char *name;
2811+
void *trp;
2812+
};
2813+
struct Baz {
2814+
char *name;
2815+
void *trp;
2816+
} baz;
2817+
};
2818+
} bar;
2819+
};
2820+
};
2821+
2822+
struct Foo foo = {0};
2823+
"#;
2824+
2825+
let expected_output = r#"
2826+
#[derive(Debug, Default, Copy, Clone)]
2827+
#[repr(C)]
2828+
pub struct Foo {
2829+
pub __anon_Foo_1: __anon_Foo_1,
2830+
}
2831+
#[derive(Copy, Clone)]
2832+
#[repr(C)]
2833+
pub union __anon_Foo_1 {
2834+
pub __anon_Foo_2: __anon_Foo_2,
2835+
pub bar: Bar,
2836+
}
2837+
impl std::fmt::Debug for __anon_Foo_1 {
2838+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2839+
write!(f, "(???)")
2840+
}
2841+
}
2842+
impl Default for __anon_Foo_1 {
2843+
fn default() -> Self {
2844+
Self {
2845+
__anon_Foo_2: __anon_Foo_2::default(),
2846+
}
2847+
}
2848+
}
2849+
#[derive(Debug, Copy, Clone)]
2850+
#[repr(C)]
2851+
pub struct __anon_Foo_2 {
2852+
pub name: *mut i8,
2853+
pub tp: *mut std::ffi::c_void,
2854+
}
2855+
impl Default for __anon_Foo_2 {
2856+
fn default() -> Self {
2857+
Self {
2858+
name: std::ptr::null_mut(),
2859+
tp: std::ptr::null_mut(),
2860+
}
2861+
}
2862+
}
2863+
#[derive(Debug, Default, Copy, Clone)]
2864+
#[repr(C)]
2865+
pub struct Bar {
2866+
pub __anon_Bar_1: __anon_Bar_1,
2867+
}
2868+
#[derive(Copy, Clone)]
2869+
#[repr(C)]
2870+
pub union __anon_Bar_1 {
2871+
pub __anon_Bar_2: __anon_Bar_2,
2872+
pub baz: Baz,
2873+
}
2874+
impl std::fmt::Debug for __anon_Bar_1 {
2875+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2876+
write!(f, "(???)")
2877+
}
2878+
}
2879+
impl Default for __anon_Bar_1 {
2880+
fn default() -> Self {
2881+
Self {
2882+
__anon_Bar_2: __anon_Bar_2::default(),
2883+
}
2884+
}
2885+
}
2886+
#[derive(Debug, Copy, Clone)]
2887+
#[repr(C)]
2888+
pub struct __anon_Bar_2 {
2889+
pub name: *mut i8,
2890+
pub trp: *mut std::ffi::c_void,
2891+
}
2892+
impl Default for __anon_Bar_2 {
2893+
fn default() -> Self {
2894+
Self {
2895+
name: std::ptr::null_mut(),
2896+
trp: std::ptr::null_mut(),
2897+
}
2898+
}
2899+
}
2900+
#[derive(Debug, Copy, Clone)]
2901+
#[repr(C)]
2902+
pub struct Baz {
2903+
pub name: *mut i8,
2904+
pub trp: *mut std::ffi::c_void,
2905+
}
2906+
impl Default for Baz {
2907+
fn default() -> Self {
2908+
Self {
2909+
name: std::ptr::null_mut(),
2910+
trp: std::ptr::null_mut(),
2911+
}
2912+
}
2913+
}
2914+
"#;
2915+
2916+
let mmap = build_btf_mmap(prog_text);
2917+
let btf = btf_from_mmap(&mmap);
2918+
let struct_foo = find_type_in_btf!(btf, types::Struct<'_>, "Foo");
2919+
2920+
assert_definition(&btf, &struct_foo, expected_output);
2921+
}
2922+
27952923
#[test]
27962924
fn test_btf_dump_definition_anon_enum() {
27972925
let prog_text = r#"

0 commit comments

Comments
 (0)