* archive.c (_bfd_write_archive_contents): Revert June 1 change.
[deliverable/binutils-gdb.git] / bfd / aoutx.h
index c0d934e924a353457485d5fe97dc53f17dbcd294..b3c660e240573ff962ea8ef55156d190da892bd5 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD semi-generic back-end for a.out binaries.
-   Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -240,7 +240,7 @@ HOWTO(10,          0,  2,   32, false, 0, complain_overflow_bitfield,0,"BASE32",    f
 
 #define TABLE_SIZE(TABLE)      (sizeof(TABLE)/sizeof(TABLE[0]))
 
-CONST struct reloc_howto_struct *
+reloc_howto_type *
 NAME(aout,reloc_type_lookup) (abfd,code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
@@ -268,7 +268,7 @@ NAME(aout,reloc_type_lookup) (abfd,code)
        EXT (BFD_RELOC_SPARC_WDISP22, 7);
        EXT (BFD_RELOC_SPARC13, 10);
        EXT (BFD_RELOC_SPARC_BASE13, 15);
-      default: return (CONST struct reloc_howto_struct *) 0;
+      default: return (reloc_howto_type *) NULL;
       }
   else
     /* std relocs */
@@ -281,7 +281,7 @@ NAME(aout,reloc_type_lookup) (abfd,code)
        STD (BFD_RELOC_32_PCREL, 6);
        STD (BFD_RELOC_16_BASEREL, 9);
        STD (BFD_RELOC_32_BASEREL, 10);
-      default: return (CONST struct reloc_howto_struct *) 0;
+      default: return (reloc_howto_type *) NULL;
       }
 }
 
@@ -562,35 +562,33 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
 
   result = (*callback_to_real_object_p)(abfd);
 
-#ifdef STAT_FOR_EXEC
-  /* The original heuristic doesn't work in some important cases. The
-   * a.out file has no information about the text start address. For
-   * files (like kernels) linked to non-standard addresses (ld -Ttext
-   * nnn) the entry point may not be between the default text start
-   * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
-   * This is not just a mach issue. Many kernels are loaded at non
-   * standard addresses.
-   */
-  {
-    struct stat stat_buf;
-    if (abfd->iostream
-       && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
-       && ((stat_buf.st_mode & 0111) != 0))
-      abfd->flags |= EXEC_P;
-  }
-#else /* ! defined (STAT_FOR_EXEC) */
   /* Now that the segment addresses have been worked out, take a better
      guess at whether the file is executable.  If the entry point
      is within the text segment, assume it is.  (This makes files
      executable even if their entry point address is 0, as long as
-     their text starts at zero.)
-
-     At some point we should probably break down and stat the file and
-     declare it executable if (one of) its 'x' bits are on...  */
+     their text starts at zero.).  */
   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
     abfd->flags |= EXEC_P;
-#endif /* ! defined (STAT_FOR_EXEC) */
+#ifdef STAT_FOR_EXEC
+  else
+    {
+      struct stat stat_buf;
+
+      /* The original heuristic doesn't work in some important cases.
+        The a.out file has no information about the text start
+        address.  For files (like kernels) linked to non-standard
+        addresses (ld -Ttext nnn) the entry point may not be between
+        the default text start (obj_textsec(abfd)->vma) and
+        (obj_textsec(abfd)->vma) + text size.  This is not just a mach
+        issue.  Many kernels are loaded at non standard addresses.  */
+      if (abfd->iostream
+         && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
+         && ((stat_buf.st_mode & 0111) != 0))
+       abfd->flags |= EXEC_P;
+    }
+#endif /* STAT_FOR_EXEC */
+
   if (result)
     {
 #if 0 /* These should be set correctly anyways.  */
@@ -723,6 +721,16 @@ NAME(aout,machine_type) (arch, machine, unknown)
     }
     break;
 
+  case bfd_arch_vax:
+    *unknown = false;
+    break;
+
+    /* start-sanitize-rce */
+  case bfd_arch_rce:
+    arch_flags = M_RCE;
+    break;
+    /* end-sanitize-rce */
+
   default:
     arch_flags = M_UNKNOWN;
   }
