sectionWithinSegment() treats an empty section as having a size of 1. Due to the rule, an empty
.tdata will not be attributed to an empty PT_TLS. (The empty p_align=64 PT_TLS is for Android
Bionic's TCB compatibility. See https://reviews.llvm.org/D62055#1507426 for more context.)
--only-keep-debug will not layout a segment with no section (layoutSegmentsForOnlyKeepDebug()), thus
p_offset of PT_TLS can go past the end of the file. The strange p_offset can trigger validation
errors for successive tools, e.g. llvm-objcopy errors when reading back the separate debug file
(readProgramHeaders()).
For an empty section on the boundary of two segments, attributing it to the second segment is better
(see empty-sections.test). The (treating sh_size=0 as sh_size=1) rule is arguably to make this
happen. We can actually make the intention more explicit in readProgramHeaders() and delete the
(treating sh_size=0 as sh_size=1) rule.
In the case of nested segments, e.g. PT_LOAD⊇PT_GNU_RELRO⊇PT_TLS. We want ParentSegment to refer
to PT_LOAD so that layoutSectionsForOnlyKeepDebug() will advance sh_offset to make sh_offset≡sh_addr
(mod p_align), this is naturally satisfied because PT_LOAD comes before PT_TLS (GNU ld/gold/lld).
(If PT_LOAD comes after PT_TLS, the rule will break, but this is really impractical.)
A side effect is that an empty non-SHF_ALLOC section following SHF_ALLOC sections will be considered
included by a segment. The change to strip-non-alloc.test and strip-all.test demonstrates this
behavior change, which should be benign.
I think this behaviour change shows the test needs changing, as it no longer tests the case "non-alloc not in segment is removed".