2001-05-16 Jeff Johnston <jjohnstn@redhat.com>
[deliverable/binutils-gdb.git] / bfd / coffcode.h
index a5721e0d2be93d4dbde1a47a0d7c9d604a8b5d3c..7415b964af0de6b89ac40b9cfc3c224d2855eebe 100644 (file)
@@ -1,5 +1,6 @@
 /* Support for the generic parts of most COFF variants, for BFD.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -175,7 +176,6 @@ SUBSUBSECTION
        the file in the string  table. This pass moves all strings
        into memory and replaces them with pointers to the strings.
 
-
        The symbol table is massaged once again, this time to create
        the canonical table used by the BFD application. Each symbol
        is inspected in turn, and a decision made (using the
@@ -301,7 +301,6 @@ CODE_FRAGMENT
 .boolean done_lineno;
 .} coff_symbol_type;
 
-
 */
 
 #ifdef COFF_WITH_PE
@@ -341,6 +340,9 @@ static long coff_canonicalize_reloc
 #ifndef coff_mkobject_hook
 static PTR coff_mkobject_hook PARAMS ((bfd *, PTR,  PTR));
 #endif
+#ifdef COFF_WITH_PE
+static flagword handle_COMDAT PARAMS ((bfd *, flagword, PTR, const char *, asection *));
+#endif
 \f
 /* void warning(); */
 
@@ -351,6 +353,19 @@ static PTR coff_mkobject_hook PARAMS ((bfd *, PTR,  PTR));
 
 #ifndef COFF_WITH_PE
 
+/* Macros for setting debugging flags.  */
+#ifdef STYP_DEBUG
+#define STYP_XCOFF_DEBUG STYP_DEBUG
+#else
+#define STYP_XCOFF_DEBUG STYP_INFO
+#endif
+
+#ifdef COFF_ALIGN_IN_S_FLAGS
+#define STYP_DEBUG_INFO STYP_DSECT
+#else
+#define STYP_DEBUG_INFO STYP_INFO
+#endif
+
 static long
 sec_to_styp_flags (sec_name, sec_flags)
      CONST char *sec_name;
@@ -388,22 +403,24 @@ sec_to_styp_flags (sec_name, sec_flags)
       styp_flags = STYP_LIT;
 #endif /* _LIT */
     }
-  else if (!strcmp (sec_name, ".debug"))
+  else if (!strncmp (sec_name, ".debug", 6))
     {
-#ifdef STYP_DEBUG
-      styp_flags = STYP_DEBUG;
-#else
-      styp_flags = STYP_INFO;
-#endif
+      /* Handle the XCOFF debug section and DWARF2 debug sections.  */
+      if (!sec_name[6])
+        styp_flags = STYP_XCOFF_DEBUG;
+      else
+        styp_flags = STYP_DEBUG_INFO;
     }
   else if (!strncmp (sec_name, ".stab", 5))
     {
-#ifdef COFF_ALIGN_IN_S_FLAGS
-      styp_flags = STYP_DSECT;
-#else
-      styp_flags = STYP_INFO;
-#endif
+      styp_flags = STYP_DEBUG_INFO;
+    }
+#ifdef COFF_LONG_SECTION_NAMES
+  else if (!strncmp (sec_name, ".gnu.linkonce.wi.", 17))
+    {
+      styp_flags = STYP_DEBUG_INFO;
     }
+#endif
 #ifdef RS6000COFF_C
   else if (!strcmp (sec_name, _PAD))
     {
@@ -507,8 +524,8 @@ sec_to_styp_flags (sec_name, sec_flags)
     styp_flags |= IMAGE_SCN_LNK_REMOVE;
   /* skip IN_MEMORY */
   /* skip SORT */
-  if (sec_flags & SEC_LINK_ONCE) 
-    styp_flags |= IMAGE_SCN_LNK_COMDAT; 
+  if (sec_flags & SEC_LINK_ONCE)
+    styp_flags |= IMAGE_SCN_LNK_COMDAT;
   /* skip LINK_DUPLICATES */
   /* skip LINKER_CREATED */
 
@@ -516,7 +533,7 @@ sec_to_styp_flags (sec_name, sec_flags)
      though the semantics don't quite match.  The bits from the input
      are retained in pei_section_data(abfd, section)->pe_flags */
 
-  styp_flags |= IMAGE_SCN_MEM_READ;       /* always readable. */
+  styp_flags |= IMAGE_SCN_MEM_READ;       /* always readable.  */
   if ((sec_flags & SEC_READONLY) == 0)
     styp_flags |= IMAGE_SCN_MEM_WRITE;    /* Invert READONLY for write */
   if (sec_flags & SEC_CODE)
@@ -524,7 +541,7 @@ sec_to_styp_flags (sec_name, sec_flags)
   if (sec_flags & SEC_SHARED)
     styp_flags |= IMAGE_SCN_MEM_SHARED;   /* Shared remains meaningful */
 
-  return styp_flags; 
+  return styp_flags;
 }
 
 #endif /* COFF_WITH_PE */
@@ -550,12 +567,12 @@ styp_to_sec_flags (abfd, hdr, name, section)
 #ifdef STYP_BLOCK
   if (styp_flags & STYP_BLOCK)
       sec_flags |= SEC_BLOCK;
-#endif  
+#endif
 
 #ifdef STYP_CLINK
   if (styp_flags & STYP_CLINK)
       sec_flags |= SEC_CLINK;
-#endif  
+#endif
 
 #ifdef STYP_NOLOAD
   if (styp_flags & STYP_NOLOAD)
@@ -628,9 +645,12 @@ styp_to_sec_flags (abfd, hdr, name, section)
 #endif
        sec_flags |= SEC_ALLOC;
     }