@@ -813,6 +821,8 @@ adjust_o_magic (abfd, execp)
       vma += pad;
       obj_datasec(abfd)->vma = vma;
     }
+  else
+    vma = obj_datasec(abfd)->vma;
   obj_datasec(abfd)->filepos = pos;
   pos += obj_datasec(abfd)->_raw_size;
   vma += obj_datasec(abfd)->_raw_size;
@@ -1156,26 +1166,32 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count)
   file_ptr text_end;
   bfd_size_type text_size;
 
-  if (abfd->output_has_begun == false)
-      {
-       if (NAME(aout,adjust_sizes_and_vmas) (abfd,
-                                             &text_size,
-                                             &text_end) == false)
-         return false;
-      }
+  if (! abfd->output_has_begun)
+    {
+      if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
+       return false;
+    }
 
-  /* regardless, once we know what we're doing, we might as well get going */
-  if (section != obj_bsssec(abfd))
-      {
-       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
-         return false;
+  if (section == obj_bsssec (abfd))
+    {
+      bfd_set_error (bfd_error_no_contents);
+      return false;
+    }
+
+  if (section != obj_textsec (abfd)
+      && section != obj_datasec (abfd))
+    {
+      bfd_set_error (bfd_error_nonrepresentable_section);
+      return false;
+    }
+
+  if (count != 0)
+    {
+      if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+         || bfd_write (location, 1, count, abfd) != count)
+       return false;
+    }
 
-       if (count) {
-         return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
-           true : false;
-       }
-       return true;
-      }
   return true;
 }
 \f
@@ -2100,11 +2116,12 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
   }                                                                    \
 
 void
-NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
+NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
      bfd *abfd;
      struct reloc_ext_external *bytes;
      arelent *cache_ptr;
      asymbol **symbols;
+     bfd_size_type symcount;
 {
   int r_index;
   int r_extern;
@@ -2131,15 +2148,33 @@ NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
   }
 
   cache_ptr->howto =  howto_table_ext + r_type;
+
+  /* Base relative relocs are always against the symbol table,
+     regardless of the setting of r_extern.  r_extern just reflects
+     whether the symbol the reloc is against is local or global.  */
+  if (r_type == RELOC_BASE10
+      || r_type == RELOC_BASE13
+      || r_type == RELOC_BASE22)
+    r_extern = 1;
+
+  if (r_extern && r_index > symcount)
+    {
+      /* We could arrange to return an error, but it might be useful
+         to see the file even if it is bad.  */
+      r_extern = 0;
+      r_index = N_ABS;
+    }
+
   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
 }
 
 void
-NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
+NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
      bfd *abfd;
      struct reloc_std_external *bytes;
      arelent *cache_ptr;
      asymbol **symbols;
+     bfd_size_type symcount;
 {
   int r_index;
   int r_extern;
@@ -2182,6 +2217,20 @@ NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
   cache_ptr->howto =  howto_table_std + howto_idx;
   BFD_ASSERT (cache_ptr->howto->type != -1);
 
+  /* Base relative relocs are always against the symbol table,
+     regardless of the setting of r_extern.  r_extern just reflects
+     whether the symbol the reloc is against is local or global.  */
+  if (r_baserel)
+    r_extern = 1;
+
+  if (r_extern && r_index > symcount)
+    {
+      /* We could arrange to return an error, but it might be useful
+         to see the file even if it is bad.  */
+      r_extern = 0;
+      r_index = N_ABS;
+    }
+
   MOVE_ADDRESS(0);
 }
 
@@ -2256,7 +2305,8 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
        (struct reloc_ext_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
-       NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
+       NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
+                                     bfd_get_symcount (abfd));
     }
   else
     {
@@ -2264,7 +2314,8 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
        (struct reloc_std_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
-       MY_swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
+       MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
+                             bfd_get_symcount (abfd));
     }
 
   free (relocs);
