From: Matthew Malcomson Date: Mon, 21 Feb 2022 13:18:30 +0000 (+0000) Subject: Adjust which sections we resize for precise bounds X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea41358b032f2811271c78ea45186aea95dbe3e1;p=thirdparty%2Fbinutils-gdb.git Adjust which sections we resize for precise bounds 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. --- diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 00f64e35034..06e3bd8aea2 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 837b9df8772..721d16e09bc 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 00000000000..e13aee24916 --- /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 00000000000..20529f8b495 --- /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 00000000000..bc91e90c2ff --- /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]