Before this change we would ensure the ability for precise bounds on any section which had a linker defined symbol pointing in it *unless* that linker defined symbol looked like a section starting symbol.
In that case we would adjust the *next* section if the current section had no padding between this one and the next.
I believe this was a mistake. The testcase we add here is a simple case of having a `__data_relro_start` symbol in the .data.rel.ro section, and that would not ensure that the .data.rel.ro section were precisely padded. The change we make here is to perform padding for precise bounds on all sections with linker defined symbols in them *and* the next section if there is no padding between this and the next section.
This is a huge overfit and we do it for the reason described in the existing comment (that we have no information on the offset of this symbol within the output section).
In the future we may want to remove this padding for linker script defined symbols which do not look like section start symbols. We would do this in conjunction with changing the bounds we put on such linker script defined symbols. This would be for another patch.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 9bec87163d30d8493b243f0cae69f6c7ab0b7fd6..c8311e9095d10bdd669de1c595d726f619475d14 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -4958,26 +4958,21 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info, { const char *name = h->root.root.string; size_t len = strlen (name); + asection *altos = NULL; + bfd_vma value = os->vma + os->size;
if (len > 8 && name[0] == '_' && name[1] == '_' && (!strncmp (name + 2, "start_", 6) - || !strcmp (name + len - 6, "_start"))) - { - bfd_vma value = os->vma + os->size; - - os = bfd_sections_find_if (info->output_bfd, - section_start_symbol, &value); - - if (os != NULL) - ensure_precisely_bounded_section (os, htab, - c64_pad_section); - } + || !strcmp (name + len - 6, "_start")) + && ((altos = bfd_sections_find_if + (info->output_bfd, section_start_symbol, &value)) + != NULL)) + ensure_precisely_bounded_section (altos, htab, + c64_pad_section); /* XXX We're overfitting here because the offset of H within the output section is not yet resolved and ldscript defined symbols do not have input section information. */ - else - ensure_precisely_bounded_section (os, htab, - c64_pad_section); + ensure_precisely_bounded_section (os, htab, c64_pad_section); } } } diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 837b9df877276029cf8d036d75de02f70e224bc0..721d16e09bc1392fbc5e7920a080962bb4b374a2 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -268,6 +268,7 @@ run_dump_test_lp64 "morello-sec-round-pcc-needed" run_dump_test_lp64 "morello-sec-round-data-only" run_dump_test_lp64 "morello-sec-round-include-relro" run_dump_test_lp64 "morello-pcc-bounds-include-readonly" +run_dump_test_lp64 "morello-sec-round-choose-linker-syms" run_dump_test_lp64 "morello-tlsdesc" run_dump_test_lp64 "morello-tlsdesc-static" run_dump_test_lp64 "morello-tlsdesc-staticpie" diff --git a/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.d b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.d new file mode 100644 index 0000000000000000000000000000000000000000..e13aee24916e857dc33c69db0b3f94dd3bbb9c81 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.d @@ -0,0 +1,23 @@ +# Checking that we include RELRO sections in PCC bounds. +# +# Check is done using the fragment values to show what the size of the PCC +# bounds is given as, and we reorder sections so that at least one RELRO +# section is ater all READONLY ALLOC section. +# +# Test only works if we have relro, so is unsupported bare-metal. +# +# Test is implemented by ensuring that the .data.rel.ro is the last section in +# the RELRO segment, and that .data is directly after it. This is ensured with +# a linker script. If we don't include RELRO in our PCC bounds then +# .data.rel.ro will not be within the range of the `obj` capability (since the +# .data.rel.ro section itself is marked as being writeable). +# +#source: morello-sec-round-choose-linker-syms.s +#as: -march=morello+c64 +#ld: -static -T morello-sec-round-choose-linker-syms.ld +#objdump: --section-headers -j .data.rel.ro + +.*: file format .* +#... +.* .data.rel.ro 00010020 [0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 2**5 +#pass diff --git a/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.ld b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.ld new file mode 100644 index 0000000000000000000000000000000000000000..20529f8b49500a1947bfa8dfa16c7af71fd78965 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.ld @@ -0,0 +1,12 @@ +SECTIONS { + . = SEGMENT_START("text-segment", SIZEOF_HEADERS); + .text : { *(.text) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data.rel.ro : { + __data_relro_start = .; + *(.data.rel.ro*) + } + .data : { *(.data) } +} + diff --git a/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.s b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.s new file mode 100644 index 0000000000000000000000000000000000000000..bc91e90c2ff1c7e2f0d5e90c103c3bf50789c8ab --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-sec-round-choose-linker-syms.s @@ -0,0 +1,16 @@ +.arch morello+c64 + + .section .data.rel.ro.local,"aw",@progbits + .asciz "Hello there ;-)" + .zero 0x10000 + + .data +data_start: + .chericap __data_relro_start + .text + +obj: + + adrp c0, data_start + add c0, c0, :lo12:data_start + ldr c0, [c0]