]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/obj-elf.c
PR23938, should not free memory alloced in obstack by free()
[thirdparty/binutils-gdb.git] / gas / config / obj-elf.c
index c7a4ee410faee8feb62d0485a0a77c36bb022303..3ec6b599f4a836e0fda112e79211e0b6f4d53894 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF object file format
-   Copyright (C) 1992-2016 Free Software Foundation, Inc.
+   Copyright (C) 1992-2018 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -23,7 +23,6 @@
 #include "safe-ctype.h"
 #include "subsegs.h"
 #include "obstack.h"
-#include "struc-symbol.h"
 #include "dwarf2dbg.h"
 
 #ifndef ECOFF_DEBUGGING
 #include "elf/ppc.h"
 #endif
 
-#ifdef TC_I370
-#include "elf/i370.h"
-#endif
-
 #ifdef TC_I386
 #include "elf/x86-64.h"
 #endif
 #include "elf/nios2.h"
 #endif
 
+#ifdef TC_PRU
+#include "elf/pru.h"
+#endif
+
 static void obj_elf_line (int);
 static void obj_elf_size (int);
 static void obj_elf_type (int);
@@ -113,8 +112,8 @@ static const pseudo_typeS elf_pseudo_table[] =
   {"subsection", obj_elf_subsection, 0},
 
   /* These are GNU extensions to aid in garbage collecting C++ vtables.  */
