* config/obj-elf.c (obj_elf_change_section): Allow "x" for .note*.
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
index 7976704de2117daabb9210fbe649415123455930..ec63baa08233a18cd36b956e1cb1e9b5daf57ab8 100644 (file)
@@ -25,6 +25,7 @@
 #include "subsegs.h"
 #include "obstack.h"
 #include "struc-symbol.h"
+#include "dwarf2dbg.h"
 
 #ifndef ECOFF_DEBUGGING
 #define ECOFF_DEBUGGING 0
@@ -126,6 +127,9 @@ static const pseudo_typeS elf_pseudo_table[] =
   {"2byte", cons, 2},
   {"4byte", cons, 4},
   {"8byte", cons, 8},
+  /* These are used for dwarf2.  */
+  { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
+  { "loc",  dwarf2_directive_loc,  0 },
 
   /* We need to trap the section changing calls to handle .previous.  */
   {"data", obj_elf_data, 0},
@@ -597,63 +601,6 @@ static struct section_stack *section_stack;
    other possibilities, but I don't know what they are.  In any case,
    BFD doesn't really let us set the section type.  */
 
-/* Certain named sections have particular defined types, listed on p.
-   4-19 of the ABI.  */
-struct special_section
-{
-  const char *name;
-  int type;
-  int attributes;
-};
-
-static struct special_section const special_sections[] =
-{
-  { ".bss",    SHT_NOBITS,     SHF_ALLOC + SHF_WRITE           },
-  { ".comment",        SHT_PROGBITS,   0                               },
-  { ".data",   SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
-  { ".data1",  SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
-  { ".debug",  SHT_PROGBITS,   0                               },
-#if defined (TC_HPPA) && !defined (TE_LINUX) && TARGET_ARCH_SIZE == 64
-  { ".fini",   SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
-  { ".init",   SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
-#else
-  { ".fini",   SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
-  { ".init",   SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
-#endif
-  { ".line",   SHT_PROGBITS,   0                               },
-  { ".note",   SHT_NOTE,       0                               },
-  { ".rodata", SHT_PROGBITS,   SHF_ALLOC                       },
-  { ".rodata1",        SHT_PROGBITS,   SHF_ALLOC                       },
-  { ".tbss",   SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { ".tdata",  SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { ".text",   SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
-  { ".init_array",SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE         },
-  { ".fini_array",SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE         },
-  { ".preinit_array",SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE   },
-
-#ifdef ELF_TC_SPECIAL_SECTIONS
-  ELF_TC_SPECIAL_SECTIONS
-#endif
-
-#if 0
-  /* The following section names are special, but they can not
-     reasonably appear in assembler code.  Some of the attributes are
-     processor dependent.  */
-  { ".dynamic",        SHT_DYNAMIC,    SHF_ALLOC /* + SHF_WRITE */     },
-  { ".dynstr", SHT_STRTAB,     SHF_ALLOC                       },
-  { ".dynsym", SHT_DYNSYM,     SHF_ALLOC                       },
-  { ".got",    SHT_PROGBITS,   0                               },
-  { ".hash",   SHT_HASH,       SHF_ALLOC                       },
-  { ".interp", SHT_PROGBITS,   /* SHF_ALLOC */                 },
-  { ".plt",    SHT_PROGBITS,   0                               },
-  { ".shstrtab",SHT_STRTAB,    0                               },
-  { ".strtab", SHT_STRTAB,     /* SHF_ALLOC */                 },
-  { ".symtab", SHT_SYMTAB,     /* SHF_ALLOC */                 },
-#endif
-
-  { NULL,      0,              0                               }
-};
-
 void
 obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
      const char *name;
@@ -667,7 +614,8 @@ obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
   asection *old_sec;
   segT sec;
   flagword flags;
-  int i;
+  int def_type;
+  int def_attr;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -691,48 +639,55 @@ obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
   old_sec = bfd_get_section_by_name (stdoutput, name);
   sec = subseg_new (name, 0);
 
-  /* See if this is one of the special sections.  */
-  for (i = 0; special_sections[i].name != NULL; i++)
-    if (strcmp (name, special_sections[i].name) == 0)
-      {
-       if (type == SHT_NULL)
-         type = special_sections[i].type;
-       else if (type != special_sections[i].type)
-         {
-           if (old_sec == NULL
-               /* FIXME: gcc, as of 2002-10-22, will emit
+  if (_bfd_elf_get_sec_type_attr (stdoutput, name, &def_type,
+                                 &def_attr))
+    {
+      if (type == SHT_NULL)
+       type = def_type;
+      else if (type != def_type)
+       {
+         if (old_sec == NULL
+             /* FIXME: gcc, as of 2002-10-22, will emit
 
-                  .section .init_array,"aw",@progbits
+                .section .init_array,"aw",@progbits
 
-                  for __attribute__ ((section (".init_array"))).
-                  "@progbits" is incorrect.  */
-               && special_sections[i].type != SHT_INIT_ARRAY
-               && special_sections[i].type != SHT_FINI_ARRAY
-               && special_sections[i].type != SHT_PREINIT_ARRAY)
-             {
-               as_warn (_("setting incorrect section type for %s"), name);
-             }
-           else
-             {
-               as_warn (_("ignoring incorrect section type for %s"), name);
-               type = special_sections[i].type;
-             }
-         }
-       if ((attr &~ special_sections[i].attributes) != 0
-           && old_sec == NULL)
-         {
-           /* As a GNU extension, we permit a .note section to be
-              allocatable.  If the linker sees an allocateable .note
-              section, it will create a PT_NOTE segment in the output
-              file.  */
-           if (strcmp (name, ".note") != 0
-               || attr != SHF_ALLOC)
-             as_warn (_("setting incorrect section attributes for %s"),
+                for __attribute__ ((section (".init_array"))).
+                "@progbits" is incorrect.  */
+             && def_type != SHT_INIT_ARRAY
+             && def_type != SHT_FINI_ARRAY
+             && def_type != SHT_PREINIT_ARRAY)
+           {
+             /* We allow to specify any type for a .note section.  */
+             if (def_type != SHT_NOTE)
+               as_warn (_("setting incorrect section type for %s"),
+                        name);
+           }
+         else
+           {
+             as_warn (_("ignoring incorrect section type for %s"),
                       name);
-         }
-       attr |= special_sections[i].attributes;
-       break;
-      }
+             type = def_type;
+           }
+       }
+
+      if (old_sec == NULL && (attr &~ def_attr) != 0)
+       {
+         /* As a GNU extension, we permit a .note section to be
+            allocatable.  If the linker sees an allocateable .note
+            section, it will create a PT_NOTE segment in the output
+            file.  We also allow "x" for .note.GNU-stack.  */
+         if (!(def_type == SHT_NOTE
+               && (attr == SHF_ALLOC || attr == SHF_EXECINSTR)))
+           as_warn (_("setting incorrect section attributes for %s"),
+                    name);
+       }
+      attr |= def_attr;
+    }
+
+  if (type != SHT_NULL)
+    elf_section_type (sec) = type;
+  if (attr != 0)
+    elf_section_flags (sec) = attr;
 
   /* Convert ELF type and flags to BFD flags.  */
   flags = (SEC_RELOC
@@ -755,11 +710,12 @@ obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
       if (type == SHT_NOBITS)
         seg_info (sec)->bss = 1;
 
+      if (linkonce)
+       flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
       bfd_set_section_flags (stdoutput, sec, flags);
       if (flags & SEC_MERGE)
        sec->entsize = entsize;
       elf_group_name (sec) = group_name;
-      elf_linkonce_p (sec) = linkonce;
 
       /* Add a symbol for this section to the symbol table.  */
       secsym = symbol_find (name);
@@ -776,8 +732,8 @@ obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
       if (((old_sec->flags ^ flags)
           & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
              | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
-             | SEC_THREAD_LOCAL))
-         || linkonce != elf_linkonce_p (sec))
+             | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+             | SEC_THREAD_LOCAL)))
        as_warn (_("ignoring changed section attributes for %s"), name);
       if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
        as_warn (_("ignoring changed section entity size for %s"), name);
@@ -844,10 +800,7 @@ obj_elf_parse_section_letters (str, len)
              attr |= md_attr;
            else
 #endif
-             {
-               as_warn ("%s", bad_msg);
-               attr = -1;
-             }
+             as_fatal ("%s", bad_msg);
          }
          break;
        }
@@ -868,6 +821,8 @@ obj_elf_section_word (str, len)
     return SHF_ALLOC;
   if (len == 9 && strncmp (str, "execinstr", 9) == 0)
     return SHF_EXECINSTR;
+  if (len == 3 && strncmp (str, "tls", 3) == 0)
+    return SHF_TLS;
 
 #ifdef md_elf_section_word
   {
@@ -890,6 +845,8 @@ obj_elf_section_type (str, len)
     return SHT_PROGBITS;
   if (len == 6 && strncmp (str, "nobits", 6) == 0)
     return SHT_NOBITS;
+  if (len == 4 && strncmp (str, "note", 4) == 0)
+    return SHT_NOTE;
 
 #ifdef md_elf_section_type
   {
@@ -937,6 +894,9 @@ obj_elf_section_name ()
       name = xmalloc (end - input_line_pointer + 1);
       memcpy (name, input_line_pointer, end - input_line_pointer);
       name[end - input_line_pointer] = '\0';
+#ifdef tc_canonicalize_section_name
+      name = tc_canonicalize_section_name (name);
+#endif
       input_line_pointer = end;
     }
   SKIP_WHITESPACE ();
@@ -1266,6 +1226,7 @@ obj_elf_symver (ignore)
     }
 
   ++input_line_pointer;
+  SKIP_WHITESPACE ();
   name = input_line_pointer;
 
   /* Temporarily include '@' in symbol names.  */
@@ -1638,6 +1599,12 @@ obj_elf_type (ignore)
   else if (strcmp (typename, "object") == 0
           || strcmp (typename, "STT_OBJECT") == 0)
     type = BSF_OBJECT;
+  else if (strcmp (typename, "tls_object") == 0
+          || strcmp (typename, "STT_TLS") == 0)
+    type = BSF_OBJECT | BSF_THREAD_LOCAL;
+  else if (strcmp (typename, "notype") == 0
+          || strcmp (typename, "STT_NOTYPE") == 0)
+    ;
 #ifdef md_elf_symbol_type
   else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
     ;
@@ -2032,7 +1999,7 @@ elf_frob_file ()
 
       flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
       for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
-       if (elf_linkonce_p (s) != ((flags & SEC_LINK_ONCE) != 0))
+       if ((s->flags ^ flags) & SEC_LINK_ONCE)
          {
            flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
            if (s != list.head[i])
@@ -2062,6 +2029,7 @@ elf_frob_file ()
          as_fatal (_("can't create group: %s"),
                    bfd_errmsg (bfd_get_error ()));
        }
+      elf_section_type (s) = SHT_GROUP;
 
       /* Pass a pointer to the first section in this group.  */
       elf_next_in_group (s) = list.head[i];
This page took 0.029893 seconds and 4 git commands to generate.