-  else if (strcmp (name, ".debug") == 0
+  else if (strncmp (name, ".debug", 6) == 0
 #ifdef _COMMENT
           || strcmp (name, _COMMENT) == 0
+#endif
+#ifdef COFF_LONG_SECTION_NAMES
+          || strncmp (name, ".gnu.linkonce.wi.", 17) == 0
 #endif
           || strncmp (name, ".stab", 5) == 0)
     {
@@ -682,327 +702,382 @@ styp_to_sec_flags (abfd, hdr, name, section)
 
 #else /* COFF_WITH_PE */
 
-/* The PE version; see above for the general comments.
-
-   Since to set the SEC_LINK_ONCE and associated flags, we have to
-   look at the symbol table anyway, we return the symbol table index
-   of the symbol being used as the COMDAT symbol.  This is admittedly
-   ugly, but there's really nowhere else that we have access to the
-   required information.  FIXME: Is the COMDAT symbol index used for
-   any purpose other than objdump?  */
-
 static flagword
-styp_to_sec_flags (abfd, hdr, name, section)
-     bfd *abfd ATTRIBUTE_UNUSED;
+handle_COMDAT (abfd, sec_flags, hdr, name, section)
+     bfd * abfd;
+     flagword sec_flags;
      PTR hdr;
      const char *name;
      asection *section;
 {
   struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
-  long styp_flags = internal_s->s_flags;
-  flagword sec_flags = 0;
+  bfd_byte *esymstart, *esym, *esymend;
+  int seen_state = 0;
+  char *target_name = NULL;
+
+  sec_flags |= SEC_LINK_ONCE;
+
+  /* Unfortunately, the PE format stores essential information in
+     the symbol table, of all places.  We need to extract that
+     information now, so that objdump and the linker will know how
+     to handle the section without worrying about the symbols.  We
+     can't call slurp_symtab, because the linker doesn't want the
+     swapped symbols.  */
+
+  /* COMDAT sections are special.  The first symbol is the section
+     symbol, which tells what kind of COMDAT section it is.  The
+     second symbol is the "comdat symbol" - the one with the
+     unique name.  GNU uses the section symbol for the unique
+     name; MS uses ".text" for every comdat section.  Sigh.  - DJ */
+
+  /* This is not mirrored in sec_to_styp_flags(), but there
+     doesn't seem to be a need to, either, and it would at best be
+     rather messy.  */
+
+  if (! _bfd_coff_get_external_symbols (abfd))
+    return sec_flags;
+  
+  esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
+  esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
 
-  if (styp_flags & STYP_DSECT)
-    abort ();  /* Don't know what to do */
-#ifdef SEC_NEVER_LOAD
-  if (styp_flags & STYP_NOLOAD)
-    sec_flags |= SEC_NEVER_LOAD;
-#endif
-  if (styp_flags & STYP_GROUP)
-    abort ();  /* Don't know what to do */
-  /* skip IMAGE_SCN_TYPE_NO_PAD */
-  if (styp_flags & STYP_COPY)
-    abort ();  /* Don't know what to do */
-  if (styp_flags & IMAGE_SCN_CNT_CODE)
-    sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD;
-  if (styp_flags & IMAGE_SCN_CNT_INITIALIZED_DATA)
-    sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
-  if (styp_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
-    sec_flags |= SEC_ALLOC;
-  if (styp_flags & IMAGE_SCN_LNK_OTHER)
-    abort ();  /* Don't know what to do */
-  if (styp_flags & IMAGE_SCN_LNK_INFO)
+  while (esym < esymend)
     {
-      /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is
-        defined.  coff_compute_section_file_positions uses
-        COFF_PAGE_SIZE to ensure that the low order bits of the
-        section VMA and the file offset match.  If we don't know
-        COFF_PAGE_SIZE, we can't ensure the correct correspondence,
-        and demand page loading of the file will fail.  */
-#ifdef COFF_PAGE_SIZE
-      sec_flags |= SEC_DEBUGGING;
-#endif
-    }
-  if (styp_flags & STYP_OVER)
-    abort ();  /* Don't know what to do */
-  if (styp_flags & IMAGE_SCN_LNK_REMOVE)
-    sec_flags |= SEC_EXCLUDE;
-
-  if (styp_flags & IMAGE_SCN_MEM_SHARED)
-    sec_flags |= SEC_SHARED;
-  /* COMDAT: see below */
-  if (styp_flags & IMAGE_SCN_MEM_DISCARDABLE)
-    sec_flags |= SEC_DEBUGGING;
-  if (styp_flags & IMAGE_SCN_MEM_NOT_CACHED)
-    abort ();/* Don't know what to do */
-  if (styp_flags & IMAGE_SCN_MEM_NOT_PAGED)
-    abort (); /* Don't know what to do */
-
-  /* We infer from the distinct read/write/execute bits the settings
-     of some of the bfd flags; the actual values, should we need them,
-     are also in pei_section_data (abfd, section)->pe_flags.  */
-
-  if (styp_flags & IMAGE_SCN_MEM_EXECUTE)
-    sec_flags |= SEC_CODE;   /* Probably redundant */
-  /* IMAGE_SCN_MEM_READ is simply ignored, assuming it always to be true. */
-  if ((styp_flags & IMAGE_SCN_MEM_WRITE) == 0)
-    sec_flags |= SEC_READONLY;
-
-  /* COMDAT gets very special treatment.  */
-  if (styp_flags & IMAGE_SCN_LNK_COMDAT)
-    {
-      sec_flags |= SEC_LINK_ONCE;
-
-      /* Unfortunately, the PE format stores essential information in
-         the symbol table, of all places.  We need to extract that
-         information now, so that objdump and the linker will know how
-         to handle the section without worrying about the symbols.  We
-         can't call slurp_symtab, because the linker doesn't want the
-         swapped symbols.  */
-
-      /* COMDAT sections are special.  The first symbol is the section
-        symbol, which tells what kind of COMDAT section it is.  The
-        second symbol is the "comdat symbol" - the one with the
-        unique name.  GNU uses the section symbol for the unique
-        name; MS uses ".text" for every comdat section.  Sigh.  - DJ */
-
-      /* This is not mirrored in sec_to_styp_flags(), but there
-        doesn't seem to be a need to, either, and it would at best be
-        rather messy.  */
-
-      if (_bfd_coff_get_external_symbols (abfd))
+      struct internal_syment isym;
+      char buf[SYMNMLEN + 1];
+      const char *symname;
+
+      bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
+
+      if (sizeof (internal_s->s_name) > SYMNMLEN)
        {
-         bfd_byte *esymstart, *esym, *esymend;
-         int seen_state = 0;
-         char *target_name = NULL;
+         /* This case implies that the matching
+            symbol name will be in the string table.  */
+         abort ();
+       }
 
-         esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
-         esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
+      if (isym.n_scnum == section->target_index)
+       {
+         /* According to the MSVC documentation, the first
+            TWO entries with the section # are both of
+            interest to us.  The first one is the "section
+            symbol" (section name).  The second is the comdat
+            symbol name.  Here, we've found the first
+            qualifying entry; we distinguish it from the
+            second with a state flag.
+
+            In the case of gas-generated (at least until that
+            is fixed) .o files, it isn't necessarily the
+            second one.  It may be some other later symbol.
+
+            Since gas also doesn't follow MS conventions and
+            emits the section similar to .text$<name>, where
+            <something> is the name we're looking for, we
+            distinguish the two as follows:
+
+            If the section name is simply a section name (no
+            $) we presume it's MS-generated, and look at
+            precisely the second symbol for the comdat name.
+            If the section name has a $, we assume it's
+            gas-generated, and look for <something> (whatever
+            follows the $) as the comdat symbol.  */
+
+         /* All 3 branches use this */
+         symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
+
+         if (symname == NULL)
+           abort ();
 
-         while (esym < esymend)
+         switch (seen_state)
            {
-             struct internal_syment isym;
-             char buf[SYMNMLEN + 1];
-             const char *symname;
+           case 0:
+             {
+               /* The first time we've seen the symbol.  */
+               union internal_auxent aux;
+
+               seen_state = 1;
+
+               /* If it isn't the stuff we're expecting, die;
+                  The MS documentation is vague, but it
+                  appears that the second entry serves BOTH
+                  as the comdat symbol and the defining
+                  symbol record (either C_STAT or C_EXT,
+                  possibly with an aux entry with debug
+                  information if it's a function.)  It
+                  appears the only way to find the second one
+                  is to count.  (On Intel, they appear to be
+                  adjacent, but on Alpha, they have been
+                  found separated.)
+
+                  Here, we think we've found the first one,
+                  but there's some checking we can do to be
+                  sure.  */
+
+               if (! (isym.n_sclass == C_STAT
+                      && isym.n_type == T_NULL
+                      && isym.n_value == 0))
+                 abort ();
 
-             bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
+               /* FIXME LATER: MSVC generates section names
+                  like .text for comdats.  Gas generates
+                  names like .text$foo__Fv (in the case of a
+                  function).  See comment above for more.  */
 
-             if (sizeof (internal_s->s_name) > SYMNMLEN)
-               {
-                 /* This case implies that the matching symbol name
-                     will be in the string table.  */
+               if (strcmp (name, symname) != 0)
                  abort ();
-               }
 
-             if (isym.n_scnum == section->target_index)
-               {
-                 /* According to the MSVC documentation, the first
-                    TWO entries with the section # are both of
-                    interest to us.  The first one is the "section
-                    symbol" (section name).  The second is the comdat
-                    symbol name.  Here, we've found the first
-                    qualifying entry; we distinguish it from the
-                    second with a state flag.
-
-                    In the case of gas-generated (at least until that
-                    is fixed) .o files, it isn't necessarily the
-                    second one.  It may be some other later symbol.
-
-                    Since gas also doesn't follow MS conventions and
-                    emits the section similar to .text$<name>, where
-                    <something> is the name we're looking for, we
-                    distinguish the two as follows:
-
-                    If the section name is simply a section name (no
-                    $) we presume it's MS-generated, and look at
-                    precisely the second symbol for the comdat name.
-                    If the section name has a $, we assume it's
-                    gas-generated, and look for <something> (whatever
-                    follows the $) as the comdat symbol.  */
-
-                 /* All 3 branches use this */
-                 symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
-
-                 if (symname == NULL)
-                   abort ();
-
-                 switch (seen_state)
-                   {
-                   case 0:
-                     {
-                       /* The first time we've seen the symbol.  */
-                       union internal_auxent aux;
-
-                       seen_state = 1;
-
-                       /* If it isn't the stuff we're expecting, die;
-                          The MS documentation is vague, but it
-                          appears that the second entry serves BOTH
-                          as the comdat symbol and the defining
-                          symbol record (either C_STAT or C_EXT,
-                          possibly with an aux entry with debug
-                          information if it's a function.)  It
-                          appears the only way to find the second one
-                          is to count.  (On Intel, they appear to be
-                          adjacent, but on Alpha, they have been
-                          found separated.)
-
-                          Here, we think we've found the first one,
-                          but there's some checking we can do to be
-                          sure.  */
-
-                       if (! (isym.n_sclass == C_STAT
-                              && isym.n_type == T_NULL
-                              && isym.n_value == 0))
-                         abort ();
-
-                       /* FIXME LATER: MSVC generates section names
-                          like .text for comdats.  Gas generates
-                          names like .text$foo__Fv (in the case of a
-                          function).  See comment above for more.  */
-
-                       if (strcmp (name, symname) != 0)
-                         abort ();
-  
-                       /* This is the section symbol.  */
-
-                       bfd_coff_swap_aux_in (abfd, (PTR) (esym + bfd_coff_symesz (abfd)),
-                                             isym.n_type, isym.n_sclass,
-                                             0, isym.n_numaux, (PTR) &aux);
-
-                       target_name = strchr (name, '$');
-                       if (target_name != NULL)
-                         {
-                           /* Gas mode.  */
-                           seen_state = 2;
-                           /* Skip the `$'.  */
-                           target_name += 1;
-                         }
-
-                       /* FIXME: Microsoft uses NODUPLICATES and
-                          ASSOCIATIVE, but gnu uses ANY and
-                          SAME_SIZE.  Unfortunately, gnu doesn't do
-                          the comdat symbols right.  So, until we can
-                          fix it to do the right thing, we are
-                          temporarily disabling comdats for the MS
-                          types (they're used in DLLs and C++, but we
-                          don't support *their* C++ libraries anyway
-                          - DJ.  */
-
-                       /* Cygwin does not follow the MS style, and
-                          uses ANY and SAME_SIZE where NODUPLICATES
-                          and ASSOCIATIVE should be used.  For
-                          Interix, we just do the right thing up
-                          front.  */
-
-                       switch (aux.x_scn.x_comdat)
-                         {
-                         case IMAGE_COMDAT_SELECT_NODUPLICATES:
-#ifdef STRICT_PE_FORMAT 
-                           sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+               /* This is the section symbol.  */
+               bfd_coff_swap_aux_in (abfd, (PTR) (esym + bfd_coff_symesz (abfd)),
+                                     isym.n_type, isym.n_sclass,
+                                     0, isym.n_numaux, (PTR) &aux);
+
+               target_name = strchr (name, '$');
+               if (target_name != NULL)
+                 {
+                   /* Gas mode.  */
+                   seen_state = 2;
+                   /* Skip the `$'.  */
+                   target_name += 1;
+                 }
+
+               /* FIXME: Microsoft uses NODUPLICATES and
+                  ASSOCIATIVE, but gnu uses ANY and
+                  SAME_SIZE.  Unfortunately, gnu doesn't do
+                  the comdat symbols right.  So, until we can
+                  fix it to do the right thing, we are
+                  temporarily disabling comdats for the MS
+                  types (they're used in DLLs and C++, but we
+                  don't support *their* C++ libraries anyway
+                  - DJ.  */
+
+               /* Cygwin does not follow the MS style, and
+                  uses ANY and SAME_SIZE where NODUPLICATES
+                  and ASSOCIATIVE should be used.  For
+                  Interix, we just do the right thing up
+                  front.  */
+
+               switch (aux.x_scn.x_comdat)
+                 {
+                 case IMAGE_COMDAT_SELECT_NODUPLICATES:
+#ifdef STRICT_PE_FORMAT
+                   sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
 #else
-                           sec_flags &= ~SEC_LINK_ONCE;
+                   sec_flags &= ~SEC_LINK_ONCE;
 #endif
-                           break;
+                   break;
 
-                         case IMAGE_COMDAT_SELECT_ANY:
-                           sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
-                           break;
+                 case IMAGE_COMDAT_SELECT_ANY:
+                   sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+                   break;
 
-                         case IMAGE_COMDAT_SELECT_SAME_SIZE:
-                           sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
-                           break;
+                 case IMAGE_COMDAT_SELECT_SAME_SIZE:
+                   sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+                   break;
 
-                         case IMAGE_COMDAT_SELECT_EXACT_MATCH:
-                           /* Not yet fully implemented ??? */
-                           sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
-                           break;
+                 case IMAGE_COMDAT_SELECT_EXACT_MATCH:
+                   /* Not yet fully implemented ??? */
+                   sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+                   break;
 
-                         /* debug$S gets this case; other
-                             implications ??? */
+                   /* debug$S gets this case; other
+                      implications ??? */
 
-                         /* There may be no symbol... we'll search
-                            the whole table... Is this the right
-                            place to play this game? Or should we do
-                            it when reading it in.  */
-                         case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+                   /* There may be no symbol... we'll search
+                      the whole table... Is this the right
+                      place to play this game? Or should we do
+                      it when reading it in.  */
+                 case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
 #ifdef STRICT_PE_FORMAT
-                           /* FIXME: This is not currently implemented.  */
-                           sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+                   /* FIXME: This is not currently implemented.  */
+                   sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
 #else
-                           sec_flags &= ~SEC_LINK_ONCE;
+                   sec_flags &= ~SEC_LINK_ONCE;
 #endif
-                           break;
+                   break;
 
-                         default:  /* 0 means "no symbol" */
-                           /* debug$F gets this case; other
-                               implications ??? */
-                           sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
-                           break;
-                         }
-                     }
-                     break;
+                 default:  /* 0 means "no symbol" */
+                   /* debug$F gets this case; other
+                      implications ??? */
+                   sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+                   break;
+                 }
+             }
+             break;
 
-                   case 2:
-                     /* Gas mode: the first matching on partial name.  */
+           case 2:
+             /* Gas mode: the first matching on partial name.  */
 
 #ifndef TARGET_UNDERSCORE
 #define TARGET_UNDERSCORE 0
 #endif
-                     /* Is this the name we're looking for? */
-                     if (strcmp (target_name, 
-                                 symname + (TARGET_UNDERSCORE ? 1 : 0)) != 0)
-                       {
-                           /* Not the name we're looking for */
-                           esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
-                           continue;
-                       }
-                     /* Fall through.  */
-                   case 1: 
-                     /* MSVC mode: the lexically second symbol (or
-                        drop through from the above).  */
-                     {
-                       char *newname;
-
-                       /* This must the the second symbol with the
-                          section #.  It is the actual symbol name.
-                          Intel puts the two adjacent, but Alpha (at
-                          least) spreads them out.  */
-
-                       section->comdat = 
-                         bfd_alloc (abfd, sizeof (struct bfd_comdat_info));
-                       if (section->comdat == NULL)
-                         abort ();
-                       section->comdat->symbol =
-                         (esym - esymstart) / bfd_coff_symesz (abfd);
-
-                       newname = bfd_alloc (abfd, strlen (symname) + 1);
-                       if (newname == NULL)
-                         abort ();
-
-                       strcpy (newname, symname);
-                       section->comdat->name = newname;
-
-                     }
-
-                     goto breakloop;
-                   }
+             /* Is this the name we're looking for? */
+             if (strcmp (target_name,
+                         symname + (TARGET_UNDERSCORE ? 1 : 0)) != 0)
+               {
+                 /* Not the name we're looking for */
+                 esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+                 continue;
                }
+             /* Fall through.  */
+           case 1:
+             /* MSVC mode: the lexically second symbol (or
+                drop through from the above).  */
+             {
+               char *newname;
+
+               /* This must the the second symbol with the
+                  section #.  It is the actual symbol name.
+                  Intel puts the two adjacent, but Alpha (at
+                  least) spreads them out.  */
+
+               section->comdat =
+                 bfd_alloc (abfd, sizeof (struct bfd_comdat_info));
+               if (section->comdat == NULL)
+                 abort ();
+
+               section->comdat->symbol =
+                 (esym - esymstart) / bfd_coff_symesz (abfd);
+
+               newname = bfd_alloc (abfd, strlen (symname) + 1);
+               if (newname == NULL)
+                 abort ();
 
-             esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+               strcpy (newname, symname);
+               section->comdat->name = newname;
+             }
+
+             goto breakloop;
            }
-         breakloop:
        }
+
+      esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+    }
+
+ breakloop:
+  return sec_flags;
+}
+
+
+/* The PE version; see above for the general comments.
+
+   Since to set the SEC_LINK_ONCE and associated flags, we have to
+   look at the symbol table anyway, we return the symbol table index
+   of the symbol being used as the COMDAT symbol.  This is admittedly
+   ugly, but there's really nowhere else that we have access to the
+   required information.  FIXME: Is the COMDAT symbol index used for
+   any purpose other than objdump?  */
+
+static flagword
+styp_to_sec_flags (abfd, hdr, name, section)
+     bfd *abfd;
+     PTR hdr;
+     const char *name;
+     asection *section;
+{
+  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+  long styp_flags = internal_s->s_flags;
+  flagword sec_flags;
+
+  /* Assume read only unless IMAGE_SCN_MEM_WRITE is specified.  */
+  sec_flags = SEC_READONLY;
+
+  /* Process each flag bit in styp_flags in turn.  */
+  while (styp_flags)
+    {
+      long flag = styp_flags & - styp_flags;
+      char * unhandled = NULL;
+      
+      styp_flags &= ~ flag;
+
+      /* We infer from the distinct read/write/execute bits the settings
+        of some of the bfd flags; the actual values, should we need them,
+        are also in pei_section_data (abfd, section)->pe_flags.  */
+
+      switch (flag)
+       {
+       case STYP_DSECT:
+         unhandled = "STYP_DSECT";
+         break;
+       case STYP_GROUP:
+         unhandled = "STYP_GROUP";
+         break;
+       case STYP_COPY:
+         unhandled = "STYP_COPY";
+         break;
+       case STYP_OVER:
+         unhandled = "STYP_OVER";
+         break;
+#ifdef SEC_NEVER_LOAD
+       case STYP_NOLOAD:
+         sec_flags |= SEC_NEVER_LOAD;
+         break;
+#endif 
+       case IMAGE_SCN_MEM_READ:
+         /* Ignored, assume it always to be true.  */
+         break;
+       case IMAGE_SCN_TYPE_NO_PAD:
+         /* Skip.  */
+         break;
+       case IMAGE_SCN_LNK_OTHER:
+         unhandled = "IMAGE_SCN_LNK_OTHER";
+         break;
+       case IMAGE_SCN_MEM_NOT_CACHED:
+         unhandled = "IMAGE_SCN_MEM_NOT_CACHED";
+         break;
+       case IMAGE_SCN_MEM_NOT_PAGED:
+         unhandled = "IMAGE_SCN_MEM_NOT_PAGED";
+         break;
+       case IMAGE_SCN_MEM_EXECUTE:
+         sec_flags |= SEC_CODE;
+         break;
+       case IMAGE_SCN_MEM_WRITE:
+         sec_flags &= ~ SEC_READONLY;
+         break;
+       case IMAGE_SCN_MEM_DISCARDABLE:
+         sec_flags |= SEC_DEBUGGING;
+         break;
+       case IMAGE_SCN_MEM_SHARED:
+         sec_flags |= SEC_SHARED;
+         break;
+       case IMAGE_SCN_LNK_REMOVE:
+         sec_flags |= SEC_EXCLUDE;
+         break;
+       case IMAGE_SCN_CNT_CODE:
+         sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD;
+         break;
+       case IMAGE_SCN_CNT_INITIALIZED_DATA:
+         sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
+         break;
+       case IMAGE_SCN_CNT_UNINITIALIZED_DATA:
+         sec_flags |= SEC_ALLOC;
+         break;
+       case IMAGE_SCN_LNK_INFO:
+         /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is
+            defined.  coff_compute_section_file_positions uses
+            COFF_PAGE_SIZE to ensure that the low order bits of the
+            section VMA and the file offset match.  If we don't know
+            COFF_PAGE_SIZE, we can't ensure the correct correspondence,
+            and demand page loading of the file will fail.  */
+#ifdef COFF_PAGE_SIZE
+         sec_flags |= SEC_DEBUGGING;
+#endif
+         break;
+       case IMAGE_SCN_LNK_COMDAT:
+         /* COMDAT gets very special treatment.  */
+         sec_flags = handle_COMDAT (abfd, sec_flags, hdr, name, section);
+         break;
+       default:
+         /* Silently ignore for now.  */
+         break;          
+       }
+
+      /* If the section flag was not handled, report it here.  This will allow
+        users of the BFD library to report a problem but continue executing.
+        Tools which need to be aware of these problems (such as the linker)
+        can override the default bfd_error_handler to intercept these reports.  */
+      if (unhandled != NULL)
+       (*_bfd_error_handler)
+         (_("%s (%s): Section flag %s (0x%x) ignored"),
+          bfd_get_filename (abfd), name, unhandled, flag);
     }
 
 #if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
@@ -1228,12 +1303,12 @@ dependent COFF routines:
 .       struct bfd_link_info *info,
 .       bfd *abfd,
 .       const char *name,
-.       flagword flags, 
+.       flagword flags,
 .       asection *section,
 .       bfd_vma value,
 .       const char *string,
 .       boolean copy,
-.       boolean collect, 
+.       boolean collect,
 .       struct bfd_link_hash_entry **hashp));
 .
 . boolean (*_bfd_coff_link_output_has_begun) PARAMS ((
@@ -1618,7 +1693,7 @@ coff_set_alignment_hook (abfd, section, scnhdr)
       if (bfd_read ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
          != bfd_coff_relsz (abfd))
        return;
-      
+
       coff_swap_reloc_in (abfd, &dst, &n);
       bfd_seek (abfd, oldpos, 0);
       section->reloc_count =
@@ -1766,12 +1841,12 @@ coff_mkobject_hook (abfd, filehdr, aouthdr)
     }
 #endif
 
-#ifdef ARM 
+#ifdef ARM
   /* Set the flags field from the COFF header read in */
   if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
     coff->flags = 0;
 #endif
-  
+
 #ifdef COFF_WITH_PE
   /* FIXME: I'm not sure this is ever executed, since peicode.h
      defines coff_mkobject_hook.  */
@@ -1806,7 +1881,7 @@ coff_set_arch_mach_hook (abfd, filehdr)
     case PPCMAGIC:
       arch = bfd_arch_powerpc;
       machine = 0; /* what does this mean? (krk) */
-      break; 
+      break;
 #endif
 #ifdef I386MAGIC
     case I386MAGIC:
@@ -1958,7 +2033,7 @@ coff_set_arch_mach_hook (abfd, filehdr)
 
                buf = (bfd_byte *) bfd_malloc (bfd_coff_symesz (abfd));
                if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
-                   || (bfd_read (buf, 1, bfd_coff_symesz (abfd), abfd) 
+                   || (bfd_read (buf, 1, bfd_coff_symesz (abfd), abfd)
                        != bfd_coff_symesz (abfd)))
                  {
                    free (buf);
@@ -2115,7 +2190,7 @@ coff_set_arch_mach_hook (abfd, filehdr)
         default:
           arch = bfd_arch_obscure;
           (*_bfd_error_handler)
-            (_("Unrecognized TI COFF target id '0x%x'"), 
+            (_("Unrecognized TI COFF target id '0x%x'"),
              internal_f->f_target_id);
           break;
         }
@@ -2383,7 +2458,7 @@ coff_write_relocs (abfd, first_undef)
             place). This is a bad thing,'cause the symbols attached
             to the output bfd are indexed, so that the relocation
             entries know which symbol index they point to.  So we
-            have to look up the output symbol here. */
+            have to look up the output symbol here.  */
 
          if (q->sym_ptr_ptr[0]->the_bfd != abfd)
            {
@@ -2578,10 +2653,10 @@ coff_set_flags (abfd, magicp, flagsp)
        {
          if (APCS_26_FLAG (abfd))
            * flagsp |= F_APCS26;
-         
+
          if (APCS_FLOAT_FLAG (abfd))
            * flagsp |= F_APCS_FLOAT;
-         
+
          if (PIC_FLAG (abfd))
            * flagsp |= F_PIC;
        }
@@ -2613,7 +2688,7 @@ coff_set_flags (abfd, magicp, flagsp)
     case bfd_arch_i386:
       *magicp = I386MAGIC;
 #ifdef LYNXOS
-      /* Just overwrite the usual value if we're doing Lynx. */
+      /* Just overwrite the usual value if we're doing Lynx.  */
       *magicp = LYNXCOFFMAGIC;
 #endif
       return true;
@@ -2644,7 +2719,7 @@ coff_set_flags (abfd, magicp, flagsp)
 #endif
 #endif
 #ifdef LYNXOS
-      /* Just overwrite the usual value if we're doing Lynx. */
+      /* Just overwrite the usual value if we're doing Lynx.  */
       *magicp = LYNXCOFFMAGIC;
 #endif
       return true;
@@ -2699,7 +2774,7 @@ coff_set_flags (abfd, magicp, flagsp)
     case bfd_arch_sparc:
       *magicp = SPARCMAGIC;
 #ifdef LYNXOS
-      /* Just overwrite the usual value if we're doing Lynx. */
+      /* Just overwrite the usual value if we're doing Lynx.  */
       *magicp = LYNXCOFFMAGIC;
 #endif
       return true;
@@ -2737,10 +2812,10 @@ coff_set_flags (abfd, magicp, flagsp)
 #ifdef XCOFF64
       if (bfd_get_mach (abfd) == bfd_mach_ppc_620
          && !strncmp (abfd->xvec->name,"aix", 3))
-       *magicp = U803XTOCMAGIC; 
+       *magicp = U803XTOCMAGIC;
       else
 #else
-       *magicp = U802TOCMAGIC; 
+       *magicp = U802TOCMAGIC;
 #endif
       return true;
       break;
@@ -2751,7 +2826,7 @@ coff_set_flags (abfd, magicp, flagsp)
       * magicp = MCOREMAGIC;
       return true;
 #endif
-      
+
 #ifdef W65MAGIC
     case bfd_arch_w65:
       *magicp = W65MAGIC;
@@ -2767,7 +2842,6 @@ coff_set_flags (abfd, magicp, flagsp)
   return false;
 }
 
-
 static boolean
 coff_set_arch_mach (abfd, arch, machine)
      bfd * abfd;
@@ -2784,7 +2858,7 @@ coff_set_arch_mach (abfd, arch, machine)
       coff_set_flags (abfd, &dummy1, &dummy2) != true)
     return false;              /* We can't represent this type */
 
-  return true;                 /* We're easy ... */
+  return true;                 /* We're easy ...  */
 }
 
 #ifdef COFF_IMAGE_WITH_PE
@@ -2812,7 +2886,7 @@ sort_by_secaddr (arg1, arg2)
 
 #endif /* COFF_IMAGE_WITH_PE */
 
-/* Calculate the file position for each section. */
+/* Calculate the file position for each section.  */
 
 #ifndef I960
 #define ALIGN_SECTIONS_IN_FILE
@@ -2874,7 +2948,7 @@ coff_compute_section_file_positions (abfd)
 
 #ifdef COFF_IMAGE_WITH_PE
   int page_size;
-  if (coff_data (abfd)->link_info) 
+  if (coff_data (abfd)->link_info)
     {
       page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
     }
@@ -3023,7 +3097,7 @@ coff_compute_section_file_positions (abfd)
       /* Align the sections in the file to the same boundary on
         which they are aligned in virtual memory.  I960 doesn't
         do this (FIXME) so we can stay in sync with Intel.  960
-        doesn't yet page from files... */
+        doesn't yet page from files...  */
 #ifdef ALIGN_SECTIONS_IN_FILE
       if ((abfd->flags & EXEC_P) != 0)
        {
@@ -3355,7 +3429,7 @@ coff_write_object_contents (abfd)
       section.s_paddr = current->lma;
       section.s_size =  current->_raw_size;
 #ifdef coff_get_section_load_page
-      section.s_page = coff_get_section_load_page (current); 
+      section.s_page = coff_get_section_load_page (current);
 #endif
 
 #ifdef COFF_WITH_PE
@@ -3429,7 +3503,7 @@ coff_write_object_contents (abfd)
                         ? 1 << current->alignment_power
                         : 0);
 #endif
-#ifdef TIC80COFF 
+#ifdef TIC80COFF
       /* TI COFF puts the alignment power in bits 8-11 of the flags */
       section.s_flags |= (current->alignment_power & 0xF) << 8;
 #endif
@@ -3579,7 +3653,7 @@ coff_write_object_contents (abfd)
     }
 #endif
 
-  /* OK, now set up the filehdr... */
+  /* OK, now set up the filehdr...  */
 
   /* Don't include the internal abs section in the section count */
 
@@ -3655,7 +3729,7 @@ coff_write_object_contents (abfd)
     coff_set_flags (abfd, &magic, &flags);
     internal_f.f_magic = magic;
     internal_f.f_flags |= flags;
-    /* ...and the "opt"hdr... */
+    /* ...and the "opt"hdr...  */
 
 #ifdef A29K
 #ifdef ULTRA3                  /* NYU's machine */
@@ -3717,7 +3791,7 @@ coff_write_object_contents (abfd)
 #if defined(ARM)
 #define __A_MAGIC_SET__
     internal_a.magic = ZMAGIC;
-#endif 
+#endif
 
 #if defined(PPC_PE)
 #define __A_MAGIC_SET__
@@ -3727,7 +3801,7 @@ coff_write_object_contents (abfd)
 #if defined MCORE_PE
 #define __A_MAGIC_SET__
     internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
-#endif 
+#endif
 
 #if defined(I386)
 #define __A_MAGIC_SET__
@@ -3939,40 +4013,40 @@ coff_write_object_contents (abfd)
   /* now write them */
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
     return false;
-  
+
   {
     char * buff;
     bfd_size_type amount;
-    
+
     buff = bfd_malloc (bfd_coff_filhsz (abfd));
-    if (buff == NULL) 
+    if (buff == NULL)
       return false;
-    
-    coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) buff);
+
+    bfd_coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) buff);
     amount = bfd_write ((PTR) buff, 1, bfd_coff_filhsz (abfd), abfd);
