@deanmlittle @clairechingching @bidhan-a
2026-01-14 EDIT: Per #97 (comment), correct description offset type to i16, and add a section about LLVM
Snippet
stxdw [r3 + 100000000000000000], r4
Description
This assembles, even though the SBPF spec stipulates u16 i16 offsets. The culprit appears to be silent truncation via the internal casting process, e.g. in this case the offset gets silently cast to 0x0
Why this is a problem
Once an instruction requires more than 6 3 accounts, hard-coded offsets relative to the start of the input buffer (r1) will exceed U16_MAX = 65535 I16_MAX = 32_767 even if all accounts have no data. This is due to the minimum 10240 bytes of account data reallocation padding.
If an sbpf user prepares .equ-style offsets using a Rust script or similar, they'll get no feedback about the offsets getting truncated, and will experience undefined behavior in the resultant program.
Regarding LLVM
If LLVM silently truncates, it is implementing a massive footgun that will lead to undefined behavior that can easily be prevented. Absent any strong argument to the contrary, I submit that with regard to silent offset truncation LLVM is itself broken and should be fixed. Assuming this, there is no merit to feature parity for the sake of feature parity if it means copying a broken implementation
Expected behavior
Some kind of error message that says offsets must fit in a u16 offsets must fit in an i16 and panics the assembler
@deanmlittle @clairechingching @bidhan-a
2026-01-14 EDIT: Per #97 (comment), correct description offset type to
i16, and add a section about LLVMSnippet
Description
This assembles, even though the SBPF spec stipulates
u16i16offsets. The culprit appears to be silent truncation via the internal casting process, e.g. in this case the offset gets silently cast to0x0Why this is a problem
Once an instruction requires more than
63 accounts, hard-coded offsets relative to the start of the input buffer (r1) will exceedU16_MAX = 65535I16_MAX = 32_767even if all accounts have no data. This is due to the minimum 10240 bytes of account data reallocation padding.If an
sbpfuser prepares.equ-style offsets using a Rust script or similar, they'll get no feedback about the offsets getting truncated, and will experience undefined behavior in the resultant program.Regarding LLVM
If LLVM silently truncates, it is implementing a massive footgun that will lead to undefined behavior that can easily be prevented. Absent any strong argument to the contrary, I submit that with regard to silent offset truncation LLVM is itself broken and should be fixed. Assuming this, there is no merit to feature parity for the sake of feature parity if it means copying a broken implementation
Expected behavior
Some kind of error message that says
offsets must fit in a u16offsets must fit in an i16and panics the assembler