* reloc16.c (bfd_coff_reloc16_relax_section): Count the total number
[deliverable/binutils-gdb.git] / bfd / mipsbsd.c
index 5d699aa85703404dca37b0d970cc6c9fc781ae49..7a680fb3894931408054583c84ef7fa0f78d28b0 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD backend for MIPS BSD (a.out) binaries.
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
    Written by Ralph Campbell.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -16,10 +16,9 @@ GNU General Public License for more details.
 
 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define BYTES_IN_WORD 4
-#define ARCH 32
 /* #define ENTRY_CAN_BE_ZERO */
 #define N_HEADER_IN_TEXT(x) 1
 #define N_SHARED_LIB(x) 0
@@ -29,8 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
     )
 #define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
 #define TEXT_START_ADDR 4096
-#define PAGE_SIZE 4096
-#define SEGMENT_SIZE PAGE_SIZE
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
 #define DEFAULT_ARCH bfd_arch_mips
 #define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
                            || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
@@ -46,7 +45,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define SET_ARCH_MACH(ABFD, EXEC) \
   MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
   MY(choose_reloc_size)(ABFD);
-void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype));
+static void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype));
 static void MY(choose_reloc_size) PARAMS ((bfd *abfd));
 
 #define MY_write_object_contents MY(write_object_contents)
@@ -59,6 +58,7 @@ static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
 
 #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define MY_final_link_callback unused
 #define MY_bfd_final_link _bfd_generic_final_link
 
 #define MY_backend_data &MY(backend_data)
@@ -66,7 +66,7 @@ static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
 
 #include "aout-target.h"
 
-void
+static void
 MY(set_arch_mach) (abfd, machtype)
      bfd *abfd;
      int machtype;
