Hi,
This is a respin of the following patch: https://op-lists.linaro.org/archives/list/gnu-morello@op-lists.linaro.org/th...
In this version we drop the adjustment of the bounds given to symbols without size information: we now leave these with zero bounds and drop the diagnostic to allow the linker to accept capability relocations against such symbols.
The new proposed commit message is below.
Regression tested on aarch64-none-elf, OK for the Morello branch?
Thanks, Alex
------------------------------------------------------------------------
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-01 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.