<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/143361>143361</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[BPF] `BTFDebug` doesn't generate BTF for all structs, if BPF map type is wrapped in Rust wrapper types
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
vadorovsky
</td>
</tr>
</table>
<pre>
This issue was detected during an attempt of supporting BTF maps in Aya (aya-rs/aya#1117).
BTF map definitions have the following format in C:
```c
struct my_key {
int a;
};
struct my_value {
int a;
};
struct {
int (*type)[BPF_MAP_TYPE_HASH];
typeof(struct my_key) *key;
typeof(struct my_value) *value;
int (*max_entries)[10];
} map_1 SEC(".maps");
```
The `map_1` instance is then used as `*void` in libbpf functions like `bpf_map_lookup_elem`, `bpf_map_update_elem` etc..
The key and value structs can be anything as long as they hold primitive/POD types and as long as they are aligned.
The program above produces the following BTF:
```
#0: <VOID>
#1: <PTR> --> [3]
#2: <INT> 'int' bits:32 off:0 enc:signed
#3: <ARRAY> n:1 idx-->[4] val-->[2]
#4: <INT> '__ARRAY_SIZE_TYPE__' bits:32 off:0
#5: <PTR> --> [6]
#6: <STRUCT> 'my_key' sz:4 n:1
#00 'a' off:0 --> [2]
#7: <PTR> --> [8]
#8: <STRUCT> 'my_value' sz:4 n:1
#00 'a' off:0 --> [2]
#9: <PTR> --> [10]
#10: <ARRAY> n:10 idx-->[4] val-->[2]
#11: <STRUCT> '<anon>' sz:32 n:4
#00 'type' off:0 --> [1]
#01 'key' off:64 --> [5]
#02 'value' off:128 --> [7]
#03 'max_entries' off:192 --> [9]
#12: <VAR> 'map_1' kind:global-alloc --> [11]
#13: <DATASEC> '.maps' sz:0 n:1
#00 off:0 sz:32 --> [12]
```
We can see both the map struct (`#11`) and the types used as key (`#6`) and value (`#8`).
However, in Rust, we want to wrap such map definitions in two wrapper types:
* A wrapper type representing a specific map type (e.g. `HashMap`, `RingBuf`), which provide methods (`get`, `update`), so people interact with those wrapper types instead of working with void pointers.
* Another wrapper type, which wraps the type above in `UnsafeCell`, so the Rust compiler doesn't complain about concurrent mutability and doesn't consider such action unsafe. It's basically a way of telling compiler, that we (Aya) guarantee that this type provides a thread-safe mutabiity (and it does out of the box, because of RCU in Linux kernel).
This ends up looking like:
```rust
#![no_std]
#![no_main]
pub const BPF_MAP_TYPE_HASH: usize = 1;
// The real map definition.
pub struct HashMapDef<K, V, const M: usize, const F: usize> {
r#type: *const [i32; BPF_MAP_TYPE_HASH],
key: *const K,
value: *const V,
max_entries: *const [i32; M],
map_flags: *const [i32; F],
}
impl<K, V, const M: usize, const F: usize> HashMapDef<K, V, M, F> {
pub const fn new() -> Self {
Self {
r#type: &[0i32; BPF_MAP_TYPE_HASH],
key: ::core::ptr::null(),
value: ::core::ptr::null(),
max_entries: &[0i32; M],
map_flags: &[0i32; F],
}
}
}
// Use `UnsafeCell` to allow the mutability by multiple threads.
pub struct HashMap<K, V, const M: usize, const F: usize = 0>(
core::cell::UnsafeCell<HashMapDef<K, V, M, F>>,
);
impl<K, V, const M: usize, const F: usize> HashMap<K, V, M, F> {
pub const fn new() -> Self {
Self(core::cell::UnsafeCell::new(HashMapDef::new()))
}
}
/// Tell Rust that `HashMap` is thread-safe.
unsafe impl<K: Sync, V: Sync, const M: usize, const F: usize> Sync for HashMap<K, V, M, F> {}
// Define custom structs for key and values.
pub struct MyKey(u32);
pub struct MyValue(u32);
#[link_section = ".maps"]
#[export_name = "HASH_MAP"]
pub static HASH_MAP: HashMap<MyKey, MyValue, 10> = HashMap::new();
```
However, for this Rust program, the BTF for `MyKey` and `MyValue` is `<FORWARD>` and does not contain the actual `<STRUCT>` definition.
The problem is reproducible only if the key and/or value type are custom structs.
I'm working on the fix, which is mostly ready, apart from llvm-lit test which will make sure it doesn't regress in the future.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0WM1u4zgSfhrmUoghU_495CDbbXRjNjtBku7B7MWgpLLNDU0KJBXH8_SLIiVLThx07w42CGyZ_Oq_WFWUcE7uNOIdGy_YeHUjar839u5VlMaaV_dyuslNebp73ksH0rka4SgclOix8FhCWVupdyA0CO_xUHkwW3B1VRnraWPxvIaDqBxIDdlJAOMzcRK31jG-FifBeDocDqeMzwcsyViSNXgocSu19NJoB3vxiuD3CFujlDkS262xB-GJ6ZKlWSRlkyT-FyzJnLd14eFw2rzgCdh0wZIMQGoPgqX0g01XzUMf_CpUjb8I76MYnzGe-VOFjM_ZeLF4WG_us4fN858PXzZfs6evbNzQA4HMlvHZhYqMz4HxjJ4i7BouaNcg43P6XoWDeNug9laii5oMk7NoNl2RbzdDePqyDHA-oNgwzgkbMa0To6nPewQ2SQIVmyQgtfNCFwjSUUQ01A5LEI5ApJSRZYSBknlebWFb6yJGUcmXwCuvthvip4x5qasNKjwE4mV_s65K4bHdBPTFYNBpRCEVuoQYregfB4XQkCMIffL7kJMOlInffo8n2BtVQmXlQXr5ioyvH35fBS-7wOw9XFgEoehslD3RlTU7Kw4gcvMafpV1ge5ddi6e1x-zkp55mrA0A5Yuf_z-bcXSL3Fx2Cw-PD-y9Avc3tInGy9SCl1A8Abx7Z_PYY9PpfaMTyGX3rE0SzmY7ZalWQKoC5Zm4VCXkThtiLPHx-xPItcszYYgy7cgiY0XIzZekTfb3_wsePRB8GYT-Gyevv3rS8zvzVVFIv34E9MmZwmTBvH0_Ph92QppD8UU3F8szUZR5ZDr8Y9cmRBSEKi1_cy-M2D6iQKzM2L2iQLNafv7Ksw_USEezZgBydUYJb8WpOHwmgksXQptNIFbI1Ie-I6uWRGL1xVDhlFOn2BIBE2AIn4y6gjGHwk4EZwdGkmGfNbRTD_SpCEO_Xp2ppzzjnLeuaE9JT-yxzaMoXDxKbxIXbI02ymTC3UrlDJFz8Jhx6M9LKvsOaMyGfk0dbJxY_JJLrSua33dCWhjdVld_8BQtBwi5MbvQxWh5tc2GD4LlZHiS9_zUKcIFKtWW3tDh2uxkx606WbtVvxqO-1Xc8RXtFR4pYbH2nl6PFJ_1x68gaMlVepi_6EhSw3-GAEV2qhNV_B4BtnFHlisLDrUYSIQ4Cos5FYWgW8AMD7DwW5AHeCrcPt7UXUt4VHq3aLeRt2DintZ7Kn0vsoS4YB-b0rXWLlD31HGJtIROgMVmkoh9Uu0ovBwlMHtxuGlNaHRoShpmjka-0KKByx1OKhMYOAGrbna-D3aCxadprTqzmFrOofUpOF37cQWl6hUo7UzAUjRgMIcKqnQQmnQaTqhYUkJqYlJTT91UVuL2sOh9iKXSvrYGfsk2skSbYykCM0Y6iB3AN-ohzjIhZOFUOoEAo7iREZ7VIqMbpUg5fxeeEoQxmcZjW5z2NXCCu0R456nITEY2UTHgQC_tyjKWxLYaElK0hyoS5A-qApkDUnd00l4I2E5FqJ2SKuPy-_kr39IXb_BC1qNqkvjMJiiLh3UFdBMQVrTrNElZO_cWUrzcNAZH7LxQpuN8-X59J8XD0LqZjXJqjoPbvTwcaxLM6id_AuBpSsYnkdExteMr4EmBotCvTtBg4Zpc86blF_hlqXL38j4H_QRRd6fRXRr626N6kszhwJYxtOQe1TCeBbBbLyQND8srmg_XjG-JOIwd_aIfmvWAaAZNHubP7rNfnm-LvS-E0LFeKvE7jPo-gylaTvJ5KFS_5NHPnHoPX2sL13WxXarQeMxjMVzCIX7CdW2B6W__tKltydsvEh-7ujeX-vzNGNpVhiL8anyNj7oWqmozkfaLii_TP0hVH2N769q-C5gfYL1B4IYs-ar-Yyn4LvDD8WOGgx14WNsel31yk9wqJWXVKZj6XDXj8t_nRnhiCZhHJqRpp3TCtIpPPV0TJc_S6PAKqRre3v6uxn7_0hXxmc_szTkS2DWN7lbDUkU_q8GOFQ6VCq2rdAJLhp5vCyeuwCFMzYgOPsrzeDppItoe-_Hr_qP8LA19hccOV1dlOgVVWWEonbeHM53SWJ1cct8n4T3p99o_J3VaXd3vtj-EYfdC0DTZMYLJfXLxmFsxpSW_av4uRmNF_hWGes3WhywhVE5oeJyRkapwssCzntp1nNEo-qyU2oJdN_4EliecZfhvvYyoDcxkn9Ctw8hby7FcUbA8M6HAGySRNmTJDgy_I4qxKQgzuly_fvjH9ljuA03wDASaBOGF0_jDnEVha-FamjOFx0iuWys3UU9V3ggMTR-0j1d5grBaHUCGUeNJsKMr41thuU4otn3CdEw_kZXivNAaKJiW_nWDXvSwcE4r07U98vgdlEJ62FrzQGUej3cKunBo_PteCgVzQcvCK622E5EcXizuLPo4sBNkmpfWxzclHdpOU_n4gbvhtPRfDRJx9PkZn83nEzKSTqcz8U8mU_EfJZP860YzfM5Tvlc8Bt5xxM-TibJfJgkk2EymA3nOEqnJRf5CIUo2SjBg5BqQJoOjN3dhHd-d8NRmk6GN0rkqFx4Vci5xmN8IxhT8cbeBfPyeufYKFHSedex8dKr8I5x8UCtg8K4eF6vMK93IYRnk3eo0QrfZZFQqo1CuKtsqb12VwfpmrG7bK8xl5P8TW3V3d77KtxQwpnfSb-v80FhDoyvScPm67ay5t9YeMbXwS7H-Lox_PWO_ycAAP__4cgn-A">