Mon Feb 12 15:16:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
authorIan Lance Taylor <ian@airs.com>
Mon, 12 Feb 1996 20:33:06 +0000 (20:33 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 12 Feb 1996 20:33:06 +0000 (20:33 +0000)
Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
* config/m68k-parse.h (enum pic_relocation): Define.
(struct m68k_exp): Add pic_reloc field.
* config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
(tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
(NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
otherwise.
* config/tc-m68k.c: Delete definition of NO_RELOC.
  (struct m68k_it): Add pic_reloc field.
(add_fix): Copy over pic_reloc field.
(md_pseudo_table): Interpret .align parameter as byte count.
(mote_pseudo_table): Likewise.
(tc_m68k_fix_adjustable): New function.
(get_reloc_code): New function.
(md_assemble): Use it as last argument to fix_new_exp.
(md_apply_fix_2): For a relocation against a symbol don't put the
addend into the data.
(tc_gen_reloc): Different addend computation for OBJ_ELF.
(m68k_ip): Don't relax an operand that requires pic relocation.
(md_begin): Align .text, .data and .bss on 4 byte boundary by
default.
* write.c (fixup_segment): Don't add symbol value to addend if
  TC_M68K and OBJ_ELF.
* config/m68k-parse.y (yylex): Handle @PLTPC, etc.
(motorola_operand): Add rule for `(zapc, EXPR)'.

gas/ChangeLog
gas/config/tc-m68k.c
gas/config/tc-m68k.h
gas/write.c

index 4452b4b083f27d124c094c7e5c79045a3f15fe71..cd321d55ed44b6e5701e2adc1966bf8eaeb61bbe 100644 (file)
@@ -1,3 +1,31 @@
+Mon Feb 12 15:16:29 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
+       * config/m68k-parse.h (enum pic_relocation): Define.
+       (struct m68k_exp): Add pic_reloc field.
+       * config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+       (tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
+       (NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
+       otherwise.
+       * config/tc-m68k.c: Delete definition of NO_RELOC.
+       (struct m68k_it): Add pic_reloc field.
+       (add_fix): Copy over pic_reloc field.
+       (md_pseudo_table): Interpret .align parameter as byte count.
+       (mote_pseudo_table): Likewise.
+       (tc_m68k_fix_adjustable): New function.
+       (get_reloc_code): New function.
+       (md_assemble): Use it as last argument to fix_new_exp.
+       (md_apply_fix_2): For a relocation against a symbol don't put the
+       addend into the data.
+       (tc_gen_reloc): Different addend computation for OBJ_ELF.
+       (m68k_ip): Don't relax an operand that requires pic relocation.
+       (md_begin): Align .text, .data and .bss on 4 byte boundary by
+       default.
+       * write.c (fixup_segment): Don't add symbol value to addend if
+       TC_M68K and OBJ_ELF.
+       * config/m68k-parse.y (yylex): Handle @PLTPC, etc.
+       (motorola_operand): Add rule for `(zapc, EXPR)'.
+
 Mon Feb 12 10:07:33 1996  David Mosberger-Tang  <davidm@azstarnet.com>
 
        * ecoff.c (ecoff_directive_weakext): Fixed so that whitespace
 Mon Feb 12 10:07:33 1996  David Mosberger-Tang  <davidm@azstarnet.com>
 
        * ecoff.c (ecoff_directive_weakext): Fixed so that whitespace
index fe6c9bd0c7dc0e2bd2a43c65eb2791cf258006ff..8b3128363e1358ff17a4d9ff788893e5acc8e987 100644 (file)
@@ -19,7 +19,6 @@
    02111-1307, USA.  */
 
 #include <ctype.h>
    02111-1307, USA.  */
 
 #include <ctype.h>
-#define  NO_RELOC 0
 #include "as.h"
 #include "obstack.h"
 #include "subsegs.h"
 #include "as.h"
 #include "obstack.h"
 #include "subsegs.h"
@@ -62,7 +61,8 @@ const int md_reloc_size = 8;  /* Size of relocation record */
 
 /* Are we trying to generate PIC code?  If so, absolute references
    ought to be made into linkage table references or pc-relative
 
 /* Are we trying to generate PIC code?  If so, absolute references
    ought to be made into linkage table references or pc-relative
-   references.  */
+   references.  Not implemented.  For ELF there are other means 
+   to denote pic relocations.  */
 int flag_want_pic;
 
 static int flag_short_refs;    /* -l option */
 int flag_want_pic;
 
 static int flag_short_refs;    /* -l option */
@@ -199,6 +199,11 @@ struct m68k_it
         significance of some values (in the branch instruction, for
         example).  */
       int pcrel_fix;
         significance of some values (in the branch instruction, for
         example).  */
       int pcrel_fix;
+#ifdef OBJ_ELF
+      /* Whether this expression needs special pic relocation, and if
+        so, which.  */
+      enum pic_relocation pic_reloc;
+#endif
     }
   reloc[5];                    /* Five is enough??? */
 };
     }
   reloc[5];                    /* Five is enough??? */
 };
