[binutils-gdb] PR24697, R_PPC_EMB_SDA21 relocation

Alan Modra amodra@sourceware.org
Wed Jun 19 04:38:00 GMT 2019


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

commit 6f5601c4d0ad43254244f1b624900cdd5afd02ba
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Jun 19 13:55:59 2019 +0930

    PR24697, R_PPC_EMB_SDA21 relocation
    
    	PR 24697
    	* elf32-ppc.c (ppc_elf_relocate_section): Don't read insn for
    	R_PPC_EMB_RELSDA.  Mask low bit of R_PPC_EMB_SDA21 r_offset.

Diff:
---
 bfd/ChangeLog   |  6 ++++++
 bfd/elf32-ppc.c | 22 +++++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ea049b1..f40f6ed 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
 2019-06-19  Alan Modra  <amodra@gmail.com>
 
+	PR 24697
+	* elf32-ppc.c (ppc_elf_relocate_section): Don't read insn for
+	R_PPC_EMB_RELSDA.  Mask low bit of R_PPC_EMB_SDA21 r_offset.
+
+2019-06-19  Alan Modra  <amodra@gmail.com>
+
 	* elf64-ppc.c (ppc64_elf_inline_plt): Correct st_other test for
 	functions that require r2 valid to use local entry.
 	(ppc64_elf_size_stubs, ppc64_elf_relocate_section): Likewise.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index e73539a..df813d3 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -8654,6 +8654,19 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		addend -= SYM_VAL (sda);
 	      }
 
+	    if (r_type == R_PPC_EMB_RELSDA)
+	      break;
+
+	    /* The PowerPC Embedded Application Binary Interface
+	       version 1.0 insanely chose to specify R_PPC_EMB_SDA21
+	       operating on a 24-bit field at r_offset.  GNU as and
+	       GNU ld have always assumed R_PPC_EMB_SDA21 operates on
+	       a 32-bit bit insn at r_offset.  Cope with object file
+	       producers that possibly comply with the EABI in
+	       generating an odd r_offset for big-endian objects.  */
+	    if (r_type == R_PPC_EMB_SDA21)
+	      rel->r_offset &= ~1;
+
 	    insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 	    if (reg == 0
 		&& (r_type == R_PPC_VLE_SDA21
@@ -8681,13 +8694,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		  goto overflow;
 		goto copy_reloc;
 	      }
-	    else if (r_type == R_PPC_EMB_SDA21
-		     || r_type == R_PPC_VLE_SDA21
-		     || r_type == R_PPC_VLE_SDA21_LO)
-	      {
-		/* Fill in register field.  */
-		insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
-	      }
+	    /* Fill in register field.  */
+	    insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
 	    bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 	  }
 	  break;



More information about the Binutils-cvs mailing list