[libc] Fix load_aligned big-endian handling. (#185937)
The variadic template helper `load_aligned` performs a specific case of
an unaligned integer load, by loading a sequence of integers from memory
at addresses expected to be aligned, and glues the results back together
with shifts and ORs into an output.
The implementation works by performing the first load, recursing on a
shorter parameter type list for the rest, and recombining via
first | (rest << size_of_first) // if little-endian
(first << size_of_first) | rest // if big-endian
But the big-endian case is wrong: it should shift left by the size of
the _rest_ of the types, not the size of the first. In the case where
you load 8, 16 and 8 bits from an odd address, you want
(first_byte << 24) | (middle_halfword << 8) | (last_byte)
but in fact we were calculating
(first_byte << 8) | (middle_halfword << 16) | (last_byte)
leading to three out of every four bytes being permuted in a memcpy from
an odd to an even address.
NOKEYCHECK=True
GitOrigin-RevId: 317972681c79fcbecbeaca94189247256b3a513a
2 files changed