Fix formatting.
[deliverable/binutils-gdb.git] / bfd / ecoff.c
index f4549d65769ca99997d164e435a496c7f4c988ff..4b136ee1f885a090948f9cd6ce6e3ebdd5e11d39 100644 (file)
@@ -1,5 +1,6 @@
 /* Generic ECOFF (Extended-COFF) routines.
-   Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Free Software Foundation, Inc.
    Original version by Per Bothner.
    Full support added by Ian Lance Taylor, ian@cygnus.com.
 
@@ -71,7 +72,23 @@ static unsigned int ecoff_armap_hash PARAMS ((CONST char *s,
 \f
 /* This stuff is somewhat copied from coffcode.h.  */
 
-static asection bfd_debug_section = { "*DEBUG*" };
+static asection bfd_debug_section =
+{
+  /* name,   index, next, flags, set_vma, reloc_done, linker_mark, gc_mark */
+  "*DEBUG*", 0,     0,    0,     0,       0,          0,           0,
+  /* vma, lma, _cooked_size, _raw_size, output_offset, output_section, */
+  0,      0,   0,            0,         0,             NULL,
+  /* alig, reloc..., orel..., reloc_count, filepos, rel_..., line_... */
+  0,       0,        0,       0,           0,       0,            0,
+  /* userdata, contents, lineno, lineno_count */
+  0,           0,        0,      0,
+  /* comdat_info, moving_line_filepos, target_index, used_by_bfd,  */
+  NULL,           0,                   0,            0,
+  /* cons, owner, symbol */
+  0,       0,     (struct symbol_cache_entry *) NULL,
+  /* symbol_ptr_ptr,                   link_order_head, ..._tail */
+  (struct symbol_cache_entry **) NULL, NULL,            NULL
+};
 
 /* Create an ECOFF object.  */
 
@@ -137,23 +154,14 @@ _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
 
 boolean
 _bfd_ecoff_new_section_hook (abfd, section)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *section;
 {
-  /* For the .pdata section, which has a special meaning on the Alpha,
-     we set the alignment power to 3.  We correct this later in
-     ecoff_compute_section_file_positions.  We do this hackery because
-     we need to know the exact unaligned size of the .pdata section in
-     order to set the lnnoptr field correctly.  For every other
-     section we use an alignment power of 4; this could be made target
-     dependent by adding a field to ecoff_backend_data, but 4 appears
-     to be correct for both the MIPS and the Alpha.  */
-  if (strcmp (section->name, _PDATA) == 0)
-    section->alignment_power = 3;
-  else
-    section->alignment_power = 4;
+  section->alignment_power = 4;
 
-  if (strcmp (section->name, _TEXT) == 0)
+  if (strcmp (section->name, _TEXT) == 0
+      || strcmp (section->name, _INIT) == 0
+      || strcmp (section->name, _FINI) == 0)
     section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
   else if (strcmp (section->name, _DATA) == 0
           || strcmp (section->name, _SDATA) == 0)
@@ -161,7 +169,8 @@ _bfd_ecoff_new_section_hook (abfd, section)
   else if (strcmp (section->name, _RDATA) == 0
           || strcmp (section->name, _LIT8) == 0
           || strcmp (section->name, _LIT4) == 0
-          || strcmp (section->name, _RCONST) == 0)
+          || strcmp (section->name, _RCONST) == 0
+          || strcmp (section->name, _PDATA) == 0)
     section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
   else if (strcmp (section->name, _BSS) == 0
           || strcmp (section->name, _SBSS) == 0)
@@ -356,10 +365,11 @@ ecoff_sec_to_styp_flags (name, flags)
 
 /*ARGSUSED*/
 flagword
-_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name)
-     bfd *abfd;
+_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name, section)
+     bfd *abfd ATTRIBUTE_UNUSED;
      PTR hdr;
