From 1c803e52238449fd464ae9ceae0d2b7c4f6e9eec Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 7 Apr 1994 18:33:09 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 12 ++++++++++++ gas/config/tc-mips.c | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 1bc9f815f58..8d093338514 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,15 @@ +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. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index b11831651dc..e13d74bdb72 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1789,7 +1789,7 @@ macro (ip) { 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; @@ -5063,15 +5063,29 @@ cons_fix_new_mips (frag, where, nbytes, exp) 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. */ @@ -5108,8 +5122,11 @@ md_apply_fix (fixP, valueP) 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; @@ -5936,7 +5953,20 @@ tc_gen_reloc (section, fixp) 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 { -- 2.30.2