use xstrdup, xmemdup0 and concat more
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
index 30eb8163ddea395a4f0ff5aff30ff930c76dbd77..b7eb7c1d41e892e13bfffb0ffb044c1c33ea973c 100644 (file)
@@ -1,7 +1,5 @@
 /* ELF object file format
-   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1992-2016 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 #include "elf/mep.h"
 #endif
 
+#ifdef TC_NIOS2
+#include "elf/nios2.h"
+#endif
+
 static void obj_elf_line (int);
 static void obj_elf_size (int);
 static void obj_elf_type (int);
@@ -72,6 +74,7 @@ static void obj_elf_visibility (int);
 static void obj_elf_symver (int);
 static void obj_elf_subsection (int);
 static void obj_elf_popsection (int);
+static void obj_elf_gnu_attribute (int);
 static void obj_elf_tls_common (int);
 static void obj_elf_lcomm (int);
 static void obj_elf_struct (int);
@@ -113,6 +116,9 @@ static const pseudo_typeS elf_pseudo_table[] =
   {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
   {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
 
+  /* A GNU extension for object attributes.  */
+  {"gnu_attribute", obj_elf_gnu_attribute, 0},
+
   /* These are used for dwarf.  */
   {"2byte", cons, 2},
   {"4byte", cons, 4},
@@ -260,7 +266,7 @@ elf_file_symbol (const char *s, int appfile)
       || (symbol_rootP->bsym->flags & BSF_FILE) == 0)
     {
       symbolS *sym;
-      unsigned int name_length;
+      size_t name_length;
 
       sym = symbol_new (s, absolute_section, 0, NULL);
       symbol_set_frag (sym, &zero_address_frag);
@@ -276,14 +282,17 @@ elf_file_symbol (const char *s, int appfile)
 
       symbol_get_bfdsym (sym)->flags |= BSF_FILE;
 
-      if (symbol_rootP != sym)
+      if (symbol_rootP != sym
+         && (symbol_rootP->bsym == NULL
+             || !(symbol_rootP->bsym->flags & BSF_FILE)))
        {
          symbol_remove (sym, &symbol_rootP, &symbol_lastP);
          symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
+       }
+
 #ifdef DEBUG
-         verify_symbol_chain (symbol_rootP, symbol_lastP);
+      verify_symbol_chain (symbol_rootP, symbol_lastP);
 #endif
-       }
     }
 
 #ifdef NEED_ECOFF_DEBUG
@@ -400,11 +409,10 @@ get_sym_from_input_line_and_check (void)
   char c;
   symbolS *sym;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (& name);
   sym = symbol_find_or_make (name);
   *input_line_pointer = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
 
   /* There is no symbol name if input_line_pointer has not moved.  */
   if (name == input_line_pointer)
@@ -447,7 +455,6 @@ obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
       symbolP = get_sym_from_input_line_and_check ();
       c = *input_line_pointer;
       S_SET_WEAK (symbolP);
-      symbol_get_obj (symbolP)->local = 1;
       if (c == ',')
        {
          input_line_pointer++;
@@ -540,7 +547,7 @@ get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 
 void
 obj_elf_change_section (const char *name,
-                       int type,
+                       unsigned int type,
                        bfd_vma attr,
                        int entsize,
                        const char *group_name,
@@ -561,7 +568,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;
@@ -614,7 +621,9 @@ obj_elf_change_section (const char *name,
              && ssect->type != SHT_PREINIT_ARRAY)
            {
              /* We allow to specify any type for a .note section.  */
-             if (ssect->type != SHT_NOTE)
+             if (ssect->type != SHT_NOTE
+                 /* Processor and application defined types are allowed too.  */
+                 && type < SHT_LOPROC)
                as_warn (_("setting incorrect section type for %s"),
                         name);
            }
@@ -626,7 +635,8 @@ obj_elf_change_section (const char *name,
            }
        }
 
-      if (old_sec == NULL && (attr & ~ssect->attr) != 0)
+      if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
+                             & ~ssect->attr) != 0)
        {
          /* As a GNU extension, we permit a .note section to be
             allocatable.  If the linker sees an allocatable .note
@@ -658,6 +668,14 @@ obj_elf_change_section (const char *name,
          /* A section on Alpha may have SHF_ALPHA_GPREL.  */
          else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
            override = TRUE;
+#endif
+#ifdef TC_RX
+         else if (attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
+                  && (ssect->type == SHT_INIT_ARRAY
+                      || ssect->type == SHT_FINI_ARRAY
+                      || ssect->type == SHT_PREINIT_ARRAY))
+           /* RX init/fini arrays can and should have the "awx" attributes set.  */
+           ;
 #endif
          else
            {
@@ -667,6 +685,7 @@ obj_elf_change_section (const char *name,
              override = TRUE;
            }
        }
+
       if (!override && old_sec == NULL)
        attr |= ssect->attr;
     }
@@ -730,6 +749,11 @@ obj_elf_change_section (const char *name,
                  | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
                  | SEC_THREAD_LOCAL)))
            as_warn (_("ignoring changed section attributes for %s"), name);
+         else
+           /* FIXME: Maybe we should consider removing a previously set
+              processor or application specific attribute as suspicious ?  */
+           elf_section_flags (sec) = attr;
+
          if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
            as_warn (_("ignoring changed section entity size for %s"), name);
        }
@@ -741,10 +765,10 @@ obj_elf_change_section (const char *name,
 }
 
 static bfd_vma
-obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *clone)
+obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
 {
   bfd_vma attr = 0;
-  *clone = FALSE;
+  *is_clone = FALSE;
 
   while (len > 0)
     {
@@ -775,7 +799,7 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *clone)
          attr |= SHF_TLS;
          break;
        case '?':
-         *clone = TRUE;
+         *is_clone = TRUE;
          break;
        /* Compatibility.  */
        case 'm':
@@ -791,14 +815,27 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *clone)
            }
        default:
          {
-           char *bad_msg = _("unrecognized .section attribute: want a,e,w,x,M,S,G,T");
+           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)
              attr |= md_attr;
            else
 #endif
-             as_fatal ("%s", bad_msg);
+             if (ISDIGIT (*str))
+               {
+                 char * end;
+
+                 attr |= strtoul (str, & end, 0);
+                 /* Update str and len, allowing for the fact that
+                    we will execute str++ and len-- below.  */
+                 end --;
+                 len -= (end - str);
+                 str = end;
+               }
+             else
+               as_fatal ("%s", bad_msg);
          }
          break;
        }
@@ -832,6 +869,17 @@ obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
   }
 #endif
 
+  if (ISDIGIT (*str))
+    {
+      char * end;
+      int type = strtoul (str, & end, 0);
+
+      if (warn && (size_t) (end - str) != len)
+       as_warn (_("extraneous characters at end of numeric section type"));
+
+      return type;
+    }
+
   if (warn)
     as_warn (_("unrecognized section type"));
   return 0;
@@ -871,7 +919,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;
@@ -901,9 +949,28 @@ 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)
+        {
+         char *subst = strchr (name, '%');
+         if (subst && subst[1] == 'S')
+           {
+             int oldlen = strlen (name);
+             int substlen = strlen (now_seg->name);
+             int newlen = oldlen - 2 + substlen;
+             char *newname = (char *) xmalloc (newlen + 1);
+             int headlen = subst - name;
+             memcpy (newname, name, headlen);
+             strcpy (newname + headlen, now_seg->name);
+             strcat (newname + headlen, subst + 2);
+             xfree (name);
+             name = newname;
+           }
+         else
+           break;
+       }
+
 #ifdef tc_canonicalize_section_name
       name = tc_canonicalize_section_name (name);
 #endif
@@ -916,7 +983,8 @@ 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;
@@ -978,16 +1046,15 @@ obj_elf_section (int push)
 
       if (*input_line_pointer == '"')
        {
-         bfd_boolean clone;
+         bfd_boolean is_clone;
 
          beg = demand_copy_C_string (&dummy);
          if (beg == NULL)
            {
              ignore_rest_of_line ();
-             xfree (name);
              return;
            }
-         attr |= obj_elf_parse_section_letters (beg, strlen (beg), &clone);
+         attr |= obj_elf_parse_section_letters (beg, strlen (beg), &is_clone);
 
          SKIP_WHITESPACE ();
          if (*input_line_pointer == ',')
@@ -1004,17 +1071,24 @@ obj_elf_section (int push)
                  if (beg == NULL)
                    {
                      ignore_rest_of_line ();
-                     xfree (name);
                      return;
                    }
                  type = obj_elf_section_type (beg, strlen (beg), TRUE);
                }
              else if (c == '@' || c == '%')
                {
-                 beg = ++input_line_pointer;
-                 c = get_symbol_end ();
-                 *input_line_pointer = c;
-                 type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
+                 ++input_line_pointer;
+
+                 if (ISDIGIT (* input_line_pointer))
+                   {
+                     type = strtoul (input_line_pointer, & input_line_pointer, 0);
+                   }
+                 else
+                   {
+                     c = get_symbol_name (& beg);
+                     (void) restore_line_pointer (c);
+                     type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
+                   }
                }
              else
                input_line_pointer = save;
@@ -1040,10 +1114,10 @@ obj_elf_section (int push)
              attr &= ~SHF_MERGE;
            }
 
-         if ((attr & SHF_GROUP) != 0 && clone)
+         if ((attr & SHF_GROUP) != 0 && is_clone)
            {
              as_warn (_("? section flag ignored with G present"));
-             clone = FALSE;
+             is_clone = FALSE;
            }
          if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
            {
@@ -1051,10 +1125,15 @@ obj_elf_section (int push)
              group_name = obj_elf_section_name ();
              if (group_name == NULL)
                attr &= ~SHF_GROUP;
-             else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
+             else if (*input_line_pointer == ',')
                {
-                 input_line_pointer += 7;
-                 linkonce = 1;
+                 ++input_line_pointer;
+                 SKIP_WHITESPACE ();
+                 if (strncmp (input_line_pointer, "comdat", 6) == 0)
+                   {
+                     input_line_pointer += 6;
+                     linkonce = 1;
+                   }
                }
              else if (strncmp (name, ".gnu.linkonce", 13) == 0)
                linkonce = 1;
@@ -1065,7 +1144,7 @@ obj_elf_section (int push)
              attr &= ~SHF_GROUP;
            }
 
-         if (clone)
+         if (is_clone)
            {
              const char *now_group = elf_group_name (now_seg);
              if (now_group != NULL)
@@ -1086,12 +1165,11 @@ obj_elf_section (int push)
                {
                  as_bad (_("character following name is not '#'"));
                  ignore_rest_of_line ();
-                 xfree (name);
                  return;
                }
-             beg = ++input_line_pointer;
-             c = get_symbol_end ();
-             *input_line_pointer = c;
+             ++input_line_pointer;
+             c = get_symbol_name (& beg);
+             (void) restore_line_pointer (c);
 
              attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
 
@@ -1283,19 +1361,18 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
 
   ++input_line_pointer;
   SKIP_WHITESPACE ();
-  name = input_line_pointer;
 
   /* Temporarily include '@' in symbol names.  */
   old_lexat = lex_type[(unsigned char) '@'];
   lex_type[(unsigned char) '@'] |= LEX_NAME;
-  c = get_symbol_end ();
+  c = get_symbol_name (& name);
   lex_type[(unsigned char) '@'] = old_lexat;
 
   if (symbol_get_obj (sym)->versioned_name == NULL)
     {
       symbol_get_obj (sym)->versioned_name = xstrdup (name);
 
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
 
       if (strchr (symbol_get_obj (sym)->versioned_name,
                  ELF_VER_CHR) == NULL)
@@ -1318,7 +1395,7 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
          return;
        }
 
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
     }
 
   demand_empty_rest_of_line ();
@@ -1338,8 +1415,7 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
   if (*input_line_pointer == '#')
     ++input_line_pointer;
 
-  cname = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (& cname);
   csym = symbol_find (cname);
 
   /* GCFIXME: should check that we don't have two .vtable_inherits for
@@ -1355,7 +1431,7 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
 
   *input_line_pointer = c;
 
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("expected comma after name in .vtable_inherit"));
@@ -1378,10 +1454,9 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
     }
   else
     {
-      pname = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& pname);
       psym = symbol_find_or_make (pname);
-      *input_line_pointer = c;
+      restore_line_pointer (c);
     }
 
   demand_empty_rest_of_line ();
@@ -1428,6 +1503,195 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
                  BFD_RELOC_VTABLE_ENTRY);
 }
 
+#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
+
+static inline int
+skip_past_char (char ** str, char c)
+{
+  if (**str == c)
+    {
+      (*str)++;
+      return 0;
+    }
+  else
+    return -1;
+}
+#define skip_past_comma(str) skip_past_char (str, ',')
+
+/* A list of attributes that have been explicitly set by the assembly code.
+   VENDOR is the vendor id, BASE is the tag shifted right by the number
+   of bits in MASK, and bit N of MASK is set if tag BASE+N has been set.  */
+struct recorded_attribute_info {
+  struct recorded_attribute_info *next;
+  int vendor;
+  unsigned int base;
+  unsigned long mask;
+};
+static struct recorded_attribute_info *recorded_attributes;
+
+/* Record that we have seen an explicit specification of attribute TAG
+   for vendor VENDOR.  */
+
+static void
+record_attribute (int vendor, unsigned int tag)
+{
+  unsigned int base;
+  unsigned long mask;
+  struct recorded_attribute_info *rai;
+
+  base = tag / (8 * sizeof (rai->mask));
+  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+  for (rai = recorded_attributes; rai; rai = rai->next)
+    if (rai->vendor == vendor && rai->base == base)
+      {
+       rai->mask |= mask;
+       return;
+      }
+
+  rai = XNEW (struct recorded_attribute_info);
+  rai->next = recorded_attributes;
+  rai->vendor = vendor;
+  rai->base = base;
+  rai->mask = mask;
+  recorded_attributes = rai;
+}
+
+/* Return true if we have seen an explicit specification of attribute TAG
+   for vendor VENDOR.  */
+
+bfd_boolean
+obj_elf_seen_attribute (int vendor, unsigned int tag)
+{
+  unsigned int base;
+  unsigned long mask;
+  struct recorded_attribute_info *rai;
+
+  base = tag / (8 * sizeof (rai->mask));
+  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+  for (rai = recorded_attributes; rai; rai = rai->next)
+    if (rai->vendor == vendor && rai->base == base)
+      return (rai->mask & mask) != 0;
+  return FALSE;
+}
+
+/* Parse an attribute directive for VENDOR.
+   Returns the attribute number read, or zero on error.  */
+
+int
+obj_elf_vendor_attribute (int vendor)
+{
+  expressionS exp;
+  int type;
+  int tag;
+  unsigned int i = 0;
+  char *s = NULL;
+
+  /* Read the first number or name.  */
+  skip_whitespace (input_line_pointer);
+  s = input_line_pointer;
+  if (ISDIGIT (*input_line_pointer))
+    {
+      expression (& exp);
+      if (exp.X_op != O_constant)
+       goto bad;
+      tag = exp.X_add_number;
+    }
+  else
+    {
+      char *name;
+
+      /* A name may contain '_', but no other punctuation.  */
+      for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
+          ++input_line_pointer)
+       i++;
+      if (i == 0)
+       goto bad;
+
+      name = xstrndup (s, i);
+
+#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
+#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
+#endif
+
+      tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
+      if (tag == -1)
+       {
+         as_bad (_("Attribute name not recognised: %s"), name);
+         ignore_rest_of_line ();
+         free (name);
+         return 0;
+       }
+      free (name);
+    }
+
+  type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
+
+  if (skip_past_comma (&input_line_pointer) == -1)
+    goto bad;
+  if (type & 1)
+    {
+      expression (& exp);
+      if (exp.X_op != O_constant)
+       {
+         as_bad (_("expected numeric constant"));
+         ignore_rest_of_line ();
+         return 0;
+       }
+      i = exp.X_add_number;
+    }
+  if ((type & 3) == 3
+      && skip_past_comma (&input_line_pointer) == -1)
+    {
+      as_bad (_("expected comma"));
+      ignore_rest_of_line ();
+      return 0;
+    }
+  if (type & 2)
+    {
+      int len;
+
+      skip_whitespace (input_line_pointer);
+      if (*input_line_pointer != '"')
+       goto bad_string;
+      s = demand_copy_C_string (&len);
+    }
+
+  record_attribute (vendor, tag);
+  switch (type & 3)
+    {
+    case 3:
+      bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
+      break;
+    case 2:
+      bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
+      break;
+    case 1:
+      bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
+      break;
+    default:
+      abort ();
+    }
+
+  demand_empty_rest_of_line ();
+  return tag;
+bad_string:
+  as_bad (_("bad string constant"));
+  ignore_rest_of_line ();
+  return 0;
+bad:
+  as_bad (_("expected <tag> , <value>"));
+  ignore_rest_of_line ();
+  return 0;
+}
+
+/* Parse a .gnu_attribute directive.  */
+
+static void
+obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
+{
+  obj_elf_vendor_attribute (OBJ_ATTR_GNU);
+}
+
 void
 elf_obj_read_begin_hook (void)
 {
@@ -1464,7 +1728,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
@@ -1542,15 +1806,15 @@ obj_elf_version (int ignore ATTRIBUTE_UNUSED)
 static void
 obj_elf_size (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
-  char c = get_symbol_end ();
+  char *name;
+  char c = get_symbol_name (&name);
   char *p;
   expressionS exp;
   symbolS *sym;
 
   p = input_line_pointer;
   *p = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer != ',')
     {
       *p = 0;
@@ -1581,8 +1845,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 ();
@@ -1622,7 +1885,7 @@ obj_elf_type_name (char *cp)
       *input_line_pointer = '\0';
     }
   else
-    *cp = get_symbol_end ();
+    *cp = get_symbol_name (&p);
 
   return p;
 }
