From: Thiemo Seufer Date: Fri, 7 Sep 2001 05:00:37 +0000 (+0000) Subject: * elf32-mips.c (mips_elf_calculate_relocation): Fix overflow handling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb56d3d327dc7fd17dbc3e3f95131cb6b312f18e;p=binutils-gdb.git * elf32-mips.c (mips_elf_calculate_relocation): Fix overflow handling of R_MIPS_PC16. * config/tc-mips.c (append_insn): Handle BFD_RELOC_16_PCREL. (macro_build): Use BFD_RELOC_16_PCREL_S2 only for embedded PIC, BFD_RELOC_16_PCREL for the rest. (mips_ip): Likewise. (md_pcrel_from): return the right offset for the differently shifted pcrel relocs. (md_apply_fix): Handle BFD_RELOC_16_PCREL. * gas/mips/beq.d: Check branches to external labels. * gas/mips/beq.s: Likewise. * gas/mips/bge.d: Likewise. * gas/mips/bge.s: Likewise. * gas/mips/bgeu.d: Likewise. * gas/mips/bgeu.s: Likewise. * gas/mips/blt.d: Likewise. * gas/mips/blt.s: Likewise. * gas/mips/bltu.d: Likewise. * gas/mips/bltu.s: Likewise. * gas/mips/elempic.d: Switch from R_MIPS_GNU_REL16_S2 to R_MIPS_PC16. * gas/mips/empic.d: Likewise. * gas/mips/empic.s: Likewise. * gas/mips/telempic.d: Likewise. * gas/mips/tempic.d: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 86fff1a6163..5f9e0a0d198 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2001-09-07 Thiemo Seufer + + * elf32-mips.c (mips_elf_calculate_relocation): Fix overflow handling + of R_MIPS_PC16. + 2001-09-06 Thiemo Seufer * elf64-mips.c (mips_elf64_howto_table_rel): Fix relocation HOWTO diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 9ba61f0be6f..935f4fbd52c 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -6480,8 +6480,8 @@ mips_elf_calculate_relocation (abfd, case R_MIPS_PC16: value = mips_elf_sign_extend (addend, 16) + symbol - p; - value = (bfd_vma) ((bfd_signed_vma) value / 4); overflowed_p = mips_elf_overflow_p (value, 16); + value = (bfd_vma) ((bfd_signed_vma) value / 4); break; case R_MIPS_GOT_HI16: diff --git a/gas/ChangeLog b/gas/ChangeLog index 7d4ba161312..18a62f01283 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2001-09-07 Thiemo Seufer + + * config/tc-mips.c (append_insn): Handle BFD_RELOC_16_PCREL. + (macro_build): Use BFD_RELOC_16_PCREL_S2 only for embedded + PIC, BFD_RELOC_16_PCREL for the rest. + (mips_ip): Likewise. + (md_pcrel_from): return the right offset for the differently shifted + pcrel relocs. + (md_apply_fix): Handle BFD_RELOC_16_PCREL. + 2001-09-05 Richard Henderson * config/tc-ia64.c (FUNC_IPLT_RELOC): New. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 8057de9e6c8..c30176754d1 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1898,6 +1898,10 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) | ((address_expr->X_add_number & 0x3fffc) >> 2)); break; + case BFD_RELOC_16_PCREL: + ip->insn_opcode |= (address_expr->X_add_number >> 2) & 0xffff; + break; + case BFD_RELOC_16_PCREL_S2: goto need_reloc; @@ -1914,7 +1918,8 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) { fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4, address_expr, - reloc_type == BFD_RELOC_16_PCREL_S2, + (reloc_type == BFD_RELOC_16_PCREL + || reloc_type == BFD_RELOC_16_PCREL_S2), reloc_type); if (unmatched_hi) { @@ -2699,7 +2704,10 @@ macro_build (place, counter, ep, name, fmt, va_alist) ep = NULL; } else - r = BFD_RELOC_16_PCREL_S2; + if (mips_pic == EMBEDDED_PIC) + r = BFD_RELOC_16_PCREL_S2; + else + r = BFD_RELOC_16_PCREL; continue; case 'a': @@ -7796,7 +7804,10 @@ mips_ip (str, ip) continue; case 'p': /* pc relative offset */ - offset_reloc = BFD_RELOC_16_PCREL_S2; + if (mips_pic == EMBEDDED_PIC) + offset_reloc = BFD_RELOC_16_PCREL_S2; + else + offset_reloc = BFD_RELOC_16_PCREL; my_getExpression (&offset_expr, s); s = expr_end; continue; @@ -9426,9 +9437,16 @@ md_pcrel_from (fixP) && fixP->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixP->fx_addsy)) { - /* This makes a branch to an undefined symbol be a branch to the - current location. */ - return 4; + if (mips_pic == EMBEDDED_PIC) + { + /* This makes a branch to an undefined symbol be a branch to the + current location. */ + return 4; + } + else + { + return 1; + } } /* return the address of the delay slot */ @@ -9665,7 +9683,8 @@ md_apply_fix (fixP, valueP) /* BFD's REL handling, for MIPS, is _very_ weird. This gives the right results, but it can't possibly be the way things are supposed to work. */ - if (fixP->fx_r_type != BFD_RELOC_16_PCREL_S2 + if ((fixP->fx_r_type != BFD_RELOC_16_PCREL + && fixP->fx_r_type != BFD_RELOC_16_PCREL_S2) || S_GET_SEGMENT (fixP->fx_addsy) != undefined_section) value += fixP->fx_frag->fr_address + fixP->fx_where; } @@ -9811,15 +9830,18 @@ md_apply_fix (fixP, valueP) break; case BFD_RELOC_16_PCREL_S2: + if ((value & 0x3) != 0) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("Branch to odd address (%lx)"), (long) value); + + /* Fall through. */ + + case BFD_RELOC_16_PCREL: /* * We need to save the bits in the instruction since fixup_segment() * might be deleting the relocation entry (i.e., a branch within * the current segment). */ - if ((value & 0x3) != 0) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("Branch to odd address (%lx)"), (long) value); - if (!fixP->fx_done && value != 0) break; /* If 'value' is zero, the remaining reloc code won't actually diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index f0422b09e20..a037123ffae 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2001-09-07 Thiemo Seufer + + * gas/mips/beq.d: Check branches to external labels. + * gas/mips/beq.s: Likewise. + * gas/mips/bge.d: Likewise. + * gas/mips/bge.s: Likewise. + * gas/mips/bgeu.d: Likewise. + * gas/mips/bgeu.s: Likewise. + * gas/mips/blt.d: Likewise. + * gas/mips/blt.s: Likewise. + * gas/mips/bltu.d: Likewise. + * gas/mips/bltu.s: Likewise. + * gas/mips/elempic.d: Switch from R_MIPS_GNU_REL16_S2 to R_MIPS_PC16. + * gas/mips/empic.d: Likewise. + * gas/mips/empic.s: Likewise. + * gas/mips/telempic.d: Likewise. + * gas/mips/tempic.d: Likewise. + 2001-09-06 Thiemo Seufer * gas/mips/tmips16-f.d: New file, testcase for big endian MIPS16 diff --git a/gas/testsuite/gas/mips/beq.d b/gas/testsuite/gas/mips/beq.d index 2fa90f51785..9eb24345e4c 100644 --- a/gas/testsuite/gas/mips/beq.d +++ b/gas/testsuite/gas/mips/beq.d @@ -37,4 +37,10 @@ Disassembly of section .text: 0+2006c <[^>]*> nop 0+20070 <[^>]*> jal 0+0000 [ ]*20070: (MIPS_JMP|JMPADDR|R_MIPS_26) .text +0+20074 <[^>]*> nop +0+20078 <[^>]*> b 0+20078 +[ ]*20078: R_MIPS_PC16 external_label +0+2007c <[^>]*> nop +0+20080 <[^>]*> bal 0+20080 +[ ]*20080: R_MIPS_PC16 external_label ... diff --git a/gas/testsuite/gas/mips/beq.s b/gas/testsuite/gas/mips/beq.s index 9922eecb279..5567f021034 100644 --- a/gas/testsuite/gas/mips/beq.s +++ b/gas/testsuite/gas/mips/beq.s @@ -22,7 +22,9 @@ text_label: b text_label bal text_label +# Branch to an external label. + b external_label + bal external_label + # Round to a 16 byte boundary, for ease in testing multiple targets. nop - nop - nop diff --git a/gas/testsuite/gas/mips/bge.d b/gas/testsuite/gas/mips/bge.d index 387fd3440b2..8ade2ad6143 100644 --- a/gas/testsuite/gas/mips/bge.d +++ b/gas/testsuite/gas/mips/bge.d @@ -50,4 +50,20 @@ Disassembly of section .text: 0+00a4 <[^>]*> nop 0+00a8 <[^>]*> slt at,a1,a0 0+00ac <[^>]*> bnezl at,0+0000 +0+00b0 <[^>]*> nop +0+00b4 <[^>]*> slt at,a0,a1 +0+00b8 <[^>]*> beqz at,000000b8 +[ ]*b8: R_MIPS_PC16 external_label +0+00bc <[^>]*> nop +0+00c0 <[^>]*> slt at,a1,a0 +0+00c4 <[^>]*> bnez at,000000c4 +[ ]*c4: R_MIPS_PC16 external_label +0+00c8 <[^>]*> nop +0+00cc <[^>]*> slt at,a0,a1 +0+00d0 <[^>]*> beqzl at,000000d0 +[ ]*d0: R_MIPS_PC16 external_label +0+00d4 <[^>]*> nop +0+00d8 <[^>]*> slt at,a1,a0 +0+00dc <[^>]*> bnezl at,000000dc +[ ]*dc: R_MIPS_PC16 external_label ... diff --git a/gas/testsuite/gas/mips/bge.s b/gas/testsuite/gas/mips/bge.s index 405fd82b2b7..4b4e58f6d69 100644 --- a/gas/testsuite/gas/mips/bge.s +++ b/gas/testsuite/gas/mips/bge.s @@ -24,6 +24,12 @@ text_label: bgel $4,$5,text_label bgtl $4,$5,text_label +# Branch to an external label. + bge $4,$5,external_label + bgt $4,$5,external_label + bgel $4,$5,external_label + bgtl $4,$5,external_label + # Round to a 16 byte boundary, for ease in testing multiple targets. nop nop diff --git a/gas/testsuite/gas/mips/bgeu.d b/gas/testsuite/gas/mips/bgeu.d index 8f2bfa7c4c1..49d11303ca4 100644 --- a/gas/testsuite/gas/mips/bgeu.d +++ b/gas/testsuite/gas/mips/bgeu.d @@ -44,4 +44,20 @@ Disassembly of section .text: 0+008c <[^>]*> nop 0+0090 <[^>]*> sltu at,a1,a0 0+0094 <[^>]*> bnezl at,0+0000 +0+0098 <[^>]*> nop +0+009c <[^>]*> sltu at,a0,a1 +0+00a0 <[^>]*> beqz at,000000a0 +[ ]*a0: R_MIPS_PC16 external_label +0+00a4 <[^>]*> nop +0+00a8 <[^>]*> sltu at,a1,a0 +0+00ac <[^>]*> bnez at,000000ac +[ ]*ac: R_MIPS_PC16 external_label +0+00b0 <[^>]*> nop +0+00b4 <[^>]*> sltu at,a0,a1 +0+00b8 <[^>]*> beqzl at,000000b8 +[ ]*b8: R_MIPS_PC16 external_label +0+00bc <[^>]*> nop +0+00c0 <[^>]*> sltu at,a1,a0 +0+00c4 <[^>]*> bnezl at,000000c4 +[ ]*c4: R_MIPS_PC16 external_label ... diff --git a/gas/testsuite/gas/mips/bgeu.s b/gas/testsuite/gas/mips/bgeu.s index 1c37f96939c..cccd584f780 100644 --- a/gas/testsuite/gas/mips/bgeu.s +++ b/gas/testsuite/gas/mips/bgeu.s @@ -22,6 +22,12 @@ text_label: bgeul $4,$5,text_label bgtul $4,$5,text_label +# Branch to an external label. + bgeu $4,$5,external_label + bgtu $4,$5,external_label + bgeul $4,$5,external_label + bgtul $4,$5,external_label + # Round to a 16 byte boundary, for ease in testing multiple targets. nop nop diff --git a/gas/testsuite/gas/mips/blt.d b/gas/testsuite/gas/mips/blt.d index 3423cdf1ec5..d7670c0fdd3 100644 --- a/gas/testsuite/gas/mips/blt.d +++ b/gas/testsuite/gas/mips/blt.d @@ -50,4 +50,20 @@ Disassembly of section .text: 0+00a4 <[^>]*> nop 0+00a8 <[^>]*> slt at,a1,a0 0+00ac <[^>]*> beqzl at,0+0000 +0+00b0 <[^>]*> nop +0+00b4 <[^>]*> slt at,a0,a1 +0+00b8 <[^>]*> bnez at,000000b8 +[ ]*b8: R_MIPS_PC16 external_label +0+00bc <[^>]*> nop +0+00c0 <[^>]*> slt at,a1,a0 +0+00c4 <[^>]*> beqz at,000000c4 +[ ]*c4: R_MIPS_PC16 external_label +0+00c8 <[^>]*> nop +0+00cc <[^>]*> slt at,a0,a1 +0+00d0 <[^>]*> bnezl at,000000d0 +[ ]*d0: R_MIPS_PC16 external_label +0+00d4 <[^>]*> nop +0+00d8 <[^>]*> slt at,a1,a0 +0+00dc <[^>]*> beqzl at,000000dc +[ ]*dc: R_MIPS_PC16 external_label ... diff --git a/gas/testsuite/gas/mips/blt.s b/gas/testsuite/gas/mips/blt.s index 000305696dd..9b2ed08524f 100644 --- a/gas/testsuite/gas/mips/blt.s +++ b/gas/testsuite/gas/mips/blt.s @@ -24,6 +24,12 @@ text_label: bltl $4,$5,text_label blel $4,$5,text_label +# Branch to an external label. + blt $4,$5,external_label + ble $4,$5,external_label + bltl $4,$5,external_label + blel $4,$5,external_label + # Round to a 16 byte boundary, for ease in testing multiple targets. nop nop diff --git a/gas/testsuite/gas/mips/bltu.d b/gas/testsuite/gas/mips/bltu.d index 63dcd1794c0..0e2a644fc43 100644 --- a/gas/testsuite/gas/mips/bltu.d +++ b/gas/testsuite/gas/mips/bltu.d @@ -44,4 +44,20 @@ Disassembly of section .text: 0+008c <[^>]*> nop 0+0090 <[^>]*> sltu at,a1,a0 0+0094 <[^>]*> beqzl at,0+0000 +0+0098 <[^>]*> nop +0+009c <[^>]*> sltu at,a0,a1 +0+00a0 <[^>]*> bnez at,000000a0 +[ ]*a0: R_MIPS_PC16 external_label +0+00a4 <[^>]*> nop +0+00a8 <[^>]*> sltu at,a1,a0 +0+00ac <[^>]*> beqz at,000000ac +[ ]*ac: R_MIPS_PC16 external_label +0+00b0 <[^>]*> nop +0+00b4 <[^>]*> sltu at,a0,a1 +0+00b8 <[^>]*> bnezl at,000000b8 +[ ]*b8: R_MIPS_PC16 external_label +0+00bc <[^>]*> nop +0+00c0 <[^>]*> sltu at,a1,a0 +0+00c4 <[^>]*> beqzl at,000000c4 +[ ]*c4: R_MIPS_PC16 external_label ... diff --git a/gas/testsuite/gas/mips/bltu.s b/gas/testsuite/gas/mips/bltu.s index 44b1ae629eb..602b7b283d6 100644 --- a/gas/testsuite/gas/mips/bltu.s +++ b/gas/testsuite/gas/mips/bltu.s @@ -22,6 +22,12 @@ text_label: bltul $4,$5,text_label bleul $4,$5,text_label +# Branch to an external label. + bltu $4,$5,external_label + bleu $4,$5,external_label + bltul $4,$5,external_label + bleul $4,$5,external_label + # Round to a 16 byte boundary, for ease in testing multiple targets. nop nop