Commit Graph

3 Commits

Author SHA1 Message Date
Fangrui Song fbf41b5267 [ELF] Simplify sh_addr computation and warn if sh_addr is not a multiple of sh_addralign
See `docs/ELF/linker_script.rst` for the new computation for sh_addr and sh_addralign.
`ALIGN(section_align)` now means: "increase alignment to section_align"
(like yet another input section requirement).

The "start of section .foo changes from 0x11 to 0x20" warning no longer
makes sense. Change it to warn if sh_addr%sh_addralign!=0.

To decrease the alignment from the default max_input_align,
use `.output ALIGN(8) : {}` instead of `.output : ALIGN(8) {}`
See linkerscript/section-address-align.test as an example.

When both an output section address and ALIGN are set (can be seen as an
"undefined behavior" https://sourceware.org/ml/binutils/2020-03/msg00115.html),
lld may align more than GNU ld, but it makes a linker script working
with GNU ld hard to break with lld.

This patch can be considered as restoring part of the behavior before D74736.

Differential Revision: https://reviews.llvm.org/D75724
2020-03-11 09:35:42 -07:00
Fangrui Song de0dda54d3 [ELF] Warn changed output section address
When the output section address (addrExpr) is specified, GNU ld warns if
sh_addr is different. This patch implements the warning.

Note, LinkerScript::assignAddresses can be called more than once. We
need to record the changed section addresses, and only report the
warnings after the addresses are finalized.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D74741
2020-02-21 08:13:29 -08:00
Fangrui Song 6ed8e20143 [ELF] Ignore the maximum of input section alignments for two cases
Follow-up for D74286.

Notations:

* alignExpr: the computed ALIGN value
* max_input_align: the maximum of input section alignments

This patch changes the following two cases to match GNU ld:

* When ALIGN is present, GNU ld sets output sh_addr to alignExpr, while lld use max(alignExpr, max_input_align)
* When addrExpr is specified but alignExpr is not, GNU ld sets output sh_addr to addrExpr, while lld uses `advance(0, max_input_align)`

Note, sh_addralign is still set to max(alignExpr, max_input_align).

lma-align.test is enhanced a bit to check we don't overalign sh_addr.

fixSectionAlignments() sets addrExpr but not alignExpr for the `!hasSectionsCommand` case.
This patch sets alignExpr as well so that max_input_align will be respected.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D74736
2020-02-21 08:12:00 -08:00