[PATCH v3 1/2] aarch64: Fix DT_RELR support with discarded sections
Szabolcs Nagy
szabolcs.nagy@arm.com
Thu Jun 6 10:53:09 GMT 2024
In case of discarded sections, via /DISCARD/ or .gnu.linkonce,
relr relocation accounting was wrong. This broke building linux.
The issue was that the *_relocate_section logic was copied to
record_relr_non_got_relocs to find the relative relocs that can
be packed, however *_relocate_section is not called on sections
that are discarded, while record_relr_non_got_relocs is called
for all input sections. The fix is to filter out the discarded
sections with the same logic that is used to count non-GOT
relocs in *_late_size_sections for local symbols earlier.
Use the discarded_section helper in both cases to clarify the
intent and handle all corner-cases consistently.
GOT relocations are affected too if all sections are discarded
that reference the GOT entry of a particular symbol, however
this can cause unused GOT entries independently of DT_RELR, and
the only difference with DT_RELR is that a relative reloc may be
emitted instead of a R_AARCH64_NONE for the unused GOT entry
which is acceptable. A proper fix would require redoing the GOT
refcounting after we know the discarded sections, see bug 31850.
---
v3:
- use discarded_section()
- adjust commit msg
v2:
- only commit msg update: i realized that the GOT case is not
handled right when DT_RELR is disabled so there is no point
trying to fix that here and unnecessary relative relocation
in such corner-case is acceptable. i updated the test case
patch to cover the GOT cases that currently work.
---
bfd/elfnn-aarch64.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 81f1a646125..2221de0a480 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -9327,6 +9327,8 @@ record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info,
return true;
if (sec->alignment_power == 0)
return true;
+ if (discarded_section (sec))
+ return true;
sreloc = elf_section_data (sec)->sreloc;
if (sreloc == NULL)
return true;
@@ -9602,8 +9604,7 @@ elfNN_aarch64_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (p = (struct elf_dyn_relocs *)
(elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
{
- if (!bfd_is_abs_section (p->sec)
- && bfd_is_abs_section (p->sec->output_section))
+ if (discarded_section (p->sec))
{
/* Input section has been discarded, either because
it is a copy of a linkonce section or due to
--
2.25.1
More information about the Binutils
mailing list