* elf32-mips.c (mips_elf_object_p): Unconditionally set
[deliverable/binutils-gdb.git] / bfd / coff-i960.c
index f58f9485c1c65e132c290d42921c32c65c649de9..cfbe5fdcbfa739610cc2ee537d0a959498f8d659 100644 (file)
@@ -1,5 +1,5 @@
-/* Intel 960 COFF support for BFD.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+/* BFD back-end for Intel 960 COFF files.
+   Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -28,6 +28,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "coff/i960.h"
 #include "coff/internal.h"
 #include "libcoff.h"           /* to allow easier abstraction-breaking */
+
+static bfd_reloc_status_type optcall_callback
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_i960_relocate
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
 #define COFF_LONG_FILENAMES
 
 #define CALLS   0x66003800     /* Template for 'calls' instruction     */
@@ -35,14 +41,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define BAL_MASK 0x00ffffff
 
 static bfd_reloc_status_type 
-DEFUN (optcall_callback, (abfd, reloc_entry, symbol_in, data,
-                         ignore_input_section, ignore_bfd),
-       bfd *abfd AND
-       arelent *reloc_entry AND
-       asymbol *symbol_in AND
-       PTR data AND
-       asection *ignore_input_section AND
-       bfd *ignore_bfd)
+optcall_callback (abfd, reloc_entry, symbol_in, data,
+                 ignore_input_section, ignore_bfd, error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol_in;
+     PTR data;
+     asection *ignore_input_section;
+     bfd *ignore_bfd;
+     char **error_message;
 {
   /* This item has already been relocated correctly, but we may be
    * able to patch in yet better code - done by digging out the
@@ -52,33 +59,36 @@ DEFUN (optcall_callback, (abfd, reloc_entry, symbol_in, data,
 
   /* So the target symbol has to be of coff type, and the symbol 
      has to have the correct native information within it */
-  if ((cs->symbol.the_bfd->xvec->flavour != bfd_target_coff_flavour)
-      || (cs->native == (combined_entry_type *)NULL)) {
-     /* This is interesting, consider the case where we're outputting */
-     /* coff from a mix n match input, linking from coff to a symbol */
-     /* defined in a bout file will cause this match to be true. Should */
-     /* I complain ? - This will only work if the bout symbol is non */
-     /* leaf. */
-     result = bfd_reloc_dangerous;
-  }
-  else  {
+  if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
+      || (cs->native == (combined_entry_type *)NULL))
+    {
+      /* This is interesting, consider the case where we're outputting coff
+        from a mix n match input, linking from coff to a symbol defined in a
+        bout file will cause this match to be true. Should I complain?  This
+        will only work if the bout symbol is non leaf.  */
+      *error_message =
+       (char *) "uncertain calling convention for non-COFF symbol";
+      result = bfd_reloc_dangerous;
+    }
+  else
+    {
     switch (cs->native->u.syment.n_sclass) 
       {
       case C_LEAFSTAT:
       case C_LEAFEXT:
        /* This is a call to a leaf procedure, replace instruction with a bal
-        to the correct location */
+          to the correct location.  */
        {
          union internal_auxent *aux = &((cs->native+2)->u.auxent);
          int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
          int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
          BFD_ASSERT(cs->native->u.syment.n_numaux==2);
-         /* We replace the original call instruction with a bal to */
-         /* the bal entry point - the offset of which is described in the */
-         /* 2nd auxent of the original symbol. We keep the native sym and */
-         /* auxents untouched, so the delta between the two is the */
-         /* offset of the bal entry point */
 
+         /* We replace the original call instruction with a bal to
+            the bal entry point - the offset of which is described in
+            the 2nd auxent of the original symbol. We keep the native
+            sym and auxents untouched, so the delta between the two
+            is the offset of the bal entry point.  */
          word = ((word +  olf)  & BAL_MASK) | BAL;
          bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address);
        }
@@ -97,20 +107,80 @@ DEFUN (optcall_callback, (abfd, reloc_entry, symbol_in, data,
   return result;
 }
 
+/* i960 COFF is used by VxWorks 5.1.  However, VxWorks 5.1 does not
+   appear to correctly handle a reloc against a symbol defined in the
+   same object file.  It appears to simply discard such relocs, rather
+   than adding their values into the object file.  We handle this here
+   by converting all relocs against defined symbols into relocs
+   against the section symbol, when generating a relocateable output
+   file.  */
+
+static bfd_reloc_status_type 
+coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section,
+                   output_bfd, error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
+{
+  const char *sec_name;
+  asymbol **syms, **sym_end;
+
+  if (output_bfd == NULL)
+    {
+      /* Not generating relocateable output file.  */
+      return bfd_reloc_continue;
+    }
+
+  if (bfd_is_und_section (bfd_get_section (symbol)))
+    {
+      /* Symbol is not defined, so no need to worry about it.  */
+      return bfd_reloc_continue;
+    }
+
+  /* Convert the reloc to use the section symbol.  FIXME: This method
+     is ridiculous.  */
+  sec_name = bfd_get_section_name (output_bfd,
+                                  bfd_get_section (symbol)->output_section);
+  syms = bfd_get_outsymbols (output_bfd);
+  sym_end = syms + bfd_get_symcount (output_bfd);
+  for (; syms < sym_end; syms++)
+    {
+      if (bfd_asymbol_name (*syms) != NULL
+         && strcmp (bfd_asymbol_name (*syms), sec_name) == 0
+         && (*syms)->value == 0)
+       {
+         reloc_entry->sym_ptr_ptr = syms;
+         break;
+       }
+    }
+
+  if (syms >= sym_end)
+    abort ();
+
+  /* Let bfd_perform_relocation do its thing, which will include
+     stuffing the symbol addend into the object file.  */
+  return bfd_reloc_continue;
+}
+
 static reloc_howto_type howto_rellong =
-  { (unsigned int) R_RELLONG, 0, 2, 32,false, 0, true, true,
-      0,"rellong", true, 0xffffffff, 0xffffffff};
+  HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,false, 0,
+        complain_overflow_bitfield, coff_i960_relocate,"rellong", true,
+        0xffffffff, 0xffffffff, 0);
 static reloc_howto_type howto_iprmed =
-  {  R_IPRMED, 0, 2, 24,true,0, true, true,0,"iprmed ", true,
-       0x00ffffff, 0x00ffffff};
+  HOWTO (R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed,
+        coff_i960_relocate, "iprmed ", true, 0x00ffffff, 0x00ffffff, 0);
 static reloc_howto_type howto_optcall =
-  {  R_OPTCALL, 0,2,24,true,0, true, true, optcall_callback,
-       "optcall", true, 0x00ffffff, 0x00ffffff};
+  HOWTO (R_OPTCALL, 0,2,24,true,0, complain_overflow_signed,
+        optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff, 0);
 
-static reloc_howto_type *
-DEFUN (coff_i960_reloc_type_lookup, (abfd, code),
-       bfd *abfd AND
-       bfd_reloc_code_real_type code)
+static const reloc_howto_type *
+coff_i960_reloc_type_lookup (abfd, code)
+     bfd *abfd;
+     bfd_reloc_code_real_type code;
 {
   switch (code)
     {
@@ -119,6 +189,7 @@ DEFUN (coff_i960_reloc_type_lookup, (abfd, code),
     case BFD_RELOC_I960_CALLJ:
       return &howto_optcall;
     case BFD_RELOC_32:
+    case BFD_RELOC_CTOR:
       return &howto_rellong;
     case BFD_RELOC_24_PCREL:
       return &howto_iprmed;
@@ -141,7 +212,10 @@ DEFUN (coff_i960_reloc_type_lookup, (abfd, code),
 
 #include "coffcode.h"
 
-bfd_target icoff_little_vec =
+#undef coff_bfd_reloc_type_lookup
+#define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup
+
+const bfd_target icoff_little_vec =
 {
   "coff-Intel-little",         /* name */
   bfd_target_coff_flavour,
@@ -150,16 +224,20 @@ bfd_target icoff_little_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
-  0,                           /* leading underscore */
+  '_',                         /* leading underscore */
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
 
   3,                           /* minimum alignment power */
-  _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
-  _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
 
  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
    bfd_generic_archive_p, _bfd_dummy_target},
@@ -167,14 +245,22 @@ bfd_target icoff_little_vec =
    _bfd_generic_mkarchive, bfd_false},
  {bfd_false, coff_write_object_contents, /* bfd_write_contents */
    _bfd_write_archive_contents, bfd_false},
-  JUMP_TABLE(coff),
+
+     BFD_JUMP_TABLE_GENERIC (coff),
+     BFD_JUMP_TABLE_COPY (coff),
+     BFD_JUMP_TABLE_CORE (_bfd_nocore),
+     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+     BFD_JUMP_TABLE_SYMBOLS (coff),
+     BFD_JUMP_TABLE_RELOCS (coff),
+     BFD_JUMP_TABLE_WRITE (coff),
+     BFD_JUMP_TABLE_LINK (coff),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
   COFF_SWAP_TABLE,
-  coff_i960_reloc_type_lookup,
-  coff_make_debug_symbol,
 };
 
 
-bfd_target icoff_big_vec =
+const bfd_target icoff_big_vec =
 {
   "coff-Intel-big",            /* name */
   bfd_target_coff_flavour,
@@ -183,16 +269,20 @@ bfd_target icoff_big_vec =
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
-  0,                           /* leading underscore */
+  '_',                         /* leading underscore */
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
 
   3,                           /* minimum alignment power */
-_do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
-_do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
 
   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
      bfd_generic_archive_p, _bfd_dummy_target},
@@ -200,8 +290,16 @@ _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs
      _bfd_generic_mkarchive, bfd_false},
   {bfd_false, coff_write_object_contents,      /* bfd_write_contents */
      _bfd_write_archive_contents, bfd_false},
-  JUMP_TABLE(coff),
+
+     BFD_JUMP_TABLE_GENERIC (coff),
+     BFD_JUMP_TABLE_COPY (coff),
+     BFD_JUMP_TABLE_CORE (_bfd_nocore),
+     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+     BFD_JUMP_TABLE_SYMBOLS (coff),
+     BFD_JUMP_TABLE_RELOCS (coff),
+     BFD_JUMP_TABLE_WRITE (coff),
+     BFD_JUMP_TABLE_LINK (coff),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
   COFF_SWAP_TABLE,
-  coff_i960_reloc_type_lookup,
-  coff_make_debug_symbol,
 };
This page took 0.026425 seconds and 4 git commands to generate.