LLVM backend handling of packed structures


Nadav Amit
 

I get a strange phenomenon with packed structs in which each byte is
loaded in a different instruction.

Consider for example xdp_prog1 for Linux samples. After building it, the
disassembly starts with:

xdp_prog1:
0: 61 12 04 00 00 00 00 00 r2 = *(u32 *)(r1 + 4)
1: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
2: bf 13 00 00 00 00 00 00 r3 = r1
3: 07 03 00 00 0e 00 00 00 r3 += 14
4: 2d 23 37 00 00 00 00 00 if r3 > r2 goto 55
5: 71 13 0c 00 00 00 00 00 r3 = *(u8 *)(r1 + 12)
6: 71 14 0d 00 00 00 00 00 r4 = *(u8 *)(r1 + 13)
7: 67 04 00 00 08 00 00 00 r4 <<= 8
8: 4f 34 00 00 00 00 00 00 r4 |= r3
9: 15 04 02 00 88 a8 00 00 if r4 == 43144 goto 2
10: b7 03 00 00 0e 00 00 00 r3 = 14
11: 55 04 05 00 81 00 00 00 if r4 != 129 goto 5


As you can see, the games in instructions 5-8 that access h_proto (u16) are
very unnecessary. Redefining 'struct ethhdr’ as “unpacked” (i.e., without
the packed attribute), eliminates this behavior.

xdp_prog1:
0: 61 12 04 00 00 00 00 00 r2 = *(u32 *)(r1 + 4)
1: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
2: bf 13 00 00 00 00 00 00 r3 = r1
3: 07 03 00 00 0e 00 00 00 r3 += 14
4: 2d 23 34 00 00 00 00 00 if r3 > r2 goto 52
5: 69 14 0c 00 00 00 00 00 r4 = *(u16 *)(r1 + 12)
6: 15 04 02 00 88 a8 00 00 if r4 == 43144 goto 2
7: b7 03 00 00 0e 00 00 00 r3 = 14
8: 55 04 05 00 81 00 00 00 if r4 != 129 goto 5

As you can see, now the the variable is accessed in one chunk, as expected.

Any clues to what went wrong?

Thanks,
Nadav

Join iovisor-dev@lists.iovisor.org to automatically receive all group messages.