aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2017-02-23 19:26:53 +0000
committerMaciej W. Rozycki <macro@imgtec.com>2017-02-23 23:45:14 +0000
commitc1556ecd7843912269aba283a0fd307729fa0c3a (patch)
tree1deeb56cbddecee8f8f62c6494d72e0883be1d9b /bfd
parenta567769b813b2538bebc97d689fc0739f172028e (diff)
downloadgdb-c1556ecd7843912269aba283a0fd307729fa0c3a.zip
gdb-c1556ecd7843912269aba283a0fd307729fa0c3a.tar.gz
gdb-c1556ecd7843912269aba283a0fd307729fa0c3a.tar.bz2
MIPS/BFD: Discard ineligible JALR relocations right away
Discard R_MIPS_JALR and R_MICROMIPS_JALR relocations associated with jumps that cannot be converted to an equivalent branch right away in `mips_elf_calculate_relocation' rather than letting them through to `mips_elf_perform_relocation'. This includes cross-mode jumps which need to flip the ISA bit or jumps to a misaligned location that cannot be encoded with a branch, in addition to preemptible symbol references already handled. Cross-mode jumps are actually already rejected as the conversion is made in `mips_elf_perform_relocation', so in this case this change only saves some processing. Jumps to a misaligned location are however converted, with bits causing misalignment lost, making resulting code functionally different even if the lone effect is avoiding an address error exception with an instruction fetch at the jump destination requested. Add test cases suitable, also including GAS verification to confirm that the JALR relocations explicitly requested have indeed been output in the intermediate objects used. bfd/ * elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS_JALR> <R_MICROMIPS_JALR>: Discard relocation if `cross_mode_jump_p' or misaligned. gas/ * testsuite/gas/mips/jalr4.d: New test. * testsuite/gas/mips/jalr4-n32.d: New test. * testsuite/gas/mips/jalr4-n64.d: New test. * testsuite/gas/mips/jalr4.s: New test source. * testsuite/gas/mips/mips.exp: Run the new tests. ld/ * testsuite/ld-mips-elf/jalr4.dd: New test. * testsuite/ld-mips-elf/mips-elf.exp: Run the new test.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elfxx-mips.c6
2 files changed, 12 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3a3ca28..46f5f9c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-23 Maciej W. Rozycki <macro@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS_JALR>
+ <R_MICROMIPS_JALR>: Discard relocation if `cross_mode_jump_p'
+ or misaligned.
+
2017-02-23 Alan Modra <amodra@gmail.com>
PR 20744
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index c184d2e..ec086de 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -6278,7 +6278,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
when the symbol does not resolve locally. */
if (h != NULL && !SYMBOL_CALLS_LOCAL (info, &h->root))
return bfd_reloc_continue;
+ /* We can't optimize cross-mode jumps either. */
+ if (*cross_mode_jump_p)
+ return bfd_reloc_continue;
value = symbol + addend;
+ /* Neither we can non-instruction-aligned targets. */
+ if (r_type == R_MIPS_JALR ? (value & 3) != 0 : (value & 1) == 0)
+ return bfd_reloc_continue;
break;
case R_MIPS_PJUMP: