* [ld] section address : ALIGN(align) and the maximum of input section alignments @ 2020-02-26 5:23 Fangrui Song 2020-02-26 6:31 ` Fangrui Song 0 siblings, 1 reply; 11+ messages in thread From: Fangrui Song @ 2020-02-26 5:23 UTC (permalink / raw) To: binutils https://sourceware.org/binutils/docs/ld/Output-Section-Description.html I have observed some strange rules while playing with the output section address and ALIGN. 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 .section .data3,"aw"; .balign 32; .byte 0 .bss; .balign 32; .byte 0 e cat > a.x <<e SECTIONS { .text 0x10000 : { *(.text) } /* sh_addr is aligned to 16. */ .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } .data 0x20000 : { *(.data) } /* The output section address is set without ALIGN. sh_addr is set to Dot, ignoring alignment. */ /* sh_addralign is the maximum of input section alignments, 8. */ .data2 . : { *(.data2) } /* sh_addr is aligned to 32. */ .data3 : ALIGN(16) { *(.data3) } /* sh_addr is aligned to 16, ???????????? */ .bss . : ALIGN(16) { *(.bss) } } e as a.s -o a.o ld.bfd -T a.x a.o -o a % readelf -WS a Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 0000000000010000 001000 000001 00 AX 0 0 1 [ 2] .data.rel.ro PROGBITS 0000000000010010 001010 000001 00 WA 0 0 16 [ 3] .data PROGBITS 0000000000020000 002000 000001 00 WA 0 0 1 [ 4] .data2 PROGBITS 0000000000020008 002008 000001 00 WA 0 0 8 [ 5] .data3 PROGBITS 0000000000020020 002020 000001 00 WA 0 0 32 [ 6] .bss NOBITS 0000000000020030 002021 000011 00 WA 0 0 32 ... Why doesn't `.bss . : ALIGN(16)` respect the maximum of input section alignments (32)? (I have verified that .bss being SHT_NOBITS is unrelated.) The rule of sh_addr computation appears to be: * ADDR is unset, ALIGN is unset => max_input_alignment * ADDR is unset, ALIGN is set => max(ALIGN, max_input_alignment) * ADDR is set, ALIGN is unset => max_input_alignment * ADDR is set, ALIGN is set => ALIGN ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-02-26 5:23 [ld] section address : ALIGN(align) and the maximum of input section alignments Fangrui Song @ 2020-02-26 6:31 ` Fangrui Song 2020-03-03 5:46 ` Fangrui Song 2020-03-03 22:39 ` Alan Modra 0 siblings, 2 replies; 11+ messages in thread From: Fangrui Song @ 2020-02-26 6:31 UTC (permalink / raw) To: Alan Modra; +Cc: binutils On 2020-02-25, Fangrui Song wrote: >https://sourceware.org/binutils/docs/ld/Output-Section-Description.html >I have observed some strange rules while playing with the output section address and ALIGN. > >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 > .section .data3,"aw"; .balign 32; .byte 0 > .bss; .balign 32; .byte 0 >e > >cat > a.x <<e > SECTIONS { > .text 0x10000 : { *(.text) } > /* sh_addr is aligned to 16. */ > .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } > > .data 0x20000 : { *(.data) } > /* The output section address is set without ALIGN. sh_addr is set to Dot, ignoring alignment. */ > /* sh_addralign is the maximum of input section alignments, 8. */ > .data2 . : { *(.data2) } > /* sh_addr is aligned to 32. */ > .data3 : ALIGN(16) { *(.data3) } > /* sh_addr is aligned to 16, ???????????? */ > .bss . : ALIGN(16) { *(.bss) } > } >e > >as a.s -o a.o >ld.bfd -T a.x a.o -o a > >% readelf -WS a > >Section Headers: > [Nr] Name Type Address Off Size ES Flg Lk Inf Al > [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 > [ 1] .text PROGBITS 0000000000010000 001000 000001 00 AX 0 0 1 > [ 2] .data.rel.ro PROGBITS 0000000000010010 001010 000001 00 WA 0 0 16 > [ 3] .data PROGBITS 0000000000020000 002000 000001 00 WA 0 0 1 > [ 4] .data2 PROGBITS 0000000000020008 002008 000001 00 WA 0 0 8 > [ 5] .data3 PROGBITS 0000000000020020 002020 000001 00 WA 0 0 32 > [ 6] .bss NOBITS 0000000000020030 002021 000011 00 WA 0 0 32 >... > > >Why doesn't `.bss . : ALIGN(16)` respect the maximum of input section alignments (32)? > >(I have verified that .bss being SHT_NOBITS is unrelated.) > >The rule of sh_addr computation appears to be: > >* ADDR is unset, ALIGN is unset => max_input_alignment >* ADDR is unset, ALIGN is set => max(ALIGN, max_input_alignment) >* ADDR is set, ALIGN is unset => max_input_alignment >* ADDR is set, ALIGN is set => ALIGN When ADDR is set, ALIGN is used while max_input_alignment is ignored. ld/ldlang.c:5582 if (os->addr_tree == NULL) { ... newdot = os->region->current; // maximum of ALIGN and input section alignments section_alignment = os->bfd_section->alignment_power; } else // ALIGN section_alignment = exp_get_power (os->section_alignment, "section alignment"); Alan, is the `else` branch supposed to use `section_alignment = os->bfd_section->alignment_power;` as well? ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-02-26 6:31 ` Fangrui Song @ 2020-03-03 5:46 ` Fangrui Song 2020-03-03 22:39 ` Alan Modra 1 sibling, 0 replies; 11+ messages in thread From: Fangrui Song @ 2020-03-03 5:46 UTC (permalink / raw) To: Alan Modra; +Cc: binutils On Tue, Feb 25, 2020 at 10:30 PM Fangrui Song <i@maskray.me> wrote: > > On 2020-02-25, Fangrui Song wrote: > >https://sourceware.org/binutils/docs/ld/Output-Section-Description.html > >I have observed some strange rules while playing with the output section address and ALIGN. > > > >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 > > .section .data3,"aw"; .balign 32; .byte 0 > > .bss; .balign 32; .byte 0 > >e > > > >cat > a.x <<e > > SECTIONS { > > .text 0x10000 : { *(.text) } > > /* sh_addr is aligned to 16. */ > > .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } > > > > .data 0x20000 : { *(.data) } > > /* The output section address is set without ALIGN. sh_addr is set to Dot, ignoring alignment. */ > > /* sh_addralign is the maximum of input section alignments, 8. */ > > .data2 . : { *(.data2) } > > /* sh_addr is aligned to 32. */ > > .data3 : ALIGN(16) { *(.data3) } > > /* sh_addr is aligned to 16, ???????????? */ > > .bss . : ALIGN(16) { *(.bss) } > > } > >e > > > >as a.s -o a.o > >ld.bfd -T a.x a.o -o a > > > >% readelf -WS a > > > >Section Headers: > > [Nr] Name Type Address Off Size ES Flg Lk Inf Al > > [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 > > [ 1] .text PROGBITS 0000000000010000 001000 000001 00 AX 0 0 1 > > [ 2] .data.rel.ro PROGBITS 0000000000010010 001010 000001 00 WA 0 0 16 > > [ 3] .data PROGBITS 0000000000020000 002000 000001 00 WA 0 0 1 > > [ 4] .data2 PROGBITS 0000000000020008 002008 000001 00 WA 0 0 8 > > [ 5] .data3 PROGBITS 0000000000020020 002020 000001 00 WA 0 0 32 > > [ 6] .bss NOBITS 0000000000020030 002021 000011 00 WA 0 0 32 > >... > > > > > >Why doesn't `.bss . : ALIGN(16)` respect the maximum of input section alignments (32)? > > > >(I have verified that .bss being SHT_NOBITS is unrelated.) > > > >The rule of sh_addr computation appears to be: > > > >* ADDR is unset, ALIGN is unset => max_input_alignment > >* ADDR is unset, ALIGN is set => max(ALIGN, max_input_alignment) > >* ADDR is set, ALIGN is unset => max_input_alignment > >* ADDR is set, ALIGN is set => ALIGN > > When ADDR is set, ALIGN is used while max_input_alignment is ignored. > > ld/ldlang.c:5582 > > if (os->addr_tree == NULL) { > ... > newdot = os->region->current; > // maximum of ALIGN and input section alignments > section_alignment = os->bfd_section->alignment_power; > } > else > // ALIGN > section_alignment = exp_get_power (os->section_alignment, "section alignment"); > > Alan, is the `else` branch supposed to use `section_alignment = os->bfd_section->alignment_power;` as well? Ping :) ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-02-26 6:31 ` Fangrui Song 2020-03-03 5:46 ` Fangrui Song @ 2020-03-03 22:39 ` Alan Modra 2020-03-04 0:03 ` Fangrui Song [not found] ` <BY5PR07MB7316674DD98011D2AD812A63CBE40@BY5PR07MB7316.namprd07.prod.outlook.com> 1 sibling, 2 replies; 11+ messages in thread From: Alan Modra @ 2020-03-03 22:39 UTC (permalink / raw) To: Fangrui Song; +Cc: binutils On Tue, Feb 25, 2020 at 10:30:03PM -0800, Fangrui Song wrote: > > Why doesn't `.bss . : ALIGN(16)` respect the maximum of input section alignments (32)? > > > > (I have verified that .bss being SHT_NOBITS is unrelated.) > > > > The rule of sh_addr computation appears to be: > > > > * ADDR is unset, ALIGN is unset => max_input_alignment > > * ADDR is unset, ALIGN is set => max(ALIGN, max_input_alignment) > > * ADDR is set, ALIGN is unset => max_input_alignment > > * ADDR is set, ALIGN is set => ALIGN > > When ADDR is set, ALIGN is used while max_input_alignment is ignored. > > ld/ldlang.c:5582 > > if (os->addr_tree == NULL) { > ... > newdot = os->region->current; > // maximum of ALIGN and input section alignments > section_alignment = os->bfd_section->alignment_power; > } > else > // ALIGN > section_alignment = exp_get_power (os->section_alignment, "section alignment"); > > Alan, is the `else` branch supposed to use `section_alignment = os->bfd_section->alignment_power;` as well? No. When you specify the address of an output section that is the address it should have. Except that specifying both an address and alignment aligns the address given. Specifying both is somewhat contradictory and it would probably have been better if we didn't support ALIGN here. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-03 22:39 ` Alan Modra @ 2020-03-04 0:03 ` Fangrui Song [not found] ` <BY5PR07MB7316674DD98011D2AD812A63CBE40@BY5PR07MB7316.namprd07.prod.outlook.com> 1 sibling, 0 replies; 11+ messages in thread From: Fangrui Song @ 2020-03-04 0:03 UTC (permalink / raw) To: Alan Modra; +Cc: binutils On Tue, Mar 3, 2020 at 2:39 PM Alan Modra <amodra@gmail.com> wrote: > > On Tue, Feb 25, 2020 at 10:30:03PM -0800, Fangrui Song wrote: > > > Why doesn't `.bss . : ALIGN(16)` respect the maximum of input section alignments (32)? > > > > > > (I have verified that .bss being SHT_NOBITS is unrelated.) > > > > > > The rule of sh_addr computation appears to be: > > > > > > * ADDR is unset, ALIGN is unset => max_input_alignment > > > * ADDR is unset, ALIGN is set => max(ALIGN, max_input_alignment) > > > * ADDR is set, ALIGN is unset => max_input_alignment > > > * ADDR is set, ALIGN is set => ALIGN > > > > When ADDR is set, ALIGN is used while max_input_alignment is ignored. > > > > ld/ldlang.c:5582 > > > > if (os->addr_tree == NULL) { > > ... > > newdot = os->region->current; > > // maximum of ALIGN and input section alignments > > section_alignment = os->bfd_section->alignment_power; > > } > > else > > // ALIGN > > section_alignment = exp_get_power (os->section_alignment, "section alignment"); > > > > Alan, is the `else` branch supposed to use `section_alignment = os->bfd_section->alignment_power;` as well? > > No. When you specify the address of an output section that is the > address it should have. Except that specifying both an address and > alignment aligns the address given. Specifying both is somewhat > contradictory and it would probably have been better if we didn't > support ALIGN here. Thanks. For the example below, do you agree with the comments in a.x below? % cat a.s .globl _start; _start: ret .section .data.rel.ro,"aw"; .balign 8; .byte 0 .data; .byte 0 .section .data2,"aw"; .balign 8; .byte 0 .section .data3,"aw"; .balign 32; .byte 0 .bss; .balign 32; .byte 0 % as a.s -o a.o % cat a.x SECTIONS { .text 0x10000 : { *(.text) } /* sh_addr is 0x10010. Specifying both address and ALIGN should be disallowed. */ .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } .data 0x20000 : { *(.data) } /* sh_addr is 0x20001. Should there be a warning that sh_addralign is 8? Even --warn-section-align does not warn. */ .data2 . : { *(.data2) } /* sh_addr is 0x20020. The input section alignment wins. */ .data3 : ALIGN(16) { *(.data3) } /* sh_addr is 0x20030. Specifying both address and ALIGN should be disallowed. */ .bss . : ALIGN(16) { *(.bss) } } % ld.bfd -T a.x a.s -o a If specifying both Output Section Address and ALIGN is disallowed, there should be no "changing start of section" warning when --warn-section-align is not specified. Is my understanding correct? BTW, I filed a bug about duplicate "changing start of section" warnings https://sourceware.org/bugzilla/show_bug.cgi?id=25570 ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <BY5PR07MB7316674DD98011D2AD812A63CBE40@BY5PR07MB7316.namprd07.prod.outlook.com>]
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments [not found] ` <BY5PR07MB7316674DD98011D2AD812A63CBE40@BY5PR07MB7316.namprd07.prod.outlook.com> @ 2020-03-04 5:56 ` Alan Modra 2020-03-04 6:40 ` Fangrui Song 0 siblings, 1 reply; 11+ messages in thread From: Alan Modra @ 2020-03-04 5:56 UTC (permalink / raw) To: Fangrui Song; +Cc: binutils On Tue, Mar 03, 2020 at 03:58:12PM -0800, Fangrui Song wrote: > Thanks. For the example below, do you agree with the comments in a.x below? > > % cat a.s > .globl _start; _start: ret > .section .data.rel.ro,"aw"; .balign 8; .byte 0 > .data; .byte 0 > .section .data2,"aw"; .balign 8; .byte 0 > .section .data3,"aw"; .balign 32; .byte 0 > .bss; .balign 32; .byte 0 > % as a.s -o a.o > > % cat a.x > SECTIONS { > .text 0x10000 : { *(.text) } > /* sh_addr is 0x10010. Specifying both address and ALIGN should be > disallowed. */ > .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } > > .data 0x20000 : { *(.data) } > /* sh_addr is 0x20001. Should there be a warning that sh_addralign > is 8? Even --warn-section-align does not warn. */ That is a bug. The ELF gABI says in part of sh_addralign: "The value of sh_addr must be congruent to 0, modulo the value of sh_addralign." * elf.c (elf_fake_sections): Ensure sh_addralign is such that sh_addr mod sh_addalign is zero. diff --git a/bfd/elf.c b/bfd/elf.c index fcd84d2d17..c4d6718aaa 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3192,6 +3192,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) unsigned int sh_type; const char *name = asect->name; bfd_boolean delay_st_name_p = FALSE; + bfd_vma mask; if (arg->failed) { @@ -3291,7 +3292,10 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) arg->failed = TRUE; return; } - this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power; + /* Set sh_addralign to the highest power of two given by alignment + consistent with the section VMA. Linker scripts can force VMA. */ + mask = ((bfd_vma) 1 << asect->alignment_power) | this_hdr->sh_addr; + this_hdr->sh_addralign = mask & -mask; /* The sh_entsize and sh_info fields may have been set already by copy_private_section_data. */ > .data2 . : { *(.data2) } > /* sh_addr is 0x20020. The input section alignment wins. */ > .data3 : ALIGN(16) { *(.data3) } > /* sh_addr is 0x20030. Specifying both address and ALIGN should be > disallowed. */ > .bss . : ALIGN(16) { *(.bss) } > } > > % ld.bfd -T a.x a.s -o a > > If specifying both Output Section Address and ALIGN is disallowed, > there should be no "changing start of section" warning when > --warn-section-align is not specified. Is my understanding correct? > > BTW, I filed a bug about duplicate "changing start of section" > warnings https://sourceware.org/bugzilla/show_bug.cgi?id=25570 -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-04 5:56 ` Alan Modra @ 2020-03-04 6:40 ` Fangrui Song 2020-03-04 8:04 ` Alan Modra 0 siblings, 1 reply; 11+ messages in thread From: Fangrui Song @ 2020-03-04 6:40 UTC (permalink / raw) To: Alan Modra; +Cc: binutils, smithp352 On Tue, Mar 3, 2020 at 9:56 PM Alan Modra <amodra@gmail.com> wrote: > > On Tue, Mar 03, 2020 at 03:58:12PM -0800, Fangrui Song wrote: > > Thanks. For the example below, do you agree with the comments in a.x below? > > > > % cat a.s > > .globl _start; _start: ret > > .section .data.rel.ro,"aw"; .balign 8; .byte 0 > > .data; .byte 0 > > .section .data2,"aw"; .balign 8; .byte 0 > > .section .data3,"aw"; .balign 32; .byte 0 > > .bss; .balign 32; .byte 0 > > % as a.s -o a.o > > > > % cat a.x > > SECTIONS { > > .text 0x10000 : { *(.text) } > > /* sh_addr is 0x10010. Specifying both address and ALIGN should be > > disallowed. */ > > .data.rel.ro . : ALIGN(16) { *(.data.rel.ro) } > > > > .data 0x20000 : { *(.data) } > > /* sh_addr is 0x20001. Should there be a warning that sh_addralign > > is 8? Even --warn-section-align does not warn. */ > > That is a bug. > > The ELF gABI says in part of sh_addralign: "The value of sh_addr must > be congruent to 0, modulo the value of sh_addralign." > > * elf.c (elf_fake_sections): Ensure sh_addralign is such that > sh_addr mod sh_addalign is zero. > > diff --git a/bfd/elf.c b/bfd/elf.c > index fcd84d2d17..c4d6718aaa 100644 > --- a/bfd/elf.c > +++ b/bfd/elf.c > @@ -3192,6 +3192,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) > unsigned int sh_type; > const char *name = asect->name; > bfd_boolean delay_st_name_p = FALSE; > + bfd_vma mask; > > if (arg->failed) > { > @@ -3291,7 +3292,10 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) > arg->failed = TRUE; > return; > } > - this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power; > + /* Set sh_addralign to the highest power of two given by alignment > + consistent with the section VMA. Linker scripts can force VMA. */ > + mask = ((bfd_vma) 1 << asect->alignment_power) | this_hdr->sh_addr; > + this_hdr->sh_addralign = mask & -mask; > /* The sh_entsize and sh_info fields may have been set already by > copy_private_section_data. */ > > > > .data2 . : { *(.data2) } > > /* sh_addr is 0x20020. The input section alignment wins. */ > > .data3 : ALIGN(16) { *(.data3) } > > /* sh_addr is 0x20030. Specifying both address and ALIGN should be > > disallowed. */ > > .bss . : ALIGN(16) { *(.bss) } > > } > > > > % ld.bfd -T a.x a.s -o a > > > > If specifying both Output Section Address and ALIGN is disallowed, > > there should be no "changing start of section" warning when > > --warn-section-align is not specified. Is my understanding correct? > > > > BTW, I filed a bug about duplicate "changing start of section" > > warnings https://sourceware.org/bugzilla/show_bug.cgi?id=25570 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. 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? * 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. --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. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-04 6:40 ` Fangrui Song @ 2020-03-04 8:04 ` Alan Modra 2020-03-05 6:41 ` Fangrui Song 0 siblings, 1 reply; 11+ messages in thread From: Alan Modra @ 2020-03-04 8:04 UTC (permalink / raw) To: Fangrui Song; +Cc: binutils, smithp352 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. > --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. It's even more noisy when relaxation is enabled.. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-04 8:04 ` Alan Modra @ 2020-03-05 6:41 ` Fangrui Song 2020-03-05 11:21 ` Alan Modra 0 siblings, 1 reply; 11+ messages in thread From: Fangrui Song @ 2020-03-05 6:41 UTC (permalink / raw) To: Alan Modra; +Cc: binutils, smithp352 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) >> --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. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-05 6:41 ` Fangrui Song @ 2020-03-05 11:21 ` Alan Modra 2020-03-10 19:00 ` Fangrui Song 0 siblings, 1 reply; 11+ messages in thread From: Alan Modra @ 2020-03-05 11:21 UTC (permalink / raw) To: Fangrui Song; +Cc: binutils, smithp352 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 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ld] section address : ALIGN(align) and the maximum of input section alignments 2020-03-05 11:21 ` Alan Modra @ 2020-03-10 19:00 ` Fangrui Song 0 siblings, 0 replies; 11+ messages in thread From: Fangrui Song @ 2020-03-10 19:00 UTC (permalink / raw) To: Alan Modra; +Cc: binutils, smithp352 On 2020-03-05, Alan Modra wrote: >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. Hi, Alan, https://reviews.llvm.org/D75724 includes the output section address/alignment changes I intended for lld. The comment https://reviews.llvm.org/D75724#1915342 includes useful user feedback: > If anything, I think the GNU linkers should warn about violating input sh_addralign requirements if they're going to have that behavior. > > But it seems likely that the most common use of explicit alignments is > exactly when setting the minimum alignment of the output section is > the intent and that being increased by input sh_addralign requirements > is normal and expected, and not a case like mine. >> > > --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 ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2020-03-10 19:00 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-02-26 5:23 [ld] section address : ALIGN(align) and the maximum of input section alignments Fangrui Song 2020-02-26 6:31 ` Fangrui Song 2020-03-03 5:46 ` Fangrui Song 2020-03-03 22:39 ` Alan Modra 2020-03-04 0:03 ` Fangrui Song [not found] ` <BY5PR07MB7316674DD98011D2AD812A63CBE40@BY5PR07MB7316.namprd07.prod.outlook.com> 2020-03-04 5:56 ` Alan Modra 2020-03-04 6:40 ` Fangrui Song 2020-03-04 8:04 ` Alan Modra 2020-03-05 6:41 ` Fangrui Song 2020-03-05 11:21 ` Alan Modra 2020-03-10 19:00 ` Fangrui Song
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).