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.
This commit is contained in:
Alan Modra 2019-06-19 13:55:59 +09:30
parent 4a4e7361d6
commit 6f5601c4d0
2 changed files with 21 additions and 7 deletions

View File

@ -1,3 +1,9 @@
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

View File

@ -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;