gas output_file_close error message
[deliverable/binutils-gdb.git] / gas / config / obj-coff.c
index fec65899e6ed8ee93262656c6e9e1b486dfa71f0..a0a30f469b9cc26eb5a06c799f3ac98c44197735 100644 (file)
@@ -1,7 +1,5 @@
 /* coff object file format
-   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1989-2020 Free Software Foundation, Inc.
 
    This file is part of GAS.
 
 
 #include "as.h"
 #include "safe-ctype.h"
-#include "obstack.h"
 #include "subsegs.h"
 
 #ifdef TE_PE
 #include "coff/pe.h"
 #endif
 
+#ifdef OBJ_XCOFF
+#include "coff/xcoff.h"
+#endif
+
 #define streq(a,b)     (strcmp ((a), (b)) == 0)
 #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
 
@@ -75,10 +76,8 @@ stack_init (unsigned long chunk_size,
 {
   stack *st;
 
-  st = malloc (sizeof (* st));
-  if (!st)
-    return NULL;
-  st->data = malloc (chunk_size);
+  st = XNEW (stack);
+  st->data = XNEWVEC (char, chunk_size);
   if (!st->data)
     {
       free (st);
@@ -97,8 +96,7 @@ stack_push (stack *st, char *element)
   if (st->pointer + st->element_size >= st->size)
     {
       st->size += st->chunk_size;
-      if ((st->data = xrealloc (st->data, st->size)) == NULL)
-       return NULL;
+      st->data = XRESIZEVEC (char, st->data, st->size);
     }
   memcpy (st->data + st->pointer, element, st->element_size);
   st->pointer += st->element_size;
@@ -119,28 +117,24 @@ stack_pop (stack *st)
 \f
 /* Maintain a list of the tagnames of the structures.  */
 
-static struct hash_control *tag_hash;
+static htab_t tag_hash;
 
 static void
 tag_init (void)
 {
-  tag_hash = hash_new ();
+  tag_hash = str_htab_create ();
 }
 
 static void
 tag_insert (const char *name, symbolS *symbolP)
 {
-  const char *error_string;
-
-  if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
-    as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
-             name, error_string);
+  str_hash_insert (tag_hash, name, symbolP, 1);
 }
 
 static symbolS *
 tag_find (char *name)
 {
-  return (symbolS *) hash_find (tag_hash, name);
+  return (symbolS *) str_hash_find (tag_hash, name);
 }
 
 static symbolS *
