aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-07-08 23:16:00 +0000
committerIan Lance Taylor <ian@airs.com>1996-07-08 23:16:00 +0000
commita8aed9ddfb605496ba1d5d6a5abd2685b48cf314 (patch)
treecdb18d5fde788f4f981869ef8addd19c01fc5df0 /gas/config
parenta5a781751a438e853d0f421909458aa3f75525aa (diff)
downloadgdb-a8aed9ddfb605496ba1d5d6a5abd2685b48cf314.zip
gdb-a8aed9ddfb605496ba1d5d6a5abd2685b48cf314.tar.gz
gdb-a8aed9ddfb605496ba1d5d6a5abd2685b48cf314.tar.bz2
* config/tc-mips.c (mips_regmask_frag): Only define if OBJ_ELF or
OBJ_MAYBE_ELF. (tc_gen_reloc): If fixup was changed to be PC relative, change reloc type accordingly. Use name of reloc in error message.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-mips.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index dbb3a1c..dd2b599 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -70,7 +70,9 @@ static int mips_output_flavor () { return OUTPUT_FLAVOR; }
#include "ecoff.h"
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
static char *mips_regmask_frag;
+#endif
#define AT 1
#define PIC_CALL_REG 25
@@ -5626,8 +5628,9 @@ mips_ip (str, ip)
if (*args == 'i')
{
if ((c == '\0' && imm_expr.X_op != O_constant)
- || imm_expr.X_add_number < 0
- || imm_expr.X_add_number >= 0x10000)
+ || ((imm_expr.X_add_number < 0
+ || imm_expr.X_add_number >= 0x10000)
+ && imm_expr.X_op == O_constant))
{
if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
!strcmp (insn->name, insn[1].name))
@@ -5660,8 +5663,9 @@ mips_ip (str, ip)
else
max = 0x10000;
if ((c == '\0' && imm_expr.X_op != O_constant)
- || imm_expr.X_add_number < -0x8000
- || imm_expr.X_add_number >= max
+ || ((imm_expr.X_add_number < -0x8000
+ || imm_expr.X_add_number >= max)
+ && imm_expr.X_op == O_constant)
|| (more
&& imm_expr.X_add_number < 0
&& mips_isa >= 3
@@ -7512,6 +7516,7 @@ tc_gen_reloc (section, fixp)
{
static arelent *retval[4];
arelent *reloc;
+ bfd_reloc_code_real_type code;
reloc = retval[0] = (arelent *) xmalloc (sizeof (arelent));
retval[1] = NULL;
@@ -7644,20 +7649,51 @@ tc_gen_reloc (section, fixp)
abort ();
}
+ /* Since DIFF_EXPR_OK is defined in tc-mips.h, it is possible that
+ fixup_segment converted a non-PC relative reloc into a PC
+ relative reloc. In such a case, we need to convert the reloc
+ code. */
+ code = fixp->fx_r_type;
+ if (fixp->fx_pcrel)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ code = BFD_RELOC_8_PCREL;
+ break;
+ case BFD_RELOC_16:
+ code = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_32:
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_16_PCREL_S2:
+ break;
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Cannot make %s relocation PC relative",
+ bfd_get_reloc_code_name (code));
+ }
+ }
+
/* To support a PC relative reloc when generating embedded PIC code
for ECOFF, we use a Cygnus extension. We check for that here to
make sure that we don't let such a reloc escape normally. */
if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
- && fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
+ && code == BFD_RELOC_16_PCREL_S2
&& mips_pic != EMBEDDED_PIC)
reloc->howto = NULL;
else
- reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
if (reloc->howto == NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
- "Can not represent relocation in this object file format");
+ "Can not represent %s relocation in this object file format",
+ bfd_get_reloc_code_name (code));
retval[0] = NULL;
}