rdar://186556339
Resolves https://github.com/swiftlang/swift/issues/91943
setTrueConstGlobal pins metadata into .rodata on ELF, but LLVM still derives
the section flags from the initializer. Two cases produced a writable
.rodata ("aw"), which GNU ld folds into the text segment, yielding an RWX
LOAD segment on AArch64 Linux (where it defaults to -z noseparate-code):
- Mangled-name references are tagged by setting the low bit with a
non-inbounds GEP. Constant::getRelocationInfo only recognizes a relative
reference as a link-time constant if it can strip the operands' offsets
with stripInBoundsConstantOffsets, so these were classified as needing a
dynamic relocation. This hit every conformance descriptor with an
associated/base conformance entry (Hashable, Comparable, the synthesized
CodingKeys: CodingKey, ...). Use inbounds GEPs instead. +1 into a string of
at least two bytes is in bounds.
- Key path patterns were created as non-constant globals. The pattern is
never written at runtime (the once cache is the separate keypath_once
global, and on Darwin the pattern already lives in __TEXT,__const), so
mark it constant.
Also assert in setTrueConstGlobal that the global is constant.
Adds a cross-target test checking that the object file has no writable
.rodata, and an AArch64 Linux executable test checking that linking with
the default linker produces no RWX segment.