From 7206b7ef958022aa71c20064222d8a5ed5ad48ff Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 16 Jan 2024 16:24:47 +0000 Subject: [PATCH] Fix creation of DT_RELR relocs for PPC64LE. --- binutils-ppc-dt_relr-relocs.patch | 114 ++++++++++++++++++++++++++++++ binutils.spec | 11 ++- 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 binutils-ppc-dt_relr-relocs.patch diff --git a/binutils-ppc-dt_relr-relocs.patch b/binutils-ppc-dt_relr-relocs.patch new file mode 100644 index 0000000..fc8202a --- /dev/null +++ b/binutils-ppc-dt_relr-relocs.patch @@ -0,0 +1,114 @@ +--- binutils.orig/bfd/elf64-ppc.c 2024-01-16 10:39:26.903071936 +0000 ++++ binutils-2.41/bfd/elf64-ppc.c 2024-01-16 10:39:38.650127903 +0000 +@@ -4749,6 +4749,21 @@ is_8byte_reloc (enum elf_ppc64_reloc_typ + || r_type == R_PPC64_PLTCALL); + } + ++/* The RELR encoding doesn't allow odd addresses, so RELR_ALIGN must ++ be at least 1. R_PPC64_RELATIVE relocs require alignment of 2**3. ++ We use 3 here to avoid complexity in relocate_section. PR30824. */ ++#define RELR_ALIGN 3 ++ ++static bool ++maybe_relr (enum elf_ppc64_reloc_type r_type, ++ const Elf_Internal_Rela *rel, ++ const asection *sec) ++{ ++ return ((r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) ++ && (rel->r_offset & ((1 << RELR_ALIGN) - 1)) == 0 ++ && sec->alignment_power >= RELR_ALIGN); ++} ++ + /* Like bfd_reloc_offset_in_range but without a howto. Return true + iff a field of SIZE bytes at OFFSET is within SEC limits. */ + +@@ -5401,9 +5416,7 @@ ppc64_elf_check_relocs (bfd *abfd, struc + p->count += 1; + if (!must_be_dyn_reloc (info, r_type)) + p->pc_count += 1; +- if ((r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) +- && rel->r_offset % 2 == 0 +- && sec->alignment_power != 0) ++ if (maybe_relr (r_type, rel, sec)) + p->rel_count += 1; + } + else +@@ -5438,9 +5451,7 @@ ppc64_elf_check_relocs (bfd *abfd, struc + p->ifunc = is_ifunc; + } + p->count += 1; +- if ((r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) +- && rel->r_offset % 2 == 0 +- && sec->alignment_power != 0) ++ if (maybe_relr (r_type, rel, sec)) + p->rel_count += 1; + } + } +@@ -7291,9 +7302,7 @@ dec_dynrel_count (const Elf_Internal_Rel + { + if (!must_be_dyn_reloc (info, r_type)) + p->pc_count -= 1; +- if ((r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) +- && rel->r_offset % 2 == 0 +- && sec->alignment_power != 0) ++ if (maybe_relr (r_type, rel, sec)) + p->rel_count -= 1; + p->count -= 1; + if (p->count == 0) +@@ -7326,9 +7335,7 @@ dec_dynrel_count (const Elf_Internal_Rel + { + if (p->sec == sec && p->ifunc == is_ifunc) + { +- if ((r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) +- && rel->r_offset % 2 == 0 +- && sec->alignment_power != 0) ++ if (maybe_relr (r_type, rel, sec)) + p->rel_count -= 1; + p->count -= 1; + if (p->count == 0) +@@ -13869,6 +13876,9 @@ ppc64_elf_size_stubs (struct bfd_link_in + switch (r_type) + { + default: ++ if (info->enable_dt_relr ++ && maybe_relr (r_type, irela, section)) ++ break; + continue; + + case R_PPC64_REL24: +@@ -13880,14 +13890,6 @@ ppc64_elf_size_stubs (struct bfd_link_in + if ((section->flags & SEC_CODE) != 0) + break; + continue; +- +- case R_PPC64_ADDR64: +- case R_PPC64_TOC: +- if (info->enable_dt_relr +- && irela->r_offset % 2 == 0 +- && section->alignment_power != 0) +- break; +- continue; + } + + /* Now determine the call target, its name, value, +@@ -15272,7 +15274,7 @@ ppc64_elf_build_stubs (struct bfd_link_i + while (i < htab->relr_count) + { + bfd_vma base = relr_addr[i]; +- BFD_ASSERT (base % 2 == 0); ++ BFD_ASSERT ((base & ((1 << RELR_ALIGN) - 1)) == 0); + bfd_put_64 (htab->elf.dynobj, base, loc); + loc += 8; + i++; +@@ -17510,9 +17512,8 @@ ppc64_elf_relocate_section (bfd *output_ + + if (!(info->enable_dt_relr + && ELF64_R_TYPE (outrel.r_info) == R_PPC64_RELATIVE +- && rel->r_offset % 2 == 0 +- && input_section->alignment_power != 0 +- && ELF64_R_TYPE (orig_rel.r_info) != R_PPC64_UADDR64)) ++ && maybe_relr (ELF64_R_TYPE (orig_rel.r_info), ++ rel, input_section))) + { + sreloc = elf_section_data (input_section)->sreloc; + if (h != NULL diff --git a/binutils.spec b/binutils.spec index 601df8b..ce8b7d8 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.41 -Release: 24%{?dist} +Release: 25%{?dist} License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -307,6 +307,10 @@ Patch32: binutils-riscv-SUB_ULEB128.patch # Lifetime: Fixed in 2.42 (maybe) Patch33: binutils-gold-ignore-execstack-error.patch +# Purpose: Fix the allocation of space for DT_RELR relocations on PPC64. +# Lifetime: Fixed in 2.42 (maybe) +Patch34: binutils-ppc-dt_relr-relocs.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -1342,7 +1346,10 @@ exit 0 #---------------------------------------------------------------------------- %changelog -* Thu Jan 11 2024 Siddhesh Poyarekar - 2.40-24 +* Mon Jan 15 2024 Nick Clifton - 2.41-25 +- Fix creation of DT_RELR relocs for PPC64LE. (#2258061) + +* Thu Jan 11 2024 Siddhesh Poyarekar - 2.41-24 - Use _fortify_level macro to control _FORTIFY_SOURCE. * Thu Jan 11 2024 Amit Shah - 2.41-23