Open rorth opened 8 months ago
FWIW, this is obviously not a Solaris issue: I see exactly the same failure in the LLVM 18 release builds on Debian/sparc64.
The analysis was only partially correct: llvm::byteswap
isn't involved (or even reached) since it gets its args by value.
However, MachOTest.UnalignedLC
(or rather swapStruct
) passes intentionally misaligned pointers/references, thus lying to sys::swapByteOrder
about it's args. E.g. when sys::swapByteOrder
is called with an unsigned int&
like for mh.magic
, it assumes (and IMO can do so) that the pointer is properly aigned for the type before dereferencing it. On strict-alignement targets like SPARC, this cannot work and leads to the observed SIGBUS
.
I think the test is at fault and needs to account for that possibility.
Unfortunately, the test author doesn't seem to have a github account at all, and there's no tag for Mach-O issues or the llvm testsuite.
The original test author is no longer working on LLVM.
I think the test might just be bogus: I don't think the actual MachO parser/writer code ever tries to use swapStruct like this. As you note, even if swapStruct itself somehow worked, constructing the reference would be undefined behavior.
The ubsan bot would probably pick this up... except I think it runs on a little-endian host, and this particular test only does the swapping on big-endian hosts.
The ubsan bot would probably pick this up... except I think it runs on a little-endian host, and this particular test only does the swapping on big-endian hosts.
FWIW, I've compiled MachOTest.cpp
with -fsanitize=undefined
on a big-endian host, but that came up blank.
The
MachOTest.UnalignedLC
test (LLVM-Unit :: BinaryFormat/./BinaryFormatTests/11/193
) has been failing on and off in the past on Solaris/sparcv9. However, since LLVM 18 the failure has become consistent, as I've just re-discovered:clang-17
as build compiler, the testPASS
es.clang-18
, the test consistentlyFAIL
s as I found when trying thatclang-17
toclang-18
switch on the Solaris/sparcv9 buildbot.The failure is like this:
With more debug info from a past build, there's
The program dies with
SIGBUS
like so:i.e. the input operand isn't properly aligned:
SPARC being a strict-alignment target, natural alignment is required for all operands, so e.g. an
unsigned int
must be at least 2-byte aligned, which isn't the case here.I think I ultimately traced this to
llvm::byteswap
being ignorant of this requirement. Considering the call chainllvm::byteswap
does nothing to deal with unaligned input.While one could force the alignment in the testcase, its name (
UnalignedLC
) strongly suggests that it's exactly about the unaligned case, so that seems wrong. Besides,llvm::byteswap
needs to be robust irrespective of input IMO.