Fix typos
[deliverable/binutils-gdb.git] / gas / config / obj-ecoff.c
index 8426c7a1164597db43fac221fa825500bd356466..3f80e7d9ce0b24153835554bc713f63a1385f543 100644 (file)
@@ -1,5 +1,6 @@
 /* ECOFF object file format.
-   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1993, 94, 95, 96, 97, 98, 99, 2000
+   Free Software Foundation, Inc.
    Contributed by Cygnus Support.
    This file was put together by Ian Lance Taylor <ian@cygnus.com>.
 
    GNU General Public License for more details.
 
    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.  */
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
+#define OBJ_HEADER "obj-ecoff.h"
 #include "as.h"
 #include "coff/internal.h"
 #include "bfd/libcoff.h"
    gas directory.  This file mostly just arranges to call that one at
    the right times.  */
 
+static int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
+static void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
+static void ecoff_pop_insert PARAMS ((void));
+static int ecoff_separate_stab_sections PARAMS ((void));
+
 /* These are the pseudo-ops we support in this file.  Only those
    relating to debugging information are supported here.
 
@@ -57,8 +65,10 @@ const pseudo_typeS obj_pseudo_table[] =
   { "file",    ecoff_directive_file,   0 },
   { "scl",     ecoff_directive_scl,    0 },
   { "size",    ecoff_directive_size,   0 },
+  { "esize",   ecoff_directive_size,   0 },
   { "tag",     ecoff_directive_tag,    0 },
   { "type",    ecoff_directive_type,   0 },
+  { "etype",   ecoff_directive_type,   0 },
   { "val",     ecoff_directive_val,    0 },
 
   /* ECOFF specific debugging information.  */
@@ -71,6 +81,14 @@ const pseudo_typeS obj_pseudo_table[] =
   { "loc",     ecoff_directive_loc,    0 },
   { "mask",    ecoff_directive_mask,   0 },
 
+  /* Other ECOFF directives.  */
+  { "extern",  ecoff_directive_extern, 0 },
+
+#ifndef TC_MIPS
+  /* For TC_MIPS, tc-mips.c adds this.  */
+  { "weakext", ecoff_directive_weakext, 0 },
+#endif
+
   /* These are used on Irix.  I don't know how to implement them.  */
   { "bgnb",    s_ignore,               0 },
   { "endb",    s_ignore,               0 },
@@ -93,15 +111,88 @@ ecoff_frob_file ()
   char *buf;
   char *set;
 
-  /* Set the section VMA values.  */
+  /* Set the section VMA values.  We force the .sdata and .sbss
+     sections to the end to ensure that their VMA addresses are close
+     together so that the GP register can address both of them.  We
+     put the .bss section after the .sbss section.
+
+     Also, for the Alpha, we must sort the sections, to make sure they
+     appear in the output file in the correct order.  (Actually, maybe
+     this is a job for BFD.  But the VMAs computed would be out of
+     whack if we computed them given our initial, random ordering.
+     It's possible that that wouldn't break things; I could do some
+     experimenting sometime and find out.
+
+     This output ordering of sections is magic, on the Alpha, at
+     least.  The .lita section must come before .lit8 and .lit4,
+     otherwise the OSF/1 linker may silently trash the .lit{4,8}
+     section contents.  Also, .text must preceed .rdata.  These differ
+     from the order described in some parts of the DEC OSF/1 Assembly
+     Language Programmer's Guide, but that order doesn't seem to work
+     with their linker.
+
+     I don't know if section ordering on the MIPS is important.  */
+
+  static const char *const names[] = {
+    /* text segment */
+    ".text", ".rdata", ".init", ".fini",
+    /* data segment */
+    ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
+    /* bss segment */
+    ".sbss", ".bss",
+  };
+#define n_names (sizeof (names) / sizeof (names[0]))
+
   addr = 0;
-  for (sec = stdoutput->sections; sec != (asection *) NULL; sec = sec->next)
-    {
-      bfd_set_section_vma (stdoutput, sec, addr);
-      addr += bfd_section_size (stdoutput, sec);
-    }
+  {
+    /* Sections that match names, order to be straightened out later.  */
+    asection *secs[n_names];
+    /* Linked list of sections with non-matching names.  Random ordering.  */
+    asection *other_sections = 0;
+    /* Pointer to next section, since we're destroying the original
+       ordering.  */
+    asection *next;
+
+    int i;
+
+    for (i = 0; i < n_names; i++)
+      secs[i] = 0;
+    for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next)
+      {
+       next = sec->next;
+       for (i = 0; i < n_names; i++)
+         if (!strcmp (sec->name, names[i]))
+           {
+             secs[i] = sec;
+             break;
+           }
+       if (i == n_names)
+         {
+           bfd_set_section_vma (stdoutput, sec, addr);
+           addr += bfd_section_size (stdoutput, sec);
+           sec->next = other_sections;
+           other_sections = sec;
+         }
+      }
+    for (i = 0; i < n_names; i++)
+      if (secs[i])
+       {
+         sec = secs[i];
+         bfd_set_section_vma (stdoutput, sec, addr);
+         addr += bfd_section_size (stdoutput, sec);
+       }
+    for (i = n_names - 1; i >= 0; i--)
+      if (secs[i])
+       {
+         sec = secs[i];
+         sec->next = other_sections;
+         other_sections = sec;
+       }
+    stdoutput->sections = other_sections;
+  }
 
   /* Build the ECOFF debugging information.  */
+  assert (ecoff_data (stdoutput) != 0);
   hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
   ecoff_build_debug (hdr, &buf, debug_swap);
 
@@ -132,29 +223,29 @@ ecoff_frob_file ()
 
   /* Fill in the register masks.  */
   {
-    asection *regsec;
-    struct ecoff_reginfo s;
-
-    regsec = bfd_make_section (stdoutput, REGINFO);
-    know (regsec != NULL);
-
-    if (bfd_get_section_contents (stdoutput, regsec, (PTR) &s,
-                                 (file_ptr) 0, sizeof s) == false)
-      as_fatal ("Can't read REGINFO section");
+    unsigned long gprmask = 0;
+    unsigned long fprmask = 0;
+    unsigned long *cprmask = NULL;
 
 #ifdef TC_MIPS
     /* Fill in the MIPS register masks.  It's probably not worth
        setting up a generic interface for this.  */
-    s.gprmask = mips_gprmask;
-    s.cprmask[0] = mips_cprmask[0];
-    s.cprmask[1] = mips_cprmask[1];
-    s.cprmask[2] = mips_cprmask[2];
-    s.cprmask[3] = mips_cprmask[3];
+    gprmask = mips_gprmask;
+    cprmask = mips_cprmask;
 #endif
 
-    if (bfd_set_section_contents (stdoutput, regsec, (PTR) &s,
-                                 (file_ptr) 0, sizeof s) == false)
-      as_fatal ("Can't write REGINFO section");
+#ifdef TC_ALPHA
+    alpha_frob_ecoff_data ();
+
+    if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
+      as_fatal (_("Can't set GP value"));
+
+    gprmask = alpha_gprmask;
+    fprmask = alpha_fprmask;
+#endif
+
+    if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
+      as_fatal (_("Can't set register masks"));
   }
 }
 
@@ -171,9 +262,73 @@ obj_ecoff_set_ext (sym, ext)
     = &ecoff_backend (stdoutput)->debug_swap;
   ecoff_symbol_type *esym;
 
-  know (bfd_asymbol_flavour (sym->bsym) == bfd_target_ecoff_flavour);
-  esym = ecoffsymbol (sym->bsym);
+  know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
+       == bfd_target_ecoff_flavour);
+  esym = ecoffsymbol (symbol_get_bfdsym (sym));
   esym->local = false;
   esym->native = xmalloc (debug_swap->external_ext_size);
   (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
 }
+
+static int
+ecoff_sec_sym_ok_for_reloc (sec)
+     asection *sec;
+{
+  return 1;
+}
+
+static void
+obj_ecoff_frob_symbol (sym, puntp)
+     symbolS *sym;
+     int *puntp;
+{
+  ecoff_frob_symbol (sym);
+}
+
+static void
+ecoff_pop_insert ()
+{
+  pop_insert (obj_pseudo_table);
+}
+
+static int
+ecoff_separate_stab_sections ()
+{
+  return 0;
+}
+
+const struct format_ops ecoff_format_ops =
+{
+  bfd_target_ecoff_flavour,
+  0,   /* dfl_leading_underscore */
+
+  /* FIXME: A comment why emit_section_symbols is different here (1) from
+     the single-format definition (0) would be in order.  */
+  1,   /* emit_section_symbols */
+  0,   /* begin */
+  ecoff_new_file,
+  obj_ecoff_frob_symbol,
+  ecoff_frob_file,
+  0,   /* frob_file_before_adjust */
+  0,   /* frob_file_after_relocs */
+  0,   /* s_get_size */
+  0,   /* s_set_size */
+  0,   /* s_get_align */
+  0,   /* s_set_align */
+  0,   /* s_get_other */
+  0,   /* s_set_other */
+  0,   /* s_get_desc */
+  0,   /* s_set_desc */
+  0,   /* s_get_type */
+  0,   /* s_set_type */
+  0,   /* copy_symbol_attributes */
+  ecoff_generate_asm_lineno,
+  ecoff_stab,
+  ecoff_separate_stab_sections,
+  0,   /* init_stab_section */
+  ecoff_sec_sym_ok_for_reloc,
+  ecoff_pop_insert,
+  ecoff_set_ext,
+  ecoff_read_begin_hook,
+  ecoff_symbol_new_hook
+};
This page took 0.032482 seconds and 4 git commands to generate.