<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/77720>77720</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
incorrect bit-field access when preserve_access_index pushed
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
zhaiyan920
</td>
</tr>
</table>
<pre>
Hi there,
I encountered incorrect bitfield access when tracing some linux kernel structure with BPF. Some attempt shows that generated code access bit fields inconsistent w/wo preserve_access_index. I managed to get a small reproducible case below:
```
//#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
//#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
//#endif
struct S {
int x;
char y;
unsigned int a0:1;
unsigned int a1:1;
unsigned int a2:1;
unsigned int a3:1;
unsigned int a4:1;
unsigned int a5:1;
unsigned int a6:1;
unsigned int a7:1;
unsigned int b0:1;
unsigned int b1:1;
unsigned int b2:1;
unsigned int b3:1;
unsigned int b4:1;
unsigned int b5:1;
unsigned int b6:1;
unsigned int b7:1;
};
//#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
//#pragma clang attribute pop
//#endif
unsigned int func1(struct S *s) {
return s->a0;
}
unsigned int func2(struct S *s) {
return s->b0;
}
```
Without the attribute, this produces:
```
$ clang-16 test.c --target=bpf -c -O3 -g
$ llvm-objdump-16 -d test.o
test.o: file format elf64-bpf
Disassembly of section .text:
0000000000000000 <func1>:
0: 71 10 05 00 00 00 00 00 r0 = *(u8 *)(r1 + 0x5)
1: 57 00 00 00 01 00 00 00 r0 &= 0x1
2: 95 00 00 00 00 00 00 00 exit
0000000000000018 <func2>:
3: 71 10 06 00 00 00 00 00 r0 = *(u8 *)(r1 + 0x6)
4: 57 00 00 00 01 00 00 00 r0 &= 0x1
5: 95 00 00 00 00 00 00 00 exit
```
If I uncomment the attribute push lines, it generates:
```
$ clang-16 test.c --target=bpf -c -O3 -g
$ llvm-objdump-16 -d test.o
test.o: file format elf64-bpf
Disassembly of section .text:
0000000000000000 <func1>:
0: 71 10 05 00 00 00 00 00 r0 = *(u8 *)(r1 + 0x5)
1: 57 00 00 00 01 00 00 00 r0 &= 0x1
2: 95 00 00 00 00 00 00 00 exit
0000000000000018 <func2>:
3: b7 02 00 00 06 00 00 00 r2 = 0x6
4: 0f 21 00 00 00 00 00 00 r1 += r2
5: 71 10 01 00 00 00 00 00 r0 = *(u8 *)(r1 + 0x1)
6: 57 00 00 00 01 00 00 00 r0 &= 0x1
7: 95 00 00 00 00 00 00 00 exit
```
Compiler info:
```
$ clang-16 --version
Debian clang version 16.0.6 (15~deb12u1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```
Pahole output:
```
struct S {
int x; /* 0 4 */
char y; /* 4 1 */
/* Bitfield combined with previous fields */
unsigned int a0:1; /* 4: 8 4 */
unsigned int a1:1; /* 4: 9 4 */
unsigned int a2:1; /* 4:10 4 */
unsigned int a3:1; /* 4:11 4 */
unsigned int a4:1; /* 4:12 4 */
unsigned int a5:1; /* 4:13 4 */
unsigned int a6:1; /* 4:14 4 */
unsigned int a7:1; /* 4:15 4 */
unsigned int b0:1; /* 4:16 4 */
unsigned int b1:1; /* 4:17 4 */
unsigned int b2:1; /* 4:18 4 */
unsigned int b3:1; /* 4:19 4 */
unsigned int b4:1; /* 4:20 4 */
unsigned int b5:1; /* 4:21 4 */
unsigned int b6:1; /* 4:22 4 */
unsigned int b7:1; /* 4:23 4 */
/* size: 8, cachelines: 1, members: 18 */
/* bit_padding: 8 bits */
/* last cacheline: 8 bytes */
};
```
I tried 17.0.2, which also shows similar result. An interesting thing is that if I remove the hole after y, everything becomes correct.
Seems a bug to me. Please let me know if there is anything else I can provide.
best
Yan
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWE-P6jgS_zTmUgqKHQhw4EA3jbYvM0_Tq_1zQnZSJJ5x7Mh2GnoO-9lX-dMPAnS3R09P2sNGUQhJ-eeqyq_KVebOyUIjrsn8gcy3E9740tj1nyWXb1yvWDwRJn9b_02CL9EiYY8k3pJ401_hGVBnptEeLeYgdWasxcyDkP4gUeXAswydg2OJGrzlmdQFOFMhKKmbE_yBVqMC522T-cYiHKUv4eHbbgovrRT3HqvagyvN0YEvuYcCNVruMYfM5Pg-gZAeuhldp4V20nnUHo6E7Y4GaosO7Svue_G91DmepvAMFde8wBy8gQI9cHAVVwos1tbkTSaFQsi4QxCozJEkm0vzSRoPZ_-X7bozkQed46E1Y__Lr_tvvz29PP32j6f95vHx6eVl__zL9ulfVyNqy4uKQ6a4LlqjrRSNR6gbVwJhy_3--7P9nrAlYcu7FhG26s5H4HWt3vbeAEm2YDEzNm_fjGdFncvDpUH9d4AXIIuH4QsPh9QeTiS5epqV3MLbzeNGd6TKu1E8JsmGfiFDxzLjlywAIAmQmQXIzANk0s-UXXwNIAI8ImiATIBjRPKJsiLAIyLAIyINkBk7hiy25_ufFT2m_orwIxUPjc4oYctzFLCNI2x1Gw0WfWM1uIgkTy2_L4z6DJz9ZXBxD_wq63TXf0pfmsa3WfrsgTYR-FI66JMZunP-us5cs957EU3Bo_PTDKLIc1ugJ8lW1AeIMoh-TSAqziOUeq0iI37Pm6puB0Z5P9ZcKjY8STZwkArhYGzFPaA6pLNI1KOPsZWOO4eVUG9gDuAw89JomHo8-avMG18dQJLH_vMlT99FB3-20TbcLijQGOI5xPHotHGXJwnbELZslv3NirClpUDYA8Sn-ffsOUDRM-p8cQFGx6gsbYHjEx0NZufBqxtl-hNP0n9sMV2-W8zuWJzcWJz-dYvTa4tnP2Jxm0VCbL3H7ecDPEOjM1NV7ZI-oni_RCqp0bVsl-f64P9k_18i-0-juVhAzN7xLmhuGfTKpB-ROD4Ao3dU6t3Q1U3slsMj394M_9q39Nq36Y_4dvEDYfVoqloqtCD1wQQFSxS9onXS6IHCKCTXw7I7vAGaTuNp2hatdP6fHAVlzdnkvw9BtoHTMt2ns6jOoq4RiArdDCKlRZ5DZXJUrWBtnDwNeUA7z5XCfCtt-4qwXeMsYTsh9Sd2fuOlUQim8XXjP7Lz68oX7hxdVdFLxj29-i---6BM_gJj1gfbCGOMNAg_vLdXmamEbEuMrm-qLb5K07j3TuhjnPsV-qe6tR5ffmTh_Wr-S7xVGB4LxKNxGF4SikfD8GaheCwMbx6Kl4ThpaF4szC8RSjePAhPhPKPpmF4ofyjizC8YP6FxYcI5l9YfIhQ_rGw-BCh_GNh8SFC-cfC4kOE8o_dxMfdbOrkn9hlt7aCzHhWYl9PJhug7aMKK4G2_7-8q94AJKTf1zzPpS76bCmkH2fhd0nFnT9PNQi_ebzK2ZdN8t3KGLyVmANdTOMpa3U9ljIrgStnhj0zJyupuAWLrlF-CrDRrRPRovNSF21_qAuQw-aabEtti5V5xa7O7lZOfvDYrl_sEfAV7Vs_RGBmKnQwbPlN4VKxF8TKAQfRFOANVDiFbwq5Q1DooUL4Q5tjO1u3q9hOz_WAi8ohPEPGddu2vsocp5fIAt1Q1Pyb69H-wcV1kq-TfJWs-ATXdBHPVrOEJXRSrpcZjVkyS_JEpCucpwlL5tmSZgnSlK7SdCLXLGazmFIaJyxO6JSmM5HkVPCVOND5fEFmMVZcqmnbEEyNLSbSuQbXi8WCxRPFBSrXbaYypvEI3UvCGJlvJ3bdNRGiKRyZxUo6784oXnqF69EOanS7hXp316_rgTCfNFatS-_rrvPptjwK6ctGTDNTEbZrpxp-otqa3zHzhO06BR1hu86A_wYAAP__tOandg">