@@ -252,6 +257,9 @@ add_fix (width, exp, pc_rel, pc_fix)
   the_ins.reloc[the_ins.nrel].exp = exp->exp;
   the_ins.reloc[the_ins.nrel].wid = width;
   the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix;
   the_ins.reloc[the_ins.nrel].exp = exp->exp;
   the_ins.reloc[the_ins.nrel].wid = width;
   the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix;
+#ifdef OBJ_ELF
+  the_ins.reloc[the_ins.nrel].pic_reloc = exp->pic_reloc;
+#endif
   the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
 }
 
   the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
 }
 
@@ -428,7 +436,7 @@ const pseudo_typeS md_pseudo_table[] =
   {"even", s_even, 0},
   {"skip", s_space, 0},
   {"proc", s_proc, 0},
   {"even", s_even, 0},
   {"skip", s_space, 0},
   {"proc", s_proc, 0},
-#ifdef TE_SUN3
+#if defined (TE_SUN3) || defined (OBJ_ELF)
   {"align", s_align_bytes, 0},
 #endif
 #ifdef OBJ_ELF
   {"align", s_align_bytes, 0},
 #endif
 #ifdef OBJ_ELF
@@ -500,7 +508,11 @@ CONST pseudo_typeS mote_pseudo_table[] =
   {"dsb", s_space, 1},
 
   {"xdef", s_globl, 0},
   {"dsb", s_space, 1},
 
   {"xdef", s_globl, 0},
+#ifdef OBJ_ELF
+  {"align", s_align_bytes, 0},
+#else
   {"align", s_align_ptwo, 0},
   {"align", s_align_ptwo, 0},
+#endif
 #ifdef M68KCOFF
   {"sect", obj_coff_section, 0},
   {"section", obj_coff_section, 0},
 #ifdef M68KCOFF
   {"sect", obj_coff_section, 0},
   {"section", obj_coff_section, 0},
@@ -585,6 +597,145 @@ tc_coff_fix2rtype (fixP)
 
 #endif
 
 
 #endif
 
