]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - gas/config/obj-coff.c
Imported binutils-2.20
[msp430-binutils.git] / gas / config / obj-coff.c
index be5755f137d30f6b28974970e4327cec663d7738..271b01ef3dc3ff3163f4b791ee135de5a169a6f0 100644 (file)
@@ -1,6 +1,6 @@
 /* coff object file format
    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
    Free Software Foundation, Inc.
 
    This file is part of GAS.
@@ -53,6 +53,8 @@ static symbolS *def_symbol_in_progress;
 static const char weak_altprefix[] = ".weak.";
 #endif /* TE_PE */
 
+#include "obj-coff-seh.c"
+
 typedef struct
   {
     unsigned long chunk_size;
@@ -169,6 +171,71 @@ obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
     s_lcomm (0);
 }
 
+#ifdef TE_PE
+/* Called from read.c:s_comm after we've parsed .comm symbol, size.
+   Parse a possible alignment value.  */
+
+static symbolS *
+obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
+{
+  addressT align = 0;
+
+  if (*input_line_pointer == ',')
+    {
+      align = parse_align (0);
+      if (align == (addressT) -1)
+       return NULL;
+    }
+
+  S_SET_VALUE (symbolP, size);
+  S_SET_EXTERNAL (symbolP);
+  S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+
+  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+
+  /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
+     Instead we must add a note to the .drectve section.  */
+  if (align)
+    {
+      segT current_seg = now_seg;
+      subsegT current_subseg = now_subseg;
+      flagword oldflags;
+      asection *sec;
+      size_t pfxlen, numlen;
+      char *frag;
+      char numbuff[20];
+
+      sec = subseg_new (".drectve", 0);
+      oldflags = bfd_get_section_flags (stdoutput, sec);
+      if (oldflags == SEC_NO_FLAGS)
+       {
+         if (!bfd_set_section_flags (stdoutput, sec,
+               TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
+           as_warn (_("error setting flags for \"%s\": %s"),
+               bfd_section_name (stdoutput, sec),
+               bfd_errmsg (bfd_get_error ()));
+       }
+
+      /* Emit a string.  Note no NUL-termination.  */
+      pfxlen = strlen (" -aligncomm:") + strlen (S_GET_NAME (symbolP)) + 1;
+      numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
+      frag = frag_more (pfxlen + numlen);
+      (void) sprintf (frag, " -aligncomm:%s,", S_GET_NAME (symbolP));
+      memcpy (frag + pfxlen, numbuff, numlen);
+      /* Restore original subseg. */
+      subseg_set (current_seg, current_subseg);
+    }
+
+  return symbolP;
+}
+
+static void
+obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
+{
+  s_comm_internal (ignore, obj_coff_common_parse);
+}
+#endif /* TE_PE */
+
 #define GET_FILENAME_STRING(X) \
   ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
 
@@ -183,7 +250,7 @@ fetch_coff_debug_section (void)
       const asymbol *s;
 
       s = bfd_make_debug_symbol (stdoutput, NULL, 0);
-      assert (s != 0);
+      gas_assert (s != 0);
       debug_section = s->section;
     }
   return debug_section;
@@ -497,7 +564,7 @@ obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
   subseg_new (".comment", 0);
 #endif
 
-  stringer (1);
+  stringer (8 + 1);
   subseg_set (current_seg, current_subseg);
 }
 
