diff --git a/binutils-ppc64-DT_RELR-relocs.patch b/binutils-ppc64-DT_RELR-relocs.patch new file mode 100644 index 0000000..b7eca2b --- /dev/null +++ b/binutils-ppc64-DT_RELR-relocs.patch @@ -0,0 +1,266 @@ +--- binutils.orig/bfd/elf64-ppc.c 2022-06-13 12:05:13.325289568 +0100 ++++ binutils-2.38/bfd/elf64-ppc.c 2022-06-13 12:05:36.080143584 +0100 +@@ -3270,10 +3270,14 @@ struct ppc_link_hash_table + /* The size of reliplt used by got entry relocs. */ + bfd_size_type got_reli_size; + +- /* DT_RELR array of r_offset. */ ++ /* DT_RELR array of section/r_offset. */ + size_t relr_alloc; + size_t relr_count; +- bfd_vma *relr_addr; ++ struct ++ { ++ asection *sec; ++ bfd_vma off; ++ } *relr; + + /* Statistics. */ + unsigned long stub_count[ppc_stub_save_res]; +@@ -13419,16 +13423,11 @@ maybe_strip_output (struct bfd_link_info + } + } + +-static int +-compare_relr_address (const void *arg1, const void *arg2) +-{ +- bfd_vma a = *(bfd_vma *) arg1; +- bfd_vma b = *(bfd_vma *) arg2; +- return a < b ? -1 : a > b ? 1 : 0; +-} ++/* Stash R_PPC64_RELATIVE reloc at input section SEC, r_offset OFF to ++ the array of such relocs. */ + + static bool +-append_relr_off (struct ppc_link_hash_table *htab, bfd_vma off) ++append_relr_off (struct ppc_link_hash_table *htab, asection *sec, bfd_vma off) + { + if (htab->relr_count >= htab->relr_alloc) + { +@@ -13436,16 +13435,51 @@ append_relr_off (struct ppc_link_hash_ta + htab->relr_alloc = 4096; + else + htab->relr_alloc *= 2; +- htab->relr_addr +- = bfd_realloc (htab->relr_addr, +- htab->relr_alloc * sizeof (htab->relr_addr[0])); +- if (htab->relr_addr == NULL) ++ htab->relr = bfd_realloc (htab->relr, ++ htab->relr_alloc * sizeof (*htab->relr)); ++ if (htab->relr == NULL) + return false; + } +- htab->relr_addr[htab->relr_count++] = off; ++ htab->relr[htab->relr_count].sec = sec; ++ htab->relr[htab->relr_count].off = off; ++ htab->relr_count++; + return true; + } + ++/* qsort comparator for bfd_vma args. */ ++ ++static int ++compare_relr_address (const void *arg1, const void *arg2) ++{ ++ bfd_vma a = *(bfd_vma *) arg1; ++ bfd_vma b = *(bfd_vma *) arg2; ++ return a < b ? -1 : a > b ? 1 : 0; ++} ++ ++/* Produce a malloc'd sorted array of reloc addresses from the info ++ stored by append_relr_off. */ ++ ++static bfd_vma * ++sort_relr (struct ppc_link_hash_table *htab) ++{ ++ bfd_vma *addr = bfd_malloc (htab->relr_count * sizeof (*addr)); ++ if (addr == NULL) ++ return NULL; ++ ++ for (size_t i = 0; i < htab->relr_count; i++) ++ addr[i] = (htab->relr[i].sec->output_section->vma ++ + htab->relr[i].sec->output_offset ++ + htab->relr[i].off); ++ ++ if (htab->relr_count > 1) ++ qsort (addr, htab->relr_count, sizeof (*addr), compare_relr_address); ++ ++ return addr; ++} ++ ++/* Look over GOT and PLT entries saved on elf_local_got_ents for all ++ input files, stashing info about needed relative relocs. */ ++ + static bool + got_and_plt_relr_for_local_syms (struct bfd_link_info *info) + { +@@ -13493,10 +13527,7 @@ got_and_plt_relr_for_local_syms (struct + && isym->st_shndx != SHN_ABS) + { + asection *got = ppc64_elf_tdata (gent->owner)->got; +- bfd_vma r_offset = (got->output_section->vma +- + got->output_offset +- + gent->got.offset); +- if (!append_relr_off (htab, r_offset)) ++ if (!append_relr_off (htab, got, gent->got.offset)) + { + htab->stub_error = true; + return false; +@@ -13511,10 +13542,7 @@ got_and_plt_relr_for_local_syms (struct + if (pent->plt.offset != (bfd_vma) -1 + && ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC) + { +- bfd_vma r_offset = (pent->plt.offset +- + htab->pltlocal->output_offset +- + htab->pltlocal->output_section->vma); +- if (!append_relr_off (htab, r_offset)) ++ if (!append_relr_off (htab, htab->pltlocal, pent->plt.offset)) + { + if (symtab_hdr->contents != (unsigned char *) local_syms) + free (local_syms); +@@ -13534,6 +13562,9 @@ got_and_plt_relr_for_local_syms (struct + return true; + } + ++/* Stash info about needed GOT and PLT entry relative relocs for ++ global symbol H. */ ++ + static bool + got_and_plt_relr (struct elf_link_hash_entry *h, void *inf) + { +@@ -13565,10 +13596,7 @@ got_and_plt_relr (struct elf_link_hash_e + && gent->got.offset != (bfd_vma) -1) + { + asection *got = ppc64_elf_tdata (gent->owner)->got; +- bfd_vma r_offset = (got->output_section->vma +- + got->output_offset +- + gent->got.offset); +- if (!append_relr_off (htab, r_offset)) ++ if (!append_relr_off (htab, got, gent->got.offset)) + { + htab->stub_error = true; + return false; +@@ -13580,10 +13608,7 @@ got_and_plt_relr (struct elf_link_hash_e + for (pent = h->plt.plist; pent != NULL; pent = pent->next) + if (pent->plt.offset != (bfd_vma) -1) + { +- bfd_vma r_offset = (htab->pltlocal->output_section->vma +- + htab->pltlocal->output_offset +- + pent->plt.offset); +- if (!append_relr_off (htab, r_offset)) ++ if (!append_relr_off (htab, htab->pltlocal, pent->plt.offset)) + { + htab->stub_error = true; + return false; +@@ -13861,9 +13886,7 @@ ppc64_elf_size_stubs (struct bfd_link_in + irela->r_offset); + if (r_offset >= (bfd_vma) -2) + continue; +- r_offset += (section->output_section->vma +- + section->output_offset); +- if (!append_relr_off (htab, r_offset)) ++ if (!append_relr_off (htab, section, r_offset)) + goto error_ret_free_internal; + continue; + } +@@ -14214,9 +14237,7 @@ ppc64_elf_size_stubs (struct bfd_link_in + bfd_vma r_offset; + + for (r_offset = 0; r_offset < htab->brlt->size; r_offset += 8) +- if (!append_relr_off (htab, (r_offset +- + htab->brlt->output_section->vma +- + htab->brlt->output_offset))) ++ if (!append_relr_off (htab, htab->brlt, r_offset)) + return false; + + if (!got_and_plt_relr_for_local_syms (info)) +@@ -14225,28 +14246,28 @@ ppc64_elf_size_stubs (struct bfd_link_in + if (htab->stub_error) + return false; + +- if (htab->relr_count > 1) +- qsort (htab->relr_addr, htab->relr_count, sizeof (*htab->relr_addr), +- compare_relr_address); ++ bfd_vma *relr_addr = sort_relr (htab); ++ if (htab->relr_count != 0 && relr_addr == NULL) ++ return false; + + size_t i = 0; + while (i < htab->relr_count) + { +- bfd_vma base = htab->relr_addr[i]; ++ bfd_vma base = relr_addr[i]; + htab->elf.srelrdyn->size += 8; + i++; + /* Handle possible duplicate address. This can happen + as sections increase in size when adding stubs. */ + while (i < htab->relr_count +- && htab->relr_addr[i] == base) ++ && relr_addr[i] == base) + i++; + base += 8; + while (1) + { + size_t start_i = i; + while (i < htab->relr_count +- && htab->relr_addr[i] - base < 63 * 8 +- && (htab->relr_addr[i] - base) % 8 == 0) ++ && relr_addr[i] - base < 63 * 8 ++ && (relr_addr[i] - base) % 8 == 0) + i++; + if (i == start_i) + break; +@@ -14254,6 +14275,7 @@ ppc64_elf_size_stubs (struct bfd_link_in + base += 63 * 8; + } + } ++ free (relr_addr); + } + + for (group = htab->group; group != NULL; group = group->next) +@@ -15193,17 +15215,21 @@ ppc64_elf_build_stubs (struct bfd_link_i + if (htab->elf.srelrdyn->contents == NULL) + return false; + ++ bfd_vma *relr_addr = sort_relr (htab); ++ if (htab->relr_count != 0 && relr_addr == NULL) ++ return false; ++ + size_t i = 0; + bfd_byte *loc = htab->elf.srelrdyn->contents; + while (i < htab->relr_count) + { +- bfd_vma base = htab->relr_addr[i]; ++ bfd_vma base = relr_addr[i]; + BFD_ASSERT (base % 2 == 0); + bfd_put_64 (htab->elf.dynobj, base, loc); + loc += 8; + i++; + while (i < htab->relr_count +- && htab->relr_addr[i] == base) ++ && relr_addr[i] == base) + { + htab->stub_error = true; + i++; +@@ -15213,10 +15239,10 @@ ppc64_elf_build_stubs (struct bfd_link_i + { + bfd_vma bits = 0; + while (i < htab->relr_count +- && htab->relr_addr[i] - base < 63 * 8 +- && (htab->relr_addr[i] - base) % 8 == 0) ++ && relr_addr[i] - base < 63 * 8 ++ && (relr_addr[i] - base) % 8 == 0) + { +- bits |= (bfd_vma) 1 << ((htab->relr_addr[i] - base) / 8); ++ bits |= (bfd_vma) 1 << ((relr_addr[i] - base) / 8); + i++; + } + if (bits == 0) +@@ -15226,6 +15252,7 @@ ppc64_elf_build_stubs (struct bfd_link_i + base += 63 * 8; + } + } ++ free (relr_addr); + /* Pad any excess with 1's, a do-nothing encoding. */ + while ((size_t) (loc - htab->elf.srelrdyn->contents) + < htab->elf.srelrdyn->size) diff --git a/binutils.spec b/binutils.spec index 89a8fc0..db88050 100644 --- a/binutils.spec +++ b/binutils.spec @@ -159,6 +159,8 @@ URL: https://sourceware.org/binutils # its debug informnation. %undefine __brp_strip_static_archive +%define _find_debuginfo_opts --remove-section .gnu.build.attributes + #---------------------------------------------------------------------------- # Note - the Linux Kernel binutils releases are too unstable and contain @@ -319,6 +321,10 @@ Patch26: binutils-x86-non-canonical-references.patch Patch27: binutils-update-linker-manual.patch %endif +# Purpose: Power64 linker: Fix bug handling DT_RELR relocs. +# Lifetime: Fixed in 2.39 +Patch28: binutils-ppc64-DT_RELR-relocs.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -933,58 +939,62 @@ exit 0 #---------------------------------------------------------------------------- %changelog -* Wed Jun 08 2022 Nick Clifton - 2.38-14 +* Mon Jun 13 2022 Nick Clifton - 2.38-15 +- Fix a problem with PowerPC's handling of DT_RELR relocs. (#2095622) +- Move annobin data into a separate debuginfo file. + +* Wed Jun 08 2022 Nick Clifton - 2.38-14 - Fix bugs preventing the linker tests from running. -* Fri May 27 2022 Nick Clifton - 2.38-14 +* Fri May 27 2022 Nick Clifton - 2.38-14 - Fix bug in binutils.spec file that was causing the wrong linker flags to be used. -* Fri May 27 2022 Nick Clifton - 2.38-13 +* Fri May 27 2022 Nick Clifton - 2.38-13 - Change the ld man page so that it says that --enable-new-dtags is the default. (#2090818) -* Tue May 24 2022 Nick Clifton - 2.38-12 +* Tue May 24 2022 Nick Clifton - 2.38-12 - x86 linker: Disallow invalid relocations against protected symbols. (#2089358) -* Fri May 20 2022 Nick Clifton - 2.38-11 +* Fri May 20 2022 Nick Clifton - 2.38-11 - Stop readelf and objdump from unnecessarily following links. (#2086863) -* Thu May 19 2022 Nick Clifton - 2.38-10 +* Thu May 19 2022 Nick Clifton - 2.38-10 - Add support for generating static PIE binaries for s390x. (#2088331) -* Thu May 12 2022 Nick Clifton - 2.38-9 +* Thu May 12 2022 Nick Clifton - 2.38-9 - Fix description of gold subpackage so that it does not include the Requires fields. (#2082919) -* Mon Apr 04 2022 Nick Clifton - 2.38-8 +* Mon Apr 04 2022 Nick Clifton - 2.38-8 - Fix linker testsuite failures. -* Wed Mar 30 2022 Nick Clifton - 2.38-7 +* Wed Mar 30 2022 Nick Clifton - 2.38-7 - Fix a bug handling indirect symbols. (PR 28879) (#2068343) -* Thu Mar 10 2022 Nick Clifton - 2.38-6 +* Thu Mar 10 2022 Nick Clifton - 2.38-6 - Simplify the assembler's evaluation of chained .loc view expressions. [Second attempt] (#2059646) -* Thu Mar 10 2022 Nick Clifton - 2.38-5 +* Thu Mar 10 2022 Nick Clifton - 2.38-5 - Add an option to objdump/readelf to disable accessing debuginfod servers. (#2051741) -* Wed Mar 09 2022 Nick Clifton - 2.38-4 +* Wed Mar 09 2022 Nick Clifton - 2.38-4 - Simplify the assembler's evaluation of chained .loc view expressions. (#2059646) -* Mon Feb 28 2022 Nick Clifton - 2.38-3 +* Mon Feb 28 2022 Nick Clifton - 2.38-3 - Do not export any windows tools (if they were built). (#2057636) -* Wed Feb 16 2022 Nick Clifton - 2.38-2 +* Wed Feb 16 2022 Nick Clifton - 2.38-2 - Add support for specifying a section type in linker scripts. (#2052801) -* Wed Feb 09 2022 Nick Clifton - 2.38-1 +* Wed Feb 09 2022 Nick Clifton - 2.38-1 - Rebase on GNU Binutils 2.38. -* Thu Jan 27 2022 Nick Clifton - 2.37-25 +* Thu Jan 27 2022 Nick Clifton - 2.37-25 - Borrow a patch from the GCC package to stop libtool from inserting needless runpaths into binaries. (#2030667) * Wed Jan 19 2022 Fedora Release Engineering - 2.37-24 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild -* Mon Dec 20 2021 Nick Clifton - 2.37-23 +* Mon Dec 20 2021 Nick Clifton - 2.37-23 - Fix a potential illegal memory access parsing a COFF format file. (#2033716) * Thu Dec 02 2021 Luca Boccassi - 2.37-22