Skip to content

Commit 4e29027

Browse files
d-e-s-odanielocfb
authored andcommitted
libbpf-cargo: Generate Default impl on overly large padding
When we pad structs to ensure proper alignment, we may end up generating padding arrays of more than 32 byte when alignment is large. In such cases, Rust would not be able to derive a Default and we'd need to make sure to generate one ourselves, or a compilation error will ensue. With this change we make sure to switch over to generating a Default impl ourselves in those cases. Signed-off-by: Daniel Müller <[email protected]>
1 parent 341cb54 commit 4e29027

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

libbpf-cargo/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Unreleased
2+
----------
3+
- Fixed generation of `Default` impl in presence of large padding arrays
4+
5+
16
0.23.1
27
------
38
- Added "import injection" escape hatch to generated skeletons

libbpf-cargo/src/gen/btf.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ impl struct_ops {{
575575
impl_default.push(format!(
576576
r#" __pad_{offset}: [u8::default(); {padding}]"#,
577577
));
578+
579+
if padding > 32 {
580+
gen_impl_default = true;
581+
}
578582
}
579583

580584
if let Some(ft) = self.type_by_id::<types::Array<'_>>(field_ty.type_id()) {
@@ -634,6 +638,10 @@ impl struct_ops {{
634638
impl_default.push(format!(
635639
r#" __pad_{offset}: [u8::default(); {padding}]"#,
636640
));
641+
642+
if padding > 32 {
643+
gen_impl_default = true;
644+
}
637645
}
638646
}
639647

libbpf-cargo/src/test.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,43 @@ pub struct Foo {
14671467
assert_definition(&btf, &struct_foo, expected_output);
14681468
}
14691469

1470+
#[test]
1471+
fn test_btf_dump_insane_align() {
1472+
let prog_text = r#"
1473+
#include "vmlinux.h"
1474+
#include <bpf/bpf_helpers.h>
1475+
1476+
struct Foo {
1477+
int x;
1478+
} __attribute__((aligned(64)));
1479+
1480+
struct Foo foo = {1};
1481+
"#;
1482+
1483+
let expected_output = r#"
1484+
#[derive(Debug, Copy, Clone)]
1485+
#[repr(C)]
1486+
pub struct Foo {
1487+
pub x: i32,
1488+
pub __pad_4: [u8; 60],
1489+
}
1490+
impl Default for Foo {
1491+
fn default() -> Self {
1492+
Foo {
1493+
x: i32::default(),
1494+
__pad_4: [u8::default(); 60],
1495+
}
1496+
}
1497+
}
1498+
"#;
1499+
1500+
let mmap = build_btf_mmap(prog_text);
1501+
let btf = btf_from_mmap(&mmap);
1502+
let struct_foo = find_type_in_btf!(btf, types::Struct<'_>, "Foo");
1503+
1504+
assert_definition(&btf, &struct_foo, expected_output);
1505+
}
1506+
14701507
#[test]
14711508
fn test_btf_dump_basic_long_array() {
14721509
let prog_text = r#"

0 commit comments

Comments
 (0)