[llvm-branch-commits] [llvm] [Offload] Make compressed offload bundle header little-endian (PR #206744)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jun 30 07:59:00 PDT 2026
michaelselehov wrote:
The compressed offload bundle ("CCOB") header stores several integer fields:
```
off 0: char Magic[4] = "CCOB"
off 4: u16 Version
off 6: u16 Method
off 8: u32/u64 FileSize (V2: u32, V3: u64)
u32/u64 UncompressedFileSize (V1/V2: u32, V3: u64)
u64 Hash
```
The on-disk format is little-endian, but the code serialized and read these
fields in host-native byte order (plain `uint32_t` / `uint64_t` writes and a
`memcpy` into a native-typed packed struct). On a big-endian host every field is
therefore byte-swapped:
- on write, the header is emitted big-endian, i.e. a malformed bundle;
- on read, `FileSize` and friends are interpreted with the wrong endianness,
so the bundle size becomes garbage.
This is what made `llvm-objdump --offloading` crash / misbehave on s390x and was
the reason the earlier bundle-size fix had to be reverted.
Fix:
- Read side: declare the `RawCompressedBundleHeader` fields as
`support::ulittle16_t` / `support::ulittle32_t` / `support::ulittle64_t`, so
reads always interpret the bytes as little-endian regardless of host.
- Write side: emit the header with `support::endian::Writer(OS,
endianness::little)` instead of host-native `OS.write(&field, sizeof field)`.
The header is now little-endian on every host.
Validation:
- x86_64 (little-endian): full `check-llvm` / `check-clang`, plus the offload
round-trip tests, pass.
- s390x (big-endian, qemu-user): using the real `llvm/Support/Endian.h`
primitives on a real bundle, the native read yields a byte-swapped
`FileSize` (garbage) while the `ulittle64` read yields the correct value.
Co-authored-by: Nikita Popov <npopov at redhat.com> (the little-endian approach is
from his patch).
Assisted-by: Claude Opus
https://github.com/llvm/llvm-project/pull/206744
More information about the llvm-branch-commits
mailing list