import gdb-2000-01-17 snapshot
[external/binutils.git] / bfd / coff-rs6000.c
index 242381d..6923000 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD back-end for IBM RS/6000 "XCOFF" files.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Free Software Foundation, Inc.
    FIXME: Can someone provide a transliteration of this name into ASCII?
    Using the following chars caused a compiler warning on HIUX (so I replaced
    them with octal escapes), and isn't useful without an understanding of what
@@ -31,7 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
-#include "obstack.h"
 #include "coff/internal.h"
 #include "coff/rs6000.h"
 #include "libcoff.h"
@@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 static boolean xcoff_mkobject PARAMS ((bfd *));
 static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean xcoff_is_local_label_name PARAMS ((bfd *, const char *));
 static void xcoff_rtype2howto
   PARAMS ((arelent *, struct internal_reloc *));
 static reloc_howto_type *xcoff_reloc_type_lookup
@@ -53,6 +54,7 @@ static const char *normalize_filename PARAMS ((bfd *));
 static boolean xcoff_write_armap
   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
 static boolean xcoff_write_archive_contents PARAMS ((bfd *));
+static int _bfd_xcoff_sizeof_headers PARAMS ((bfd *, boolean));
 \f
 /* We use our own tdata type.  Its first field is the COFF tdata type,
    so the COFF routines are compatible.  */
@@ -67,10 +69,7 @@ xcoff_mkobject (abfd)
     ((struct xcoff_tdata *)
      bfd_zalloc (abfd, sizeof (struct xcoff_tdata)));
   if (abfd->tdata.xcoff_obj_data == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   coff = coff_data (abfd);
   coff->symbols = (coff_symbol_type *) NULL;
   coff->conversion_table = (unsigned int *) NULL;
@@ -97,6 +96,7 @@ xcoff_copy_private_bfd_data (ibfd, obfd)
      bfd *obfd;
 {
   struct xcoff_tdata *ix, *ox;
+  asection *sec;
 
   if (ibfd->xvec != obfd->xvec)
     return true;
@@ -104,14 +104,26 @@ xcoff_copy_private_bfd_data (ibfd, obfd)
   ox = xcoff_data (obfd);
   ox->full_aouthdr = ix->full_aouthdr;
   ox->toc = ix->toc;
-  if (ix->toc_section == NULL)
-    ox->toc_section = NULL;
+  if (ix->sntoc == 0)
+    ox->sntoc = 0;
   else
-    ox->toc_section = ix->toc_section->output_section;
-  if (ix->entry_section == NULL)
-    ox->entry_section = NULL;
+    {
+      sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
+      if (sec == NULL)
+       ox->sntoc = 0;
+      else
+       ox->sntoc = sec->output_section->target_index;
+    }
+  if (ix->snentry == 0)
+    ox->snentry = 0;
   else
-    ox->entry_section = ix->entry_section->output_section;
+    {
+      sec = coff_section_from_bfd_index (ibfd, ix->snentry);
+      if (sec == NULL)
+       ox->snentry = 0;
+      else
+       ox->snentry = sec->output_section->target_index;
+    }
   ox->text_align_power = ix->text_align_power;
   ox->data_align_power = ix->data_align_power;
   ox->modtype = ix->modtype;
@@ -120,6 +132,19 @@ xcoff_copy_private_bfd_data (ibfd, obfd)
   ox->maxstack = ix->maxstack;
   return true;
 }
+
+/* I don't think XCOFF really has a notion of local labels based on
+   name.  This will mean that ld -X doesn't actually strip anything.
+   The AIX native linker does not have a -X option, and it ignores the
+   -x option.  */
+
+static boolean
+xcoff_is_local_label_name (abfd, name)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
+{
+  return false;
+}
 \f
 /* The XCOFF reloc table.  Actually, XCOFF relocations specify the
    bitsize and whether they are signed or not, along with a
@@ -234,7 +259,7 @@ static reloc_howto_type xcoff_howto_table[] =
         0xffff,                /* dst_mask */                             
         false),                /* pcrel_offset */
   
-  { 7 },
+  EMPTY_HOWTO (7),
   
   /* Non modifiable absolute branch.  */
   HOWTO (8,                    /* type */                                 
@@ -251,7 +276,7 @@ static reloc_howto_type xcoff_howto_table[] =
         0x3fffffc,             /* dst_mask */                             
         false),                /* pcrel_offset */
   
-  { 9 },
+  EMPTY_HOWTO (9),
 
   /* Non modifiable relative branch.  */
   HOWTO (0xa,                  /* type */                                 
@@ -268,7 +293,7 @@ static reloc_howto_type xcoff_howto_table[] =
         0x3fffffc,             /* dst_mask */                             
         false),                /* pcrel_offset */
   
-  { 0xb },
+  EMPTY_HOWTO (0xb),
 
   /* Indirect load.  */
   HOWTO (0xc,                  /* type */                                 
@@ -300,7 +325,7 @@ static reloc_howto_type xcoff_howto_table[] =
         0xffff,                /* dst_mask */                             
         false),                /* pcrel_offset */
   
-  { 0xe },
+  EMPTY_HOWTO (0xe),
   
   /* Non-relocating reference.  */
   HOWTO (0xf,                  /* type */                                 
@@ -317,8 +342,8 @@ static reloc_howto_type xcoff_howto_table[] =
         0,                     /* dst_mask */                             
         false),                /* pcrel_offset */
   
