* ecoff.c (_bfd_ecoff_write_armap): give the symtab element a
authorDJ Delorie <dj@redhat.com>
Tue, 11 May 1999 21:05:44 +0000 (21:05 +0000)
committerDJ Delorie <dj@redhat.com>
Tue, 11 May 1999 21:05:44 +0000 (21:05 +0000)
reasonable mode until "ar x" is smart enough to skip it (fixes
gcc/libgcc.a builds on mips-ecoff targets
* coffcode.h (styp_to_sec_flags): Explain how COMDATs are supposed
to work.  Hack to support MS import libraries, which use different
COMDAT types than GNU.
(coff_slurp_symbol_table): C_SECTION symbols are local; they refer
to implied zero-length sections (see peicode below)
* coffgen.c (coff_get_normalized_symtab): Properly read long MS
filename symbols, which use one *or more* auxents.
* coffswap.h (coff_swap_aux_in): ditto
* peicode.h (coff_swap_sym_in): Build the implied zero-length
sections

bfd/ChangeLog
bfd/coffcode.h
bfd/coffgen.c
bfd/coffswap.h
bfd/ecoff.c
bfd/peicode.h

index ff6e00582708ac2ea0ca29fb684ab3318bcd1638..26fe092678fc097d69e452008a95b5224b6f918f 100644 (file)
@@ -1,3 +1,20 @@
+1999-05-10  DJ Delorie  <dj@cygnus.com>
+
+       * ecoff.c (_bfd_ecoff_write_armap): give the symtab element a
+       reasonable mode until "ar x" is smart enough to skip it (fixes
+       gcc/libgcc.a builds on mips-ecoff targets
+
+       * coffcode.h (styp_to_sec_flags): Explain how COMDATs are supposed
+       to work.  Hack to support MS import libraries, which use different
+       COMDAT types than GNU.
+       (coff_slurp_symbol_table): C_SECTION symbols are local; they refer
+       to implied zero-length sections (see peicode below)
+       * coffgen.c (coff_get_normalized_symtab): Properly read long MS
+       filename symbols, which use one *or more* auxents.
+       * coffswap.h (coff_swap_aux_in): ditto
+       * peicode.h (coff_swap_sym_in): Build the implied zero-length
+       sections
+       
 Tue May 11 15:51:58 1999  Jeffrey A Law  (law@cygnus.com)
 
        * elf32-v850.c (v850_elf_howto_table): Make partial_inplace false
index 383719c00c96265adb02f086b1de4175af6d31fd..bee6b666e47ac3a39d4330c4f2bad82ddbac5911 100644 (file)
@@ -588,6 +588,12 @@ styp_to_sec_flags (abfd, hdr, name)
          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 */
+
       if (_bfd_coff_get_external_symbols (abfd))
        {
          bfd_byte *esym, *esymend;
@@ -629,10 +635,23 @@ styp_to_sec_flags (abfd, hdr, name)
                                            isym.n_type, isym.n_sclass,
                                            0, isym.n_numaux, (PTR) &aux);
 
+                     /* 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 */
+
                      switch (aux.x_scn.x_comdat)
                        {
                        case IMAGE_COMDAT_SELECT_NODUPLICATES:
+#if 0
                          sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+#else
+                         sec_flags &= ~SEC_LINK_ONCE;
+#endif
                          break;
 
                        default:
@@ -649,8 +668,12 @@ styp_to_sec_flags (abfd, hdr, name)
                          break;
 
                        case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+#if 0
                          /* FIXME: This is not currently implemented.  */
                          sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+#else
+                         sec_flags &= ~SEC_LINK_ONCE;
+#endif
                          break;
                        }
 
@@ -3581,6 +3604,11 @@ coff_slurp_symbol_table (abfd)
 #ifdef COFF_WITH_PE
              if (src->u.syment.n_sclass == C_NT_WEAK)
                dst->symbol.flags = BSF_WEAK;
+             if (src->u.syment.n_sclass == C_SECTION
+                 && src->u.syment.n_scnum > 0)
+               {
+                 dst->symbol.flags = BSF_LOCAL;
+               }
 #endif
 
              if (src->u.syment.n_sclass == C_WEAKEXT)
index df413833bd3c6251a537229a7df5905d8dd50ed8..a06ed663b3d264f3cfa359e100d97439749bac09 100644 (file)
@@ -1747,9 +1747,19 @@ coff_get_normalized_symtab (abfd)
          else
            {
              /* ordinary short filename, put into memory anyway */
-             internal_ptr->u.syment._n._n_n._n_offset = (long)
-               copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
-                          FILNMLEN);
+             if (internal_ptr->u.syment.n_numaux > 1
+                 && coff_data (abfd)->pe)
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset = (long)
+                   copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                              internal_ptr->u.syment.n_numaux * symesz);
+               }
+             else
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset = (long)
+                   copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                              FILNMLEN);
+               }
            }
        }
       else
