OSDN Git Service

daily update
[pf3gnuchains/pf3gnuchains3x.git] / bfd / aoutx.h
index 7dce072..9521d0a 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD semi-generic back-end for a.out binaries.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,7 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 /*
 SECTION
@@ -118,8 +119,8 @@ DESCRIPTION
 
 #define KEEPIT udata.i
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "safe-ctype.h"
 #include "bfdlink.h"
 
@@ -129,8 +130,6 @@ DESCRIPTION
 #include "aout/stab_gnu.h"
 #include "aout/ar.h"
 
-reloc_howto_type * NAME (aout, reloc_type_lookup)  (bfd *, bfd_reloc_code_real_type);
-
 /*
 SUBSECTION
        Relocations
@@ -319,6 +318,31 @@ NAME (aout, reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
       }
 }
 
+reloc_howto_type *
+NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name)
+{
+  unsigned int i, size;
+  reloc_howto_type *howto_table;
+
+  if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
+    {
+      howto_table = howto_table_ext;
+      size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]);
+    }
+  else
+    {
+      howto_table = howto_table_std;
+      size = sizeof (howto_table_std) / sizeof (howto_table_std[0]);
+    }
+
+  for (i = 0; i < size; i++)
+    if (howto_table[i].name != NULL
+       && strcasecmp (howto_table[i].name, r_name) == 0)
+      return &howto_table[i];
+
+  return NULL;
+}
+
 /*
 SUBSECTION
        Internal entry points
@@ -440,7 +464,7 @@ NAME (aout, some_aout_object_p) (bfd *abfd,
   const bfd_target *result;
   bfd_size_type amt = sizeof (* rawptr);
 
-  rawptr = bfd_zalloc (abfd, amt);
+  rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
   if (rawptr == NULL)
     return NULL;
 
@@ -655,7 +679,7 @@ NAME (aout, mkobject) (bfd *abfd)
 
   bfd_set_error (bfd_error_system_call);
 
-  rawptr = bfd_zalloc (abfd, amt);
+  rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
   if (rawptr == NULL)
     return FALSE;
 
@@ -762,6 +786,8 @@ NAME (aout, machine_type) (enum bfd_architecture arch,
        case bfd_mach_mips9000:
        case bfd_mach_mips10000:
        case bfd_mach_mips12000:
+       case bfd_mach_mips14000:
+       case bfd_mach_mips16000:
        case bfd_mach_mips16:
        case bfd_mach_mipsisa32:
        case bfd_mach_mipsisa32r2:
@@ -769,6 +795,7 @@ NAME (aout, machine_type) (enum bfd_architecture arch,
        case bfd_mach_mipsisa64:
        case bfd_mach_mipsisa64r2:
        case bfd_mach_mips_sb1:
+       case bfd_mach_mips_xlr:
          /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc.  */
          arch_flags = M_MIPS2;
          break;
@@ -1193,26 +1220,21 @@ NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
        {
          obj_textsec (abfd)= newsect;
          newsect->target_index = N_TEXT;
-         return TRUE;
        }
-
-      if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
+      else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
        {
          obj_datasec (abfd) = newsect;
          newsect->target_index = N_DATA;
-         return TRUE;
        }
-
-      if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
+      else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
        {
          obj_bsssec (abfd) = newsect;
          newsect->target_index = N_BSS;
-         return TRUE;
        }
     }
 
   /* We allow more than three sections internally.  */
-  return TRUE;
+  return _bfd_generic_new_section_hook (abfd, newsect);
 }
 
 bfd_boolean
