Fix handling of Risc-V SUB_LEB128 relocation. (PR31179)
This commit is contained in:
parent
4196d43202
commit
3b7f3a5c52
239
binutils-riscv-SUB_ULEB128.patch
Normal file
239
binutils-riscv-SUB_ULEB128.patch
Normal file
@ -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 <<EOF
|
||||||
|
#include "elf/riscv.h"
|
||||||
|
#include "elfxx-riscv.h"
|
||||||
|
|
||||||
|
-static struct riscv_elf_params params = { .relax_gp = 1 };
|
||||||
|
+static struct riscv_elf_params params = { .relax_gp = 1,
|
||||||
|
+ .check_uleb128 = 0};
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Define some shell vars to insert bits of code into the standard elf
|
||||||
|
@@ -35,17 +36,23 @@ enum risccv_opt
|
||||||
|
{
|
||||||
|
OPTION_RELAX_GP = 321,
|
||||||
|
OPTION_NO_RELAX_GP,
|
||||||
|
+ OPTION_CHECK_ULEB128,
|
||||||
|
+ OPTION_NO_CHECK_ULEB128,
|
||||||
|
};
|
||||||
|
'
|
||||||
|
|
||||||
|
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
|
||||||
|
{ "relax-gp", no_argument, NULL, OPTION_RELAX_GP },
|
||||||
|
{ "no-relax-gp", no_argument, NULL, OPTION_NO_RELAX_GP },
|
||||||
|
+ { "check-uleb128", no_argument, NULL, OPTION_CHECK_ULEB128 },
|
||||||
|
+ { "no-check-uleb128", no_argument, NULL, OPTION_NO_CHECK_ULEB128 },
|
||||||
|
'
|
||||||
|
|
||||||
|
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
|
||||||
|
fprintf (file, _(" --relax-gp Perform GP relaxation\n"));
|
||||||
|
fprintf (file, _(" --no-relax-gp Don'\''t perform GP relaxation\n"));
|
||||||
|
+ fprintf (file, _(" --check-uleb128 Check if SUB_ULEB128 has non-zero addend\n"));
|
||||||
|
+ fprintf (file, _(" --no-check-uleb128 Don'\''t check if SUB_ULEB128 has non-zero addend\n"));
|
||||||
|
'
|
||||||
|
|
||||||
|
PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
|
||||||
|
@@ -56,6 +63,14 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LI
|
||||||
|
case OPTION_NO_RELAX_GP:
|
||||||
|
params.relax_gp = 0;
|
||||||
|
break;
|
||||||
|
+
|
||||||
|
+ case OPTION_CHECK_ULEB128:
|
||||||
|
+ params.check_uleb128 = 1;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case OPTION_NO_CHECK_ULEB128:
|
||||||
|
+ params.check_uleb128 = 0;
|
||||||
|
+ break;
|
||||||
|
'
|
||||||
|
|
||||||
|
fragment <<EOF
|
||||||
|
diff -rupN binutils.orig/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp binutils-2.41/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
|
||||||
|
--- binutils.orig/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp 2024-01-02 17:35:07.942218600 +0000
|
||||||
|
+++ binutils-2.41/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp 2024-01-02 17:35:24.252233056 +0000
|
||||||
|
@@ -173,6 +173,8 @@ if [istarget "riscv*-*-*"] {
|
||||||
|
run_dump_test "attr-phdr"
|
||||||
|
run_dump_test "relax-max-align-gp"
|
||||||
|
run_dump_test "uleb128"
|
||||||
|
+ run_dump_test "pr31179"
|
||||||
|
+ run_dump_test "pr31179-r"
|
||||||
|
run_ld_link_tests [list \
|
||||||
|
[list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \
|
||||||
|
"-march=rv32i -mabi=ilp32" {weakref32.s} \
|
||||||
|
diff -rupN binutils.orig/ld/testsuite/ld-riscv-elf/pr31179-r.d binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179-r.d
|
||||||
|
--- binutils.orig/ld/testsuite/ld-riscv-elf/pr31179-r.d 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179-r.d 2024-01-02 17:35:24.252233056 +0000
|
||||||
|
@@ -0,0 +1,10 @@
|
||||||
|
+#source: pr31179.s
|
||||||
|
+#as:
|
||||||
|
+#readelf: -Wr
|
||||||
|
+
|
||||||
|
+Relocation section '.rela.text' at .*
|
||||||
|
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
|
||||||
|
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_SET_ULEB128[ ]+[0-9a-f]+[ ]+bar \+ 1
|
||||||
|
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_SUB_ULEB128[ ]+[0-9a-f]+[ ]+foo \+ 0
|
||||||
|
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_SET_ULEB128[ ]+[0-9a-f]+[ ]+bar \+ 1
|
||||||
|
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_SUB_ULEB128[ ]+[0-9a-f]+[ ]+foo \+ 1
|
||||||
|
diff -rupN binutils.orig/ld/testsuite/ld-riscv-elf/pr31179.d binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179.d
|
||||||
|
--- binutils.orig/ld/testsuite/ld-riscv-elf/pr31179.d 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179.d 2024-01-02 17:35:24.252233056 +0000
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+#source: pr31179.s
|
||||||
|
+#as:
|
||||||
|
+#ld: --check-uleb128
|
||||||
|
+#objdump: -sj .text
|
||||||
|
+#warning: .*R_RISCV_SUB_ULEB128 with non-zero addend, please rebuild by Fedora 40 binutils or up
|
||||||
|
+
|
||||||
|
+.*:[ ]+file format .*
|
||||||
|
+
|
||||||
|
+Contents of section .text:
|
||||||
|
+
|
||||||
|
+[ ]+[0-9a-f]+[ ]+00000303[ ]+.*
|
||||||
|
diff -rupN binutils.orig/ld/testsuite/ld-riscv-elf/pr31179.s binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179.s
|
||||||
|
--- binutils.orig/ld/testsuite/ld-riscv-elf/pr31179.s 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ binutils-2.41/ld/testsuite/ld-riscv-elf/pr31179.s 2024-01-02 17:35:24.252233056 +0000
|
||||||
|
@@ -0,0 +1,13 @@
|
||||||
|
+.globl _start
|
||||||
|
+_start:
|
||||||
|
+
|
||||||
|
+foo:
|
||||||
|
+.2byte 0
|
||||||
|
+bar:
|
||||||
|
+
|
||||||
|
+.uleb128 bar - foo + 1
|
||||||
|
+
|
||||||
|
+reloc:
|
||||||
|
+.reloc reloc, R_RISCV_SET_ULEB128, bar + 1
|
||||||
|
+.reloc reloc, R_RISCV_SUB_ULEB128, foo + 1
|
||||||
|
+.byte 0x0
|
||||||
|
--- binutils.orig/gas/config/tc-riscv.c 2024-01-03 13:08:16.588286420 +0000
|
||||||
|
+++ binutils-2.41/gas/config/tc-riscv.c 2024-01-03 13:08:32.749297812 +0000
|
||||||
|
@@ -4949,6 +4949,7 @@ riscv_insert_uleb128_fixes (bfd *abfd AT
|
||||||
|
fix_new_exp (fragP, fragP->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);
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
Summary: A GNU collection of binary utilities
|
Summary: A GNU collection of binary utilities
|
||||||
Name: binutils%{?_with_debug:-debug}
|
Name: binutils%{?_with_debug:-debug}
|
||||||
Version: 2.41
|
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
|
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
|
URL: https://sourceware.org/binutils
|
||||||
|
|
||||||
@ -299,6 +299,10 @@ Patch29: i686-AVX10.1-part-4.patch
|
|||||||
Patch30: i686-AVX10.1-part-5.patch
|
Patch30: i686-AVX10.1-part-5.patch
|
||||||
Patch31: i686-AVX10.1-part-6.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)
|
Provides: bundled(libiberty)
|
||||||
@ -1324,6 +1328,9 @@ exit 0
|
|||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 02 2024 Nick Clifton <nickc@redhat.com> - 2.41-18
|
||||||
|
- Fix handling of Risc-V SUB_LEB128 relocation. (PR31179)
|
||||||
|
|
||||||
* Mon Dec 11 2023 Nick Clifton <nickc@redhat.com> - 2.41-17
|
* Mon Dec 11 2023 Nick Clifton <nickc@redhat.com> - 2.41-17
|
||||||
- Fix failure in binutils testsuite for RiscV architecture.
|
- Fix failure in binutils testsuite for RiscV architecture.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user