* coff-alpha.c: Implemented reloc handling for the linker, made
authorIan Lance Taylor <ian@airs.com>
Tue, 19 Oct 1993 19:41:44 +0000 (19:41 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 19 Oct 1993 19:41:44 +0000 (19:41 +0000)
various other related changes.
* libecoff.h (ecoff_backend_data): Added rdata_in_text field.
Renamed finish_reloc to adjust_reloc_in.  Added adjust_reloc_out
field.
(ecoff_bfd_get_relocated_section_contents): Don't define.
* ecoff.c (ecoff_sec_to_styp_flags, ecoff_styp_to_sec_flags):
Handle .lita section.
(ecoff_slurp_reloc_table): Handle RELOC_SECTION_FINI.
finish_reloc backend field renamed to adjust_reloc_in.
(ecoff_bfd_seclet_link): Adjust number of aux entries to
debug_align boundary.
(ecoff_compute_section_file_positions): If rdata_in_text put
.rdata section in text segment, not data segment.  Put .pdata
section in text segment.
(ecoff_write_object_contents): Likewise.  Also, call
adjust_reloc_out, and handle .lita, .xdata, .pdata, .fini and
absolute sections when writing out relocs.
* coffswap.h (coff_swap_aouthdr_out): For ALPHAECOFF, output 2 for
bldrev field, as on Alpha OSF/1.  Padding field is now 2 bytes.
* coff-mips.c (mips_ecoff_swap_reloc_out): Added assertion.
(mips_adjust_reloc_in): Renamed from mips_finish_reloc.
(mips_adjust_reloc_out): New function (does nothing).
(mips_ecoff_backend_data): Initialize new fields.
(ecoff_bfd_get_relocation_section_contents): Define to be
bfd_generic_get_relocated_section_contents.

* reloc.c (bfd_perform_relocation): Added casts to avoid Alpha
OSF/1 cc bug.

bfd/ChangeLog
bfd/coff-mips.c

index b22e099..cab64d7 100644 (file)
@@ -1,5 +1,40 @@
+Tue Oct 19 15:26:26 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * coff-alpha.c: Implemented reloc handling for the linker, made
+       various other related changes.
+       * libecoff.h (ecoff_backend_data): Added rdata_in_text field.
+       Renamed finish_reloc to adjust_reloc_in.  Added adjust_reloc_out
+       field.
+       (ecoff_bfd_get_relocated_section_contents): Don't define.
+       * ecoff.c (ecoff_sec_to_styp_flags, ecoff_styp_to_sec_flags):
+       Handle .lita section.
+       (ecoff_slurp_reloc_table): Handle RELOC_SECTION_FINI.
+       finish_reloc backend field renamed to adjust_reloc_in.
+       (ecoff_bfd_seclet_link): Adjust number of aux entries to
+       debug_align boundary.
+       (ecoff_compute_section_file_positions): If rdata_in_text put
+       .rdata section in text segment, not data segment.  Put .pdata
+       section in text segment.
+       (ecoff_write_object_contents): Likewise.  Also, call
+       adjust_reloc_out, and handle .lita, .xdata, .pdata, .fini and
+       absolute sections when writing out relocs.
+       * coffswap.h (coff_swap_aouthdr_out): For ALPHAECOFF, output 2 for
+       bldrev field, as on Alpha OSF/1.  Padding field is now 2 bytes.
+       * coff-mips.c (mips_ecoff_swap_reloc_out): Added assertion.
+       (mips_adjust_reloc_in): Renamed from mips_finish_reloc.
+       (mips_adjust_reloc_out): New function (does nothing).
+       (mips_ecoff_backend_data): Initialize new fields.
+       (ecoff_bfd_get_relocation_section_contents): Define to be
+       bfd_generic_get_relocated_section_contents.
+
+       * reloc.c (bfd_perform_relocation): Added casts to avoid Alpha
+       OSF/1 cc bug.
+
 Thu Oct 14 01:10:35 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
+       * reloc.c (bfd_perform_relocation): Add comments attempting to
+       explain PC relative relocations.
+
        * coffcode.h (styp_to_sec_flags): Don't set SEC_DEBUGGING until it
        is made to work.
        (coff_compute_section_file_positions): Remove check for
index baffd44..e641b60 100644 (file)
@@ -34,13 +34,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* Prototypes for static functions.  */
 
 static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
-static PTR mips_ecoff_mkobject_hook PARAMS ((bfd *abfd, PTR filehdr,
-                                            PTR aouthdr));
 static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
                                              struct internal_reloc *));
 static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
                                               const struct internal_reloc *,
                                               PTR));
+static void mips_adjust_reloc_in PARAMS ((bfd *,
+                                         const struct internal_reloc *,
+                                         arelent *));
+static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,
+                                          struct internal_reloc *));
 static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
                                                         arelent *reloc,
                                                         asymbol *symbol,
@@ -148,7 +151,10 @@ static reloc_howto_type mips_howto_table[] =
         26,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
+                               /* This needs complex overflow
+                                  detection, because the upper four
+                                  bits must match the PC.  */
         mips_generic_reloc,    /* special_function */
         "JMPADDR",             /* name */
         true,                  /* partial_inplace */
