}
else
{
- reloc_howto_type *howto;
-
need_reloc:
/* Don't generate a reloc if we are writing into a variant frag. */
if (place == NULL)
{
- howto = bfd_reloc_type_lookup (stdoutput, reloc_type[0]);
+ reloc_howto_type *howto;
+ int i;
+
+ /* In a compound relocation, it is the final (outermost)
+ operator that determines the relocated field. */
+ for (i = 1; i < 3; i++)
+ if (reloc_type[i] == BFD_RELOC_UNUSED)
+ break;
+
+ howto = bfd_reloc_type_lookup (stdoutput, reloc_type[i - 1]);
fixp[0] = fix_new_exp (frag_now, f - frag_now->fr_literal,
bfd_get_reloc_size(howto),
address_expr,
hi_fixup->seg = now_seg;
}
- if (reloc_type[1] != BFD_RELOC_UNUSED)
- {
- /* FIXME: This symbol can be one of
- RSS_UNDEF, RSS_GP, RSS_GP0, RSS_LOC. */
- address_expr->X_op = O_absent;
- address_expr->X_add_symbol = 0;
- address_expr->X_add_number = 0;
-
- howto = bfd_reloc_type_lookup (stdoutput, reloc_type[1]);
- fixp[1] = fix_new_exp (frag_now, f - frag_now->fr_literal,
- bfd_get_reloc_size(howto),
- address_expr, FALSE, reloc_type[1]);
-
- /* These relocations can have an addend that won't fit in
- 4 octets for 64bit assembly. */
- if (HAVE_64BIT_GPRS
- && ! howto->partial_inplace
- && (reloc_type[1] == BFD_RELOC_16
- || reloc_type[1] == BFD_RELOC_32
- || reloc_type[1] == BFD_RELOC_MIPS_JMP
- || reloc_type[1] == BFD_RELOC_HI16_S
- || reloc_type[1] == BFD_RELOC_LO16
- || reloc_type[1] == BFD_RELOC_GPREL16
- || reloc_type[1] == BFD_RELOC_MIPS_LITERAL
- || reloc_type[1] == BFD_RELOC_GPREL32
- || reloc_type[1] == BFD_RELOC_64
- || reloc_type[1] == BFD_RELOC_CTOR
- || reloc_type[1] == BFD_RELOC_MIPS_SUB
- || reloc_type[1] == BFD_RELOC_MIPS_HIGHEST
- || reloc_type[1] == BFD_RELOC_MIPS_HIGHER
- || reloc_type[1] == BFD_RELOC_MIPS_SCN_DISP
- || reloc_type[1] == BFD_RELOC_MIPS_REL16
- || reloc_type[1] == BFD_RELOC_MIPS_RELGOT))
- fixp[1]->fx_no_overflow = 1;
-
- if (reloc_type[2] != BFD_RELOC_UNUSED)
- {
- address_expr->X_op = O_absent;
- address_expr->X_add_symbol = 0;
- address_expr->X_add_number = 0;
-
- howto = bfd_reloc_type_lookup (stdoutput, reloc_type[2]);
- fixp[2] = fix_new_exp (frag_now,
- f - frag_now->fr_literal,
- bfd_get_reloc_size(howto),
- address_expr, FALSE,
- reloc_type[2]);
-
- /* These relocations can have an addend that won't fit in
- 4 octets for 64bit assembly. */
- if (HAVE_64BIT_GPRS
- && ! howto->partial_inplace
- && (reloc_type[2] == BFD_RELOC_16
- || reloc_type[2] == BFD_RELOC_32
- || reloc_type[2] == BFD_RELOC_MIPS_JMP
- || reloc_type[2] == BFD_RELOC_HI16_S
- || reloc_type[2] == BFD_RELOC_LO16
- || reloc_type[2] == BFD_RELOC_GPREL16
- || reloc_type[2] == BFD_RELOC_MIPS_LITERAL
- || reloc_type[2] == BFD_RELOC_GPREL32
- || reloc_type[2] == BFD_RELOC_64
- || reloc_type[2] == BFD_RELOC_CTOR
- || reloc_type[2] == BFD_RELOC_MIPS_SUB
- || reloc_type[2] == BFD_RELOC_MIPS_HIGHEST
- || reloc_type[2] == BFD_RELOC_MIPS_HIGHER
- || reloc_type[2] == BFD_RELOC_MIPS_SCN_DISP
- || reloc_type[2] == BFD_RELOC_MIPS_REL16
- || reloc_type[2] == BFD_RELOC_MIPS_RELGOT))
- fixp[2]->fx_no_overflow = 1;
- }
- }
+ /* Add fixups for the second and third relocations, if given.
+ Note that the ABI allows the second relocation to be
+ against RSS_UNDEF, RSS_GP, RSS_GP0 or RSS_LOC. At the
+ moment we only use RSS_UNDEF, but we could add support
+ for the others if it ever becomes necessary. */
+ for (i = 1; i < 3; i++)
+ if (reloc_type[i] != BFD_RELOC_UNUSED)
+ {
+ address_expr->X_op = O_absent;
+ address_expr->X_add_symbol = 0;
+ address_expr->X_add_number = 0;
+
+ fixp[i] = fix_new_exp (frag_now, fixp[0]->fx_where,
+ fixp[0]->fx_size, address_expr,
+ FALSE, reloc_type[i]);
+ }
}
}
}