]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
ld: Adjust bounds, base, and size for various symbols
authorAlex Coplan <alex.coplan@arm.com>
Thu, 3 Feb 2022 08:59:49 +0000 (08:59 +0000)
committerAlex Coplan <alex.coplan@arm.com>
Thu, 3 Feb 2022 08:59:49 +0000 (08:59 +0000)
commit5fa80905897b81492bc9d04cd5f2e3b5f33bd8e0
tree6da8258692edbc7851bd083bafea5fecdf735294
parentc50aec7291154cf4c97c2a011a8b656bcd8c46da
ld: Adjust bounds, base, and size for various symbols

This patch has two main goals:

 - Relax an existing diagnostic to permit the linker to accept
   capability relocations against symbols without size information.
 - Adjust the capability base and bounds for symbols which point into
   sections which may be accessed via the PCC.

The Morello ABI accesses global data using ADR and ADRP, and has no
special indirection to jump to other functions.  Given this, the PCC
must maintain its bounds and base so that during execution loading
global data and jumping to other functions can be done without worrying
about the current PCC permissions and bounds.

To implement this, all capabilities that could be loaded into the PCC
(via BLR or similar) must have a bounds and base according to the PCC.
This must span all global data and text sections (i.e. .got, .text,
.got.plt and the like).
There is already code finding the range that the PCC should span, this
patch records the information in a variable that we can query later.

There are two places where we create a relocation requesting a
capability to be initialised at runtime.  When handling relocations
which request a capability from the GOT, and when handling a CAPINIT
relocation.  This patch adjusts both.

We can't tell from inspection which symbols would be loaded into the
PCC, but we know that those symbols must point into a section which is
executable.  For now, we do this operation for all symbols which point
into an executable section.

Most RELATIVE relocations don't use the addend.  Rather the VA and size
we want are put in the relative fragment and the addend is zero.
This is because the *base* of the capability usually matches the VA we
want that capability initialised to.
In these possibly-code symbols we want the base of the capability bounds
to be the base of the PCC, and the VA to be something very different.
Hence we make use of the addend in the RELA relocations to encode this
offset.

Note on implementation:

c64_fixup_frag takes the base and size of a capability we want to
request from the runtime and checks that these are exactly representable
in a capability.  This patch changes many of the capabilities we request
from the runtime to have the same bounds (those of the PCC).  We leave
the check to look at the bounds requested by the symbol rather than to
check the PCC bounds multiple times.  That means that if a symbol that
points into an executable section has incorrect bounds then this will
trigger a linker error even though it will cause no security problem
when this executes.  This is a trade-off between getting extra checks
that the compiler is handling object bounds sizes and erroring on
non-problematic code.

We have a compatibility hack that if a symbol is defined in the linker
script to be directly after a given section but is *named* something
like __.*_start or __start_.* then we treat it as if it is defined at
the very start of the next section.  The new behaviour introduced in
this patch needs to take account of the above compatibility hack.

This patch also updates the testsuite according to these changes.
In some places the original test no longer checks what it wanted, since
the base of all symbols pointing into executable sections are now the
same.  There we add extra symbols and things to check so we ensure that
this behaviour of PCC bounds is seen and that the original behaviour is
still seen on non-executable sections.

This commit also includes a few tidy-ups:

We adjust the base and limit that are checked in c64_fixup_frag.
Originally this would calculate the base as value + addend.  As
discussed above the way we treat capabilities in Morello is such that
the value determines the base and the addend determines the initial
value pointing from that base.  Hence the check that these capabilities
had correct bounds was not correct.

We add an extra assertion in final_link_relocate for robustness
purposes.  There is an existing bug in the assembler where GOT
relocations against local symbols can be turned into relocations against
the relevant section symbol plus an addend.  This is problematic for
multiple reasons, one being that the linker implementation does not have
any way to associate different GOT entries with the same symbol but
multiple offsets.  In fact the linker ignores any offset.  Here we
simply add an assertion that this never happens.  It turns a silent
pre-existing error into a noisy one.

2022-02-03  Alex Coplan  <alex.coplan@arm.com>
    Matthew Malcomson  <matthew.malcomson@arm.com>

bfd/ChangeLog:

* elfnn-aarch64.c (pcc_low): New.
(pcc_high): New.
(elfNN_c64_resize_sections): Update new global variables
pcc_{low,high} instead of local variables to track PCC span.
(enum c64_section_perm_type): New.
(c64_symbol_section_adjustment): New.
(c64_fixup_frag): Rework to calculate size appropriately for
symbols that need adjustment.
(c64_symbol_adjust): New. Use it ...
(elfNN_aarch64_final_link_relocate): ... here.

ld/ChangeLog:

* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/emit-relocs-morello-6.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-6.s: Assembly.
* testsuite/ld-aarch64/emit-relocs-morello-6b.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.d: New test.
* testsuite/ld-aarch64/emit-relocs-morello-7.ld: Linker script thereof.
* testsuite/ld-aarch64/emit-relocs-morello-7.s: Assembly.
* testsuite/ld-aarch64/morello-capinit.d: New test.
* testsuite/ld-aarch64/morello-capinit.ld: Linker script.
* testsuite/ld-aarch64/morello-capinit.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-global-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-global-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-got-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-got-syms.s: Assembly.
* testsuite/ld-aarch64/morello-sizeless-local-syms.d: New test.
* testsuite/ld-aarch64/morello-sizeless-local-syms.s: Assembly.

Co-authored-by: Matthew Malcomson <matthew.malcomson@arm.com>
19 files changed:
bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-morello-6.d
ld/testsuite/ld-aarch64/emit-relocs-morello-6.s
ld/testsuite/ld-aarch64/emit-relocs-morello-6b.d
ld/testsuite/ld-aarch64/emit-relocs-morello-7.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-morello-7.ld [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-morello-7.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-capinit.d
ld/testsuite/ld-aarch64/morello-capinit.ld
ld/testsuite/ld-aarch64/morello-capinit.s
ld/testsuite/ld-aarch64/morello-sizeless-global-syms.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sizeless-global-syms.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sizeless-got-syms.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sizeless-got-syms.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sizeless-local-syms.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sizeless-local-syms.s [new file with mode: 0644]