-  {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
-  {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
+  {"vtable_inherit", obj_elf_vtable_inherit, 0},
+  {"vtable_entry", obj_elf_vtable_entry, 0},
 
   /* A GNU extension for object attributes.  */
   {"gnu_attribute", obj_elf_gnu_attribute, 0},
@@ -124,7 +123,7 @@ static const pseudo_typeS elf_pseudo_table[] =
   {"4byte", cons, 4},
   {"8byte", cons, 8},
   /* These are used for dwarf2.  */
-  { "file", (void (*) (int)) dwarf2_directive_file, 0 },
+  { "file", dwarf2_directive_file, 0 },
   { "loc",  dwarf2_directive_loc,  0 },
   { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
 
@@ -160,6 +159,7 @@ static const pseudo_typeS ecoff_debug_pseudo_table[] =
   { "etype",   ecoff_directive_type,   0 },
 
   /* ECOFF specific debugging information.  */
+  { "aent",    ecoff_directive_ent,    1 },
   { "begin",   ecoff_directive_begin,  0 },
   { "bend",    ecoff_directive_bend,   0 },
   { "end",     ecoff_directive_end,    0 },
@@ -260,10 +260,12 @@ elf_sec_sym_ok_for_reloc (asection *sec)
 void
 elf_file_symbol (const char *s, int appfile)
 {
+  asymbol *bsym;
+
   if (!appfile
       || symbol_rootP == NULL
-      || symbol_rootP->bsym == NULL
-      || (symbol_rootP->bsym->flags & BSF_FILE) == 0)
+      || (bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
+      || (bsym->flags & BSF_FILE) == 0)
     {
       symbolS *sym;
       size_t name_length;
@@ -283,8 +285,8 @@ elf_file_symbol (const char *s, int appfile)
       symbol_get_bfdsym (sym)->flags |= BSF_FILE;
 
       if (symbol_rootP != sym
-         && (symbol_rootP->bsym == NULL
-             || !(symbol_rootP->bsym->flags & BSF_FILE)))
+         && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
+             || (bsym->flags & BSF_FILE) == 0))
        {
          symbol_remove (sym, &symbol_rootP, &symbol_lastP);
          symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
@@ -515,16 +517,26 @@ struct section_stack
 
 static struct section_stack *section_stack;
 
+/* Match both section group name and the sh_info field.  */
+struct section_match
+{
+  const char *group_name;
+  unsigned int info;
+};
+
 static bfd_boolean
 get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 {
-  const char *gname = (const char *) inf;
+  struct section_match *match = (struct section_match *) inf;
+  const char *gname = match->group_name;
   const char *group_name = elf_group_name (sec);
+  unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
 
-  return (group_name == gname
-         || (group_name != NULL
-             && gname != NULL
-             && strcmp (group_name, gname) == 0));
+  return (info == match->info
+         && (group_name == gname
+             || (group_name != NULL
+                 && gname != NULL
+                 && strcmp (group_name, gname) == 0)));
 }
 
 /* Handle the .section pseudo-op.  This code supports two different
@@ -548,6 +560,7 @@ get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 void
 obj_elf_change_section (const char *name,
                        unsigned int type,
+                       unsigned int info,
                        bfd_vma attr,
                        int entsize,
                        const char *group_name,
@@ -559,6 +572,7 @@ obj_elf_change_section (const char *name,
   flagword flags;
   const struct elf_backend_data *bed;
   const struct bfd_elf_special_section *ssect;
+  struct section_match match;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -568,7 +582,7 @@ obj_elf_change_section (const char *name,
   if (push)
     {
       struct section_stack *elt;
-      elt = (struct section_stack *) xmalloc (sizeof (struct section_stack));
+      elt = XNEW (struct section_stack);
       elt->next = section_stack;
       elt->seg = now_seg;
       elt->prev_seg = previous_section;
@@ -579,8 +593,10 @@ obj_elf_change_section (const char *name,
   previous_section = now_seg;
   previous_subsection = now_subseg;
 
+  match.group_name = group_name;
+  match.info = info;
   old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
-                                       (void *) group_name);
+                                       (void *) &match);
   if (old_sec)
     {
       sec = old_sec;
@@ -690,6 +706,9 @@ obj_elf_change_section (const char *name,
        attr |= ssect->attr;
     }
 
+  if ((attr & (SHF_ALLOC | SHF_GNU_MBIND)) == SHF_GNU_MBIND)
+    as_fatal (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
+
   /* Convert ELF type and flags to BFD flags.  */
   flags = (SEC_RELOC
           | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
@@ -715,6 +734,7 @@ obj_elf_change_section (const char *name,
        type = bfd_elf_get_default_section_type (flags);
       elf_section_type (sec) = type;
       elf_section_flags (sec) = attr;
+      elf_section_data (sec)->this_hdr.sh_info = info;
 
       /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
       if (type == SHT_NOBITS)
@@ -798,6 +818,9 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
        case 'T':
          attr |= SHF_TLS;
          break;
+       case 'd':
+         attr |= SHF_GNU_MBIND;
+         break;
        case '?':
          *is_clone = TRUE;
          break;
@@ -813,9 +836,11 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
                }
              break;
            }
+         /* Fall through.  */
        default:
          {
-           char *bad_msg = _("unrecognized .section attribute: want a,e,w,x,M,S,G,T or number");
+           const char *bad_msg = _("unrecognized .section attribute:"
+                                   " want a,e,w,x,M,S,G,T or number");
 #ifdef md_elf_section_letter
            bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
            if (md_attr != (bfd_vma) -1)
@@ -918,7 +943,7 @@ obj_elf_section_word (char *str, size_t len, int *type)
 }
 
 /* Get name of section.  */
-char *
+const char *
 obj_elf_section_name (void)
 {
   char *name;
@@ -948,9 +973,7 @@ obj_elf_section_name (void)
          return NULL;
        }
 
-      name = (char *) xmalloc (end - input_line_pointer + 1);
-      memcpy (name, input_line_pointer, end - input_line_pointer);
-      name[end - input_line_pointer] = '\0';
+      name = xmemdup0 (input_line_pointer, end - input_line_pointer);
 
       while (flag_sectname_subst)
         {
@@ -960,7 +983,7 @@ obj_elf_section_name (void)
              int oldlen = strlen (name);
              int substlen = strlen (now_seg->name);
              int newlen = oldlen - 2 + substlen;
-             char *newname = (char *) xmalloc (newlen + 1);
+             char *newname = XNEWVEC (char, newlen + 1);
              int headlen = subst - name;
              memcpy (newname, name, headlen);
              strcpy (newname + headlen, now_seg->name);
@@ -984,14 +1007,15 @@ obj_elf_section_name (void)
 void
 obj_elf_section (int push)
 {
-  char *name, *group_name, *beg;
+  const char *name, *group_name;
+  char *beg;
   int type, dummy;
   bfd_vma attr;
   int entsize;
   int linkonce;
   subsegT new_subsection = -1;
+  unsigned int info = 0;
 
-#ifndef TC_I370
   if (flag_mri)
     {
       char mri_type;
@@ -1011,7 +1035,6 @@ obj_elf_section (int push)
 
       return;
     }
-#endif /* ! defined (TC_I370) */
 
   name = obj_elf_section_name ();
   if (name == NULL)
@@ -1153,6 +1176,23 @@ obj_elf_section (int push)
                  linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
                }
            }
+
+         if ((attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
+           {
+             ++input_line_pointer;
+             SKIP_WHITESPACE ();
+             if (ISDIGIT (* input_line_pointer))
+               {
+                 char *t = input_line_pointer;
+                 info = strtoul (input_line_pointer,
+                                 &input_line_pointer, 0);
+                 if (info == (unsigned int) -1)
+                   {
+                     as_warn (_("unsupported mbind section info: %s"), t);
+                     info = 0;
+                   }
+               }
+           }
        }
       else
        {
@@ -1183,7 +1223,8 @@ obj_elf_section (int push)
 done:
   demand_empty_rest_of_line ();
 
-  obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
+  obj_elf_change_section (name, type, info, attr, entsize, group_name,
+                         linkonce, push);
 
   if (push && new_subsection != -1)
     subseg_set (now_seg, new_subsection);
@@ -1368,6 +1409,14 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
   c = get_symbol_name (& name);
   lex_type[(unsigned char) '@'] = old_lexat;
 
+  if (S_IS_COMMON (sym))
+    {
+      as_bad (_("`%s' can't be versioned to common symbol '%s'"),
+             name, S_GET_NAME (sym));
+      ignore_rest_of_line ();
+      return;
+    }
+
   if (symbol_get_obj (sym)->versioned_name == NULL)
     {
       symbol_get_obj (sym)->versioned_name = xstrdup (name);
@@ -1406,7 +1455,7 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
    syntax is ".vtable_inherit CHILDNAME, PARENTNAME".  */
 
 struct fix *
-obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
+obj_elf_get_vtable_inherit (void)
 {
   char *cname, *pname;
   symbolS *csym, *psym;
@@ -1470,12 +1519,21 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
                  0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
 }
 
+/* This is a version of obj_elf_get_vtable_inherit() that is
+   suitable for use in struct _pseudo_type tables.  */
+
+void
+obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
+{
+  (void) obj_elf_get_vtable_inherit ();
+}
+
 /* This handles the .vtable_entry pseudo-op, which is used to indicate
    to the linker that a vtable slot was used.  The syntax is
    ".vtable_entry tablename, offset".  */
 
 struct fix *
-obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
+obj_elf_get_vtable_entry (void)
 {
   symbolS *sym;
   offsetT offset;
@@ -1503,6 +1561,15 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
                  BFD_RELOC_VTABLE_ENTRY);
 }
 
+/* This is a version of obj_elf_get_vtable_entry() that is
+   suitable for use in struct _pseudo_type tables.  */
+
+void
+obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
+{
+  (void) obj_elf_get_vtable_entry ();
+}
+
 #define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
 
 static inline int
@@ -1607,9 +1674,7 @@ obj_elf_vendor_attribute (int vendor)
       if (i == 0)
        goto bad;
 
-      name = xmalloc (i + 1);
-      memcpy (name, s, i);
-      name[i] = '\0';
+      name = xstrndup (s, i);
 
 #ifndef CONVERT_SYMBOLIC_ATTRIBUTE
 #define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
@@ -1730,7 +1795,7 @@ elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
   if (srcelf->size)
     {
       if (destelf->size == NULL)
-       destelf->size = (expressionS *) xmalloc (sizeof (expressionS));
+       destelf->size = XNEW (expressionS);
       *destelf->size = *srcelf->size;
     }
   else
@@ -1777,6 +1842,7 @@ obj_elf_version (int ignore ATTRIBUTE_UNUSED)
       bfd_set_section_flags (stdoutput,
                             note_secp,
                             SEC_HAS_CONTENTS | SEC_READONLY);
+      record_alignment (note_secp, 2);
 
       /* Process the version string.  */
       len = strlen (name) + 1;
@@ -1847,8 +1913,7 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
     }
   else
     {
-      symbol_get_obj (sym)->size =
-          (expressionS *) xmalloc (sizeof (expressionS));
+      symbol_get_obj (sym)->size = XNEW (expressionS);
       *symbol_get_obj (sym)->size = exp;
     }
   demand_empty_rest_of_line ();
@@ -2061,10 +2126,8 @@ obj_elf_init_stab_section (segT seg)
   /* Zero it out.  */
   memset (p, 0, 12);
   file = as_where (NULL);
-  stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4);
-  strcpy (stabstr_name, segment_name (seg));
-  strcat (stabstr_name, "str");
-  stroff = get_stab_string_offset (file, stabstr_name);
+  stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
+  stroff = get_stab_string_offset (file, stabstr_name, TRUE);
   know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
   md_number_to_chars (p, stroff, 4);
   seg_info (seg)->stabu.p = p;
@@ -2236,6 +2299,13 @@ elf_frob_symbol (symbolS *symp, int *puntp)
              symp2 = symbol_find_or_make (sy_obj->versioned_name);
 
              /* Now we act as though we saw symp2 = sym.  */
+             if (S_IS_COMMON (symp))
+               {
+                 as_bad (_("`%s' can't be versioned to common symbol '%s'"),
+                         sy_obj->versioned_name, S_GET_NAME (symp));
+                 *puntp = TRUE;
+                 return;
+               }
 
              S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
 
@@ -2290,11 +2360,12 @@ elf_frob_symbol (symbolS *symp, int *puntp)
 struct group_list
 {
   asection **head;             /* Section lists.  */
-  unsigned int *elt_count;     /* Number of sections in each list.  */
   unsigned int num_group;      /* Number of lists.  */
   struct hash_control *indexes; /* Maps group name to index in head array.  */
 };
 
+static struct group_list groups;
+
 /* Called via bfd_map_over_sections.  If SEC is a member of a group,
    add it to a list of sections belonging to the group.  INF is a
    pointer to a struct group_list, which is where we store the head of
@@ -2319,7 +2390,6 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
     {
       elf_next_in_group (sec) = list->head[*elem_idx];
       list->head[*elem_idx] = sec;
-      list->elt_count[*elem_idx] += 1;
       return;
     }
 
@@ -2329,17 +2399,13 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
   if ((i & 127) == 0)
     {
       unsigned int newsize = i + 128;
-      list->head = (asection **) xrealloc (list->head,
-                                           newsize * sizeof (*list->head));
-      list->elt_count = (unsigned int *)
-          xrealloc (list->elt_count, newsize * sizeof (*list->elt_count));
+      list->head = XRESIZEVEC (asection *, list->head, newsize);
     }
   list->head[i] = sec;
-  list->elt_count[i] = 1;
   list->num_group += 1;
 
   /* Add index to hash.  */
-  idx_ptr = (unsigned int *) xmalloc (sizeof (unsigned int));
+  idx_ptr = XNEW (unsigned int);
   *idx_ptr = i;
   hash_insert (list->indexes, group_name, idx_ptr);
 }
@@ -2349,38 +2415,37 @@ static void free_section_idx (const char *key ATTRIBUTE_UNUSED, void *val)
   free ((unsigned int *) val);
 }
 
+/* Create symbols for group signature.  */
+
 void
 elf_adjust_symtab (void)
 {
-  struct group_list list;
   unsigned int i;
 
   /* Go find section groups.  */
-  list.num_group = 0;
-  list.head = NULL;
-  list.elt_count = NULL;
-  list.indexes = hash_new ();
-  bfd_map_over_sections (stdoutput, build_group_lists, &list);
+  groups.num_group = 0;
+  groups.head = NULL;
+  groups.indexes = hash_new ();
+  bfd_map_over_sections (stdoutput, build_group_lists, &groups);
 
   /* Make the SHT_GROUP sections that describe each section group.  We
      can't set up the section contents here yet, because elf section
      indices have yet to be calculated.  elf.c:set_group_contents does
      the rest of the work.  */
- for (i = 0; i < list.num_group; i++)
+ for (i = 0; i < groups.num_group; i++)
     {
-      const char *group_name = elf_group_name (list.head[i]);
+      const char *group_name = elf_group_name (groups.head[i]);
       const char *sec_name;
       asection *s;
       flagword flags;
       struct symbol *sy;
-      bfd_size_type size;
 
       flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
-      for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
+      for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
        if ((s->flags ^ flags) & SEC_LINK_ONCE)
          {
            flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
-           if (s != list.head[i])
+           if (s != groups.head[i])
              {
                as_warn (_("assuming all members of group `%s' are COMDAT"),
                         group_name);
@@ -2400,14 +2465,12 @@ elf_adjust_symtab (void)
       elf_section_type (s) = SHT_GROUP;
 
       /* Pass a pointer to the first section in this group.  */
-      elf_next_in_group (s) = list.head[i];
+      elf_next_in_group (s) = groups.head[i];
+      elf_sec_group (groups.head[i]) = s;
       /* Make sure that the signature symbol for the group has the
         name of the group.  */
       sy = symbol_find_exact (group_name);
-      if (!sy
-         || (sy != symbol_lastP
-             && (sy->sy_next == NULL
-                 || sy->sy_next->sy_previous != sy)))
+      if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
        {
          /* Create the symbol now.  */
          sy = symbol_new (group_name, now_seg, (valueT) 0, frag_now);
@@ -2422,17 +2485,7 @@ elf_adjust_symtab (void)
          symbol_table_insert (sy);
        }
       elf_group_id (s) = symbol_get_bfdsym (sy);
-
-      size = 4 * (list.elt_count[i] + 1);
-      bfd_set_section_size (stdoutput, s, size);
-      s->contents = (unsigned char *) frag_more (size);
-      frag_now->fr_fix = frag_now_fix_octets ();
-      frag_wane (frag_now);
     }
-
-  /* Cleanup hash.  */
-  hash_traverse (list.indexes, free_section_idx);
-  hash_die (list.indexes);
 }
 
 void
@@ -2496,6 +2549,31 @@ elf_frob_file_before_adjust (void)
 void
 elf_frob_file_after_relocs (void)
 {
+  unsigned int i;
+
+  /* Set SHT_GROUP section size.  */
+  for (i = 0; i < groups.num_group; i++)
+    {
+      asection *s, *head, *group;
+      bfd_size_type size;
+
+      head = groups.head[i];
+      size = 4;
+      for (s = head; s != NULL; s = elf_next_in_group (s))
+       size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
+
+      group = elf_sec_group (head);
+      subseg_set (group, 0);
+      bfd_set_section_size (stdoutput, group, size);
+      group->contents = (unsigned char *) frag_more (size);
+      frag_now->fr_fix = frag_now_fix_octets ();
+      frag_wane (frag_now);
+    }
+
+  /* Cleanup hash.  */
+  hash_traverse (groups.indexes, free_section_idx);
+  hash_die (groups.indexes);
+
 #ifdef NEED_ECOFF_DEBUG
   if (ECOFF_DEBUGGING)
     /* Generate the ECOFF debugging information.  */
@@ -2566,103 +2644,6 @@ elf_frob_file_after_relocs (void)
 #endif /* NEED_ECOFF_DEBUG */
 }
 
-#ifdef SCO_ELF
-
-/* Heavily plagiarized from obj_elf_version.  The idea is to emit the
-   SCO specific identifier in the .notes section to satisfy the SCO
-   linker.
-
-   This looks more complicated than it really is.  As opposed to the
-   "obvious" solution, this should handle the cross dev cases
-   correctly.  (i.e, hosting on a 64 bit big endian processor, but
-   generating SCO Elf code) Efficiency isn't a concern, as there
-   should be exactly one of these sections per object module.
-
-   SCO OpenServer 5 identifies it's ELF modules with a standard ELF
-   .note section.
-
-   int_32 namesz  = 4 ;  Name size
-   int_32 descsz  = 12 ; Descriptive information
-   int_32 type    = 1 ;
-   char   name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
-   int_32 version = (major ver # << 16)  | version of tools ;
-   int_32 source  = (tool_id << 16 ) | 1 ;
-   int_32 info    = 0 ;    These are set by the SCO tools, but we
-                          don't know enough about the source
-                          environment to set them.  SCO ld currently
-                          ignores them, and recommends we set them
-                          to zero.  */
-
-#define SCO_MAJOR_VERSION 0x1
-#define SCO_MINOR_VERSION 0x1
-
-void
-sco_id (void)
-{
-
-  char *name;
-  unsigned int c;
-  char ch;
-  char *p;
-  asection *seg = now_seg;
-  subsegT subseg = now_subseg;
-  Elf_Internal_Note i_note;
-  Elf_External_Note e_note;
-  asection *note_secp = NULL;
-  int i, len;
-
-  /* create the .note section */
-
-  note_secp = subseg_new (".note", 0);
-  bfd_set_section_flags (stdoutput,
-                        note_secp,
-                        SEC_HAS_CONTENTS | SEC_READONLY);
-
-  /* process the version string */
-
-  i_note.namesz = 4;
-  i_note.descsz = 12;          /* 12 descriptive bytes */
-  i_note.type = NT_VERSION;    /* Contains a version string */
-
-  p = frag_more (sizeof (i_note.namesz));
-  md_number_to_chars (p, i_note.namesz, 4);
-
-  p = frag_more (sizeof (i_note.descsz));
-  md_number_to_chars (p, i_note.descsz, 4);
-
-  p = frag_more (sizeof (i_note.type));
-  md_number_to_chars (p, i_note.type, 4);
-
-  p = frag_more (4);
-  strcpy (p, "SCO");
-
-  /* Note: this is the version number of the ELF we're representing */
-  p = frag_more (4);
-  md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
-
-  /* Here, we pick a magic number for ourselves (yes, I "registered"
-     it with SCO.  The bottom bit shows that we are compat with the
-     SCO ABI.  */
-  p = frag_more (4);
-  md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
-
-  /* If we knew (or cared) what the source language options were, we'd
-     fill them in here.  SCO has given us permission to ignore these
-     and just set them to zero.  */
-  p = frag_more (4);
-  md_number_to_chars (p, 0x0000, 4);
-
-  frag_align (2, 0, 0);
-
-  /* We probably can't restore the current segment, for there likely
-     isn't one yet...  */
-  if (seg && subseg)
-    subseg_set (seg, subseg);
-
-}
-
-#endif /* SCO_ELF */
-
 static void
 elf_generate_asm_lineno (void)
 {