@@ -777,7 +844,6 @@ obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
 
   if (SF_GET_FUNCTION (def_symbol_in_progress))
     {
-      know (sizeof (def_symbol_in_progress) <= sizeof (long));
       set_function (def_symbol_in_progress);
       SF_SET_PROCESS (def_symbol_in_progress);
 
@@ -1034,7 +1100,7 @@ weak_altname2name (const char * name)
   char * weak_name;
   char * dot;
 
-  assert (weak_is_altname (name));
+  gas_assert (weak_is_altname (name));
 
   weak_name = xstrdup (name + 6);
   if ((dot = strchr (weak_name, '.')))
@@ -1051,11 +1117,11 @@ weak_uniquify (const char * name)
   char *ret;
   const char * unique = "";
 
-#ifdef USE_UNIQUE
+#ifdef TE_PE
   if (an_external_name != NULL)
     unique = an_external_name;
 #endif
-  assert (weak_is_altname (name));
+  gas_assert (weak_is_altname (name));
 
   if (strchr (name + sizeof (weak_altprefix), '.'))
     return name;
@@ -1185,8 +1251,8 @@ coff_frob_symbol (symbolS *symp, int *punt)
       symbolS *weakp = symbol_find_noref (weak_altname2name
                                          (S_GET_NAME (symp)), 1);
 
-      assert (weakp);
-      assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
+      gas_assert (weakp);
+      gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
 
       if (! S_IS_WEAK (weakp))
        {
@@ -1268,7 +1334,7 @@ coff_frob_symbol (symbolS *symp, int *punt)
 
       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
        {
-         assert (S_GET_VALUE (symp) == 0);
+         gas_assert (S_GET_VALUE (symp) == 0);
          if (S_IS_WEAKREFD (symp))
            *punt = 1;
          else
@@ -1370,7 +1436,7 @@ coff_frob_symbol (symbolS *symp, int *punt)
   if (next_set_end != NULL)
     {
       if (set_end != NULL)
-       as_warn ("Warning: internal error: forgetting to set endndx of %s",
+       as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
                 S_GET_NAME (set_end));
       set_end = next_set_end;
     }
@@ -1476,6 +1542,7 @@ coff_frob_file_after_relocs (void)
                                                  'x' for text
                                                 'r' for read-only data
                                                 's' for shared data (PE)
+                                                'y' for noread
    But if the argument is not a quoted string, treat it as a
    subsegment number.
 
@@ -1585,6 +1652,10 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
                    flags |= SEC_READONLY;
                  break;
 
+               case 'y':
+                 flags |= SEC_COFF_NOREAD | SEC_READONLY;
+                 break;
+
                case 'i': /* STYP_INFO */
                case 'l': /* STYP_LIB */
                case 'o': /* STYP_OVER */
@@ -1629,7 +1700,8 @@ obj_coff_section (int ignore ATTRIBUTE_UNUSED)
       /* This section's attributes have already been set.  Warn if the
          attributes don't match.  */
       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
-                            | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD);
+                            | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
+                            | SEC_COFF_NOREAD);
       if ((flags ^ oldflags) & matchflags)
        as_warn (_("Ignoring changed section attributes for %s"), name);
     }
@@ -1698,7 +1770,6 @@ coff_frob_section (segT sec)
       SF_SET_STATICS (secsym);
       SA_SET_SCN_SCNLEN (secsym, size);
     }
-
   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
 #ifndef STAB_SECTION_NAME
 #define STAB_SECTION_NAME ".stab"
@@ -1720,7 +1791,7 @@ coff_frob_section (segT sec)
   fragp = seg_info (sec)->frchainP->frch_root;
   while (fragp && fragp->fr_fix == 0)
     fragp = fragp->fr_next;
-  assert (fragp != 0 && fragp->fr_fix >= 12);
+  gas_assert (fragp != 0 && fragp->fr_fix >= 12);
 
   /* Store the values.  */
   p = fragp->fr_literal;
@@ -1779,6 +1850,10 @@ const pseudo_typeS coff_pseudo_table[] =
   /* We accept the .bss directive for backward compatibility with
      earlier versions of gas.  */
   {"bss", obj_coff_bss, 0},
+#ifdef TE_PE
+  /* PE provides an enhanced version of .comm with alignment.  */
+  {"comm", obj_coff_comm, 0},
+#endif /* TE_PE */
   {"def", obj_coff_def, 0},
   {"dim", obj_coff_dim, 0},
   {"endef", obj_coff_endef, 0},
@@ -1802,6 +1877,9 @@ const pseudo_typeS coff_pseudo_table[] =
 #if defined TC_TIC4X
   /* The tic4x uses sdef instead of def.  */
   {"sdef", obj_coff_def, 0},
+#endif
+#if defined(SEH_CMDS)
+  SEH_CMDS
 #endif
   {NULL, NULL, 0}
 };