riscv32: use the 32-bit pthread_rwlock_t layout
riscv32 carried the 64-bit variant of the struct: eleven members with
__writer and __shared as ints, two long pads, and __flags last. That is what
aarch64, alpha and riscv64 use, and it matches the __WORDSIZE == 64 branch of
the initializers in pthread.h. On a 32-bit target the 32-bit branch is taken
instead, which places the value in member seven -- __writer here, not __flags.
So PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP wrote its 2 into
__writer, leaving __flags 0: reader preference, plus a bogus writer tid in a
freshly initialized lock. Measured in the object file before the change,
offsetof(__flags) was 44 and the 2 landed at 28.
Switch to the i386 layout, the four char fields in little endian order, which
is what the 32-bit initializers address. __SIZEOF_PTHREAD_RWLOCK_T stays 48,
so the union does not change size and nothing outside moves; only the members
inside it do.
Found on riscv32 with NPTL and shared libraries, gcc 15 against 6.5.10
headers: ten tst-initializers1 variants plus tst-rwlock8 and its -O2 twin,
16 failures in 775 tests. The rwlock8 pair is the runtime half of the same
bug, so this was never a test-only detail. Verified in the object file after
the change: __flags at 24, __writer at 28, and the initializer's 2 sits in
__flags.
Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>