diff --git a/binutils-riscv-SUB_ULEB128.patch b/binutils-riscv-SUB_ULEB128.patch new file mode 100644 index 0000000..16480cf --- /dev/null +++ b/binutils-riscv-SUB_ULEB128.patch @@ -0,0 +1,239 @@ +diff -rupN binutils.orig/bfd/elfnn-riscv.c binutils-2.41/bfd/elfnn-riscv.c +--- binutils.orig/bfd/elfnn-riscv.c 2024-01-02 17:35:07.412218130 +0000 ++++ binutils-2.41/bfd/elfnn-riscv.c 2024-01-02 17:36:52.274311071 +0000 +@@ -1737,7 +1737,10 @@ perform_relocation (const reloc_howto_ty + { + if (howto->pc_relative) + value -= sec_addr (input_section) + rel->r_offset; +- value += rel->r_addend; ++ ++ /* PR31179, ignore the non-zero addend of R_RISCV_SUB_ULEB128. */ ++ if (ELFNN_R_TYPE (rel->r_info) != R_RISCV_SUB_ULEB128) ++ value += rel->r_addend; + + switch (ELFNN_R_TYPE (rel->r_info)) + { +@@ -1818,10 +1821,7 @@ perform_relocation (const reloc_howto_ty + value = ENCODE_CITYPE_LUI_IMM (RISCV_CONST_HIGH_PART (value)); + break; + +- /* SUB_ULEB128 must be applied after SET_ULEB128, so we only write the +- value back for SUB_ULEB128 should be enough. */ +- case R_RISCV_SET_ULEB128: +- break; ++ /* R_RISCV_SET_ULEB128 won't go into here. */ + case R_RISCV_SUB_ULEB128: + { + unsigned int len = 0; +@@ -2514,7 +2514,7 @@ riscv_elf_relocate_section (bfd *output_ + else + { + msg = ("Mismatched R_RISCV_SET_ULEB128, it must be paired with" +- "and applied before R_RISCV_SUB_ULEB128"); ++ " and applied before R_RISCV_SUB_ULEB128"); + r = bfd_reloc_dangerous; + } + break; +@@ -2523,14 +2523,40 @@ riscv_elf_relocate_section (bfd *output_ + if (uleb128_set_rel != NULL + && uleb128_set_rel->r_offset == rel->r_offset) + { +- relocation = uleb128_set_vma - relocation; ++ relocation = uleb128_set_vma - relocation ++ + uleb128_set_rel->r_addend; + uleb128_set_vma = 0; + uleb128_set_rel = NULL; ++ ++ /* PR31179, the addend of SUB_ULEB128 should be zero if using ++ .uleb128, but we make it non-zero by accident in assembler, ++ so just ignore it in perform_relocation, and make assembler ++ continue doing the right thing. Don't reset the addend of ++ SUB_ULEB128 to zero here since it will break the --emit-reloc, ++ even though the non-zero addend is unexpected. ++ ++ We encourage people to rebuild their stuff to get the ++ non-zero addend of SUB_ULEB128, but that might need some ++ times, so report warnings to inform people need to rebuild ++ if --check-uleb128 is enabled. However, since the failed ++ .reloc cases for ADD/SET/SUB/ULEB128 are rarely to use, it ++ may acceptable that stop supproting them until people rebuld ++ their stuff, maybe half-year or one year later. I believe ++ this might be the least harmful option that we should go. ++ ++ Or maybe we should teach people that don't write the ++ .reloc R_RISCV_SUB* with non-zero constant, and report ++ warnings/errors in assembler. */ ++ if (htab->params->check_uleb128 ++ && rel->r_addend != 0) ++ _bfd_error_handler (_("%pB: warning: R_RISCV_SUB_ULEB128 with" ++ " non-zero addend, please rebuild by" ++ " Fedora 40 binutils or up"), input_bfd); + } + else + { + msg = ("Mismatched R_RISCV_SUB_ULEB128, it must be paired with" +- "and applied after R_RISCV_SET_ULEB128"); ++ " and applied after R_RISCV_SET_ULEB128"); + r = bfd_reloc_dangerous; + } + break; +@@ -5123,7 +5149,13 @@ _bfd_riscv_relax_section (bfd *abfd, ase + if (h != NULL && h->type == STT_GNU_IFUNC) + continue; + ++ /* Maybe we should check UNDEFWEAK_NO_DYNAMIC_RELOC here? But that ++ will break the undefweak relaxation testcases, so just make sure ++ we won't do relaxations for linker_def symbols in short-term. */ + if (h->root.type == bfd_link_hash_undefweak ++ /* The linker_def symbol like __ehdr_start that may be undefweak ++ for now, but will be guaranteed to be defined later. */ ++ && !h->root.linker_def + && (relax_func == _bfd_riscv_relax_lui + || relax_func == _bfd_riscv_relax_pc)) + { +diff -rupN binutils.orig/bfd/elfxx-riscv.h binutils-2.41/bfd/elfxx-riscv.h +--- binutils.orig/bfd/elfxx-riscv.h 2024-01-02 17:35:07.412218130 +0000 ++++ binutils-2.41/bfd/elfxx-riscv.h 2024-01-02 17:35:24.252233056 +0000 +@@ -31,6 +31,8 @@ struct riscv_elf_params + { + /* Whether to relax code sequences to GP-relative addressing. */ + bool relax_gp; ++ /* Whether to check if SUB_ULEB128 relocation has non-zero addend. */ ++ bool check_uleb128; + }; + + extern void riscv_elf32_set_options (struct bfd_link_info *, +diff -rupN binutils.orig/ld/NEWS binutils-2.41/ld/NEWS +--- binutils.orig/ld/NEWS 2024-01-02 17:35:08.012218662 +0000 ++++ binutils-2.41/ld/NEWS 2024-01-02 17:35:56.139261318 +0000 +@@ -1,5 +1,10 @@ + -*- text -*- + ++* On RISC-V, add ld target option --[no-]check-uleb128. Should rebuild the ++ objects by binutils 2.42 and up if enabling the option and get warnings, ++ since the non-zero addend of SUB_ULEB128 shouldn't be generated from .uleb128 ++ directives. ++ + * Added --warn-execstack-objects to warn about executable stacks only when an + input object file requests one. Also added --error-execstack and + --error-rxw-segments options to convert warnings about executable stacks and +diff -rupN binutils.orig/ld/emultempl/riscvelf.em binutils-2.41/ld/emultempl/riscvelf.em +--- binutils.orig/ld/emultempl/riscvelf.em 2024-01-02 17:35:07.699218385 +0000 ++++ binutils-2.41/ld/emultempl/riscvelf.em 2024-01-02 17:35:24.252233056 +0000 +@@ -25,7 +25,8 @@ fragment <fr_fix, 0, + exp_dup, 0, BFD_RELOC_RISCV_SET_ULEB128); + exp_dup->X_add_symbol = exp->X_op_symbol; ++ exp_dup->X_add_number = 0; /* Set addend of SUB_ULEB128 to zero. */ + fix_new_exp (fragP, fragP->fr_fix, 0, + exp_dup, 0, BFD_RELOC_RISCV_SUB_ULEB128); + } diff --git a/binutils.spec b/binutils.spec index 9b90dfe..ec42abb 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: 17%{?dist} +Release: 18%{?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 LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -299,6 +299,10 @@ Patch29: i686-AVX10.1-part-4.patch Patch30: i686-AVX10.1-part-5.patch Patch31: i686-AVX10.1-part-6.patch +# Purpose: Fix: PR31179, The SET/ADD/SUB fix breaks ABI compatibility with 2.41 objects +# Lifetime: Fixed in 2.42 +Patch32: binutils-riscv-SUB_ULEB128.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -1324,6 +1328,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Tue Jan 02 2024 Nick Clifton - 2.41-18 +- Fix handling of Risc-V SUB_LEB128 relocation. (PR31179) + * Mon Dec 11 2023 Nick Clifton - 2.41-17 - Fix failure in binutils testsuite for RiscV architecture.