Files
Dario Rexin f6268ecd88 [IRGen] Don't emit writable .rodata sections on ELF
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.
2026-10-12 14:20:05 -07:00
..