+Thu Apr 7 14:28:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Pass NULL for expression argument to
+ macro_build for nori case.
+ (SWITCH_TABLE): Define.
+ (mips_force_relocation): Force a relocation for a switch table
+ entry.
+ (md_apply_fix): Write switch table entry value into file.
+ (tc_gen_reloc): Use BFD_RELOC_GPREL32 for a switch table entry,
+ and set the addend to the difference between the reloc address and
+ the subtrahend.
+
Thu Apr 7 10:38:18 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
* config/tc-hppa.h (elf_tc_symbol): Delete. No longer used.
{
macro_build ((char *) NULL, &icnt, &imm_expr, "ori", "t,r,i",
treg, sreg, (int) BFD_RELOC_LO16);
- macro_build ((char *) NULL, &icnt, &imm_expr, "nor", "d,v,t",
+ macro_build ((char *) NULL, &icnt, NULL, "nor", "d,v,t",
treg, treg, 0);
}
return;
nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32);
}
+/* When generating embedded PIC code we need to use a special
+ relocation to represent the difference of two symbols in the .text
+ section (switch tables use a difference of this sort). See
+ include/coff/mips.h for details. This macro checks whether this
+ fixup requires the special reloc. */
+#define SWITCH_TABLE(fixp) \
+ ((fixp)->fx_r_type == BFD_RELOC_32 \
+ && (fixp)->fx_addsy != NULL \
+ && (fixp)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \
+ && S_GET_SEGMENT ((fixp)->fx_subsy) == text_section)
+
/* When generating embedded PIC code we must keep all PC relative
- relocations, in case the linker has to relax a call. */
+ relocations, in case the linker has to relax a call. We also need
+ to keep relocations for switch table entries. */
/*ARGSUSED*/
int
mips_force_relocation (fixp)
fixS *fixp;
{
- return fixp->fx_pcrel && mips_pic == EMBEDDED_PIC;
+ return (mips_pic == EMBEDDED_PIC
+ && (fixp->fx_pcrel || SWITCH_TABLE (fixp)));
}
/* Apply a fixup to the object file. */
case BFD_RELOC_32:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
- resolved when it appears but is later defined. */
- if (fixP->fx_done)
+ resolved when it appears but is later defined. We also need
+ to fill in the value if this is an embedded PIC switch table
+ entry. */
+ if (fixP->fx_done
+ || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))
md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
value, 4);
break;
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
- if (fixp->fx_pcrel == 0)
+
+ if (mips_pic == EMBEDDED_PIC
+ && SWITCH_TABLE (fixp))
+ {
+ /* For a switch table entry we use a special reloc. The addend
+ is actually the difference between the reloc address and the
+ subtrahend. */
+ reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+#ifndef OBJ_ECOFF
+ #error Double check fx_r_type here
+#endif
+ fixp->fx_r_type = BFD_RELOC_GPREL32;
+ }
+ else if (fixp->fx_pcrel == 0)
reloc->addend = fixp->fx_addnumber;
else
{