-    
+
     free (buff);
-    
+
     if (amount != bfd_coff_filhsz (abfd))
       return false;
   }
-  
+
   if (abfd->flags & EXEC_P)
     {
-      /* Note that peicode.h fills in a PEAOUTHDR, not an AOUTHDR. 
-        include/coff/pe.h sets AOUTSZ == sizeof(PEAOUTHDR)) */
+      /* Note that peicode.h fills in a PEAOUTHDR, not an AOUTHDR.
+        include/coff/pe.h sets AOUTSZ == sizeof (PEAOUTHDR)) */
       char * buff;
       bfd_size_type amount;
 
       buff = bfd_malloc (bfd_coff_aoutsz (abfd));
-      if (buff == NULL) 
+      if (buff == NULL)
        return false;
-      
+
       coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) buff);
       amount = bfd_write ((PTR) buff, 1, bfd_coff_aoutsz (abfd), abfd);
-      
+
       free (buff);
-      
+
       if (amount != bfd_coff_aoutsz (abfd))
        return false;
     }
@@ -4030,7 +4104,7 @@ coff_set_section_contents (abfd, section, location, offset, count)
       to write a section which doesn't follow these assumptions.  The
       code has been tested on ISC 4.1 by me, and on SCO by Robert Lipe
       <robertl@arnet.com> (Thanks!).