index ae30a5d966f497bd00a5f35d4cd7fb0d1661fd24..9bc180f4de868ab9a173100f82c1567bbcc826ff 100644 (file)
@@ -422,7 +422,16 @@ coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
 #if FILNMLEN != E_FILNMLEN
            -> Error, we need to cope with truncating or extending FILNMLEN!;
 #else
-           memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+           if (numaux > 1)
+             {
+               if (indx == 0)
+                 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
+                         numaux * sizeof (AUXENT));
+             }
+           else
+             {
+               memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+             }
 #endif
          }
       goto end;
index d5c6f85a7170a5e2082da2c92c00f0d788daaf42..32a2309e941db78ed19cc2b5e1da40aa098a85a7 100644 (file)
@@ -3181,7 +3181,14 @@ _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx)
      armap.  */
   hdr.ar_uid[0] = '0';
   hdr.ar_gid[0] = '0';
+#if 0
   hdr.ar_mode[0] = '0';
+#else
+  /* Building gcc ends up extracting the armap as a file - twice. */
+  hdr.ar_mode[0] = '6';
+  hdr.ar_mode[1] = '4';
+  hdr.ar_mode[2] = '4';
+#endif
 
   sprintf (hdr.ar_size, "%-10d", (int) mapsize);
 
index 79d16e5abe9520c2f2e9aa3e408ec320eab70938..f15e0ec28bac40defe1716ea3de15a9f10fa25c5 100644 (file)
@@ -504,6 +504,7 @@ coff_swap_sym_in (abfd, ext1, in1)
     {
       in->n_value = 0x0;
 
+#if 0
       /* FIXME: This is clearly wrong.  The problem seems to be that
          undefined C_SECTION symbols appear in the first object of a
          MS generated .lib file, and the symbols are not defined
@@ -518,6 +519,55 @@ coff_swap_sym_in (abfd, ext1, in1)
       /*      in->n_scnum = 3; */
       /*    else */
       /*      in->n_scnum = 2; */
+#else
+      /* Create synthetic empty sections as needed.  DJ */
+      if (in->n_scnum == 0)
+       {
+         asection *sec;
+         for (sec=abfd->sections; sec; sec=sec->next)
+           {
+             if (strcmp (sec->name, in->n_name) == 0)
+               {
+                 in->n_scnum = sec->target_index;
+                 break;
+               }
+           }
+       }
+      if (in->n_scnum == 0)
+       {
+         int unused_section_number = 0;
+         asection *sec;
+         char *name;
+         for (sec=abfd->sections; sec; sec=sec->next)
+           if (unused_section_number <= sec->target_index)
+             unused_section_number = sec->target_index+1;
+
+         name = bfd_alloc (abfd, strlen (in->n_name) + 10);
+         if (name == NULL)
+           return;
+         strcpy (name, in->n_name);
+         sec = bfd_make_section_anyway (abfd, name);
+
+         sec->vma = 0;
+         sec->lma = 0;
+         sec->_cooked_size = 0;
+         sec->_raw_size = 0;
+         sec->filepos = 0;
+         sec->rel_filepos = 0;
+         sec->reloc_count = 0;
+         sec->line_filepos = 0;
+         sec->lineno_count = 0;
+         sec->userdata = NULL;
+         sec->next = (asection *) NULL;
+         sec->flags = 0;
+         sec->alignment_power = 2;
+         sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
+
+         sec->target_index = unused_section_number;
+
+         in->n_scnum = unused_section_number;
+       }
+#endif
     }
 
 #ifdef coff_swap_sym_in_hook