diff options
author | Thiemo Seufer <ths@networkno.de> | 2001-09-07 05:00:37 +0000 |
---|---|---|
committer | Thiemo Seufer <ths@networkno.de> | 2001-09-07 05:00:37 +0000 |
commit | cb56d3d327dc7fd17dbc3e3f95131cb6b312f18e (patch) | |
tree | 35b652e23a7ce84c43b26d953323437cd503d94d /gas/config | |
parent | c0a1a2e89b45a2eff4279723544ed4fd69d5cbdf (diff) | |
download | gdb-cb56d3d327dc7fd17dbc3e3f95131cb6b312f18e.zip gdb-cb56d3d327dc7fd17dbc3e3f95131cb6b312f18e.tar.gz gdb-cb56d3d327dc7fd17dbc3e3f95131cb6b312f18e.tar.bz2 |
* 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.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-mips.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 8057de9..c301767 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 |