-  
+
       Gvran Uddeborg <gvran@uddeborg.pp.se> */
 
     if (strcmp (section->name, _LIB) == 0)
@@ -4051,7 +4125,7 @@ coff_set_section_contents (abfd, section, location, offset, count)
 #endif
 
   /* Don't write out bss sections - one way to do this is to
-       see if the filepos has not been set. */
+       see if the filepos has not been set.  */
   if (section->filepos == 0)
     return true;
 
@@ -4208,7 +4282,7 @@ coff_slurp_line_table (abfd, asect)
 
     }
   asect->lineno = lineno_cache;
-  /* FIXME, free native_lineno here, or use alloca or something. */
+  /* FIXME, free native_lineno here, or use alloca or something.  */
   return true;
 }
 
@@ -4328,7 +4402,7 @@ coff_slurp_symbol_table (abfd)
                case COFF_SYMBOL_UNDEFINED:
                  dst->symbol.section = bfd_und_section_ptr;
                  dst->symbol.value = 0;
-                 break; 
+                 break;
 
                case COFF_SYMBOL_PE_SECTION:
                  dst->symbol.flags |= BSF_EXPORT | BSF_SECTION_SYM;
@@ -4375,7 +4449,7 @@ coff_slurp_symbol_table (abfd)
 #ifdef I960
            case C_LEAFSTAT:    /* static leaf procedure        */
 #endif
