* config/tc-arm.c (encode_arm_addr_mode_2): Fix comment.
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
index 4bd4514d1407954e7fb11afb09d0c0e513de3908..fc22d6e9cf0d37abf5239817d68f3fb18b02e3ad 100644 (file)
@@ -393,20 +393,35 @@ obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
 }
 
+static symbolS *
+get_sym_from_input_line_and_check (void)
+{
+  char *name;
+  char c;
+  symbolS *sym;
+
+  name = input_line_pointer;
+  c = get_symbol_end ();
+  sym = symbol_find_or_make (name);
+  *input_line_pointer = c;
+  SKIP_WHITESPACE ();
+
+  /* There is no symbol name if input_line_pointer has not moved.  */
+  if (name == input_line_pointer)
+    as_bad (_("Missing symbol name in directive"));
+  return sym;
+}
+
 static void
 obj_elf_local (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name;
   int c;
   symbolS *symbolP;
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      symbolP = symbol_find_or_make (name);
-      *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      symbolP = get_sym_from_input_line_and_check ();
+      c = *input_line_pointer;
       S_CLEAR_EXTERNAL (symbolP);
       symbol_get_obj (symbolP)->local = 1;
       if (c == ',')
@@ -424,17 +439,13 @@ obj_elf_local (int ignore ATTRIBUTE_UNUSED)
 static void
 obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name;
   int c;
   symbolS *symbolP;
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      symbolP = symbol_find_or_make (name);
-      *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      symbolP = get_sym_from_input_line_and_check ();
+      c = *input_line_pointer;
       S_SET_WEAK (symbolP);
       symbol_get_obj (symbolP)->local = 1;
       if (c == ',')
@@ -452,7 +463,6 @@ obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
 static void
 obj_elf_visibility (int visibility)
 {
-  char *name;
   int c;
   symbolS *symbolP;
   asymbol *bfdsym;
@@ -460,12 +470,7 @@ obj_elf_visibility (int visibility)
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      symbolP = symbol_find_or_make (name);
-      *input_line_pointer = c;
-
-      SKIP_WHITESPACE ();
+      symbolP = get_sym_from_input_line_and_check ();
 
       bfdsym = symbol_get_bfdsym (symbolP);
       elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
@@ -475,6 +480,7 @@ obj_elf_visibility (int visibility)
       elfsym->internal_elf_sym.st_other &= ~3;
       elfsym->internal_elf_sym.st_other |= visibility;
 
+      c = *input_line_pointer;
       if (c == ',')
        {
          input_line_pointer ++;
@@ -673,6 +679,7 @@ obj_elf_change_section (const char *name,
           | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
           | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
           | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
+          | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
           | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
 #ifdef md_elf_section_flags
   flags = md_elf_section_flags (flags, attr, type);
@@ -734,9 +741,10 @@ obj_elf_change_section (const char *name,
 }
 
 static bfd_vma
-obj_elf_parse_section_letters (char *str, size_t len)
+obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *clone)
 {
   bfd_vma attr = 0;
+  *clone = FALSE;
 
   while (len > 0)
     {
@@ -745,6 +753,9 @@ obj_elf_parse_section_letters (char *str, size_t len)
        case 'a':
          attr |= SHF_ALLOC;
          break;
+       case 'e':
+         attr |= SHF_EXCLUDE;
+         break;
        case 'w':
          attr |= SHF_WRITE;
          break;
@@ -763,6 +774,9 @@ obj_elf_parse_section_letters (char *str, size_t len)
        case 'T':
          attr |= SHF_TLS;
          break;
+       case '?':
+         *clone = TRUE;
+         break;
        /* Compatibility.  */
        case 'm':
          if (*(str - 1) == 'a')
@@ -777,7 +791,7 @@ obj_elf_parse_section_letters (char *str, size_t len)
            }
        default:
          {
-           char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
+           char *bad_msg = _("unrecognized .section attribute: want a,e,w,x,M,S,G,T");
 #ifdef md_elf_section_letter
            bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
            if (md_attr > 0)
@@ -834,6 +848,8 @@ obj_elf_section_word (char *str, size_t len, int *type)
     return SHF_ALLOC;
   if (len == 9 && strncmp (str, "execinstr", 9) == 0)
     return SHF_EXECINSTR;
+  if (len == 7 && strncmp (str, "exclude", 7) == 0)
+    return SHF_EXCLUDE;
   if (len == 3 && strncmp (str, "tls", 3) == 0)
     return SHF_TLS;
 
@@ -962,13 +978,15 @@ obj_elf_section (int push)
 
       if (*input_line_pointer == '"')
        {
+         bfd_boolean clone;
+
          beg = demand_copy_C_string (&dummy);
          if (beg == NULL)
            {
              ignore_rest_of_line ();
              return;
            }
-         attr |= obj_elf_parse_section_letters (beg, strlen (beg));
+         attr |= obj_elf_parse_section_letters (beg, strlen (beg), &clone);
 
          SKIP_WHITESPACE ();
          if (*input_line_pointer == ',')
@@ -1020,6 +1038,11 @@ obj_elf_section (int push)
              attr &= ~SHF_MERGE;
            }
 
+         if ((attr & SHF_GROUP) != 0 && clone)
+           {
+             as_warn (_("? section flag ignored with G present"));
+             clone = FALSE;
+           }
          if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
            {
              ++input_line_pointer;
@@ -1039,6 +1062,16 @@ obj_elf_section (int push)
              as_warn (_("group name for SHF_GROUP not specified"));
              attr &= ~SHF_GROUP;
            }
+
+         if (clone)
+           {
+             const char *now_group = elf_group_name (now_seg);
+             if (now_group != NULL)
+               {
+                 group_name = xstrdup (now_group);
+                 linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
+               }
+           }
        }
       else
        {
@@ -1236,14 +1269,8 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
   char old_lexat;
   symbolS *sym;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
-
-  sym = symbol_find_or_make (name);
-
-  *input_line_pointer = c;
+  sym = get_sym_from_input_line_and_check ();
 
-  SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("expected comma after name in .symver"));
@@ -1372,20 +1399,13 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
 struct fix *
 obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name;
   symbolS *sym;
   offsetT offset;
-  char c;
 
   if (*input_line_pointer == '#')
     ++input_line_pointer;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
-  sym = symbol_find_or_make (name);
-  *input_line_pointer = c;
-
-  SKIP_WHITESPACE ();
+  sym = get_sym_from_input_line_and_check ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("expected comma after name in .vtable_entry"));
@@ -1607,20 +1627,16 @@ obj_elf_type_name (char *cp)
 static void
 obj_elf_type (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name;
   char c;
   int type;
   const char *type_name;
   symbolS *sym;
   elf_symbol_type *elfsym;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
-  sym = symbol_find_or_make (name);
+  sym = get_sym_from_input_line_and_check ();
+  c = *input_line_pointer;
   elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
-  *input_line_pointer = c;
 
-  SKIP_WHITESPACE ();
   if (*input_line_pointer == ',')
     ++input_line_pointer;
 
This page took 0.028352 seconds and 4 git commands to generate.