-     const char *name;
+     const char *name ATTRIBUTE_UNUSED;
+     asection *section ATTRIBUTE_UNUSED;
 {
   struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
   long styp_flags = internal_s->s_flags;
@@ -503,7 +513,7 @@ ecoff_slurp_symbolic_header (abfd)
 boolean
 _bfd_ecoff_slurp_symbolic_info (abfd, ignore, debug)
      bfd *abfd;
-     asection *ignore;
+     asection *ignore ATTRIBUTE_UNUSED;
      struct ecoff_debug_info *debug;
 {
   const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
@@ -842,6 +852,10 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak)
        case N_SETD:
        case N_SETB:
          {
+           /* This code is no longer needed.  It used to be used to
+              make the linker handle set symbols, but they are now
+              handled in the add_symbols routine instead.  */
+#if 0
            const char *name;
            asection *section;
            arelent_chain *reloc_chain;
@@ -901,6 +915,8 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak)
            section->constructor_chain = reloc_chain;
            section->_raw_size += bitsize / 8;
 
+#endif /* 0 */
+
            /* Mark the symbol as a constructor.  */
            asym->flags |= BSF_CONSTRUCTOR;
          }
@@ -1306,7 +1322,7 @@ ecoff_type_to_string (abfd, fdr, indx)
       break;
 
     default:
-      sprintf (p1, "Unknown basic type %d", (int) basic_type);
+      sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
       break;
     }
 
@@ -1434,7 +1450,7 @@ ecoff_type_to_string (abfd, fdr, indx)
 /*ARGSUSED*/
 void
 _bfd_ecoff_get_symbol_info (abfd, symbol, ret)
-     bfd *abfd;                        /* Ignored.  */
+     bfd *abfd ATTRIBUTE_UNUSED;
      asymbol *symbol;
      symbol_info *ret;
 {
@@ -1445,11 +1461,11 @@ _bfd_ecoff_get_symbol_info (abfd, symbol, ret)
 
 /*ARGSUSED*/
 boolean
-_bfd_ecoff_bfd_is_local_label (abfd, symbol)
-     bfd *abfd;
-     asymbol *symbol;
+_bfd_ecoff_bfd_is_local_label_name (abfd, name)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     const char *name;
 {
-  return symbol->name[0] == '$';
+  return name[0] == '$';
 }
 
 /* Print information about an ECOFF symbol.  */
@@ -1578,17 +1594,17 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how)
 
              case stFile:
              case stBlock:
