From 0e9c5a5c9916efc8a6c518c84ffdd50a745482c3 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 23 Jun 2016 11:33:52 +0100 Subject: MIPS/GAS: Keep the original microMIPS symbol reference in branch relocs Keep original microMIPS symbols in references from branch relocations so that the ISA bit is retained and can be verified for validity in static link. No need to update WRT MIPS16 symbols because we keep them all anyway for other reasons. gas/ * config/tc-mips.c (b_reloc_p): New function. (mips_fix_adjustable): Also keep the original microMIPS symbol referred from branch relocations. * testsuite/gas/mips/branch-local-1.d: New test. * testsuite/gas/mips/branch-local-n32-1.d: New test. * testsuite/gas/mips/branch-local-n64-1.d: New test. * testsuite/gas/mips/micromips@branch-misc-4-64.d: Update relocations. * testsuite/gas/mips/branch-local-1.s: New test source. * testsuite/gas/mips/mips.exp: Run the new cases. --- gas/config/tc-mips.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'gas/config/tc-mips.c') diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 6891508..bbb604a 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -4109,6 +4109,17 @@ jmp_reloc_p (bfd_reloc_code_real_type reloc) } static inline bfd_boolean +b_reloc_p (bfd_reloc_code_real_type reloc) +{ + return (reloc == BFD_RELOC_MIPS_26_PCREL_S2 + || reloc == BFD_RELOC_MIPS_21_PCREL_S2 + || reloc == BFD_RELOC_16_PCREL_S2 + || reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1 + || reloc == BFD_RELOC_MICROMIPS_10_PCREL_S1 + || reloc == BFD_RELOC_MICROMIPS_7_PCREL_S1); +} + +static inline bfd_boolean got16_reloc_p (bfd_reloc_code_real_type reloc) { return (reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16 @@ -17218,13 +17229,16 @@ mips_fix_adjustable (fixS *fixp) There is a further restriction: 5. We cannot reduce jump relocations (R_MIPS_26, R_MIPS16_26 or - R_MICROMIPS_26_S1) against MIPS16 or microMIPS symbols because - we need to keep the MIPS16 or microMIPS symbol for the purpose - of converting JAL to JALX instructions in the linker. + R_MICROMIPS_26_S1) or branch relocations (R_MIPS_PC26_S2, + R_MIPS_PC21_S2, R_MIPS_PC16, R_MICROMIPS_PC16_S1, + R_MICROMIPS_PC10_S1 or R_MICROMIPS_PC7_S1) against MIPS16 or + microMIPS symbols because we need to keep the MIPS16 or + microMIPS symbol for the purpose of mode mismatch detection + and JAL to JALX instruction conversion in the linker. For simplicity, we deal with (3)-(4) by not reducing _any_ relocation against a MIPS16 symbol. We deal with (5) by additionally leaving - alone any jump relocations against a microMIPS symbol. + alone any jump and branch relocations against a microMIPS symbol. We deal with (1)-(2) by saying that, if there's a R_MIPS16_26 relocation against some symbol R, no relocation against R may be @@ -17236,7 +17250,8 @@ mips_fix_adjustable (fixS *fixp) if (fixp->fx_subsy == NULL && (ELF_ST_IS_MIPS16 (S_GET_OTHER (fixp->fx_addsy)) || (ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy)) - && jmp_reloc_p (fixp->fx_r_type)) + && (jmp_reloc_p (fixp->fx_r_type) + || b_reloc_p (fixp->fx_r_type))) || *symbol_get_tc (fixp->fx_addsy))) return 0; -- cgit v1.1