@@ -1704,10 +1967,11 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
       const struct elf_backend_data *bed;
 
       bed = get_elf_backend_data (stdoutput);
-      if (!(bed->elf_osabi == ELFOSABI_LINUX
-           /* GNU/Linux is still using the default value 0.  */
+      if (!(bed->elf_osabi == ELFOSABI_GNU
+           || bed->elf_osabi == ELFOSABI_FREEBSD
+           /* GNU is still using the default value 0.  */
            || bed->elf_osabi == ELFOSABI_NONE))
-       as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
+       as_bad (_("symbol type \"%s\" is supported only by GNU and FreeBSD targets"),
                type_name);
       type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
     }
@@ -1716,14 +1980,14 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
       struct elf_backend_data *bed;
 
       bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
-      if (!(bed->elf_osabi == ELFOSABI_LINUX
-           /* GNU/Linux is still using the default value 0.  */
+      if (!(bed->elf_osabi == ELFOSABI_GNU
+           /* GNU is still using the default value 0.  */
            || bed->elf_osabi == ELFOSABI_NONE))
        as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
                type_name);
       type = BSF_OBJECT | BSF_GNU_UNIQUE;
-      /* PR 10549: Always set OSABI field to LINUX for objects containing unique symbols.  */
-      bed->elf_osabi = ELFOSABI_LINUX;
+      /* PR 10549: Always set OSABI field to GNU for objects containing unique symbols.  */
+      bed->elf_osabi = ELFOSABI_GNU;
     }
 #ifdef md_elf_symbol_type
   else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
@@ -1780,7 +2044,7 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
 void
 obj_elf_init_stab_section (segT seg)
 {
-  char *file;
+  const char *file;
   char *p;
   char *stabstr_name;
   unsigned int stroff;
@@ -1793,10 +2057,8 @@ obj_elf_init_stab_section (segT seg)
   p = frag_more (12);
   /* Zero it out.  */
   memset (p, 0, 12);
-  as_where (&file, NULL);
-  stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4);
-  strcpy (stabstr_name, segment_name (seg));
-  strcat (stabstr_name, "str");
+  file = as_where (NULL);
+  stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
   stroff = get_stab_string_offset (file, stabstr_name);
   know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
   md_number_to_chars (p, stroff, 4);
@@ -1820,9 +2082,7 @@ adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
     return;
 
-  name = (char *) alloca (strlen (sec->name) + 4);
-  strcpy (name, sec->name);
-  strcat (name, "str");
+  name = concat (sec->name, "str", NULL);
   strsec = bfd_get_section_by_name (abfd, name);
   if (strsec)
     strsz = bfd_section_size (abfd, strsec);
@@ -1835,6 +2095,7 @@ adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
 
   bfd_h_put_16 (abfd, nsyms, p + 6);
   bfd_h_put_32 (abfd, strsz, p + 8);
+  free (name);
 }
 
 #ifdef NEED_ECOFF_DEBUG
