Closed dhduvall closed 7 years ago
You're transmuting from a u8
array, which has no alignment requirements, to a u64
array, which has an alignment requirement of 8. There was no guarantee that this would work, even before that patch, since the Blake2bCtx
struct only has an alignment of 2 due to the u16
inside.
Perhaps I failed to trim down blake2b.rs correctly, but this is the same error I'm seeing in the compiler, out of https://github.com/rust-lang/rust/blob/master/src/librustc_data_structures/blake2b.rs
Though there the loads are more complex:
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x14: ca 5e 00 00 ldx [%i0], %g5
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x18: c8 5e 20 08 ldx [%i0 + 0x8], %g4
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x1c: c6 5e 20 10 ldx [%i0 + 0x10], %g3
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x20: fa 5e 20 18 ldx [%i0 + 0x18], %i5
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x24: e0 5e 20 20 ldx [%i0 + 0x20], %l0
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x28: f8 5e 20 28 ldx [%i0 + 0x28], %i4
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x2c: f6 5e 20 30 ldx [%i0 + 0x30], %i3
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x30: d2 5e 20 5a ldx [%i0 + 0x5a], %o1
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x34: c4 5e 20 38 ldx [%i0 + 0x38], %g2
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x38: e2 5e 20 40 ldx [%i0 + 0x40], %l1
rustc_data_structures::blake2b::blake2b_compress::hb082a32bbe0c2ce5+0x3c: d0 5e 20 48 ldx [%i0 + 0x48], %o0
(See the +0x5a
which is where we get the SIGBUS.)
Ah, ok. That would have worked before the patch, of course.
Yes. Or by using -Z fuel=<mod>=0
.
It doesn't look like I can use RUSTFLAGS
to inject -Z fuel=rustc_data_structures::blake2b=0
, since my bootstrapping compiler is 1.17.0 and doesn't understand that.
I reimplemented the transmute()
in blake2b_compress
with a pair of for loops and lots of shifting and oring, and the compiler works again, even if it uses a lot more instructions doing so (and blake2b_selftest()
passes). If there's a faster way that's akin to transmute()
, but works, I've no idea. I looked at the various alternatives in the transmute()
docs, but when I got a warning about a non-scalar cast, I gave up. I don't know how performance-critical this is, anyway.
I could, I suppose, build a patched 1.18.0 and use that for the bootstrap so that the above RUSTFLAGS
workaround could then work to build a good compiler against the existing sources, but I keep worrying about the use of -Z
going away, and don't really want to depend on that.
I'll leave this open until someone else wants to pick it up. If anyone thinks it'd be worthwhile for me to simply submit a PR with my slow code, and get it code-reviewed into existence as folks have time, I'm happy to do that.
I think the simplest workaround would be to add #[repr(C)]
to Blake2bCtx
. If you can confirm that that works then it would be worth submitting that. There's probably a better way of fixing this though like changing the type of Blake2bCtx.b
to [u64; 16]
because transmuting from &mut [u64; 16]
to &mut [u8; 128]
should be safe.
Indeed, #[repr(C)]
does the trick.
My apologies for not catching this sooner.
The struct alignment and packing that landed (well, was re-enabled) with 1.18.0 produces either improperly aligned structs or improperly aligned loads and stores (or both) on SPARC. The following test program demonstrates it (extracted from where I originally saw the compiler die):
The disassembly looks like this:
Note the
ldx
of[%i0 + 0x2]
. That would be valid if%i0
were itself misaligned, but it's not, andldx
requires an 8-byte alignment. I can attach the entire IR if necessary, but I believe these are the relevant bits:I don't see anything obviously wrong in the code, but my knowledge here is pretty slim, so if it's obvious to someone else, I'd love the help. Otherwise, I'm probably going to be putting debugging statements into
rustc::ty::layout::Struct::new
, hope I'm poking around in the right area, and doing a lot of recompiling.cc @binarycrusader