+#ifdef OBJ_ELF
+
+/* Compute the relocation code for a fixup of SIZE bytes, using pc
+   relative relocation if PCREL is non-zero.  PIC says whether a special
+   pic relocation was requested.  */
+
+static bfd_reloc_code_real_type get_reloc_code
+  PARAMS ((int, int, enum pic_relocation));
+
+static bfd_reloc_code_real_type
+get_reloc_code (size, pcrel, pic)
+     int size;
+     int pcrel;
+     enum pic_relocation pic;
+{
+  switch (pic)
+    {
+    case pic_got_pcrel:
+      switch (size)
+       {
+       case 1:
+         return BFD_RELOC_8_GOT_PCREL;
+       case 2:
+         return BFD_RELOC_16_GOT_PCREL;
+       case 4:
+         return BFD_RELOC_32_GOT_PCREL;
+       }
+      break;
+
+    case pic_got_off:
+      switch (size)
+       {
+       case 1:
+         return BFD_RELOC_8_GOTOFF;
+       case 2:
+         return BFD_RELOC_16_GOTOFF;
+       case 4:
+         return BFD_RELOC_32_GOTOFF;
+       }
+      break;
+
+    case pic_plt_pcrel:
+      switch (size)
+       {
+       case 1:
+         return BFD_RELOC_8_PLT_PCREL;
+       case 2:
+         return BFD_RELOC_16_PLT_PCREL;
+       case 4:
+         return BFD_RELOC_32_PLT_PCREL;
+       }
+      break;
+
+    case pic_plt_off:
+      switch (size)
+       {
+       case 1:
+         return BFD_RELOC_8_PLTOFF;
+       case 2:
+         return BFD_RELOC_16_PLTOFF;
+       case 4:
+         return BFD_RELOC_32_PLTOFF;
+       }
+      break;
+
+    case pic_none:
+      if (pcrel)
+       {
+         switch (size)
+           {
+           case 1:
+             return BFD_RELOC_8_PCREL;
+           case 2:
+             return BFD_RELOC_16_PCREL;
+           case 4:
+             return BFD_RELOC_32_PCREL;
+           }
+       }
+      else
+       {
+         switch (size)
+           {
+           case 1:
+             return BFD_RELOC_8;
+           case 2:
+             return BFD_RELOC_16;
+           case 4:
+             return BFD_RELOC_32;
+           }
+       }
+    }
+
+  as_bad ("Can not do %d byte %s%srelocation", size,
+         pcrel ? "pc-relative " : "",
+         pic == pic_none ? "" : "pic ");
+  return BFD_RELOC_NONE;
+}
+
+/* Here we decide which fixups can be adjusted to make them relative
+   to the beginning of the section instead of the symbol.  Basically
+   we need to make sure that the dynamic relocations are done
+   correctly, so in some cases we force the original symbol to be
+   used.  */
+int
+tc_m68k_fix_adjustable (fixP)
+     fixS *fixP;
+{
+  /* Prevent all adjustments to global symbols. */
+  if (S_IS_EXTERNAL (fixP->fx_addsy))
+    return 0;
+
+  /* adjust_reloc_syms doesn't know about the GOT */
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_8_GOT_PCREL:
+    case BFD_RELOC_16_GOT_PCREL:
+    case BFD_RELOC_32_GOT_PCREL:
+    case BFD_RELOC_8_GOTOFF:
+    case BFD_RELOC_16_GOTOFF:
+    case BFD_RELOC_32_GOTOFF:
+    case BFD_RELOC_8_PLT_PCREL:
+    case BFD_RELOC_16_PLT_PCREL:
+    case BFD_RELOC_32_PLT_PCREL:
+    case BFD_RELOC_8_PLTOFF:
+    case BFD_RELOC_16_PLTOFF:
+    case BFD_RELOC_32_PLTOFF:
+      return 0;
+
+    default:
+      return 1;
+    }
+}
+
+#else /* !OBJ_ELF */
+
+#define get_reloc_code(SIZE,PCREL,OTHER) NO_RELOC
+
+#endif /* OBJ_ELF */
+
 #ifdef BFD_ASSEMBLER
 
 arelent *
 #ifdef BFD_ASSEMBLER
 
 arelent *
@@ -598,28 +749,50 @@ tc_gen_reloc (section, fixp)
   if (fixp->fx_tcbit)
     abort ();
 
   if (fixp->fx_tcbit)
     abort ();
 