@@ -2729,11 +2780,26 @@ NAME(aout,link_add_symbols) (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
 {
+  bfd *first;
+
   switch (bfd_get_format (abfd))
     {
     case bfd_object:
       return aout_link_add_object_symbols (abfd, info);
     case bfd_archive:
+      first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+      if (first == NULL)
+       return false;
+      if (! bfd_check_format (first, bfd_object))
+       return false;
+      if (bfd_get_flavour (first) != bfd_target_aout_flavour)
+       {
+         /* On Linux, we may have an ELF archive which got recognized
+             as an a.out archive.  Therefore, we treat all archives as
+             though they were actually of the flavour of their first
+             element.  */
+         return (*first->xvec->_bfd_link_add_symbols) (abfd, info);
+       }
       return _bfd_generic_link_add_archive_symbols
        (abfd, info, aout_link_check_archive_element);
     default:
@@ -2930,13 +2996,13 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
                  /* Turn the current link symbol into a common
                     symbol.  It is already on the undefs list.  */
                  h->type = bfd_link_hash_common;
+                 h->u.c.p = ((struct bfd_link_hash_common_entry *)
+                             bfd_hash_allocate (&info->hash->table,
+                                 sizeof (struct bfd_link_hash_common_entry)));
+                 if (h->u.c.p == NULL)
+                   return false;
+
                  h->u.c.size = value;
-                 if (h->u.c.size != value)
-                   {
-                     /* The size did not fit in the bitfield.  */
-                     bfd_set_error (bfd_error_bad_value);
-                     return false;
-                   }
 
                  /* FIXME: This isn't quite right.  The maximum
                     alignment of a common symbol should be set by the
@@ -2945,10 +3011,10 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
                  power = bfd_log2 (value);
                  if (power > bfd_get_arch_info (abfd)->section_align_power)
                    power = bfd_get_arch_info (abfd)->section_align_power;
-                 h->u.c.alignment_power = power;
+                 h->u.c.p->alignment_power = power;
 
-                 h->u.c.section = bfd_make_section_old_way (symbfd,
-                                                            "COMMON");
+                 h->u.c.p->section = bfd_make_section_old_way (symbfd,
+                                                               "COMMON");
                }
              else
                {
@@ -3183,9 +3249,9 @@ aout_link_add_symbols (abfd, info)
         This isn't quite right: it should use the architecture of the
         output file, not the input files.  */
       if ((*sym_hash)->root.type == bfd_link_hash_common
-         && ((*sym_hash)->root.u.c.alignment_power >
+         && ((*sym_hash)->root.u.c.p->alignment_power >
              bfd_get_arch_info (abfd)->section_align_power))
-       (*sym_hash)->root.u.c.alignment_power =
+       (*sym_hash)->root.u.c.p->alignment_power =
          bfd_get_arch_info (abfd)->section_align_power;
 
       /* If this is a set symbol, and we are not building sets, then
@@ -3762,6 +3828,7 @@ aout_link_write_symbols (finfo, input_bfd)
          else if (((type & N_TYPE) == N_INDR
                    && (hresolve == (struct aout_link_hash_entry *) NULL
                        || (hresolve->root.type != bfd_link_hash_defined
+                           && hresolve->root.type != bfd_link_hash_defweak
                            && hresolve->root.type != bfd_link_hash_common)))
                   || type == N_WARNING)
            {
@@ -3814,13 +3881,14 @@ aout_link_write_symbols (finfo, input_bfd)
                      break;
                    }
                }
-             else if (hresolve->root.type == bfd_link_hash_defined)
+             else if (hresolve->root.type == bfd_link_hash_defined
+                      || hresolve->root.type == bfd_link_hash_defweak)
                {
                  asection *input_section;
                  asection *output_section;
 
-                 /* This case means a common symbol which was turned
-                    into a defined symbol.  */
+                 /* This case usually means a common symbol which was
+                    turned into a defined symbol.  */
                  input_section = hresolve->root.u.def.section;
                  output_section = input_section->output_section;
                  BFD_ASSERT (bfd_is_abs_section (output_section)
@@ -3841,17 +3909,25 @@ aout_link_write_symbols (finfo, input_bfd)
                  type &=~ N_TYPE;
 
                  if (output_section == obj_textsec (output_bfd))
-                   type |= N_TEXT;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_TEXT
+                            : N_WEAKT);
                  else if (output_section == obj_datasec (output_bfd))
-                   type |= N_DATA;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_DATA
+                            : N_WEAKD);
                  else if (output_section == obj_bsssec (output_bfd))
-                   type |= N_BSS;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_BSS
+                            : N_WEAKB);
                  else
-                   type |= N_ABS;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_ABS
+                            : N_WEAKA);
                }
              else if (hresolve->root.type == bfd_link_hash_common)
                val = hresolve->root.u.c.size;