-               fprintf (file, "\n      End+1 symbol: %ld",
+               fprintf (file, _("\n      End+1 symbol: %ld"),
                         (long) (indx + sym_base));
                break;
 
              case stEnd:
                if (ecoff_ext.asym.sc == scText
                    || ecoff_ext.asym.sc == scInfo)
-                 fprintf (file, "\n      First symbol: %ld",
+                 fprintf (file, _("\n      First symbol: %ld"),
                           (long) (indx + sym_base));
                else
-                 fprintf (file, "\n      First symbol: %ld"
+                 fprintf (file, _("\n      First symbol: %ld")
                           ((long)
                            (AUX_GET_ISYM (bigendian,
                                           &aux_base[ecoff_ext.asym.index])
@@ -1600,14 +1616,14 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how)
                if (ECOFF_IS_STAB (&ecoff_ext.asym))
                  ;
                else if (ecoffsymbol (symbol)->local)
-                 fprintf (file, "\n      End+1 symbol: %-7ld   Type:  %s",
+                 fprintf (file, _("\n      End+1 symbol: %-7ld   Type:  %s"),
                           ((long)
                            (AUX_GET_ISYM (bigendian,
                                           &aux_base[ecoff_ext.asym.index])
                             + sym_base)),
                           ecoff_type_to_string (abfd, fdr, indx + 1));
                else
-                 fprintf (file, "\n      Local symbol: %ld",
+                 fprintf (file, _("\n      Local symbol: %ld"),
                           ((long) indx
                            + (long) sym_base
                            + (ecoff_data (abfd)
@@ -1615,23 +1631,23 @@ _bfd_ecoff_print_symbol (abfd, filep, symbol, how)
                break;
 
              case stStruct:
-               fprintf (file, "\n      struct; End+1 symbol: %ld",
+               fprintf (file, _("\n      struct; End+1 symbol: %ld"),
                         (long) (indx + sym_base));
                break;
 
              case stUnion:
-               fprintf (file, "\n      union; End+1 symbol: %ld",
+               fprintf (file, _("\n      union; End+1 symbol: %ld"),
                         (long) (indx + sym_base));
                break;
 
              case stEnum:
-               fprintf (file, "\n      enum; End+1 symbol: %ld",
+               fprintf (file, _("\n      enum; End+1 symbol: %ld"),
                         (long) (indx + sym_base));
                break;
 
              default:
                if (! ECOFF_IS_STAB (&ecoff_ext.asym))
-                 fprintf (file, "\n      Type: %s",
+                 fprintf (file, _("\n      Type: %s"),
                           ecoff_type_to_string (abfd, fdr, indx));
                break;
              }
@@ -1802,7 +1818,7 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
                              filename_ptr, functionname_ptr, retline_ptr)
      bfd *abfd;
      asection *section;
-     asymbol **ignore_symbols;
+     asymbol **ignore_symbols ATTRIBUTE_UNUSED;
      bfd_vma offset;
      CONST char **filename_ptr;
      CONST char **functionname_ptr;
@@ -1858,10 +1874,10 @@ _bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd)
   size_t c;
   boolean local;
 
-  /* This function is selected based on the input vector.  We only
-     want to copy information over if the output BFD also uses ECOFF
+  /* We only want to copy information over if both BFD's use ECOFF
      format.  */
-  if (bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
+  if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour
+      || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
     return true;
 
   /* Copy the GP value and the register masks.  */
@@ -1972,7 +1988,7 @@ _bfd_ecoff_set_arch_mach (abfd, arch, machine)
 int
 _bfd_ecoff_sizeof_headers (abfd, reloc)
      bfd *abfd;
-     boolean reloc;
+     boolean reloc ATTRIBUTE_UNUSED;
 {
   asection *current;
   int c;
@@ -2045,6 +2061,7 @@ ecoff_compute_section_file_positions (abfd)
   asection *current;
   unsigned int i;
   file_ptr old_sofar;
+  boolean rdata_in_text;
   boolean first_data, first_nonalloc;
   const bfd_vma round = ecoff_backend (abfd)->round;
 
@@ -2065,6 +2082,27 @@ ecoff_compute_section_file_positions (abfd)
   qsort (sorted_hdrs, abfd->section_count, sizeof (asection *),
         ecoff_sort_hdrs);
 
+  /* Some versions of the OSF linker put the .rdata section in the
+     text segment, and some do not.  */
+  rdata_in_text = ecoff_backend (abfd)->rdata_in_text;
+  if (rdata_in_text)
+    {
+      for (i = 0; i < abfd->section_count; i++)
+       {
+         current = sorted_hdrs[i];
+         if (strcmp (current->name, _RDATA) == 0)
+           break;
+         if ((current->flags & SEC_CODE) == 0
+             && strcmp (current->name, _PDATA) != 0
+             && strcmp (current->name, _RCONST) != 0)
+           {
+             rdata_in_text = false;
+             break;
+           }
+       }
+    }
+  ecoff_data (abfd)->rdata_in_text = rdata_in_text;
+
   first_data = true;
   first_nonalloc = true;
   for (i = 0; i < abfd->section_count; i++)
@@ -2077,13 +2115,10 @@ ecoff_compute_section_file_positions (abfd)
         supposed to indicate the number of .pdata entries that are
         really in the section.  Each entry is 8 bytes.  We store this
         away in line_filepos before increasing the section size.  */
-      if (strcmp (current->name, _PDATA) != 0)
-       alignment_power = current->alignment_power;
-      else
-       {
-         current->line_filepos = current->_raw_size / 8;
-         alignment_power = 4;
-       }
+      if (strcmp (current->name, _PDATA) == 0)
+       current->line_filepos = current->_raw_size / 8;
+
+      alignment_power = current->alignment_power;
 
       /* On Ultrix, the data sections in an executable file must be
         aligned to a page boundary within the file.  This does not
@@ -2095,7 +2130,7 @@ ecoff_compute_section_file_positions (abfd)
          && (abfd->flags & D_PAGED) != 0
          && ! first_data
          && (current->flags & SEC_CODE) == 0
-         && (! ecoff_backend (abfd)->rdata_in_text
+         && (! rdata_in_text
              || strcmp (current->name, _RDATA) != 0)
          && strcmp (current->name, _PDATA) != 0
          && strcmp (current->name, _RCONST) != 0)
@@ -2550,7 +2585,7 @@ _bfd_ecoff_write_object_contents (abfd)
 
       if ((section.s_flags & STYP_TEXT) != 0
          || ((section.s_flags & STYP_RDATA) != 0
-             && backend->rdata_in_text)
+             && ecoff_data (abfd)->rdata_in_text)
          || section.s_flags == STYP_PDATA
          || (section.s_flags & STYP_DYNAMIC) != 0
          || (section.s_flags & STYP_LIBLIST) != 0
@@ -2921,6 +2956,8 @@ ecoff_armap_hash (s, rehash, size, hlog)
 {
   unsigned int hash;
 
+  if (hlog == 0)
+    return 0;
   hash = *s++;
   while (*s != '\0')
     hash = ((hash >> 27) | (hash << 5)) + *s++;
@@ -3122,7 +3159,7 @@ _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx)
 
   /* Ultrix appears to use as a hash table size the least power of two
      greater than twice the number of entries.  */
-  for (hashlog = 0; (1 << hashlog) <= 2 * orl_count; hashlog++)
+  for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++)
     ;
   hashsize = 1 << hashlog;
 
@@ -3161,7 +3198,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);
 
@@ -3265,16 +3309,24 @@ const bfd_target *
 _bfd_ecoff_archive_p (abfd)
      bfd *abfd;
 {
+  struct artdata *tdata_hold;
   char armag[SARMAG + 1];
 
-  if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG
-      || strncmp (armag, ARMAG, SARMAG) != 0)
+  tdata_hold = abfd->tdata.aout_ar_data;
+
+  if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG)
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
       return (const bfd_target *) NULL;
     }
 
+  if (strncmp (armag, ARMAG, SARMAG) != 0)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
   /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
      involves a cast, we can't do it as the left operand of
      assignment.  */
@@ -3282,7 +3334,10 @@ _bfd_ecoff_archive_p (abfd)
     (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
 
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
-    return (const bfd_target *) NULL;
+    {
+      abfd->tdata.aout_ar_data = tdata_hold;
+      return (const bfd_target *) NULL;
+    }
 
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
   bfd_ardata (abfd)->cache = NULL;
@@ -3295,10 +3350,43 @@ _bfd_ecoff_archive_p (abfd)
       || _bfd_ecoff_slurp_extended_name_table (abfd) == false)
     {
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = (struct artdata *) NULL;
+      abfd->tdata.aout_ar_data = tdata_hold;
       return (const bfd_target *) NULL;
     }
   
+  if (bfd_has_map (abfd))
+    {
+      bfd *first;
+
+      /* This archive has a map, so we may presume that the contents
+        are object files.  Make sure that if the first file in the
+        archive can be recognized as an object file, it is for this
+        target.  If not, assume that this is the wrong format.  If
+        the first file is not an object file, somebody is doing
+        something weird, and we permit it so that ar -t will work.  */
+
+      first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+      if (first != NULL)
+       {
+         boolean fail;
+
+         first->target_defaulted = false;
+         fail = false;
+         if (bfd_check_format (first, bfd_object)
+             && first->xvec != abfd->xvec)
+           {
+             (void) bfd_close (first);
+             bfd_release (abfd, bfd_ardata (abfd));
+             abfd->tdata.aout_ar_data = tdata_hold;
+             bfd_set_error (bfd_error_wrong_format);
+             return NULL;
+           }
+
+         /* We ought to close first here, but we can't, because we
+             have no way to remove it from the archive cache.  FIXME.  */
+       }
+    }
+
   return abfd->xvec;
 }
 \f
This page took 0.028252 seconds and 4 git commands to generate.