]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit - ld/testsuite/ld-aarch64/aarch64-elf.exp
Handle locally-resolving entries in the GOT
authorMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 28 Apr 2022 08:50:27 +0000 (09:50 +0100)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 28 Apr 2022 08:52:39 +0000 (09:52 +0100)
commit808c324b6d4ac59d8cf9f71776a788c8cfa3e131
tree8115ca831f0ef4324222dcd15739ed0f0ce94f5b
parentbc1f23a5478d47ea0c4bd3c2c90e74602b61688b
Handle locally-resolving entries in the GOT

In standard AArch64 linking by the BFD linker, dynamic symbols in PIC
code have their dynamic relocations created by
elfNN_aarch64_finish_dynamic_symbol.  Any required information in the
relevant fragment is added by elfNN_aarch64_final_link_relocate.

Non-dynamic symbols that are supposed to go in the GOT have their
RELATIVE relocations created in elfNN_aarch64_final_link_relocate next
to the place where the fragment is populated.

The code in elfNN_aarch64_finish_dynamic_symbol was not updated when we
ensured that RELATIVE relocations against function symbols were
generated with the PCC base stored in their fragment and an addend
defined to make up the difference so that the relocation pointed at the
relevant function.

On top of this, elfNN_aarch64_final_link_relocate was never written to
include the size and permission information in the GOT fragment for
RELATIVE relocations that will be generated by
elfNN_aarch64_finish_dynamic_symbol.

This patch resolves both issues by adding code to
elfNN_aarch64_final_link_relocate to handle setting up the fragment of a
RELATIVE relocation that elfNN_aarch64_finish_dynamic_symbol will
create, and adding code in elfNN_aarch64_finish_dynamic_symbol to use
the correct addend for the RELATIVE relocation that it generates.

Implementation choices:

The check in elfNN_aarch64_final_link_relocate for "cases where we would
generate a RELATIVE relocation through
elfNN_aarch64_finish_dynamic_symbol" is believed to handle undefined
weak symbols by checking SYMBOL_REFERENCES_LOCAL on the belief that the
latter would not return true if on undefined weak symbols.  This is not
as clearly correct as the rest of the condition, so seems reasonable to
bring to the attention of anyone interested.

We add an assertion that this is the case so we get alerted if it is
not, we could choose to include !UNDEFWEAK_NO_DYNAMIC_RELOC in the
condition instead, but believe that would lead to confusion in the code
(i.e. why check something that will always be false).

Similarly, when we check against SYMBOL_REFERENCES_LOCAL to decide
whether to populate the fragment for this relocation this does not
directly correspond to `h->dynindx == -1` (which would indicate that
this symbol is not in the dynamic symbol table).
This means that our clause catches symbols which would appear in the
dynamic symbol table as long as SYMBOL_REFERENCES_LOCAL returns true.
The only case in which we know this can happen is for PROTECTED
visibility data when GNU_PROPERTY_NO_COPY_ON_PROTECTED is set.
When this happens a RELATIVE relocation is generated (since this is
an object we know will resove to the current binary) and the static
linker provides the permissions and size of the associated object in the
relevant fragment.
This behaviour matches all other RELATIVE relocations and allows the
dynamic loader to assume that all RELATIVE relocations should have their
associated permissions and size provided.
We mention this behaviour since the symbol for this object will appear
in the dynamic symbol table and hence the dynamic loader *could*
determine the size and permissions itself.

In our condition to decide whether to update this relocation we include
a check that we `WILL_CALL_FINISH_DYNAMIC_SYMBOL`.  This is not
necessary, since the combination of conditions implies it, however it
makes things much clearer as to what we're checking for.

Testsuite notes:

When testing our change here we check:
  1) The addend and base of the RELATIVE relocation gives the required
     address of the hidden function.
  2) The bounds of the RELATIVE relocation is non-zero.
  3) The permissions of the RELATIVE relocation are executable.
Lacking in this particular test is a check that the PCC bounds are
calculated correctly, and that the base we define is the base of the
PCC.  We rely on existing tests to check our calculation of the PCC
bounds.
bfd/elfnn-aarch64.c
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-morello-hidden.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-morello-hidden.s [new file with mode: 0644]