@@ -1272,9 +1294,10 @@ aout_get_external_symbols (bfd *abfd)
     {
       bfd_size_type count;
       struct external_nlist *syms;
-      bfd_size_type amt;
 
       count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
+      if (count == 0)
+       return TRUE;            /* Nothing to do.  */
 
 #ifdef USE_MMAP
       if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
@@ -1286,17 +1309,20 @@ aout_get_external_symbols (bfd *abfd)
       /* We allocate using malloc to make the values easy to free
         later on.  If we put them on the objalloc it might not be
         possible to free them.  */
-      syms = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
-      if (syms == NULL && count != 0)
+      syms = (struct external_nlist *) bfd_malloc (count * EXTERNAL_NLIST_SIZE);
+      if (syms == NULL)
        return FALSE;
 
-      amt = exec_hdr (abfd)->a_syms;
-      if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
-         || bfd_bread (syms, amt, abfd) != amt)
-       {
-         free (syms);
-         return FALSE;
-       }
+      {
+       bfd_size_type amt;
+       amt = exec_hdr (abfd)->a_syms;
+       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+           || bfd_bread (syms, amt, abfd) != amt)
+         {
+           free (syms);
+           return FALSE;
+         }
+      }
 #endif
 
       obj_aout_external_syms (abfd) = syms;
@@ -1323,7 +1349,7 @@ aout_get_external_symbols (bfd *abfd)
        return FALSE;
       strings = (char *) obj_aout_string_window (abfd).data;
 #else
-      strings = bfd_malloc (stringsize + 1);
+      strings = (char *) bfd_malloc (stringsize + 1);
       if (strings == NULL)
        return FALSE;
 
@@ -1642,12 +1668,12 @@ NAME (aout, make_empty_symbol) (bfd *abfd)
 {
   bfd_size_type amt = sizeof (aout_symbol_type);
 
-  aout_symbol_type *new = bfd_zalloc (abfd, amt);
-  if (!new)
+  aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt);
+  if (!new_symbol)
     return NULL;
-  new->symbol.the_bfd = abfd;
+  new_symbol->symbol.the_bfd = abfd;
 
-  return &new->symbol;
+  return &new_symbol->symbol;
 }
 
 /* Translate a set of internal symbols into external symbols.  */
@@ -1720,9 +1746,12 @@ NAME (aout, slurp_symbol_table) (bfd *abfd)
     return FALSE;
 
   cached_size = obj_aout_external_sym_count (abfd);
+  if (cached_size == 0)
+    return TRUE;               /* Nothing to do.  */
+
   cached_size *= sizeof (aout_symbol_type);
-  cached = bfd_zmalloc (cached_size);
-  if (cached == NULL && cached_size != 0)
+  cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
+  if (cached == NULL)
     return FALSE;
 
   /* Convert from external symbol information to internal.  */
