diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bf95751371..e6ed9609fc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,23 @@ +2016-06-28 Maciej W. Rozycki + + * elf32-mips.c (elf_mips16_howto_table_rel): Add + R_MIPS16_PC16_S1. + (mips16_reloc_map): Likewise. + * elf64-mips.c (mips16_elf64_howto_table_rel): Likewise. + (mips16_elf64_howto_table_rela): Likewise. + (mips16_reloc_map): Likewise. + * elfn32-mips.c (elf_mips16_howto_table_rel): Likewise. + (elf_mips16_howto_table_rela): Likewise. + (mips16_reloc_map): Likewise. + * elfxx-mips.c (mips16_branch_reloc_p): New function. + (mips16_reloc_p): Handle R_MIPS16_PC16_S1. + (b_reloc_p): Likewise. + (mips_elf_calculate_relocation): Likewise. + (_bfd_mips_elf_check_relocs): Likewise. + * reloc.c (BFD_RELOC_MIPS16_16_PCREL_S1): New relocation. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + 2016-06-27 Alan Modra PR ld/19264 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ebed9664bb..30513c4c3f 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2998,6 +2998,9 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_MICROMIPS_10_PCREL_S1, BFD_RELOC_MICROMIPS_16_PCREL_S1, +/* MIPS16 PC-relative relocation. */ + BFD_RELOC_MIPS16_16_PCREL_S1, + /* MIPS PC-relative relocations. */ BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2, diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 5654fb664e..029de279fe 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1027,6 +1027,21 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; static reloc_howto_type elf_micromips_howto_table_rel[] = @@ -2023,7 +2038,8 @@ static const struct elf_reloc_map mips16_reloc_map[] = R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, - { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 34144f038b..f04c4b5a80 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -1881,6 +1881,21 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; static reloc_howto_type mips16_elf64_howto_table_rela[] = @@ -2082,6 +2097,21 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] = 0, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; static reloc_howto_type micromips_elf64_howto_table_rel[] = @@ -3415,7 +3445,8 @@ static const struct elf_reloc_map mips16_reloc_map[] = R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, - { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index c955877afe..734ebf63f2 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -1847,6 +1847,21 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; static reloc_howto_type elf_mips16_howto_table_rela[] = @@ -2048,6 +2063,21 @@ static reloc_howto_type elf_mips16_howto_table_rela[] = 0, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 16-bit PC-relative branch offset. */ + HOWTO (R_MIPS16_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_PC16_S1", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; static reloc_howto_type elf_micromips_howto_table_rel[] = @@ -3231,7 +3261,8 @@ static const struct elf_reloc_map mips16_reloc_map[] = R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, - { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 3b7723e3d0..e47276bc61 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -2090,7 +2090,11 @@ mips_elf_check_symbols (struct mips_elf_link_hash_entry *h, void *data) All we need to do here is shuffle the bits appropriately. As above, the two 16-bit halves must be swapped on a - little-endian system. */ + little-endian system. + + Finally R_MIPS16_PC16_S1 corresponds to R_MIPS_PC16, however the + relocatable field is shifted by 1 rather than 2 and the same bit + shuffling is done as with the relocations above. */ static inline bfd_boolean mips16_reloc_p (int r_type) @@ -2110,6 +2114,7 @@ mips16_reloc_p (int r_type) case R_MIPS16_TLS_GOTTPREL: case R_MIPS16_TLS_TPREL_HI16: case R_MIPS16_TLS_TPREL_LO16: + case R_MIPS16_PC16_S1: return TRUE; default: @@ -2221,7 +2226,8 @@ b_reloc_p (int r_type) return (r_type == R_MIPS_PC26_S2 || r_type == R_MIPS_PC21_S2 || r_type == R_MIPS_PC16 - || r_type == R_MIPS_GNU_REL16_S2); + || r_type == R_MIPS_GNU_REL16_S2 + || r_type == R_MIPS16_PC16_S1); } static inline bfd_boolean @@ -2231,6 +2237,13 @@ aligned_pcrel_reloc_p (int r_type) || r_type == R_MIPS_PC19_S2); } +static inline bfd_boolean +mips16_branch_reloc_p (int r_type) +{ + return (r_type == R_MIPS16_26 + || r_type == R_MIPS16_PC16_S1); +} + static inline bfd_boolean micromips_branch_reloc_p (int r_type) { @@ -5562,7 +5575,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, } /* Make sure MIPS16 and microMIPS are not used together. */ - if ((r_type == R_MIPS16_26 && target_is_micromips_code_p) + if ((mips16_branch_reloc_p (r_type) && target_is_micromips_code_p) || (micromips_branch_reloc_p (r_type) && target_is_16_bit_code_p)) { (*_bfd_error_handler) @@ -5994,6 +6007,21 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, value &= howto->dst_mask; break; + case R_MIPS16_PC16_S1: + if (howto->partial_inplace) + addend = _bfd_mips_elf_sign_extend (addend, 17); + + if ((was_local_p || h->root.root.type != bfd_link_hash_undefweak) + && ((symbol + addend) & 1) == 0) + return bfd_reloc_outofrange; + + value = symbol + addend - p; + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 17); + value >>= howto->rightshift; + value &= howto->dst_mask; + break; + case R_MIPS_PC21_S2: if (howto->partial_inplace) addend = _bfd_mips_elf_sign_extend (addend, 23); @@ -8346,6 +8374,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_MIPS_PC21_S2: case R_MIPS_PC26_S2: case R_MIPS16_26: + case R_MIPS16_PC16_S1: case R_MICROMIPS_26_S1: case R_MICROMIPS_PC7_S1: case R_MICROMIPS_PC10_S1: diff --git a/bfd/libbfd.h b/bfd/libbfd.h index bf17f43534..2b1777ef21 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1156,6 +1156,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MICROMIPS_7_PCREL_S1", "BFD_RELOC_MICROMIPS_10_PCREL_S1", "BFD_RELOC_MICROMIPS_16_PCREL_S1", + "BFD_RELOC_MIPS16_16_PCREL_S1", "BFD_RELOC_MIPS_21_PCREL_S2", "BFD_RELOC_MIPS_26_PCREL_S2", "BFD_RELOC_MIPS_18_PCREL_S3", diff --git a/bfd/reloc.c b/bfd/reloc.c index 443ad6f755..e962e71868 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2304,6 +2304,11 @@ ENUMX ENUMDOC microMIPS PC-relative relocations. +ENUM + BFD_RELOC_MIPS16_16_PCREL_S1 +ENUMDOC + MIPS16 PC-relative relocation. + ENUM BFD_RELOC_MIPS_21_PCREL_S2 ENUMX diff --git a/gas/ChangeLog b/gas/ChangeLog index d6afee21d4..ba19df2eae 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,36 @@ +2016-06-28 Maciej W. Rozycki + + * config/tc-mips.c (mips16_reloc_p): Handle + BFD_RELOC_MIPS16_16_PCREL_S1. + (b_reloc_p): Likewise. + (limited_pcrel_reloc_p): Likewise. + (md_pcrel_from): Likewise. + (md_apply_fix): Likewise. + (tc_gen_reloc): Likewise. + (md_convert_frag): Likewise. + (mips_fix_adjustable): Update comment. + * testsuite/gas/mips/mips16-branch-reloc-2.d: Remove error + output, add dump patterns. + * testsuite/gas/mips/mips16-branch-reloc-3.d: Remove error + output, add dump patterns. + * testsuite/gas/mips/mips16-branch-addend-2.d: Remove error + output, add dump patterns. + * testsuite/gas/mips/mips16-branch-addend-3.d: Remove error + output, add dump patterns. + * testsuite/gas/mips/mips16-branch-absolute.d: Remove error + output, add dump patterns. + * testsuite/gas/mips/mips16-branch-reloc-2.l: Remove file. + * testsuite/gas/mips/mips16-branch-reloc-3.l: Remove file. + * testsuite/gas/mips/mips16-branch-addend-2.l: Remove file. + * testsuite/gas/mips/mips16-branch-addend-3.l: Remove file. + * testsuite/gas/mips/mips16-branch-absolute.l: Remove file. + * testsuite/gas/mips/mips16-branch-addend-2.s: Add padding. + * testsuite/gas/mips/branch-weak.s: Adjust alignment, avoid + implicit instruction padding, avoid MIPS16 JR->JRC conversion. + * testsuite/gas/mips/branch-weak-6.d: New test. + * testsuite/gas/mips/branch-weak-7.d: New test. + * testsuite/gas/mips/mips.exp: Run the new tests. + 2016-06-27 Vineet Gupta * config//tc-arc.c (tc_arc_frame_initial_instructions): Use diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index ab2ea0c8c7..092e7b430d 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -4060,6 +4060,7 @@ mips16_reloc_p (bfd_reloc_code_real_type reloc) case BFD_RELOC_MIPS16_HI16_S: case BFD_RELOC_MIPS16_HI16: case BFD_RELOC_MIPS16_LO16: + case BFD_RELOC_MIPS16_16_PCREL_S1: return TRUE; default: @@ -4114,6 +4115,7 @@ 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_MIPS16_16_PCREL_S1 || reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1 || reloc == BFD_RELOC_MICROMIPS_10_PCREL_S1 || reloc == BFD_RELOC_MICROMIPS_7_PCREL_S1); @@ -4162,6 +4164,7 @@ limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc) switch (reloc) { case BFD_RELOC_16_PCREL_S2: + case BFD_RELOC_MIPS16_16_PCREL_S1: case BFD_RELOC_MICROMIPS_7_PCREL_S1: case BFD_RELOC_MICROMIPS_10_PCREL_S1: case BFD_RELOC_MICROMIPS_16_PCREL_S1: @@ -14628,6 +14631,7 @@ md_pcrel_from (fixS *fixP) case BFD_RELOC_MICROMIPS_16_PCREL_S1: case BFD_RELOC_MICROMIPS_JMP: + case BFD_RELOC_MIPS16_16_PCREL_S1: case BFD_RELOC_16_PCREL_S2: case BFD_RELOC_MIPS_21_PCREL_S2: case BFD_RELOC_MIPS_26_PCREL_S2: @@ -14852,6 +14856,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) switch (fixP->fx_r_type) { case BFD_RELOC_16_PCREL_S2: + case BFD_RELOC_MIPS16_16_PCREL_S1: case BFD_RELOC_MICROMIPS_7_PCREL_S1: case BFD_RELOC_MICROMIPS_10_PCREL_S1: case BFD_RELOC_MICROMIPS_16_PCREL_S1: @@ -15184,6 +15189,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) } break; + case BFD_RELOC_MIPS16_16_PCREL_S1: case BFD_RELOC_MICROMIPS_7_PCREL_S1: case BFD_RELOC_MICROMIPS_10_PCREL_S1: case BFD_RELOC_MICROMIPS_16_PCREL_S1: @@ -17216,11 +17222,11 @@ mips_fix_adjustable (fixS *fixp) 5. We cannot reduce jump relocations (R_MIPS_26, R_MIPS16_26 or 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. + R_MIPS_PC21_S2, R_MIPS_PC16, R_MIPS16_PC16_S1, + 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 @@ -17263,6 +17269,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) if (fixp->fx_pcrel) { gas_assert (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2 + || fixp->fx_r_type == BFD_RELOC_MIPS16_16_PCREL_S1 || fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1 || fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1 || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1 @@ -17870,8 +17877,41 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp) || (operand->root.type == OP_PCREL ? asec != symsec : !bfd_is_abs_section (symsec))) - as_bad_where (fragp->fr_file, fragp->fr_line, - _("unsupported relocation")); + { + bfd_reloc_code_real_type reloc = BFD_RELOC_NONE; + expressionS exp; + fixS *fixp; + + switch (type) + { + case 'p': + case 'q': + reloc = BFD_RELOC_MIPS16_16_PCREL_S1; + break; + default: + as_bad_where (fragp->fr_file, fragp->fr_line, + _("unsupported relocation")); + break; + } + if (reloc != BFD_RELOC_NONE) + { + gas_assert (ext); + + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + fixp = fix_new_exp (fragp, buf - fragp->fr_literal, 2, &exp, + TRUE, reloc); + + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + /* These relocations can have an addend that won't fit + in 2 octets. */ + fixp->fx_no_overflow = 1; + } + } else mips16_immed (fragp->fr_file, fragp->fr_line, type, BFD_RELOC_UNUSED, val, user_length, &insn); diff --git a/gas/testsuite/gas/mips/branch-weak-6.d b/gas/testsuite/gas/mips/branch-weak-6.d new file mode 100644 index 0000000000..e16b1b89c1 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-6.d @@ -0,0 +1,14 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 branch to a weak symbol +#as: -32 -mips16 --defsym align=12 +#source: branch-weak.s + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> f7ff 101e b 00000000 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar + \.\.\. +[0-9a-f]+ <[^>]*> e820 jr ra +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/branch-weak-7.d b/gas/testsuite/gas/mips/branch-weak-7.d new file mode 100644 index 0000000000..b291289fbf --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-7.d @@ -0,0 +1,14 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 short branch to a weak symbol +#as: -32 -mips16 --defsym align=4 +#source: branch-weak.s + +.*: +file format .*mips.* + +Disassembly of section \.text: +[0-9a-f]+ <[^>]*> f7ff 101e b 00000000 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar + \.\.\. +[0-9a-f]+ <[^>]*> e820 jr ra +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/branch-weak.s b/gas/testsuite/gas/mips/branch-weak.s index eedef7a547..a2dc7344a1 100644 --- a/gas/testsuite/gas/mips/branch-weak.s +++ b/gas/testsuite/gas/mips/branch-weak.s @@ -1,5 +1,5 @@ .text - .align 4, 0 + .align align, 0 .globl foo .ent foo foo: @@ -11,9 +11,9 @@ foo: .weak bar .ent bar bar: + nop jr $ra .end bar # Force some (non-delay-slot) zero bytes, to make 'objdump' print ... - .align 4, 0 - .space 16 + .align align, 0 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index d268dc00ce..4f5651b4a4 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -588,6 +588,8 @@ if { [istarget mips*-*-vxworks*] } { run_dump_test "branch-weak-3" run_dump_test "branch-weak-4" run_dump_test "branch-weak-5" + run_dump_test "branch-weak-6" + run_dump_test "branch-weak-7" run_dump_test "branch-local-1" if $has_newabi { run_dump_test "branch-local-n32-1" diff --git a/gas/testsuite/gas/mips/mips16-branch-absolute.d b/gas/testsuite/gas/mips/mips16-branch-absolute.d index 90a9ea7cc7..3e1ec8e3d3 100644 --- a/gas/testsuite/gas/mips/mips16-branch-absolute.d +++ b/gas/testsuite/gas/mips/mips16-branch-absolute.d @@ -1,3 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS16 branch to absolute expression #as: -32 -#error-output: mips16-branch-absolute.l + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f000 1000 b 00001004 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 \*ABS\* +[0-9a-f]+ <[^>]*> f000 6000 bteqz 00001008 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 \*ABS\* +[0-9a-f]+ <[^>]*> f000 6100 btnez 0000100c +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 \*ABS\* +[0-9a-f]+ <[^>]*> f000 2200 beqz v0,00001010 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 \*ABS\* +[0-9a-f]+ <[^>]*> f000 2a00 bnez v0,00001014 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 \*ABS\* +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-branch-absolute.l b/gas/testsuite/gas/mips/mips16-branch-absolute.l deleted file mode 100644 index c72b8d03b0..0000000000 --- a/gas/testsuite/gas/mips/mips16-branch-absolute.l +++ /dev/null @@ -1,6 +0,0 @@ -.*: Assembler messages: -.*:8: Error: unsupported relocation -.*:9: Error: unsupported relocation -.*:10: Error: unsupported relocation -.*:11: Error: unsupported relocation -.*:12: Error: unsupported relocation diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.d b/gas/testsuite/gas/mips/mips16-branch-addend-2.d index ae9854666d..3e61c24e5e 100644 --- a/gas/testsuite/gas/mips/mips16-branch-addend-2.d +++ b/gas/testsuite/gas/mips/mips16-branch-addend-2.d @@ -1,3 +1,22 @@ +#objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS16 branch relocation with addend 2 #as: -32 -#error-output: mips16-branch-addend-2.l + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f101 1018 b 00002234 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 6018 bteqz 00002238 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 6118 btnez 0000223c +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 2218 beqz v0,00002240 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 2a18 bnez v0,00002244 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.l b/gas/testsuite/gas/mips/mips16-branch-addend-2.l deleted file mode 100644 index d30fd62237..0000000000 --- a/gas/testsuite/gas/mips/mips16-branch-addend-2.l +++ /dev/null @@ -1,6 +0,0 @@ -.*: Assembler messages: -.*:9: Error: unsupported relocation -.*:10: Error: unsupported relocation -.*:11: Error: unsupported relocation -.*:12: Error: unsupported relocation -.*:13: Error: unsupported relocation diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-2.s b/gas/testsuite/gas/mips/mips16-branch-addend-2.s index fe9e5b8aa5..6035db89be 100644 --- a/gas/testsuite/gas/mips/mips16-branch-addend-2.s +++ b/gas/testsuite/gas/mips/mips16-branch-addend-2.s @@ -26,6 +26,8 @@ bar: .set nomips16 .end bar + .space 0x1000 + # Force some (non-delay-slot) zero bytes, to make 'objdump' print ... .align 4, 0 .space 16 diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-3.d b/gas/testsuite/gas/mips/mips16-branch-addend-3.d index 165e8f1e7e..f3ecb7516d 100644 --- a/gas/testsuite/gas/mips/mips16-branch-addend-3.d +++ b/gas/testsuite/gas/mips/mips16-branch-addend-3.d @@ -1,3 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS16 branch relocation with addend 3 #as: -32 -#error-output: mips16-branch-reloc-3.l + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f101 1018 b 00002234 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 6018 bteqz 00002238 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 6118 btnez 0000223c +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 2218 beqz v0,00002240 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f101 2a18 bnez v0,00002244 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-branch-addend-3.l b/gas/testsuite/gas/mips/mips16-branch-addend-3.l deleted file mode 100644 index c72b8d03b0..0000000000 --- a/gas/testsuite/gas/mips/mips16-branch-addend-3.l +++ /dev/null @@ -1,6 +0,0 @@ -.*: Assembler messages: -.*:8: Error: unsupported relocation -.*:9: Error: unsupported relocation -.*:10: Error: unsupported relocation -.*:11: Error: unsupported relocation -.*:12: Error: unsupported relocation diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-2.d b/gas/testsuite/gas/mips/mips16-branch-reloc-2.d index 1e6ecb4b20..4f920d203c 100644 --- a/gas/testsuite/gas/mips/mips16-branch-reloc-2.d +++ b/gas/testsuite/gas/mips/mips16-branch-reloc-2.d @@ -1,3 +1,22 @@ +#objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS16 branch relocation 2 #as: -32 -#error-output: mips16-branch-reloc-2.l + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f7ff 101e b 00001000 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 601e bteqz 00001004 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 611e btnez 00001008 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 221e beqz v0,0000100c +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 2a1e bnez v0,00001010 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-2.l b/gas/testsuite/gas/mips/mips16-branch-reloc-2.l deleted file mode 100644 index d30fd62237..0000000000 --- a/gas/testsuite/gas/mips/mips16-branch-reloc-2.l +++ /dev/null @@ -1,6 +0,0 @@ -.*: Assembler messages: -.*:9: Error: unsupported relocation -.*:10: Error: unsupported relocation -.*:11: Error: unsupported relocation -.*:12: Error: unsupported relocation -.*:13: Error: unsupported relocation diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-3.d b/gas/testsuite/gas/mips/mips16-branch-reloc-3.d index d25d42e362..c8e75fba22 100644 --- a/gas/testsuite/gas/mips/mips16-branch-reloc-3.d +++ b/gas/testsuite/gas/mips/mips16-branch-reloc-3.d @@ -1,3 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS16 branch relocation 3 #as: -32 -#error-output: mips16-branch-reloc-3.l + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f7ff 101e b 00001000 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 601e bteqz 00001004 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 611e btnez 00001008 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 221e beqz v0,0000100c +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> f7ff 2a1e bnez v0,00001010 +[ ]*[0-9a-f]+: R_MIPS16_PC16_S1 bar +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-branch-reloc-3.l b/gas/testsuite/gas/mips/mips16-branch-reloc-3.l deleted file mode 100644 index c72b8d03b0..0000000000 --- a/gas/testsuite/gas/mips/mips16-branch-reloc-3.l +++ /dev/null @@ -1,6 +0,0 @@ -.*: Assembler messages: -.*:8: Error: unsupported relocation -.*:9: Error: unsupported relocation -.*:10: Error: unsupported relocation -.*:11: Error: unsupported relocation -.*:12: Error: unsupported relocation diff --git a/include/ChangeLog b/include/ChangeLog index ecfac71641..ad63599b0b 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2016-06-28 Maciej W. Rozycki + + * elf/mips.h (R_MIPS16_PC16_S1): New relocation. + 2016-06-25 Trevor Saunders * elf/xtensa.h (xtensa_make_property_section): New prototype. diff --git a/include/elf/mips.h b/include/elf/mips.h index d6fd808cbe..7e813de828 100644 --- a/include/elf/mips.h +++ b/include/elf/mips.h @@ -114,7 +114,8 @@ START_RELOC_NUMBERS (elf_mips_reloc_type) RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110) RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111) RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112) - FAKE_RELOC (R_MIPS16_max, 113) + RELOC_NUMBER (R_MIPS16_PC16_S1, 113) + FAKE_RELOC (R_MIPS16_max, 114) /* These relocations are specific to VxWorks. */ RELOC_NUMBER (R_MIPS_COPY, 126) RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127) diff --git a/ld/ChangeLog b/ld/ChangeLog index c1b7f45c03..be31872c04 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2016-06-28 Maciej W. Rozycki + + * testsuite/ld-mips-elf/mips16-branch-2.d: New test. + * testsuite/ld-mips-elf/mips16-branch-3.d: New test. + * testsuite/ld-mips-elf/mips16-branch-addend-2.d: New test. + * testsuite/ld-mips-elf/mips16-branch-addend-3.d: New test. + * testsuite/ld-mips-elf/mips16-branch.s: New test source. + * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. + 2016-06-27 Nick Clifton PR ld/20302 diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index 8fb55e48ba..0d5842ffcf 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -143,6 +143,11 @@ run_dump_test "mips16-1" # MIPS branch offset final link checking. run_dump_test "branch-misc-1" +run_dump_test "mips16-branch-2" [list [list ld $abi_ldflags(o32)]] +run_dump_test "mips16-branch-3" [list [list ld $abi_ldflags(o32)]] +run_dump_test "mips16-branch-addend-2" [list [list ld $abi_ldflags(o32)]] +run_dump_test "mips16-branch-addend-3" [list [list ld $abi_ldflags(o32)]] + # Jalx test run_dump_test "jalx-1" diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-2.d b/ld/testsuite/ld-mips-elf/mips16-branch-2.d new file mode 100644 index 0000000000..95287334a2 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/mips16-branch-2.d @@ -0,0 +1,19 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 link branch 2 +#source: ../../../gas/testsuite/gas/mips/mips16-branch-reloc-2.s +#as: -EB -32 +#ld: -EB -Ttext 0x1c000000 -e bar + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f000 1016 b 1c001030 +[0-9a-f]+ <[^>]*> f000 6014 bteqz 1c001030 +[0-9a-f]+ <[^>]*> f000 6112 btnez 1c001030 +[0-9a-f]+ <[^>]*> f000 2210 beqz v0,1c001030 +[0-9a-f]+ <[^>]*> f000 2a0e bnez v0,1c001030 +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-3.d b/ld/testsuite/ld-mips-elf/mips16-branch-3.d new file mode 100644 index 0000000000..88918c1a93 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/mips16-branch-3.d @@ -0,0 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 link branch 3 +#source: mips16-branch.s +#source: ../../../gas/testsuite/gas/mips/mips16-branch-reloc-3.s +#as: -EB -32 +#ld: -EB -Ttext 0x1c000000 -e bar + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> f7fe 100e b 1c001000 +[0-9a-f]+ <[^>]*> f7fe 600c bteqz 1c001000 +[0-9a-f]+ <[^>]*> f7fe 610a btnez 1c001000 +[0-9a-f]+ <[^>]*> f7fe 2208 beqz v0,1c001000 +[0-9a-f]+ <[^>]*> f7fe 2a06 bnez v0,1c001000 +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d b/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d new file mode 100644 index 0000000000..c724bddbe2 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/mips16-branch-addend-2.d @@ -0,0 +1,19 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 link branch addend 2 +#source: ../../../gas/testsuite/gas/mips/mips16-branch-addend-2.s +#as: -EB -32 +#ld: -EB -Ttext 0x1c000000 -e bar + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> f121 1010 b 1c002264 +[0-9a-f]+ <[^>]*> f121 600e bteqz 1c002264 +[0-9a-f]+ <[^>]*> f121 610c btnez 1c002264 +[0-9a-f]+ <[^>]*> f121 220a beqz v0,1c002264 +[0-9a-f]+ <[^>]*> f121 2a08 bnez v0,1c002264 +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d b/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d new file mode 100644 index 0000000000..84bccc7817 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/mips16-branch-addend-3.d @@ -0,0 +1,20 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#name: MIPS16 link branch addend 3 +#source: mips16-branch.s +#source: ../../../gas/testsuite/gas/mips/mips16-branch-addend-3.s +#as: -EB -32 +#ld: -EB -Ttext 0x1c000000 -e bar + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. +[0-9a-f]+ <[^>]*> f100 1008 b 1c002234 +[0-9a-f]+ <[^>]*> f100 6006 bteqz 1c002234 +[0-9a-f]+ <[^>]*> f100 6104 btnez 1c002234 +[0-9a-f]+ <[^>]*> f100 2202 beqz v0,1c002234 +[0-9a-f]+ <[^>]*> f100 2a00 bnez v0,1c002234 +[0-9a-f]+ <[^>]*> 6500 nop + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/mips16-branch.s b/ld/testsuite/ld-mips-elf/mips16-branch.s new file mode 100644 index 0000000000..0024cdd5fc --- /dev/null +++ b/ld/testsuite/ld-mips-elf/mips16-branch.s @@ -0,0 +1,15 @@ + .text + .globl bar + + .space 0x1000 + + .ent bar + .set mips16 +bar: + nop + .set nomips16 + .end bar + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16