[ld] section address : ALIGN(align) and the maximum of input section alignments
Alan Modra
amodra@gmail.com
Thu Mar 5 11:21:00 GMT 2020
More information about the Binutils mailing list
Thu Mar 5 11:21:00 GMT 2020
- Previous message (by thread): [ld] section address : ALIGN(align) and the maximum of input section alignments
- Next message (by thread): Don't merge sections with differing MASKPROC or MASKOS flags
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Wed, Mar 04, 2020 at 10:41:28PM -0800, Fangrui Song wrote: > For convenience, I will use some notations: > > max_input_align: maximum of input section alignments. > addr_tree: output section address > > On 2020-03-04, Alan Modra wrote: > > On Tue, Mar 03, 2020 at 10:39:45PM -0800, Fangrui Song wrote: > > > The implementation is complex. For users to understand, I think it > > > will be helpful to have something more detailed in > > > https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address > > > > > > If my understanding is correct > > > https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=233bf4f847b136705247e2f7f11bae41c72448a4 > > > makes the output section address override sh_addralign computed from > > > the maximum of input section alignments. > > > > Right. > > > > > So, generally the rules are: > > > * The max of ALIGN and (the maximum of input section alignments) is taken. > > > * The output section address overrides the above. If sh_addr % > > > alignment != 0, set sh_addralign to the largest alignment that makes > > > sh_addr%alignment=0 > > > In this case, should the linker emit a warning? > > > > I don't think so. The input sections are still aligned within the > > output section to their required alignment. > > > > > * ALIGN and the output section address cannot be specified at the same > > > time. This is considered a linker script "undefined behavior". Users > > > should not rely on a particular result. > > > > I'm not going to make that change for ld.bfd. I said it probably > > would have been better if ALIGN for output section statements hadn't > > been invented, but once there are users for a script feature it can't > > be removed without a good reason. > > I take ALIGN as a way to overalign an output section. > When ALIGN < max_input_align, do we agree that sh_addralign = max(ALIGN, max_input_align) = max_input_align ? > > When both addr_tree and ALIGN are specified (what I called "undefined behavior"), and addr_tree is misaligned, > sh_addralign can be decreased from max(ALIGN,max_input_align) to > (addr_tree|max(ALIGN,max_input_align)) & -(addr_tree|max(ALIGN,max_input_align)) > > Commit 233bf4f847b136705247e2f7f11bae41c72448a4 is made so that > "The value of sh_addr must be congruent to 0, modulo the value of sh_addralign." > is obeyed. > > Another view is that the user intentionally breaks the ELF rule. We can keep > sh_addralign as max(ALIGN,max_input_align) and emit a warning along the line of: > > warning: address (0x10010) of section .foo is not a multiple of alignment (32) I'm not going to do that for BFD ld. The user chose an address for an output section, and all input sections are placed in that section according to their alignment. No warning needed, just a change in sh_addralign calculation. I'll note that ld could quite correctly set sh_addralign to 0 or 1 for any final linked executable. > > > --warn-section-align may be out of place. It can be noisy for normal > > > output section descriptions like .foo : ALIGN(16) { ... } without > > > a preceding dot advancing to a multiple of 16. > > /* Without this assignment, the ALIGN(16) below will likely report a warning */ > . = ALIGN(16); > .foo : ALIGN(16) { ... } > > Does this suggest that --warn-section-align is not very useful? > Keep reading. > > > It's even more noisy when relaxation is enabled.. > > https://sourceware.org/ml/binutils/2020-03/msg00107.html does not fix > the --warn-section-align version of PR25570. > > # My original example. > cat > a.s <<e > .globl _start; _start: ret > .section .data.rel.ro,"aw"; .balign 8; .byte 0 > .data; .byte 0 > .section .data2,"aw"; .balign 8; .byte 0 > .bss; .balign 32; .byte 0 > e > as a.s -o a.o > > % ./ld-new a.o -o a --warn-section-align ./ld-new: warning: start > of section .got changed by 7 > ./ld-new: warning: start of section .got.plt changed by 7 > ./ld-new: warning: start of section .data2 changed by 6 > ./ld-new: warning: start of section .bss changed by 23 > ./ld-new: warning: start of section .data.rel.ro changed by 4088 > ./ld-new: warning: start of section .got changed by 4088 > ./ld-new: warning: start of section .got.plt changed by 4088 > ./ld-new: warning: start of section .data2 changed by 4096 > ./ld-new: warning: start of section .bss changed by 4096 > ./ld-new: warning: start of section .rela.dyn changed by 56 > ./ld-new: warning: start of section .rela.plt changed by 56 > ./ld-new: warning: start of section .data.rel.ro changed by -4088 > ./ld-new: warning: start of section .got changed by -4088 > ./ld-new: warning: start of section .got.plt changed by -4088 > ./ld-new: warning: start of section .data2 changed by -4096 > ./ld-new: warning: start of section .bss changed by -4096 > ./ld-new: warning: start of section .data.rel.ro changed by 4088 > ./ld-new: warning: start of section .got changed by 4088 > ./ld-new: warning: start of section .got.plt changed by 4088 > ./ld-new: warning: start of section .data2 changed by 4096 > ./ld-new: warning: start of section .bss changed by 4096 > > This also demonstrates how annoying --warn-section-align can be. PR 25570 * ldlang.c (lang_size_sections_1): Don't report changes on second and subsequent iterations that make no change in alignment from that already reported. diff --git a/ld/ldlang.c b/ld/ldlang.c index 6ffa7af575..63f9d182ea 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -5597,7 +5597,13 @@ lang_size_sections_1 if (lang_sizing_iteration == 1) diff = dotdelta; else if (lang_sizing_iteration > 1) - diff = newdot - os->bfd_section->vma; + { + /* Only report adjustments that would change + alignment from what we have already reported. */ + diff = newdot - os->bfd_section->vma; + if (!(diff & (((bfd_vma) 1 << section_alignment) - 1))) + diff = 0; + } if (diff != 0 && (config.warn_section_align || os->addr_tree != NULL)) -- Alan Modra Australia Development Lab, IBM
- Previous message (by thread): [ld] section address : ALIGN(align) and the maximum of input section alignments
- Next message (by thread): Don't merge sections with differing MASKPROC or MASKOS flags
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list