The stub that moves a hazard scalar compare out of line is checked
through its bytes but never run, so nothing confirms that the compare
still produces the mask it would inline. The x86-64 execution section
now calls the stub for both outcomes of a CMPSS with an unsafe predicate
and checks the destination's lanes.
getTagValue returned the first entry of a dynamic tag, so an executable
with DT_RELASZ 0 followed by DT_RELASZ 24 converted for Linux with exit
0 and an output without DT_RELA, while the reverse order kept the
relocation. getTagValue now scans every entry and throws "Conflicting
duplicate <NAME> tags" when a tag it is asked for repeats with a
different value, the rule RelativeRelocationIndex already applies with
unused-filter=1. The pipeline check accepts a repeat with the same
value: it is not ambiguous, and #1938, which rejected it, was closed
because no title was shown and because rejecting it could refuse an
input the console loads. The code analysis on Windows and macOS and the
strict filter keep their own duplicate checks. Inputs without such a
conflict convert as before, and an input with one now fails with the
same message on every target.
An executable's local TPOFF64, DTPOFF64 or DTPMOD64 relocation passed
whenever a PT_TLS header existed, so the Linux targets emitted it next
to a PT_TLS with p_memsz 0, while the Windows and macOS relocation
builder rejected the same input. glibc's ld.so sets up the main
program's TLS module only for a PT_TLS with p_memsz > 0, so such a
relocation has no block to resolve against. The pipeline now requires a
PT_TLS with a nonzero p_memsz and fails on every target with "TLS
relocation in an executable without a non-empty PT_TLS segment".
Relocations against imported TLS symbols are unchanged.
A guest STT_NOTYPE import that resolved to another guest's STT_TLS
export was accepted when R_X86_64_64, R_X86_64_GLOB_DAT or
R_X86_64_JUMP_SLOT referenced it, and every target filled the slot
with an address that is not the variable. The gABI lets only TLS
relocations reference an STT_TLS symbol; the reader already rejects
such relocations against a TLS-typed import, and the builder rejects
OBJECT and FUNC imports of a TLS export as a type mismatch. The
builder now also rejects a referenced NOTYPE import of a guest TLS
export with "Non-TLS relocation against guest TLS export". These
inputs exit 2 on Linux, Windows and macOS instead of producing
outputs; unreferenced NOTYPE entries and TLS relocations are
unchanged.
GuestImageReader rejected a defined symbol whose section index is
SHN_LORESERVE (0xff00) or higher, SHN_ABS excepted, only when it was
not STT_TLS, so a TLS symbol in SHN_ABS, SHN_COMMON, 0xff00 or
SHN_XINDEX was accepted. The Linux output kept it in .dynsym with that
section index, Windows and macOS failed only for an export outside
SHN_ABS, and both wrote st_value plus addend for a DTPOFF64 relocation
against a local one. The gABI gives a defined STT_TLS symbol its
assigned TLS offset and no meaning in a special section index, so
every such symbol now fails with "Unsupported special symbol section"
before the TLS bounds check. SHN_ABS stays accepted for other symbol
types.
The pipeline read an executable's DT_NEEDED names with readCStr and
checked only bounds and the NUL terminator, so without bundled modules
an empty name, $LIB.prx, a:b.prx or a name with CR or LF relinked with
exit 0 and reached the Linux DT_NEEDED unchanged, while the Windows and
macOS outputs each rejected a different subset. The DT_NEEDED loop now
applies the rule GuestImageReader applies to a module's DT_NEEDED: a
name is not empty and contains no backslash, colon, dollar, CR or LF; a
slash stays allowed. Such an executable now fails on every target with
"Invalid dependency: <name>" at the name's file offset, and outputs for
valid names do not change.
Windows output replaced each guest GS memory instruction with UD2 and
NOP fill without checking the decoded direct branch targets, so a branch
past the first byte of such an instruction was converted and landed in
the second UD2 byte or the NOP fill. A branch target strictly inside a
trapped GS instruction is now refused with "Branch enters a guest GS
instruction", the rule macOS applies since #7706 and this builder
already applies to its FS rewrites. The branch targets are sorted before
the trap loop, which runs before the PT_TLS early returns, so images
without PT_TLS are covered; guest modules go through the same builder. A
branch to the first byte still converts and reaches the UD2.
The Linux output writes every import symbol with st_size 0 and copies
a COPY relocation into the output unchanged, so ld.so copies
MIN(st_size of the definition, 0) = 0 bytes and the variable stays
zero. Windows and macOS already rejected the type in the relocation
builder. ValidationPolicy now rejects type 5 before any target code,
so every target reports the same error, and the COPY case of the
fixed-base rebasing, which validation makes unreachable, is gone.