Closed
Description
Clang has TargetInfo::MinGlobalAlign
which sets a minimum alignment for global variables (unless explicitly aligned less). This is needed for s390x to have 2-byte alignment even for 1-byte-aligned types, as explained in clang r181210:
This patch adds a new common code feature that allows platform code to
request minimum alignment of global symbols. The background for this is
that on SystemZ, the most efficient way to load addresses of global symbol
is the LOAD ADDRESS RELATIVE LONG (LARL) instruction. This instruction
provides PC-relative addressing, but only to *even* addresses. For this
reason, existing compilers will guarantee that global symbols are always
aligned to at least 2. [ Since symbols would otherwise already use a
default alignment based on their type, this will usually only affect global
objects of character type or character arrays. ] GCC also allows creating
symbols without that extra alignment by using explicit "aligned" attributes
(which then need to be used on both definition and each use of the symbol).
For Rust, I ran into trouble here when running bootstrap
from 1.21-beta. It now uses serde_json
, and the static serde_json::read::ESCAPE: [bool; 256]
was misaligned. In the binary and in memory it was at an odd address, but the generated code/relocation tried to read it from an even address, so it was off by one. This led to serde_json
throwing an InvalidUnicodeCodePoint
error on a space (0x20), because it was effectively indexing the entry for 0x1F (which needs to be escaped in JSON).