@@ -150,8 +144,7 @@ tag_find_or_make (char *name)
 
   if ((symbolP = tag_find (name)) == NULL)
     {
-      symbolP = symbol_new (name, undefined_section,
-                           0, &zero_address_frag);
+      symbolP = symbol_new (name, undefined_section, &zero_address_frag, 0);
 
       tag_insert (S_GET_NAME (symbolP), symbolP);
       symbol_table_insert (symbolP);
@@ -207,13 +200,12 @@ obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT s
       char numbuff[20];
 
       sec = subseg_new (".drectve", 0);
-      oldflags = bfd_get_section_flags (stdoutput, sec);
+      oldflags = bfd_section_flags (sec);
       if (oldflags == SEC_NO_FLAGS)
        {
-         if (!bfd_set_section_flags (stdoutput, sec,
-               TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
+         if (!bfd_set_section_flags (sec, TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
            as_warn (_("error setting flags for \"%s\": %s"),
-               bfd_section_name (stdoutput, sec),
+               bfd_section_name (sec),
                bfd_errmsg (bfd_get_error ()));
        }
 
@@ -237,9 +229,6 @@ obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
 }
 #endif /* TE_PE */
 
-#define GET_FILENAME_STRING(X) \
-  ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
-
 /* @@ Ick.  */
 static segT
 fetch_coff_debug_section (void)
@@ -334,7 +323,7 @@ c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
 
   /* BFD converts filename to a .file symbol with an aux entry.  It
      also handles chaining.  */
-  symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
+  symbolP = symbol_new (filename, bfd_abs_section_ptr, &zero_address_frag, 0);
 
   S_SET_STORAGE_CLASS (symbolP, C_FILE);
   S_SET_NUMBER_AUXILIARY (symbolP, 1);
@@ -381,10 +370,11 @@ void
 coff_obj_symbol_new_hook (symbolS *symbolP)
 {
   long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
-  char * s  = xmalloc (sz);
+  char * s  = XNEWVEC (char, sz);
 
   memset (s, 0, sz);
   coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
+  coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
 
   S_SET_DATA_TYPE (symbolP, T_NULL);
   S_SET_STORAGE_CLASS (symbolP, 0);
@@ -400,10 +390,11 @@ coff_obj_symbol_new_hook (symbolS *symbolP)
 void
 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
 {
-  long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
-  combined_entry_type * s = xmalloc (sz);
+  long elts = OBJ_COFF_MAX_AUXENTRIES + 1;
+  combined_entry_type * s = XNEWVEC (combined_entry_type, elts);
 
-  memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
+  memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native,
+         elts * sizeof (combined_entry_type));
   coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
 
   SF_SET (newsymP, SF_GET (orgsymP));
@@ -420,7 +411,7 @@ int coff_n_line_nos;
 static void
 add_lineno (fragS * frag, addressT offset, int num)
 {
-  struct line_no * new_line = xmalloc (sizeof (* new_line));
+  struct line_no * new_line = XNEW (struct line_no);
 
   if (!current_lineno_sym)
     abort ();
@@ -557,7 +548,7 @@ obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
        that shouldn't be loaded into memory, which requires linker
        changes...  For now, until proven otherwise, use .rdata.  */
     sec = subseg_new (".rdata$zzz", 0);
-    bfd_set_section_flags (stdoutput, sec,
+    bfd_set_section_flags (sec,
                           ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
                            & bfd_applicable_section_flags (stdoutput)));
   }
@@ -589,7 +580,6 @@ obj_coff_def (int what ATTRIBUTE_UNUSED)
   char name_end;               /* Char after the end of name.  */
   char *symbol_name;           /* Name of the debug symbol.  */
   char *symbol_name_copy;      /* Temporary copy of the name.  */
-  unsigned int symbol_name_length;
 
   if (def_symbol_in_progress != NULL)
     {
@@ -600,11 +590,8 @@ obj_coff_def (int what ATTRIBUTE_UNUSED)
 
   SKIP_WHITESPACES ();
 
-  symbol_name = input_line_pointer;
-  name_end = get_symbol_end ();
-  symbol_name_length = strlen (symbol_name);
-  symbol_name_copy = xmalloc (symbol_name_length + 1);
-  strcpy (symbol_name_copy, symbol_name);
+  name_end = get_symbol_name (&symbol_name);
+  symbol_name_copy = xstrdup (symbol_name);
 #ifdef tc_canonicalize_symbol_name
   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
 #endif
@@ -617,7 +604,7 @@ obj_coff_def (int what ATTRIBUTE_UNUSED)
   if (S_IS_STRING (def_symbol_in_progress))
     SF_SET_STRING (def_symbol_in_progress);
 
-  *input_line_pointer = name_end;
+  (void) restore_line_pointer (name_end);
 
   demand_empty_rest_of_line ();
 }
@@ -781,8 +768,7 @@ obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
 
   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
-      || (streq (bfd_get_section_name (stdoutput,
-                                      S_GET_SEGMENT (def_symbol_in_progress)),
+      || (streq (bfd_section_name (S_GET_SEGMENT (def_symbol_in_progress)),
                 "*DEBUG*")
          && !SF_GET_TAG (def_symbol_in_progress))
       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
@@ -932,7 +918,7 @@ obj_coff_size (int ignore ATTRIBUTE_UNUSED)
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
+      as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -947,7 +933,7 @@ obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
+      as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -964,14 +950,13 @@ obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
 
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
+      as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
 
   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
-  symbol_name = input_line_pointer;
-  name_end = get_symbol_end ();
+  name_end = get_symbol_name (&symbol_name);
 
 #ifdef tc_canonicalize_symbol_name
   symbol_name = tc_canonicalize_symbol_name (symbol_name);
@@ -985,8 +970,8 @@ obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
     as_warn (_("tag not found for .tag %s"), symbol_name);
 
   SF_SET_TAGGED (def_symbol_in_progress);
-  *input_line_pointer = name_end;
 
+  (void) restore_line_pointer (name_end);
   demand_empty_rest_of_line ();
 }
 
@@ -995,7 +980,7 @@ obj_coff_type (int ignore ATTRIBUTE_UNUSED)
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
+      as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
@@ -1014,18 +999,18 @@ obj_coff_val (int ignore ATTRIBUTE_UNUSED)
 {
   if (def_symbol_in_progress == NULL)
     {
-      as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
+      as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
       demand_empty_rest_of_line ();
       return;
     }
 
   if (is_name_beginner (*input_line_pointer))
     {
-      char *symbol_name = input_line_pointer;
-      char name_end = get_symbol_end ();
+      char *symbol_name;
+      char name_end = get_symbol_name (&symbol_name);
 
 #ifdef tc_canonicalize_symbol_name
-  symbol_name = tc_canonicalize_symbol_name (symbol_name);
+      symbol_name = tc_canonicalize_symbol_name (symbol_name);
 #endif
       if (streq (symbol_name, "."))
        {
@@ -1056,7 +1041,7 @@ obj_coff_val (int ignore ATTRIBUTE_UNUSED)
        }
       /* Otherwise, it is the name of a non debug symbol and its value
          will be calculated later.  */
-      *input_line_pointer = name_end;
+      (void) restore_line_pointer (name_end);
     }
   else
     {
@@ -1082,11 +1067,7 @@ weak_is_altname (const char * name)
 static const char *
 weak_name2altname (const char * name)
 {
-  char *alt_name;
-
-  alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
-  strcpy (alt_name, weak_altprefix);
-  return strcat (alt_name, name);
+  return concat (weak_altprefix, name, (char *) NULL);
 }
 
 /* Return the name of the weak symbol corresponding to an
@@ -1105,7 +1086,6 @@ weak_altname2name (const char * name)
 static const char *
 weak_uniquify (const char * name)
 {
-  char *ret;
   const char * unique = "";
 
 #ifdef TE_PE
@@ -1114,11 +1094,7 @@ weak_uniquify (const char * name)
 #endif
   gas_assert (weak_is_altname (name));
 
-  ret = xmalloc (strlen (name) + strlen (unique) + 2);
-  strcpy (ret, name);
-  strcat (ret, ".");
-  strcat (ret, unique);
-  return ret;
+  return concat (name, ".", unique, (char *) NULL);
 }
 
 void
@@ -1167,8 +1143,7 @@ obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       if (*name == 0)
        {
          as_warn (_("badly formed .weak directive ignored"));
@@ -1178,7 +1153,7 @@ obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
       c = 0;
       symbolP = symbol_find_or_make (name);
       *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       S_SET_WEAK (symbolP);
 
       if (c == ',')
@@ -1355,7 +1330,8 @@ coff_frob_symbol (symbolS *symp, int *punt)
                }
            }
 
-         if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
+         if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
+             && S_IS_DEFINED (symp))
            {
              union internal_auxent *auxp;
 
@@ -1367,7 +1343,8 @@ coff_frob_symbol (symbolS *symp, int *punt)
                      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
            }
 
-         if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
+         if (S_GET_STORAGE_CLASS (symp) == C_EFCN
+             && S_IS_DEFINED (symp))
            {
              if (coff_last_function == 0)
                as_fatal (_("C_EFCN symbol for %s out of scope"),
@@ -1453,7 +1430,7 @@ coff_frob_symbol (symbolS *symp, int *punt)
       /* We need i entries for line numbers, plus 1 for the first
         entry which BFD will override, plus 1 for the last zero
         entry (a marker for BFD).  */
-      l = xmalloc ((i + 2) * sizeof (* l));
+      l = XNEWVEC (alent, (i + 2));
       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
       l[i + 1].line_number = 0;
       l[i + 1].u.sym = NULL;
@@ -1496,7 +1473,7 @@ coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
        fixp = fixp->fx_next;
       }
   }
-  if (bfd_get_section_size (sec) == 0
+  if (bfd_section_size (sec) == 0
       && nrelocs == 0
       && nlnno == 0
       && sec != text_section
@@ -1527,6 +1504,7 @@ coff_frob_file_after_relocs (void)
                                                  'o' for over
                                                  'w' for data
                                                 'd' (apparently m88k for data)
+                                                'e' for exclude
                                                  'x' for text
                                                 'r' for read-only data
                                                 's' for shared data (PE)
@@ -1549,6 +1527,7 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
   unsigned int exp;
   flagword flags, oldflags;
   asection *sec;
+  bfd_boolean is_bss = FALSE;
 
   if (flag_mri)
     {
@@ -1558,15 +1537,10 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
       return;
     }
 
-  section_name = input_line_pointer;
-  c = get_symbol_end ();
-
-  name = xmalloc (input_line_pointer - section_name + 1);
-  strcpy (name, section_name);
-
+  c = get_symbol_name (&section_name);
+  name = xmemdup0 (section_name, input_line_pointer - section_name);
   *input_line_pointer = c;
-
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
 
   exp = 0;
   flags = SEC_NO_FLAGS;
@@ -1594,10 +1568,16 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
                }
              switch (attr)
                {
+               case 'e':
+                 /* Exclude section from linking.  */
+                 flags |= SEC_EXCLUDE;
+                 break;
+
                case 'b':
                  /* Uninitialised data section.  */
                  flags |= SEC_ALLOC;
                  flags &=~ SEC_LOAD;
+                 is_bss = TRUE;
                  break;
 
                case 'n':
@@ -1668,10 +1648,14 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
     }
 
   sec = subseg_new (name, (subsegT) exp);
+
+  if (is_bss)
+    seg_info (sec)->bss = 1;
+
   if (alignment >= 0)
     sec->alignment_power = alignment;
 
-  oldflags = bfd_get_section_flags (stdoutput, sec);
+  oldflags = bfd_section_flags (sec);
   if (oldflags == SEC_NO_FLAGS)
     {
       /* Set section flags for a new section just created by subseg_new.
@@ -1687,9 +1671,9 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
        flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
 #endif
 
-      if (! bfd_set_section_flags (stdoutput, sec, flags))
+      if (!bfd_set_section_flags (sec, flags))
        as_warn (_("error setting flags for \"%s\": %s"),
-                bfd_section_name (stdoutput, sec),
+                bfd_section_name (sec),
                 bfd_errmsg (bfd_get_error ()));
     }
   else if (flags != SEC_NO_FLAGS)
@@ -1727,7 +1711,7 @@ coff_frob_section (segT sec)
      supposedly because standard COFF has no other way of encoding alignment
      for sections.  If your COFF flavor has a different way of encoding
      section alignment, then skip this step, as TICOFF does.  */
-  bfd_vma size = bfd_get_section_size (sec);
+  bfd_vma size = bfd_section_size (sec);
 #if !defined(TICOFF)
   bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
   bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
@@ -1738,7 +1722,7 @@ coff_frob_section (segT sec)
       fragS *last;
 
       new_size = (size + mask) & ~mask;
-      bfd_set_section_size (stdoutput, sec, new_size);
+      bfd_set_section_size (sec, new_size);
 
       /* If the size had to be rounded up, add some padding in
          the last non-empty frag.  */
@@ -1762,8 +1746,13 @@ coff_frob_section (segT sec)
 #endif
     {
       symbolS *secsym = section_symbol (sec);
+      unsigned char sclass = C_STAT;
 
-      S_SET_STORAGE_CLASS (secsym, C_STAT);
+#ifdef OBJ_XCOFF
+      if (bfd_section_flags (sec) & SEC_DEBUGGING)
+        sclass = C_DWARF;
+#endif
+      S_SET_STORAGE_CLASS (secsym, sclass);
       S_SET_NUMBER_AUXILIARY (secsym, 1);
       SF_SET_STATICS (secsym);
       SA_SET_SCN_SCNLEN (secsym, size);
@@ -1781,9 +1770,9 @@ coff_frob_section (segT sec)
   strsec = sec;
   sec = subseg_get (STAB_SECTION_NAME, 0);
   /* size is already rounded up, since other section will be listed first */
-  size = bfd_get_section_size (strsec);
+  size = bfd_section_size (strsec);
 
-  n_entries = bfd_get_section_size (sec) / 12 - 1;
+  n_entries = bfd_section_size (sec) / 12 - 1;
 
   /* Find first non-empty frag.  It should be large enough.  */
   fragp = seg_info (sec)->frchainP->frch_root;
@@ -1800,7 +1789,7 @@ coff_frob_section (segT sec)
 void
 obj_coff_init_stab_section (segT seg)
 {
-  char *file;
+  const char *file;
   char *p;
   char *stabstr_name;
   unsigned int stroff;
@@ -1809,11 +1798,9 @@ obj_coff_init_stab_section (segT seg)
   p = frag_more (12);
   /* Zero it out.  */
   memset (p, 0, 12);
-  as_where (&file, (unsigned int *) NULL);
-  stabstr_name = xmalloc (strlen (seg->name) + 4);
-  strcpy (stabstr_name, seg->name);
-  strcat (stabstr_name, "str");
-  stroff = get_stab_string_offset (file, stabstr_name);
+  file = as_where ((unsigned int *) NULL);
+  stabstr_name = concat (seg->name, "str", (char *) NULL);
+  stroff = get_stab_string_offset (file, stabstr_name, TRUE);
   know (stroff == 1);
   md_number_to_chars (p, stroff, 4);
 }
This page took 0.045627 seconds and 4 git commands to generate.