@@ -1934,7 +1963,10 @@ NAME (aout, swap_std_reloc_out) (bfd *abfd,
 
   if (bfd_is_com_section (output_section)
       || bfd_is_abs_section (output_section)
-      || bfd_is_und_section (output_section))
+      || bfd_is_und_section (output_section)
+      /* PR gas/3041  a.out relocs against weak symbols
+        must be treated as if they were against externs.  */
+      || (sym->flags & BSF_WEAK))
     {
       if (bfd_abs_section_ptr->symbol == sym)
        {
@@ -2137,7 +2169,10 @@ NAME (aout, swap_ext_reloc_in) (bfd *abfd,
                >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
     }
 
-  cache_ptr->howto =  howto_table_ext + r_type;
+  if (r_type < TABLE_SIZE (howto_table_ext))
+    cache_ptr->howto = howto_table_ext + r_type;
+  else
+    cache_ptr->howto = NULL;
 
   /* Base relative relocs are always against the symbol table,
      regardless of the setting of r_extern.  r_extern just reflects
@@ -2205,9 +2240,14 @@ NAME (aout, swap_std_reloc_in) (bfd *abfd,
 
   howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
               + 16 * r_jmptable + 32 * r_relative);
-  BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
-  cache_ptr->howto =  howto_table_std + howto_idx;
-  BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
+  if (howto_idx < TABLE_SIZE (howto_table_std))
+    {
+      cache_ptr->howto = howto_table_std + howto_idx;
+      if (cache_ptr->howto->type == (unsigned int) -1)
+       cache_ptr->howto = NULL;
+    }
+  else
+    cache_ptr->howto = NULL;
 
   /* Base relative relocs are always against the symbol table,
      regardless of the setting of r_extern.  r_extern just reflects
@@ -2258,20 +2298,25 @@ NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
       return FALSE;
     }
 
+  if (reloc_size == 0)
+    return TRUE;               /* Nothing to be done.  */
+
   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
     return FALSE;
 
   each_size = obj_reloc_entry_size (abfd);
 
   count = reloc_size / each_size;
+  if (count == 0)
+    return TRUE;               /* Nothing to be done.  */
 
   amt = count * sizeof (arelent);
-  reloc_cache = bfd_zmalloc (amt);
-  if (reloc_cache == NULL && count != 0)
+  reloc_cache = (arelent *) bfd_zmalloc (amt);
+  if (reloc_cache == NULL)
     return FALSE;
 
   relocs = bfd_malloc (reloc_size);
-  if (relocs == NULL && reloc_size != 0)
+  if (relocs == NULL)
     {
       free (reloc_cache);
       return FALSE;
@@ -2327,7 +2372,7 @@ NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
 
   each_size = obj_reloc_entry_size (abfd);
   natsize = (bfd_size_type) each_size * count;
-  native = bfd_zalloc (abfd, natsize);
+  native = (unsigned char *) bfd_zalloc (abfd, natsize);
   if (!native)
     return FALSE;
 
@@ -2741,7 +2786,7 @@ NAME (aout, find_nearest_line) (bfd *abfd,
     adata (abfd).line_buf = buf = NULL;
   else
     {
-      buf = bfd_malloc (filelen + funclen + 3);
+      buf = (char *) bfd_malloc (filelen + funclen + 3);
       adata (abfd).line_buf = buf;
       if (buf == NULL)
        return FALSE;
@@ -2785,7 +2830,8 @@ NAME (aout, find_nearest_line) (bfd *abfd,
 }
 
 int
-NAME (aout, sizeof_headers) (bfd *abfd, bfd_boolean execable ATTRIBUTE_UNUSED)
+NAME (aout, sizeof_headers) (bfd *abfd,
+                            struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   return adata (abfd).exec_bytes_size;
 }
@@ -2834,7 +2880,8 @@ NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
   if (ret == NULL)
-    ret = bfd_hash_allocate (table, sizeof (* ret));
+    ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
+                                                             sizeof (* ret));
   if (ret == NULL)
     return NULL;
 
@@ -2873,7 +2920,7 @@ NAME (aout, link_hash_table_create) (bfd *abfd)
   struct aout_link_hash_table *ret;
   bfd_size_type amt = sizeof (* ret);
 
-  ret = bfd_malloc (amt);
+  ret = (struct aout_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
 
@@ -2920,13 +2967,16 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
        return FALSE;
     }
 
+  if (sym_count == 0)
+    return TRUE;               /* Nothing to do.  */
+
   /* We keep a list of the linker hash table entries that correspond
      to particular symbols.  We could just look them up in the hash
      table, but keeping the list is more efficient.  Perhaps this
      should be conditional on info->keep_memory.  */
   amt = sym_count * sizeof (struct aout_link_hash_entry *);
-  sym_hash = bfd_alloc (abfd, amt);
-  if (sym_hash == NULL && sym_count != 0)
+  sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
+  if (sym_hash == NULL)
     return FALSE;
   obj_aout_sym_hashes (abfd) = sym_hash;
 
@@ -3234,7 +3284,7 @@ aout_link_check_ar_symbols (bfd *abfd,
            {
              int skip = 0;
 
-             switch (info->common_skip_ar_aymbols)
+             switch (info->common_skip_ar_symbols)
                {
                case bfd_link_common_skip_text:
                  skip = (type == (N_TEXT | N_EXT));
@@ -3289,8 +3339,9 @@ aout_link_check_ar_symbols (bfd *abfd,
                  /* 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 = bfd_hash_allocate (&info->hash->table,
-                                               sizeof (struct bfd_link_hash_common_entry));
+                 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;
 
@@ -3460,7 +3511,8 @@ aout_link_includes_newfunc (struct bfd_hash_entry *entry,
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
   if (ret == NULL)
-    ret = bfd_hash_allocate (table, sizeof (* ret));
+    ret = (struct aout_link_includes_entry *)
+        bfd_hash_allocate (table, sizeof (* ret));
   if (ret == NULL)
     return NULL;
 
@@ -3737,7 +3789,7 @@ aout_link_reloc_link_order (struct aout_final_link_info *finfo,
          bfd_boolean ok;
 
          size = bfd_get_reloc_size (howto);
-         buf = bfd_zmalloc (size);
+         buf = (bfd_byte *) bfd_zmalloc (size);
          if (buf == NULL)
            return FALSE;
          r = MY_relocate_contents (howto, finfo->output_bfd,
@@ -3932,11 +3984,21 @@ aout_link_input_section_std (struct aout_final_link_info *finfo,
 
        howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
                     + 16 * r_jmptable + 32 * r_relative);
-       BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
-       howto = howto_table_std + howto_idx;
+       if (howto_idx < TABLE_SIZE (howto_table_std))
+         howto = howto_table_std + howto_idx;
+       else
+         howto = NULL;
       }
 #endif
 
+      if (howto == NULL)
+       {
+         (*finfo->info->callbacks->einfo)
+           (_("%P: %B: unexpected relocation type\n"), input_bfd);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+
       if (relocatable)
        {
          /* We are generating a relocatable output file, and must
@@ -4255,7 +4317,13 @@ aout_link_input_section_ext (struct aout_final_link_info *finfo,
 
       r_addend = GET_SWORD (input_bfd, rel->r_addend);
 
-      BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
+      if (r_type >= TABLE_SIZE (howto_table_ext))
+       {
+         (*finfo->info->callbacks->einfo)
+           (_("%P: %B: unexpected relocation type\n"), input_bfd);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
 
       if (relocatable)
        {
@@ -5071,7 +5139,8 @@ aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
                {
                  /* This is the first time we have seen this header
                      file with this set of stabs strings.  */
-                 t = bfd_hash_allocate (&finfo->includes.root,
+                 t = (struct aout_link_includes_totals *)
+                      bfd_hash_allocate (&finfo->includes.root,
                                         sizeof *t);
                  if (t == NULL)
                    return FALSE;
@@ -5362,11 +5431,11 @@ NAME (aout, final_link) (bfd *abfd,
     goto error_return;
 
   /* Allocate buffers to hold section contents and relocs.  */
-  aout_info.contents = bfd_malloc (max_contents_size);
+  aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   aout_info.relocs = bfd_malloc (max_relocs_size);
-  aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
-  aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
-                                     * sizeof (struct external_nlist));
+  aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
+  aout_info.output_syms = (struct external_nlist *)
+      bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist));
   if ((aout_info.contents == NULL && max_contents_size != 0)
       || (aout_info.relocs == NULL && max_relocs_size != 0)
       || (aout_info.symbol_map == NULL && max_sym_count != 0)
@@ -5526,22 +5595,19 @@ NAME (aout, final_link) (bfd *abfd,
     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
 
   /* Write out the string table, unless there are no symbols.  */
+  if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
+    goto error_return;
   if (abfd->symcount > 0)
     {
-      if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
-         || ! emit_stringtab (abfd, aout_info.strtab))
+      if (!emit_stringtab (abfd, aout_info.strtab))
        goto error_return;
     }
-  else if (obj_textsec (abfd)->reloc_count == 0
-          && obj_datasec (abfd)->reloc_count == 0)
+  else
     {
-      bfd_byte b;
-      file_ptr pos;
+      bfd_byte b[BYTES_IN_WORD];
 
-      b = 0;
-      pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
-      if (bfd_seek (abfd, pos, SEEK_SET) != 0
-         || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+      memset (b, 0, BYTES_IN_WORD);
+      if (bfd_bwrite (b, (bfd_size_type) BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
        goto error_return;
     }