-#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
-  switch (F (fixp->fx_size, fixp->fx_pcrel))
+  if (fixp->fx_r_type != BFD_RELOC_NONE)
+    code = fixp->fx_r_type;
+  else
     {
     {
+#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
+      switch (F (fixp->fx_size, fixp->fx_pcrel))
+       {
 #define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
 #define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
-      MAP (1, 0, BFD_RELOC_8);
-      MAP (2, 0, BFD_RELOC_16);
-      MAP (4, 0, BFD_RELOC_32);
-      MAP (1, 1, BFD_RELOC_8_PCREL);
-      MAP (2, 1, BFD_RELOC_16_PCREL);
-      MAP (4, 1, BFD_RELOC_32_PCREL);
-    default:
-      abort ();
+         MAP (1, 0, BFD_RELOC_8);
+         MAP (2, 0, BFD_RELOC_16);
+         MAP (4, 0, BFD_RELOC_32);
+         MAP (1, 1, BFD_RELOC_8_PCREL);
+         MAP (2, 1, BFD_RELOC_16_PCREL);
+         MAP (4, 1, BFD_RELOC_32_PCREL);
+       default:
+         abort ();
+       }
     }
     }
+#undef F
+#undef MAP
 
   reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
   assert (reloc != 0);
   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
 
   reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
   assert (reloc != 0);
   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+#ifndef OBJ_ELF
   if (fixp->fx_pcrel)
     reloc->addend = fixp->fx_addnumber;
   else
     reloc->addend = 0;
   if (fixp->fx_pcrel)
     reloc->addend = fixp->fx_addnumber;
   else
     reloc->addend = 0;
+#else
+  if (!fixp->fx_pcrel)
+    reloc->addend = fixp->fx_addnumber;
+  else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+    reloc->addend = (section->vma
+                    + (fixp->fx_pcrel_adjust == 64
+                       ? -1 : fixp->fx_pcrel_adjust)
+                    + fixp->fx_addnumber
+                    + md_pcrel_from (fixp));
+  else
+    reloc->addend = (fixp->fx_offset
+                    + (fixp->fx_pcrel_adjust == 64
+                       ? -1 : fixp->fx_pcrel_adjust));
+#endif
 
   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   assert (reloc->howto != 0);
 
   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   assert (reloc->howto != 0);
