[binutils-gdb] MIPS/BFD: Fix ELF link orphan REL HI16 relocation addend processing

Maciej W. Rozycki macro@sourceware.org
Wed Jan 14 22:31:31 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a85a420984db83a33be4af777f0b94ed94c1b9f2

commit a85a420984db83a33be4af777f0b94ed94c1b9f2
Author: Maciej W. Rozycki <macro@orcam.me.uk>
Date:   Wed Jan 14 22:28:44 2026 +0000

    MIPS/BFD: Fix ELF link orphan REL HI16 relocation addend processing
    
    Correct the addend being ignored for orphan REL HI16 relocations.
    
    For ELF links `_bfd_mips_elf_relocate_section' handles relocation and
    uses `mips_elf_add_lo16_rel_addend' to shift the incoming HI16 in-place
    addend into its intended [31:16] bit positions and combine it with the
    LO16 part.  If no matching LO16 reloc has been found, then the function
    returns early and consequently the incoming HI16 addend is not shifted
    and remains in bits [0:15].  For final links any value of the symbol
    referred is then added.  Then the final value is shifted back into bits
    [0:15] for installation into the field relocated.  It is obviously wrong
    as the original HI16 in-place addend has now been lost.
    
    Fix the issue by shifting the incoming HI16 in-place addend before using
    `mips_elf_next_relocation' to find the matching LO16 relocation.  Then
    upon early return from `mips_elf_add_lo16_rel_addend' the addend is in
    the intended [31:16] bit positions already.
    
    Test cases will be added with a separate change.

Diff:
---
 bfd/elfxx-mips.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index f4424aca504..d3d989eae82 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -8370,9 +8370,10 @@ mips_elf_add_lo16_rel_addend (bfd *abfd,
   /* The combined value is the sum of the HI16 addend, left-shifted by
      sixteen bits, and the LO16 addend, sign extended.  (Usually, the
      code does a `lui' of the HI16 value, and then an `addiu' of the
-     LO16 value.)
+     LO16 value.)  */
+  *addend <<= 16;
 
-     Scan ahead to find a matching LO16 relocation.
+  /* Scan ahead to find a matching LO16 relocation.
 
      According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must
      be immediately following.  However, for the IRIX6 ABI, the next
@@ -8400,7 +8401,6 @@ mips_elf_add_lo16_rel_addend (bfd *abfd,
     l = (l - (lo16_relocation->r_offset - rel->r_offset)) & 0xffff;
   l = _bfd_mips_elf_sign_extend (l, 16);
 
-  *addend <<= 16;
   *addend += l;
   return true;
 }


More information about the Binutils-cvs mailing list