-             else if (hresolve->root.type == bfd_link_hash_weak)
+             else if (hresolve->root.type == bfd_link_hash_undefweak)
                {
                  val = 0;
                  type = N_WEAKU;
@@ -4003,6 +4079,7 @@ aout_link_write_other_symbol (h, data)
       val = 0;
       break;
     case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
       {
        asection *sec;
 
@@ -4010,13 +4087,14 @@ aout_link_write_other_symbol (h, data)
        BFD_ASSERT (bfd_is_abs_section (sec)
                    || sec->owner == output_bfd);
        if (sec == obj_textsec (output_bfd))
-         type = N_TEXT | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
        else if (sec == obj_datasec (output_bfd))
-         type = N_DATA | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
        else if (sec == obj_bsssec (output_bfd))
-         type = N_BSS | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
        else
-         type = N_ABS | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
+       type |= N_EXT;
        val = (h->root.u.def.value
               + sec->vma
               + h->root.u.def.section->output_offset);
@@ -4026,7 +4104,7 @@ aout_link_write_other_symbol (h, data)
       type = N_UNDF | N_EXT;
       val = h->root.u.c.size;
       break;
-    case bfd_link_hash_weak:
+    case bfd_link_hash_undefweak:
       type = N_WEAKU;
       val = 0;
     case bfd_link_hash_indirect:
@@ -4278,7 +4356,8 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                 is what the native linker does.  */
              h = sym_hashes[r_index];
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  asection *output_section;
 
@@ -4416,14 +4495,15 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                }
 
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  relocation = (h->root.u.def.value
                                + h->root.u.def.section->output_section->vma
                                + h->root.u.def.section->output_offset);
                }
              else if (h != (struct aout_link_hash_entry *) NULL
-                      && h->root.type == bfd_link_hash_weak)
+                      && h->root.type == bfd_link_hash_undefweak)
                relocation = 0;
              else
                {
@@ -4579,7 +4659,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                 is what the native linker does.  */
              h = sym_hashes[r_index];
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  asection *output_section;
 
@@ -4734,14 +4815,15 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                }
 
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  relocation = (h->root.u.def.value
                                + h->root.u.def.section->output_section->vma
                                + h->root.u.def.section->output_offset);
                }
              else if (h != (struct aout_link_hash_entry *) NULL
-                      && h->root.type == bfd_link_hash_weak)
+                      && h->root.type == bfd_link_hash_undefweak)
                relocation = 0;
              else
                {
@@ -4844,7 +4926,7 @@ aout_link_reloc_link_order (finfo, o, p)
   struct bfd_link_order_reloc *pr;
   int r_index;
   int r_extern;
-  const reloc_howto_type *howto;
+  reloc_howto_type *howto;
   file_ptr *reloff_ptr;
   struct reloc_std_external srel;
   struct reloc_ext_external erel;
@@ -4897,7 +4979,7 @@ aout_link_reloc_link_order (finfo, o, p)
     }
 
   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
-  if (howto == (const reloc_howto_type *) NULL)
+  if (howto == 0)
     {
       bfd_set_error (bfd_error_bad_value);
       return false;
This page took 0.029249 seconds and 4 git commands to generate.