diff options
author | Alan Modra <amodra@gmail.com> | 2017-02-28 08:32:36 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-02-28 11:59:47 +1030 |
commit | 7ba71655a425ac44721f97cc0ad7922ca15bce43 (patch) | |
tree | 21c74fc0cf464c5ef896b43c385daa8f6f47b0a7 /bfd/elf32-ppc.c | |
parent | afbf7e8e3aa24152ad58e430c8d37d82e5751f1c (diff) | |
download | gdb-7ba71655a425ac44721f97cc0ad7922ca15bce43.zip gdb-7ba71655a425ac44721f97cc0ad7922ca15bce43.tar.gz gdb-7ba71655a425ac44721f97cc0ad7922ca15bce43.tar.bz2 |
PowerPC addpcis fix
This came up because I was looking at ld/tmpdir/addpcis.o and noticed
the odd addends on REL16DX_HA. They ought to both be -4. The error
crept in due REL16DX_HA howto being pc-relative (as indeed it should
be), and code at gas/write.c:1001 after this comment
/* Make it pc-relative. If the back-end code has not
selected a pc-relative reloc, cancel the adjustment
we do later on all pc-relative relocs. */
*not* cancelling the pc-relative adjustment. So I've made a dummy
non-relative split reloc so that the generic code handles this, rather
than attempting to add hacks later in md_apply_fix which would not be
very robust. Having the new internal reloc also makes it easy to
support
addpcis rx,sym@ha
as an equivalent to
addpcis rx,(sym-0f)@ha
0:
The patch also fixes overflow checking, which must test whether the
addi will overflow too since @l relocs don't have any overflow check.
Lastly, since I was poking at md_apply_fix, I arranged to have the
generic gas/write.c code emit errors for subtraction expressions where
we lack reloc support.
include/
* elf/ppc64.h (R_PPC64_16DX_HA): New. Expand fake reloc comment.
* elf/ppc.h (R_PPC_16DX_HA): Likewise.
bfd/
* reloc.c (BFD_RELOC_PPC_16DX_HA): New.
* elf64-ppc.c (ppc64_elf_howto_raw <R_PPC64_16DX_HA>): New howto.
(ppc64_elf_reloc_type_lookup): Translate new bfd reloc.
(ppc64_elf_ha_reloc): Correct overflow test on REL16DX_HA.
(ppc64_elf_relocate_section): Likewise.
* elf32-ppc.c (ppc_elf_howto_raw <R_PPC_16DX_HA>): New howto.
(ppc_elf_reloc_type_lookup): Translate new bfd reloc.
(ppc_elf_check_relocs): Handle R_PPC_16DX_HA to pacify gcc.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c (md_assemble): Use BFD_RELOC_PPC_16DX_HA for addpcis.
(md_apply_fix): Remove fx_subsy check. Move code converting to
pcrel reloc earlier and handle BFD_RELOC_PPC_16DX_HA. Remove code
emiiting errors on seeing fx_pcrel set on unexpected relocs, as
that is done now by the generic code via..
* config/tc-ppc.h (TC_FORCE_RELOCATION_SUB_LOCAL): ..this. Define.
(TC_VALIDATE_FIX_SUB): Define.
ld/
* testsuite/ld-powerpc/addpcis.d: Define ext1 and ext2 at
limits of addpcis range.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r-- | bfd/elf32-ppc.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 834ef67..d98b776 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -1746,6 +1746,21 @@ static reloc_howto_type ppc_elf_howto_raw[] = { 0x1fffc1, /* dst_mask */ TRUE), /* pcrel_offset */ + /* A split-field reloc for addpcis, non-relative (gas internal use only). */ + HOWTO (R_PPC_16DX_HA, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + ppc_elf_addr16_ha_reloc, /* special_function */ + "R_PPC_16DX_HA", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x1fffc1, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_PPC_GNU_VTINHERIT, /* type */ 0, /* rightshift */ @@ -2002,6 +2017,7 @@ ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, case BFD_RELOC_LO16_PCREL: r = R_PPC_REL16_LO; break; case BFD_RELOC_HI16_PCREL: r = R_PPC_REL16_HI; break; case BFD_RELOC_HI16_S_PCREL: r = R_PPC_REL16_HA; break; + case BFD_RELOC_PPC_16DX_HA: r = R_PPC_16DX_HA; break; case BFD_RELOC_PPC_REL16DX_HA: r = R_PPC_REL16DX_HA; break; case BFD_RELOC_VTABLE_INHERIT: r = R_PPC_GNU_VTINHERIT; break; case BFD_RELOC_VTABLE_ENTRY: r = R_PPC_GNU_VTENTRY; break; @@ -4351,6 +4367,7 @@ ppc_elf_check_relocs (bfd *abfd, case R_PPC_RELAX: case R_PPC_RELAX_PLT: case R_PPC_RELAX_PLTREL24: + case R_PPC_16DX_HA: break; /* These should only appear in dynamic objects. */ |