@@ -232,46 +238,25 @@ mips_ecoff_bad_format_hook (abfd, filehdr)
 {
   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
 
-  if (MIPS_ECOFF_BADMAG (*internal_f))
-    return false;
-
-  return true;
-}
-
-/* Create the MIPS ECOFF backend specific information.  */
-
-static PTR
-mips_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
-     bfd *abfd;
-     PTR filehdr;
-     PTR aouthdr;
-{
-  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
-  struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
-  ecoff_data_type *ecoff;
+  switch (internal_f->f_magic)
+    {
+    case MIPS_MAGIC_1:
+      /* I don't know what endianness this implies.  */
+      return true;
 
-  if (ecoff_mkobject (abfd) == false)
-    return NULL;
+    case MIPS_MAGIC_BIG:
+    case MIPS_MAGIC_BIG2:
+    case MIPS_MAGIC_BIG3:
+      return abfd->xvec->byteorder_big_p;
 
-  ecoff = ecoff_data (abfd);
-  ecoff->gp_size = 8;
-  ecoff->sym_filepos = internal_f->f_symptr;
+    case MIPS_MAGIC_LITTLE:
+    case MIPS_MAGIC_LITTLE2:
+    case MIPS_MAGIC_LITTLE3:
+      return abfd->xvec->byteorder_big_p == false;
 
-  if (internal_a != (struct internal_aouthdr *) NULL)
-    {
-      int i;
-
-      ecoff->text_start = internal_a->text_start;
-      ecoff->text_end = internal_a->text_start + internal_a->tsize;
-      ecoff->gp = internal_a->gp_value;
-      ecoff->gprmask = internal_a->gprmask;
-      for (i = 0; i < 4; i++)
-       ecoff->cprmask[i] = internal_a->cprmask[i];
-      if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
-       abfd->flags |= D_PAGED;
+    default:
+      return false;
     }
-
-  return (PTR) ecoff;
 }
 \f
 /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
@@ -325,6 +310,9 @@ mips_ecoff_swap_reloc_out (abfd, intern, dst)
 {
   RELOC *ext = (RELOC *) dst;
 
+  BFD_ASSERT (intern->r_extern
+             || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
+
   bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
   if (abfd->xvec->header_byteorder_big_p != false)
     {
@@ -351,9 +339,9 @@ mips_ecoff_swap_reloc_out (abfd, intern, dst)
    this backend routine.  It must fill in the howto field.  */
 
 static void
-mips_finish_reloc (abfd, intern, rptr)
+mips_adjust_reloc_in (abfd, intern, rptr)
      bfd *abfd;
-     struct internal_reloc *intern;
+     const struct internal_reloc *intern;
      arelent *rptr;
 {
   if (intern->r_type > MIPS_R_LITERAL)
@@ -372,6 +360,17 @@ mips_finish_reloc (abfd, intern, rptr)
   rptr->howto = &mips_howto_table[intern->r_type];
 }
 
+/* Make any adjustments needed to a reloc before writing it out.  None
+   are needed for MIPS.  */
+
+static void
+mips_adjust_reloc_in (abfd, rel, intern)
+     bfd *abfd;
+     const arelent *rel;
+     struct internal_reloc *intern;
+{
+}
+
 /* ECOFF relocs are either against external symbols, or against
    sections.  If we are producing relocateable output, and the reloc
    is against an external symbol, and nothing has given us any
@@ -863,16 +862,12 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
     mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
-    ecoff_set_arch_mach_hook, mips_ecoff_mkobject_hook,
+    ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
     ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
     ecoff_slurp_symbol_table, NULL, NULL
   },
   /* Supported architecture.  */
   bfd_arch_mips,
-  /* Big endian magic number.  */
-  MIPS_MAGIC_BIG,
-  /* Little endian magic number.  */
-  MIPS_MAGIC_LITTLE,
   /* Symbol table magic number.  */
   magicSym,
   /* Initial portion of armap string.  */
@@ -882,6 +877,10 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
   /* The page boundary used to align sections in a demand-paged
      executable file.  E.g., 0x1000.  */
   0x1000,
+  /* True if the .rdata section is part of the text segment, as on the
+     Alpha.  False if .rdata is part of the data segment, as on the
+     MIPS.  */
+  false,
   /* Bitsize of constructor entries.  */
   32,
   /* Reloc to use for constructor entries.  */
@@ -919,12 +918,17 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
   mips_ecoff_swap_reloc_in,
   mips_ecoff_swap_reloc_out,
   /* Backend reloc tweaking.  */
-  mips_finish_reloc
+  mips_adjust_reloc_in,
+  mips_adjust_reloc_out
 };
 
 /* Looking up a reloc type is MIPS specific.  */
 #define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
 
+/* Getting relocated section contents is generic.  */
+#define ecoff_bfd_get_relocated_section_contents \
+  bfd_generic_get_relocated_section_contents
+
 bfd_target ecoff_little_vec =
 {
   "ecoff-littlemips",          /* name */