@@ -1899,7 +2160,7 @@ elf_frob_symbol (symbolS *symp, int *puntp)
        S_SET_SIZE (symp, size->X_add_number);
       else
        {
-         if (flag_size_check == size_check_error)
+         if (!flag_allow_nonconst_size)
            as_bad (_(".size expression for %s "
                      "does not evaluate to a constant"), S_GET_NAME (symp));
          else
@@ -1915,7 +2176,9 @@ elf_frob_symbol (symbolS *symp, int *puntp)
       char *p;
 
       p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
-      know (p != NULL);
+      if (p == NULL)
+       /* We will have already reported an error about a missing version.  */
+       *puntp = TRUE;
 
       /* This symbol was given a new name with the .symver directive.
 
@@ -1928,14 +2191,15 @@ elf_frob_symbol (symbolS *symp, int *puntp)
         symbol.  However, it's not clear whether it is the best
         approach.  */
 
-      if (! S_IS_DEFINED (symp))
+      else if (! S_IS_DEFINED (symp))
        {
          /* Verify that the name isn't using the @@ syntax--this is
             reserved for definitions of the default version to link
             against.  */
          if (p[1] == ELF_VER_CHR)
            {
-             as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
+             as_bad (_("invalid attempt to declare external version name"
+                       " as default in symbol `%s'"),
                      sy_obj->versioned_name);
              *puntp = TRUE;
            }
@@ -2070,7 +2334,7 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
   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);
 }
@@ -2092,7 +2356,7 @@ elf_adjust_symtab (void)
   list.elt_count = NULL;
   list.indexes = hash_new ();
   bfd_map_over_sections (stdoutput, build_group_lists, &list);
-  
+
   /* 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
@@ -2198,8 +2462,7 @@ elf_frob_file_before_adjust (void)
 
                p = strchr (symbol_get_obj (symp)->versioned_name,
                            ELF_VER_CHR);
-               know (p != NULL);
-               if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
+               if (p != NULL && p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
                  {
                    size_t l = strlen (&p[3]) + 1;
                    memmove (&p[1], &p[3], l);
This page took 0.033319 seconds and 4 git commands to generate.