@@ -127,11 +127,11 @@ MY(write_object_contents) (abfd)
   switch (bfd_get_arch(abfd)) {
   case bfd_arch_m68k:
     switch (bfd_get_mach(abfd)) {
-    case 68010:
+    case bfd_mach_m68010:
       N_SET_MACHTYPE(*execp, M_68010);
       break;
     default:
-    case 68020:
+    case bfd_mach_m68020:
       N_SET_MACHTYPE(*execp, M_68020);
       break;
     }
@@ -177,6 +177,56 @@ MY(write_object_contents) (abfd)
 #define MIPS_RELOC_HI16_S      4
 #define MIPS_RELOC_LO16                5
 
+/*
+ * This is only called when performing a BFD_RELOC_MIPS_JMP relocation.
+ * The jump destination address is formed from the upper 4 bits of the
+ * "current" program counter concatenated with the jump instruction's
+ * 26 bit field and two trailing zeros.
+ * If the destination address is not in the same segment as the "current"
+ * program counter, then we need to signal an error.
+ */
+static bfd_reloc_status_type
+mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     arelent *reloc_entry;
+     struct symbol_cache_entry *symbol;
+     PTR data ATTRIBUTE_UNUSED;
+     asection *input_section;
+     bfd *output_bfd;
+{
+  bfd_vma relocation, pc;
+  /* If this is a partial relocation, just continue. */
+  if (output_bfd != (bfd *)NULL)
+    return bfd_reloc_continue;
+
+  /* If this is an undefined symbol, return error */
+  if (bfd_is_und_section (symbol->section)
+      && (symbol->flags & BSF_WEAK) == 0)
+    return bfd_reloc_undefined;
+
+  /* 
+   * Work out which section the relocation is targetted at and the
+   * initial relocation command value.
+   */
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  relocation += symbol->section->output_section->vma;
+  relocation += symbol->section->output_offset;
+  relocation += reloc_entry->addend;
+
+  pc = input_section->output_section->vma + input_section->output_offset +
+    reloc_entry->address + 4;
+
+  if ((relocation & 0xF0000000) != (pc & 0xF0000000))
+    return bfd_reloc_overflow;
+
+  return bfd_reloc_continue;
+}
+
 /*
  * This is only called when performing a BFD_RELOC_HI16_S relocation.
  * We need to see if bit 15 is set in the result. If it is, we add
@@ -190,13 +240,13 @@ mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR,
 static bfd_reloc_status_type
 mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
                 output_bfd, error_message)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      arelent *reloc_entry;
      asymbol *symbol;
-     PTR data;
-     asection *input_section;
+     PTR data ATTRIBUTE_UNUSED;
+     asection *input_section ATTRIBUTE_UNUSED;
      bfd *output_bfd;
-     char **error_message;
+     char **error_message ATTRIBUTE_UNUSED;
 {
   bfd_vma relocation;
  
@@ -204,11 +254,16 @@ mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
   if (output_bfd != (bfd *)NULL)
     return bfd_reloc_continue;
 
+  /* If this is an undefined symbol, return error */
+  if (bfd_is_und_section (symbol->section)
+      && (symbol->flags & BSF_WEAK) == 0)
+    return bfd_reloc_undefined;
+
   /* 
    * Work out which section the relocation is targetted at and the
    * initial relocation command value.
    */
-  if (symbol->section == &bfd_com_section)
+  if (bfd_is_com_section (symbol->section))
     relocation = 0;
   else
     relocation = symbol->value;
@@ -226,20 +281,21 @@ mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
 static reloc_howto_type mips_howto_table_ext[] = {
   {MIPS_RELOC_32,      0, 2, 32, false, 0,  complain_overflow_bitfield, 0,
        "32",       false, 0, 0xffffffff, false},
-  {MIPS_RELOC_JMP,     2, 2, 26, false, 0, complain_overflow_bitfield, 0,
+  {MIPS_RELOC_JMP,     2, 2, 26, false, 0, complain_overflow_dont,
+       mips_fix_jmp_addr,
        "MIPS_JMP", false, 0, 0x03ffffff, false},
-  {MIPS_RELOC_WDISP16, 2, 1, 16, true,  0, complain_overflow_signed, 0,
+  {MIPS_RELOC_WDISP16, 2, 2, 16, true,  0, complain_overflow_signed, 0,
        "WDISP16",  false, 0, 0x0000ffff, false},
-  {MIPS_RELOC_HI16,   16, 1, 16, false, 0, complain_overflow_bitfield, 0,
+  {MIPS_RELOC_HI16,   16, 2, 16, false, 0, complain_overflow_bitfield, 0,
        "HI16",     false, 0, 0x0000ffff, false},
-  {MIPS_RELOC_HI16_S, 16, 1, 16, false, 0, complain_overflow_bitfield,
+  {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield,
         mips_fix_hi16_s,
         "HI16_S",   false, 0, 0x0000ffff, false},
-  {MIPS_RELOC_LO16,    0, 1, 16, false, 0, complain_overflow_dont, 0,
+  {MIPS_RELOC_LO16,    0, 2, 16, false, 0, complain_overflow_dont, 0,
        "LO16",     false, 0, 0x0000ffff, false},
 };
 
-static const reloc_howto_type *
+static reloc_howto_type *
 MY(reloc_howto_type_lookup) (abfd, code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
@@ -250,6 +306,7 @@ MY(reloc_howto_type_lookup) (abfd, code)
 
   switch (code)
     {
+    case BFD_RELOC_CTOR:
     case BFD_RELOC_32:
       return (&mips_howto_table_ext[MIPS_RELOC_32]);
     case BFD_RELOC_MIPS_JMP:
@@ -303,8 +360,6 @@ MY(canonicalize_reloc)(abfd, section, relptr, symbols)
   if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols))
     return -1;
   tblptr = section->relocation;
-  if (!tblptr)
-    return -1;
 
   /* fix up howto entries */
   for (count = 0; count++ < section->reloc_count;) 
@@ -321,25 +376,34 @@ MY(canonicalize_reloc)(abfd, section, relptr, symbols)
 static CONST struct aout_backend_data MY(backend_data) = {
   0,                           /* zmagic contiguous */
   1,                           /* text incl header */
-  PAGE_SIZE,                   /* text vma */
+  0,                           /* entry is text address */
+  0,                           /* exec_hdr_flags */
+  TARGET_PAGE_SIZE,                    /* text vma */
   MY_set_sizes,
   0,                           /* text size includes exec header */
+  0,                           /* add_dynamic_symbols */
+  0,                           /* add_one_symbol */
+  0,                           /* link_dynamic_object */
+  0,                           /* write_dynamic_symbol */
+  0,                           /* check_dynamic_reloc */
+  0                            /* finish_dynamic_link */
 };
 
-bfd_target aout_mips_little_vec =
+extern const bfd_target aout_mips_big_vec;
+
+const bfd_target aout_mips_little_vec =
 {
   "a.out-mips-little",         /* name */
   bfd_target_aout_flavour,
-  false,                       /* target byte order (little) */
-  false,                       /* target headers byte order (little) */
+  BFD_ENDIAN_LITTLE,           /* target byte order (little) */
+  BFD_ENDIAN_LITTLE,           /* target headers byte order (little) */
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
-  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
   MY_symbol_leading_char,
   ' ',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
-  1,                           /* minimum alignment */
   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 */
@@ -352,24 +416,35 @@ bfd_target aout_mips_little_vec =
        _bfd_generic_mkarchive, bfd_false},
     {bfd_false, MY_write_object_contents, /* bfd_write_contents */
        _bfd_write_archive_contents, bfd_false},
-  JUMP_TABLE (MY),
-  (PTR) MY_backend_data,
+
+     BFD_JUMP_TABLE_GENERIC (MY),
+     BFD_JUMP_TABLE_COPY (MY),
+     BFD_JUMP_TABLE_CORE (MY),
+     BFD_JUMP_TABLE_ARCHIVE (MY),
+     BFD_JUMP_TABLE_SYMBOLS (MY),
+     BFD_JUMP_TABLE_RELOCS (MY),
+     BFD_JUMP_TABLE_WRITE (MY),
+     BFD_JUMP_TABLE_LINK (MY),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  & aout_mips_big_vec,
+  
+  (PTR) MY_backend_data
 };
 
-bfd_target aout_mips_big_vec =
+const bfd_target aout_mips_big_vec =
 {
   "a.out-mips-big",            /* name */
   bfd_target_aout_flavour,
-  true,                                /* target byte order (big) */
-  true,                                /* target headers byte order (big) */
+  BFD_ENDIAN_BIG,              /* target byte order (big) */
+  BFD_ENDIAN_BIG,              /* target headers byte order (big) */
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
-  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
   MY_symbol_leading_char,
   ' ',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
-  1,                           /* minimum alignment */
   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
@@ -382,6 +457,18 @@ bfd_target aout_mips_big_vec =
        _bfd_generic_mkarchive, bfd_false},
     {bfd_false, MY_write_object_contents, /* bfd_write_contents */
        _bfd_write_archive_contents, bfd_false},
-  JUMP_TABLE (MY),
-  (PTR) MY_backend_data,
+
+     BFD_JUMP_TABLE_GENERIC (MY),
+     BFD_JUMP_TABLE_COPY (MY),
+     BFD_JUMP_TABLE_CORE (MY),
+     BFD_JUMP_TABLE_ARCHIVE (MY),
+     BFD_JUMP_TABLE_SYMBOLS (MY),
+     BFD_JUMP_TABLE_RELOCS (MY),
+     BFD_JUMP_TABLE_WRITE (MY),
+     BFD_JUMP_TABLE_LINK (MY),
+     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  & aout_mips_little_vec,
+  
+  (PTR) MY_backend_data
 };
This page took 0.027991 seconds and 4 git commands to generate.