Skip to content

Commit a349885

Browse files
d-e-s-odanielocfb
authored andcommitted
Fix handling of function prototype type declaration inference in BTF
We currently do not handle type declaration querying for function prototypes correctly in our BTF logic. That can lead to errors during skeleton generation. With this change we treat them similar to how we treat functions themselves (which can only occur in the form of pointers). Signed-off-by: Daniel Müller <[email protected]>
1 parent 64ed5be commit a349885

File tree

3 files changed

+48
-6
lines changed

3 files changed

+48
-6
lines changed

libbpf-cargo/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Unreleased
22
----------
33
- Added `Default` impl for generated `struct` types containing pointers
4+
- Fixed handling of function prototype type declaration inference in BTF and
5+
skeleton generation
46
- Improved error reporting in build script usage
57
- Bumped minimum Rust version to `1.64`
68

libbpf-cargo/src/gen/btf.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@ impl<'s> GenBtf<'s> {
134134
}
135135
BtfKind::Struct | BtfKind::Union | BtfKind::Enum | BtfKind::Enum64 =>
136136
self.get_type_name_handling_anon_types(&ty).into_owned(),
137-
// // The only way a variable references a function is through a function pointer.
138-
// // Return c_void here so the final def will look like `*mut c_void`.
139-
// //
140-
// // It's not like rust code can call a function inside a bpf prog either so we don't
141-
// // really need a full definition. `void *` is totally sufficient for sharing a pointer.
142-
BtfKind::Func => "std::ffi::c_void".to_string(),
137+
// The only way a variable references a function is through a function pointer.
138+
// Return c_void here so the final def will look like `*mut c_void`.
139+
//
140+
// It's not like rust code can call a function inside a bpf prog either so we don't
141+
// really need a full definition. `void *` is totally sufficient for sharing a pointer.
142+
BtfKind::Func | BtfKind::FuncProto => "std::ffi::c_void".to_string(),
143143
BtfKind::Var(t) => self.type_declaration(t.referenced_type())?,
144144
_ => bail!("Invalid type: {ty:?}"),
145145
});

libbpf-cargo/src/test.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,46 @@ pub struct Bar {
14371437
assert_definition(&btf, &struct_foo, expected_output);
14381438
}
14391439

1440+
#[test]
1441+
fn test_btf_dump_struct_definition_func_proto() {
1442+
let prog_text = r#"
1443+
#include "vmlinux.h"
1444+
#include <bpf/bpf_helpers.h>
1445+
1446+
struct with_func_proto {
1447+
struct with_func_proto *next;
1448+
void (*func)(struct with_func_proto *);
1449+
};
1450+
1451+
struct with_func_proto w;
1452+
"#;
1453+
1454+
let expected_output = r#"
1455+
#[derive(Debug, Copy, Clone)]
1456+
#[repr(C)]
1457+
pub struct with_func_proto {
1458+
pub next: *mut with_func_proto,
1459+
pub func: *mut std::ffi::c_void,
1460+
}
1461+
impl Default for with_func_proto {
1462+
fn default() -> Self {
1463+
with_func_proto {
1464+
next: std::ptr::null_mut(),
1465+
func: std::ptr::null_mut(),
1466+
}
1467+
}
1468+
}
1469+
"#;
1470+
1471+
let mmap = build_btf_mmap(prog_text);
1472+
let btf = btf_from_mmap(&mmap);
1473+
1474+
// Find our struct
1475+
let struct_foo = find_type_in_btf!(btf, types::Struct<'_>, "with_func_proto");
1476+
1477+
assert_definition(&btf, &struct_foo, expected_output);
1478+
}
1479+
14401480
#[test]
14411481
fn test_btf_dump_struct_definition_long_array() {
14421482
let prog_text = r#"

0 commit comments

Comments
 (0)