diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-05-20 13:32:19 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@imgtec.com> | 2016-05-20 13:38:48 +0100 |
commit | 17c6c9d9f3e71459edb4b6af5ec75125f0d06f87 (patch) | |
tree | 8ea38eb69685fd05cbeb181263dbd87556da3919 /bfd | |
parent | 134c0c8bf4a258ba10e72b724eadf40f731bb7ec (diff) | |
download | gdb-17c6c9d9f3e71459edb4b6af5ec75125f0d06f87.zip gdb-17c6c9d9f3e71459edb4b6af5ec75125f0d06f87.tar.gz gdb-17c6c9d9f3e71459edb4b6af5ec75125f0d06f87.tar.bz2 |
MIPS: Fix the encoding of immediates with microMIPS JALX
The microMIPS JALX instruction shares the R_MICROMIPS_26_S1 relocation
with microMIPS J/JAL/JALS instructions, however unlike the latters its
encoded immediate argument is unusually shifted left by 2 rather than 1
in calculating the value used for the operation requested.
We already handle this exception in `mips_elf_calculate_relocation' in
LD, in a scenario where JALX is produced as a result of relaxing JAL for
the purpose of making a cross-mode jump. We also get it right in the
disassembler in `decode_micromips_operand'.
What we don't correctly do however is processing microMIPS JALX produced
by GAS from an assembly source, where a non-zero constant argument or a
symbol reference with a non-zero in-place addend has been used. In this
case the same calculation is made as for microMIPS J/JAL/JALS, causing
the wrong encoding to be produced by GAS on making an object file, and
then again by LD in the final link. The latter in particular causes the
calculation, where the addend fits in the relocatable field, to produce
different final addresses for the same source code depending on whether
REL or RELA relocations are used.
Correct these issues by special-casing microMIPS JALX in the places that
have been previously missed.
bfd/
* elfxx-mips.c (mips_elf_read_rel_addend): Adjust the addend for
microMIPS JALX.
gas/
* config/tc-mips.c (append_insn): Correct the encoding of a
constant argument for microMIPS JALX.
(tc_gen_reloc): Correct the encoding of an in-place addend for
microMIPS JALX.
* testsuite/gas/mips/jalx-addend.d: New test.
* testsuite/gas/mips/jalx-addend-n32.d: New test.
* testsuite/gas/mips/jalx-addend-n64.d: New test.
* testsuite/gas/mips/jalx-imm.d: New test.
* testsuite/gas/mips/jalx-imm-n32.d: New test.
* testsuite/gas/mips/jalx-imm-n64.d: New test.
* testsuite/gas/mips/jalx-addend.s: New test source.
* testsuite/gas/mips/jalx-imm.s: New test source.
* testsuite/gas/mips/mips.exp: Run the new tests.
ld/
* testsuite/ld-mips-elf/jalx-addend.d: New test.
* testsuite/ld-mips-elf/jalx-addend-n32.d: New test.
* testsuite/ld-mips-elf/jalx-addend-n64.d: New test.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 12 |
2 files changed, 15 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 64aac63..1a9eeb6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2016-05-20 Maciej W. Rozycki <macro@imgtec.com> + + * elfxx-mips.c (mips_elf_read_rel_addend): Adjust the addend for + microMIPS JALX. + 2016-05-19 H.J. Lu <hongjiu.lu@intel.com> PR ld/20117 diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index cb775bb..b561b43 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -7780,16 +7780,24 @@ mips_elf_read_rel_addend (bfd *abfd, const Elf_Internal_Rela *rel, bfd_byte *location; unsigned int r_type; bfd_vma addend; + bfd_vma bytes; r_type = ELF_R_TYPE (abfd, rel->r_info); location = contents + rel->r_offset; /* Get the addend, which is stored in the input file. */ _bfd_mips_elf_reloc_unshuffle (abfd, r_type, FALSE, location); - addend = mips_elf_obtain_contents (howto, rel, abfd, contents); + bytes = mips_elf_obtain_contents (howto, rel, abfd, contents); _bfd_mips_elf_reloc_shuffle (abfd, r_type, FALSE, location); - return addend & howto->src_mask; + addend = bytes & howto->src_mask; + + /* Shift is 2, unusually, for microMIPS JALX. Adjust the addend + accordingly. */ + if (r_type == R_MICROMIPS_26_S1 && (bytes >> 26) == 0x3c) + addend <<= 1; + + return addend; } /* REL is a relocation in ABFD that needs a partnering LO16 relocation |