-  { 0x10 },
-  { 0x11 },
+  EMPTY_HOWTO (0x10),
+  EMPTY_HOWTO (0x11),
   
   /* TOC relative indirect load.  */
   HOWTO (0x12,                 /* type */                                 
@@ -494,7 +519,7 @@ xcoff_rtype2howto (relent, internal)
 
 static reloc_howto_type *
 xcoff_reloc_type_lookup (abfd, code)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      bfd_reloc_code_real_type code;
 {
   switch (code)
@@ -531,6 +556,7 @@ xcoff_reloc_type_lookup (abfd, code)
 
 #define coff_mkobject xcoff_mkobject
 #define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data
+#define coff_bfd_is_local_label_name xcoff_is_local_label_name
 #define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup
 #define coff_relocate_section _bfd_ppc_xcoff_relocate_section
 
@@ -661,6 +687,10 @@ struct xcoff_ar_hdr
    bfd_false)
 #define xcoff_truncate_arname bfd_dont_truncate_arname
 
+/* We can use the standard get_elt_at_index routine.  */
+
+#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
+
 /* XCOFF archives do not have a timestamp.  */
 
 #define xcoff_update_armap_timestamp bfd_true
@@ -709,10 +739,7 @@ xcoff_slurp_armap (abfd)
   sz = strtol (hdr.size, (char **) NULL, 10);
   contents = (bfd_byte *) bfd_alloc (abfd, sz);
   if (contents == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
     return false;
 
@@ -728,10 +755,7 @@ xcoff_slurp_armap (abfd)
   bfd_ardata (abfd)->symdefs = ((carsym *)
                                bfd_alloc (abfd, c * sizeof (carsym)));
   if (bfd_ardata (abfd)->symdefs == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   /* After the count comes a list of four byte file offsets.  */
   for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
@@ -788,10 +812,7 @@ xcoff_archive_p (abfd)
     (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
 
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
                                                  (char **) NULL, 10);
@@ -802,10 +823,7 @@ xcoff_archive_p (abfd)
 
   bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
   if (bfd_ardata (abfd)->tdata == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
 
@@ -834,12 +852,9 @@ xcoff_read_ar_hdr (abfd)
     return NULL;
 
   namlen = strtol (hdr.namlen, (char **) NULL, 10);
-  hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
+  hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
   if (hdrp == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
   memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
   if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
     return NULL;
@@ -847,10 +862,7 @@ xcoff_read_ar_hdr (abfd)
 
   ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
   if (ret == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
   ret->arch_header = (char *) hdrp;
   ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
   ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
@@ -945,7 +957,7 @@ normalize_filename (abfd)
 static boolean
 xcoff_write_armap (abfd, elength, map, orl_count, stridx)
      bfd *abfd;
-     unsigned int elength;
+     unsigned int elength ATTRIBUTE_UNUSED;
      struct orl *map;
      unsigned int orl_count;
      int stridx;
@@ -1062,10 +1074,7 @@ xcoff_write_archive_contents (abfd)
     }
   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
   if (offsets == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
     return false;
@@ -1115,13 +1124,9 @@ xcoff_write_archive_contents (abfd)
 
          if (sub->arelt_data == NULL)
            {
-             sub->arelt_data = ((struct areltdata *)
-                                bfd_alloc (sub, sizeof (struct areltdata)));
+             sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata));
              if (sub->arelt_data == NULL)
-               {
-                 bfd_set_error (bfd_error_no_memory);
-                 return false;
-               }
+               return false;
            }
 
          arch_eltdata (sub)->parsed_size = s.st_size;
@@ -1282,6 +1287,26 @@ xcoff_write_archive_contents (abfd)
   return true;
 }
 \f
+/* We can't use the usual coff_sizeof_headers routine, because AIX
+   always uses an a.out header.  */
+
+/*ARGSUSED*/
+static int
+_bfd_xcoff_sizeof_headers (abfd, reloc)
+     bfd *abfd;
+     boolean reloc ATTRIBUTE_UNUSED;
+{
+  int size;
+
+  size = FILHSZ;
+  if (xcoff_data (abfd)->full_aouthdr)
+    size += AOUTSZ;
+  else
+    size += SMALL_AOUTSZ;
+  size += abfd->section_count * SCNHSZ;
+  return size;
+}
+\f
 #define CORE_FILE_P _bfd_dummy_target
 
 #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
@@ -1333,20 +1358,29 @@ extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
 
 #endif /* LYNX_CORE */
 
-#define _bfd_xcoff_sizeof_headers coff_sizeof_headers
 #define _bfd_xcoff_bfd_get_relocated_section_contents \
   coff_bfd_get_relocated_section_contents
 #define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section
+#define _bfd_xcoff_bfd_gc_sections coff_bfd_gc_sections
 #define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section
 
 /* The transfer vector that leads the outside world to all of the above. */
 
-const bfd_target rs6000coff_vec =
+const bfd_target
+#ifdef TARGET_SYM
+  TARGET_SYM =
+#else
+  rs6000coff_vec =
+#endif
 {
+#ifdef TARGET_NAME
+  TARGET_NAME,
+#else
   "aixcoff-rs6000",            /* name */
+#endif
   bfd_target_coff_flavour,     
-  true,                                /* data byte order is big */
-  true,                                /* header byte order is big */
+  BFD_ENDIAN_BIG,              /* data byte order is big */
+  BFD_ENDIAN_BIG,              /* header byte order is big */
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG | DYNAMIC |
@@ -1379,7 +1413,9 @@ const bfd_target rs6000coff_vec =
      BFD_JUMP_TABLE_RELOCS (coff),
      BFD_JUMP_TABLE_WRITE (coff),
      BFD_JUMP_TABLE_LINK (_bfd_xcoff),
-     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
 
-  COFF_SWAP_TABLE,
+  NULL,
+  
+  COFF_SWAP_TABLE
 };