PR binutils/1568
authorNick Clifton <nickc@redhat.com>
Mon, 7 Nov 2005 17:57:00 +0000 (17:57 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 7 Nov 2005 17:57:00 +0000 (17:57 +0000)
* config/obj-coff.c (obj_coff_section): Set readonly flag with the 'x'
attribute.  Remember the actions of the 'w' and 'n' attributes and do not
allow the 'x','s' or 'd' attributes to change them.

gas/ChangeLog
gas/config/obj-coff.c

index b7ec09a..e1d2fe7 100644 (file)
@@ -1,3 +1,10 @@
+2005-11-07  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/1568
+       * config/obj-coff.c (obj_coff_section): Set readonly flag with the
+       'x' attribute.  Remember the actions of the 'w' and 'n' attributes
+       and do not allow the 'x','s' or 'd' attributes to change them.
+
 2005-11-07  John Levon  <levon@movementarian.org>
 
        * config/tc-i386.h (tc_comment_chars): Define.
index ce4d6f5..a5a76ff 100644 (file)
@@ -1522,38 +1522,81 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
        exp = get_absolute_expression ();
       else
        {
-         ++input_line_pointer;
-         while (*input_line_pointer != '"'
-                && ! is_end_of_line[(unsigned char) *input_line_pointer])
+         unsigned char attr;
+         int readonly_removed = 0;
+         int load_removed = 0;
+
+         while (attr = *++input_line_pointer,
+                attr != '"'
+                && ! is_end_of_line[attr])
            {
-             switch (*input_line_pointer)
+             switch (attr)
                {
-               case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
-               case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
+               case 'b':
+                 /* Uninitialised data section.  */
+                 flags |= SEC_ALLOC;
+                 flags &=~ SEC_LOAD;
+                 break;
+
+               case 'n':
+                 /* Section not loaded.  */
+                 flags &=~ SEC_LOAD;
+                 flags |= SEC_NEVER_LOAD;
+                 load_removed = 1;
+                 break;
+
+               case 's':
+                 /* Shared section.  */
+                 flags |= SEC_COFF_SHARED;
+                 /* Fall through.  */
+               case 'd':
+                 /* Data section.  */
+                 flags |= SEC_DATA;
+                 if (! load_removed)
+                   flags |= SEC_LOAD;
+                 flags &=~ SEC_READONLY;
+                 break;
 
-               case 's': flags |= SEC_COFF_SHARED; /* Fall through.  */
-               case 'd': flags |= SEC_DATA | SEC_LOAD; /* Fall through.  */
-               case 'w': flags &=~ SEC_READONLY; break;
+               case 'w':
+                 /* Writable section.  */
+                 flags &=~ SEC_READONLY;
+                 readonly_removed = 1;
+                 break;
 
-               case 'a': break; /* For compatibility with ELF.  */
-               case 'x': flags |= SEC_CODE | SEC_LOAD; break;
-               case 'r': flags |= SEC_DATA | SEC_LOAD | SEC_READONLY; break;
+               case 'a':
+                 /* Ignore.  Here for compatibility with ELF.  */
+                 break;
+
+               case 'r': /* Read-only section.  Implies a data section.  */
+                 readonly_removed = 0;
+                 /* Fall through.  */
+               case 'x': /* Executable section.  */
+                 /* If we are setting the 'x' attribute or if the 'r'
+                    attribute is being used to restore the readonly status
+                    of a code section (eg "wxr") then set the SEC_CODE flag,
+                    otherwise set the SEC_DATA flag.  */
+                 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
+                 if (! load_removed)
+                   flags |= SEC_LOAD;
+                 /* Note - the READONLY flag is set here, even for the 'x'
+                    attrbiute in order to be compatible with the MSVC
+                    linker.  */
+                 if (! readonly_removed)
+                   flags |= SEC_READONLY;
+                 break;
 
                case 'i': /* STYP_INFO */
                case 'l': /* STYP_LIB */
                case 'o': /* STYP_OVER */
-                 as_warn (_("unsupported section attribute '%c'"),
-                          *input_line_pointer);
+                 as_warn (_("unsupported section attribute '%c'"), attr);
                  break;
 
                default:
-                 as_warn (_("unknown section attribute '%c'"),
-                          *input_line_pointer);
+                 as_warn (_("unknown section attribute '%c'"), attr);
                  break;
                }
-             ++input_line_pointer;
            }
-         if (*input_line_pointer == '"')
+         if (attr == '"')
            ++input_line_pointer;
        }
     }