This change affects the non-linker script case (precisely, when the
`SECTIONS` command is not used). Let me demonstrate the idea with a
When assigning the address to the first output section of a new PT_LOAD,
if the end position of last section of the previous PT_LOAD is 0x10020,
we advance to the next multiple of maxPageSize: 0x20000. The new PT_LOAD
will thus have p_vaddr=0x20000. Because p_offset and p_vaddr are
congruent modulo maxPageSize, p_offset will be 0x20000, leaving a
p_offset gap [0x10020, 0x20000) in the output.
Alternatively, if we advance the position to 0x20020, the new PT_LOAD
will have p_vaddr=0x20020. We can pick either 0x10020 or 0x20020 for p_offset!
Obviously 0x10020 is the choice because it leaves no gap.
At runtime, p_vaddr will be rounded down by pagesize
(0x20000 if pagesize=maxPageSize). This PT_LOAD will load initial
contents from p_offset ranges [0x10000,0x10020), which will also be
loaded by the previous PT_LOAD. This is fine if -z noseparate-code is in
effect or if we are not transiting between executable and non-executable
ld.bfd leverages this technique to keep output small. This can be
observed with its -z noseparate-code output. This patch implements the
technique in lld. With our default -z noseparate-code, it removes 2
alignment boundaries, as indicated by `|`:
`R | RX | RW(relro) RW(non-relro)`
This technique is mostly effective on targets with large
defaultMaxPageSize (AArch64/MIPS/PPC: 65536). The two alignment
boundaries can increase the file size by almost 2*65536 bytes.
A note about p_memsz of PT_GNU_RELRO: we used to round it up to
commonPageSize (defaults to 4096 on all targets). Now
p_vaddr%commonPageSize may be non-zero so we need to take account of
Due to the large number of tests I have to fix (offset/address changes)
and potential risk, this technique is only enabled for PPC in this