-#if defined ARM 
+#if defined ARM
             case C_THUMBSTAT:   /* Thumb static                  */
             case C_THUMBLABEL:  /* Thumb label                   */
             case C_THUMBSTATFUNC:/* Thumb static function        */
@@ -4540,7 +4614,7 @@ coff_slurp_symbol_table (abfd)
              /* NT uses 0x67 for a weak symbol, not C_ALIAS.  */
            case C_ALIAS:       /* duplicate tag                 */
 #endif
-             /* New storage classes for TI COFF */ 
+             /* New storage classes for TI COFF */
 #if defined(TIC80COFF) || defined(TICOFF)
            case C_UEXT:        /* Tentative external definition */
 #endif
@@ -4713,7 +4787,6 @@ SUBSUBSECTION
        into a howto table vector; the 88k subtracts a number from the
        @code{r_type} field and creates an addend field.
 
-
 */
 
 #ifndef CALC_ADDEND
@@ -4768,7 +4841,6 @@ coff_slurp_reloc_table (abfd, asect, symbols)
   if (reloc_cache == NULL)
     return false;
 
-
   for (idx = 0; idx < asect->reloc_count; idx++)
     {
       struct internal_reloc dst;
@@ -4889,7 +4961,6 @@ coff_canonicalize_reloc (abfd, section, relptr, symbols)
   arelent *tblptr = section->relocation;
   unsigned int count = 0;
 
-
   if (section->flags & SEC_CONSTRUCTOR)
     {
       /* this section has relocs made up by us, they are not in the
@@ -4912,8 +4983,6 @@ coff_canonicalize_reloc (abfd, section, relptr, symbols)
 
       for (; count++ < section->reloc_count;)
        *relptr++ = tblptr++;
-
-
     }
   *relptr = 0;
   return section->reloc_count;
@@ -5142,7 +5211,7 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table =
 #define coff_bfd_copy_private_section_data  _bfd_generic_bfd_copy_private_section_data
 #endif
 
-#ifndef coff_bfd_copy_private_bfd_data 
+#ifndef coff_bfd_copy_private_bfd_data
 #define coff_bfd_copy_private_bfd_data      _bfd_generic_bfd_copy_private_bfd_data
 #endif
 
@@ -5154,7 +5223,7 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table =
 #define coff_bfd_set_private_flags          _bfd_generic_bfd_set_private_flags
 #endif
 
-#ifndef coff_bfd_print_private_bfd_data 
+#ifndef coff_bfd_print_private_bfd_data
 #define coff_bfd_print_private_bfd_data     _bfd_generic_bfd_print_private_bfd_data
 #endif
 
@@ -5189,6 +5258,10 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table =
 #define coff_bfd_gc_sections               bfd_generic_gc_sections
 #endif
 
+#ifndef coff_bfd_merge_sections
+#define coff_bfd_merge_sections                    bfd_generic_merge_sections
+#endif
+
 #define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE)        \
 const bfd_target VAR =                                                 \
 {                                                                      \
This page took 0.099336 seconds and 4 git commands to generate.