aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorThiemo Seufer <ths@networkno.de>2001-09-07 05:00:37 +0000
committerThiemo Seufer <ths@networkno.de>2001-09-07 05:00:37 +0000
commitcb56d3d327dc7fd17dbc3e3f95131cb6b312f18e (patch)
tree35b652e23a7ce84c43b26d953323437cd503d94d /gas/config
parentc0a1a2e89b45a2eff4279723544ed4fd69d5cbdf (diff)
downloadgdb-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.c44
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