@@ -1575,16 +1748,24 @@ m68k_ip (instring)
                    {
                      if (opP->reg == PC)
                        {
                    {
                      if (opP->reg == PC)
                        {
-#if 0
-                         addword (0x0170);
-                         add_fix ('l', &opP->disp, 1, 2);
-                         addword (0), addword (0);
-#else
-                         add_frag (adds (&opP->disp),
-                                   offs (&opP->disp),
-                                   TAB (PCLEA, SZ_UNDEF));
+                         if (opP->disp.size == SIZE_LONG
+#ifdef OBJ_ELF
+                             /* If the displacement needs pic
+                                relocation it cannot be relaxed.  */
+                             || opP->disp.pic_reloc != pic_none
 #endif
 #endif
-                         break;
+                             )
+                           {
+                             addword (0x0170);
+                             add_fix ('l', &opP->disp, 1, 2);
+                           }
+                         else
+                           {
+                             add_frag (adds (&opP->disp),
+                                       offs (&opP->disp),
+                                       TAB (PCLEA, SZ_UNDEF));
+                             break;
+                           }
                        }
                      else
                        {
                        }
                      else
                        {
@@ -1730,7 +1911,13 @@ m68k_ip (instring)
                      else if (siz1 == SIZE_UNSPEC
                               && opP->reg == PC
                               && isvar (&opP->disp)
                      else if (siz1 == SIZE_UNSPEC
                               && opP->reg == PC
                               && isvar (&opP->disp)
-                              && subs (&opP->disp) == NULL)
+                              && subs (&opP->disp) == NULL
+#ifdef OBJ_ELF
+                              /* If the displacement needs pic
+                                 relocation it cannot be relaxed.  */
+                              && opP->disp.pic_reloc == pic_none
+#endif
+                              )
                        {
                          nextword += baseo & 0xff;
                          addword (nextword);
                        {
                          nextword += baseo & 0xff;
                          addword (nextword);
@@ -1866,6 +2053,11 @@ m68k_ip (instring)
                  if (isvar (&opP->disp)
                      && !subs (&opP->disp)
                      && adds (&opP->disp)
                  if (isvar (&opP->disp)
                      && !subs (&opP->disp)
                      && adds (&opP->disp)
+#ifdef OBJ_ELF
+                     /* If the displacement needs pic relocation it
+                        cannot be relaxed.  */
+                     && opP->disp.pic_reloc == pic_none
+#endif
                      && S_GET_SEGMENT (adds (&opP->disp)) == now_seg
                      && cpu_of_arch (current_architecture) >= m68020
                      && !flag_long_jumps
                      && S_GET_SEGMENT (adds (&opP->disp)) == now_seg
                      && cpu_of_arch (current_architecture) >= m68020
                      && !flag_long_jumps
@@ -2005,6 +2197,13 @@ m68k_ip (instring)
              if (subs (&opP->disp))    /* We can't relax it */
                goto long_branch;
 
              if (subs (&opP->disp))    /* We can't relax it */
                goto long_branch;
 
+#ifdef OBJ_ELF
+             /* If the displacement needs pic relocation it cannot be
+                relaxed.  */
+             if (opP->disp.pic_reloc != pic_none)
+               goto long_branch;
+#endif
+
              /* This could either be a symbol, or an absolute
                 address.  No matter, the frag hacking will finger it
                 out.  Not quite: it can't switch from BRANCH to
              /* This could either be a symbol, or an absolute
                 address.  No matter, the frag hacking will finger it
                 out.  Not quite: it can't switch from BRANCH to
@@ -2938,7 +3137,8 @@ md_assemble (str)
                              n,
                              &the_ins.reloc[m].exp,
                              the_ins.reloc[m].pcrel,
                              n,
                              &the_ins.reloc[m].exp,
                              the_ins.reloc[m].pcrel,
-                             NO_RELOC);
+                             get_reloc_code (n, the_ins.reloc[m].pcrel,
+                                             the_ins.reloc[m].pic_reloc));
          fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       return;
          fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       return;
@@ -2982,7 +3182,8 @@ md_assemble (str)
                              wid,
                              &the_ins.reloc[m].exp,
                              the_ins.reloc[m].pcrel,
                              wid,
                              &the_ins.reloc[m].exp,
                              the_ins.reloc[m].pcrel,
-                             NO_RELOC);
+                             get_reloc_code (wid, the_ins.reloc[m].pcrel,
+                                             the_ins.reloc[m].pic_reloc));
          fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       (void) frag_var (rs_machine_dependent, 10, 0,
          fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       (void) frag_var (rs_machine_dependent, 10, 0,
@@ -3018,7 +3219,8 @@ md_assemble (str)
                          wid,
                          &the_ins.reloc[m].exp,
                          the_ins.reloc[m].pcrel,
                          wid,
                          &the_ins.reloc[m].exp,
                          the_ins.reloc[m].pcrel,
-                         NO_RELOC);
+                         get_reloc_code (wid, the_ins.reloc[m].pcrel,
+                                         the_ins.reloc[m].pic_reloc));
       fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
     }
 }
       fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
     }
 }
@@ -3185,6 +3387,12 @@ md_begin ()
 #endif
 
   init_regtable ();
 #endif
 
   init_regtable ();
+
+#ifdef OBJ_ELF
+  record_alignment (text_section, 2);
+  record_alignment (data_section, 2);
+  record_alignment (bss_section, 2);
+#endif
 }
 
 void
 }
 
 void
@@ -3371,6 +3579,15 @@ md_apply_fix_2 (fixP, val)
   else
     val &= 0x7fffffff;
 
   else
     val &= 0x7fffffff;
 
+#ifdef OBJ_ELF
+  if (fixP->fx_addsy)
+    {
+      memset (buf, 0, fixP->fx_size);
+      fixP->fx_addnumber = val;        /* Remember value for emit_reloc */
+      return;
+    }
+#endif
+
   switch (fixP->fx_size)
     {
       /* The cast to offsetT below are necessary to make code correct for
   switch (fixP->fx_size)
     {
       /* The cast to offsetT below are necessary to make code correct for
@@ -5974,8 +6191,14 @@ md_parse_option (c, arg)
       flag_reg_prefix_optional = 1;
       break;
 
       flag_reg_prefix_optional = 1;
       break;
 
-    case 'Q':
+      /* -V: SVR4 argument to print version ID.  */
     case 'V':
     case 'V':
+      print_version_id ();
+      break;
+
+      /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+        should be emitted or not.  FIXME: Not implemented.  */
+    case 'Q':
       break;
 
     default:
       break;
 
     default:
index 36abd6c2e974061078b681f5a499afe219da0359..3f99de9e69d0894515ac04da45c626dbdd41584e 100644 (file)
@@ -1,6 +1,7 @@
 /* This file is tc-m68k.h
 
 /* This file is tc-m68k.h
 
-   Copyright (C) 1987-1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 89, 90, 91, 92, 93, 94, 95, 1996
+   Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 
    This file is part of GAS, the GNU Assembler.
 
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define TC_M68K 1
 
 
 #define TC_M68K 1
 
+#define TARGET_BYTES_BIG_ENDIAN 1
+
 #ifdef OBJ_AOUT
 #ifdef OBJ_AOUT
+#ifdef TE_SUN3
 #define TARGET_FORMAT "a.out-sunos-big"
 #define TARGET_FORMAT "a.out-sunos-big"
+#else
+#ifdef TE_NetBSD
+#define TARGET_FORMAT "a.out-m68k-netbsd"
+#else
+#define TARGET_FORMAT "a.out-zero-big"
+#endif
+#endif
+#endif
+
+#ifdef OBJ_ELF
+#define TARGET_FORMAT "elf32-m68k"
 #endif
 
 #ifdef TE_APOLLO
 #endif
 
 #ifdef TE_APOLLO
 #ifdef TE_LYNX
 #define TARGET_FORMAT          "coff-m68k-lynx"
 #endif
 #ifdef TE_LYNX
 #define TARGET_FORMAT          "coff-m68k-lynx"
 #endif
+#ifdef TE_AUX
+#define TARGET_FORMAT          "coff-m68k-aux"
+#endif
 
 #ifndef COFF_MAGIC
 #define COFF_MAGIC MC68MAGIC
 #endif
 
 #ifndef COFF_MAGIC
 #define COFF_MAGIC MC68MAGIC
 #endif
-#define BFD_ARCH bfd_arch_m68k
+#define BFD_ARCH bfd_arch_m68k /* for non-BFD_ASSEMBLER */
+#define TARGET_ARCH bfd_arch_m68k /* BFD_ASSEMBLER */
 #define COFF_FLAGS F_AR32W
 #define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
 
 #define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
 #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
 #define COFF_FLAGS F_AR32W
 #define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
 
 #define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
 #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((struct frag *));
 #ifdef TE_SUN3
 /* This variable contains the value to write out at the beginning of
    the a.out file.  The 2<<16 means that this is a 68020 file instead
 #ifdef TE_SUN3
 /* This variable contains the value to write out at the beginning of
    the a.out file.  The 2<<16 means that this is a 68020 file instead
@@ -77,7 +97,7 @@ extern int m68k_aout_machtype;
 #endif
 
 #if !defined (REGISTER_PREFIX_OPTIONAL)
 #endif
 
 #if !defined (REGISTER_PREFIX_OPTIONAL)
-#ifdef M68KCOFF
+#if defined (M68KCOFF) || defined (OBJ_ELF)
 #define LOCAL_LABEL(name) (name[0] == '.' \
                           && (name[1] == 'L' || name[1] == '.'))
 #define FAKE_LABEL_NAME ".L0\001"
 #define LOCAL_LABEL(name) (name[0] == '.' \
                           && (name[1] == 'L' || name[1] == '.'))
 #define FAKE_LABEL_NAME ".L0\001"
@@ -92,11 +112,36 @@ extern int m68k_aout_machtype;
    can't be used as the initial character.  If that's not true, more
    work will be needed to fix this up.  */
 #define LEX_PCT 1
    can't be used as the initial character.  If that's not true, more
    work will be needed to fix this up.  */
 #define LEX_PCT 1
+/* On the Delta, dots are not required before pseudo-ops.  */
+#define NO_PSEUDO_DOT
 #endif
 
 #ifdef BFD_ASSEMBLER
 #endif
 
 #ifdef BFD_ASSEMBLER
+
 #define tc_frob_symbol(sym,punt) \
     if (S_GET_SEGMENT (sym) == reg_section) punt = 1
 #define tc_frob_symbol(sym,punt) \
     if (S_GET_SEGMENT (sym) == reg_section) punt = 1
+
+#define NO_RELOC BFD_RELOC_NONE
+
+#ifdef OBJ_ELF
+
+/* This expression evaluates to false if the relocation is for a local object
+   for which we still want to do the relocation at runtime.  True if we
+   are willing to perform this relocation while building the .o file.  */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX)                  \
+       ((FIX)->fx_r_type != BFD_RELOC_8_PLT_PCREL      \
+        && (FIX)->fx_r_type != BFD_RELOC_16_PLT_PCREL  \
+        && (FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL  \
+        && (FIX)->fx_r_type != BFD_RELOC_8_GOT_PCREL   \
+        && (FIX)->fx_r_type != BFD_RELOC_16_GOT_PCREL  \
+        && (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL)
+
+#define tc_fix_adjustable(X) tc_m68k_fix_adjustable(X)
+#endif
+
+#else
+#define NO_RELOC 0
 #endif
 
 #define DIFF_EXPR_OK
 #endif
 
 #define DIFF_EXPR_OK
@@ -107,4 +152,12 @@ extern void m68k_init_after_args PARAMS ((void));
 extern int m68k_parse_long_option PARAMS ((char *));
 #define md_parse_long_option m68k_parse_long_option
 
 extern int m68k_parse_long_option PARAMS ((char *));
 #define md_parse_long_option m68k_parse_long_option
 
+#define md_operand(x)
+
+#define TARGET_WORD_SIZE 32
+#define TARGET_ARCH bfd_arch_m68k
+
+extern struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
 /* end of tc-m68k.h */
 /* end of tc-m68k.h */
index 91871da548ee4ee06766e22e1b8afc4b3eea4e05..97df4fb1553772df00bd733440115aacce34515c 100644 (file)
@@ -1,5 +1,5 @@
 /* write.c - emit .o file
 /* write.c - emit .o file
-   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 1995
+   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 1996
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -94,6 +94,8 @@ int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
 
 #endif /* BFD_ASSEMBLER */
 
 
 #endif /* BFD_ASSEMBLER */
 
+static int n_fixups;
+
 #ifdef BFD_ASSEMBLER
 static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
                                       symbolS *add, symbolS *sub,
 #ifdef BFD_ASSEMBLER
 static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
                                       symbolS *add, symbolS *sub,
@@ -133,6 +135,8 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
 {
   fixS *fixP;
 
 {
   fixS *fixP;
 
+  n_fixups++;
+
   fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
 
   fixP->fx_frag = frag;
   fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
 
   fixP->fx_frag = frag;
@@ -799,12 +803,23 @@ write_relocs (abfd, sec, xxx)
     {
       arelent *reloc;
       bfd_reloc_status_type s;
     {
       arelent *reloc;
       bfd_reloc_status_type s;
+      symbolS *sym;
 
       if (fixp->fx_done)
        {
          n--;
          continue;
        }
 
       if (fixp->fx_done)
        {
          n--;
          continue;
        }
+
+      /* If this is an undefined symbol which was equated to another
+         symbol, then use generate the reloc against the latter symbol
+         rather than the former.  */
+      sym = fixp->fx_addsy;
+      while (sym->sy_value.X_op == O_symbol
+            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+       sym = sym->sy_value.X_add_symbol;
+      fixp->fx_addsy = sym;
+
       reloc = tc_gen_reloc (sec, fixp);
       if (!reloc)
        {
       reloc = tc_gen_reloc (sec, fixp);
       if (!reloc)
        {
@@ -844,6 +859,7 @@ write_relocs (abfd, sec, xxx)
       arelent **reloc;
       char *data;
       bfd_reloc_status_type s;
       arelent **reloc;
       char *data;
       bfd_reloc_status_type s;
+      symbolS *sym;
       int j;
 
       if (fixp->fx_done)
       int j;
 
       if (fixp->fx_done)
@@ -851,6 +867,16 @@ write_relocs (abfd, sec, xxx)
          n--;
          continue;
        }
          n--;
          continue;
        }
+
+      /* If this is an undefined symbol which was equated to another
+         symbol, then use generate the reloc against the latter symbol
+         rather than the former.  */
+      sym = fixp->fx_addsy;
+      while (sym->sy_value.X_op == O_symbol
+            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+       sym = sym->sy_value.X_add_symbol;
+      fixp->fx_addsy = sym;
+
       reloc = tc_gen_reloc (sec, fixp);
 
       for (j = 0; reloc[j]; j++)
       reloc = tc_gen_reloc (sec, fixp);
 
       for (j = 0; reloc[j]; j++)
@@ -1642,6 +1668,15 @@ write_object_file ()
                resolve_symbol_value (symp);
            }
 
                resolve_symbol_value (symp);
            }
 
+         /* Skip symbols which were equated to undefined or common
+             symbols.  */
+         if (symp->sy_value.X_op == O_symbol
+             && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
+           {
+             symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+             continue;
+           }
+
          /* So far, common symbols have been treated like undefined symbols.
             Put them in the common section now.  */
          if (S_IS_DEFINED (symp) == 0
          /* So far, common symbols have been treated like undefined symbols.
             Put them in the common section now.  */
          if (S_IS_DEFINED (symp) == 0
@@ -1703,6 +1738,9 @@ write_object_file ()
 
   /* Now do any format-specific adjustments to the symbol table, such
      as adding file symbols.  */
 
   /* Now do any format-specific adjustments to the symbol table, such
      as adding file symbols.  */
+#ifdef tc_adjust_symtab
+  tc_adjust_symtab ();
+#endif
 #ifdef obj_adjust_symtab
   obj_adjust_symtab ();
 #endif
 #ifdef obj_adjust_symtab
   obj_adjust_symtab ();
 #endif
@@ -2402,8 +2440,10 @@ fixup_segment (fixP, this_segment_type)
              else
                {
                  seg_reloc_count++;
              else
                {
                  seg_reloc_count++;
+#if !(defined (TC_M68K) && defined (OBJ_ELF))
 #if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF))
                  add_number += S_GET_VALUE (add_symbolP);
 #if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF))
                  add_number += S_GET_VALUE (add_symbolP);
+#endif
 #endif
                }
            }
 #endif
                }
            }
@@ -2531,6 +2571,13 @@ number_to_chars_littleendian (buf, val, n)
     }
 }
 
     }
 }
 
+void
+write_print_statistics (file)
+     FILE *file;
+{
+  fprintf (stderr, "fixups: %d\n", n_fixups);
+}
+
 /* for debugging */
 extern int indent_level;
 extern void print_symbol_value_1 ();
 /* for debugging */
 extern int indent_level;
 extern void print_symbol_value_1 ();