2000-07-09 Koundinya K <kk@ddeorg.soft.net>
[deliverable/binutils-gdb.git] / bfd / elf32-mips.c
index 52471c87f1e95fb0e221c580628f58f1ab3be6fd..a0512acc1589a4116a543f6ee5d7e77cf4bdf6f2 100644 (file)
@@ -195,6 +195,8 @@ static void mips_elf_allocate_dynamic_relocations
   PARAMS ((bfd *, unsigned int));
 static boolean mips_elf_stub_section_p 
   PARAMS ((bfd *, asection *));
+static int sort_dynamic_relocs
+  PARAMS ((const void *, const void *));
 
 /* The level of IRIX compatibility we're striving for.  */
 
@@ -204,6 +206,9 @@ typedef enum {
   ict_irix6
 } irix_compat_t;
 
+/* This will be used when we sort the dynamic relocation records.  */
+static bfd *reldyn_sorting_bfd;
+
 /* Nonzero if ABFD is using the N32 ABI.  */
 
 #define ABI_N32_P(abfd) \
@@ -944,7 +949,6 @@ static reloc_howto_type elf_mips16_gprel_howto =
         0x07ff001f,            /* dst_mask */
         false);                /* pcrel_offset */
 
-
 /* GNU extensions for embedded-pic.  */
 /* High 16 bits of symbol value, pc-relative.  */
 static reloc_howto_type elf_mips_gnu_rel_hi16 =
@@ -5142,6 +5146,26 @@ _bfd_mips_elf_final_link (abfd, info)
   return true;
 }
 
+/* This function is called via qsort() to sort the dynamic relocation
+   entries by increasing r_symndx value.  */
+
+static int
+sort_dynamic_relocs (arg1,arg2)
+        const PTR arg1;
+        const PTR arg2;
+{
+  const Elf32_External_Rel *ext_reloc1 = (const Elf32_External_Rel *) arg1;
+  const Elf32_External_Rel *ext_reloc2 = (const Elf32_External_Rel *) arg2;
+
+  Elf_Internal_Rel int_reloc1;
+  Elf_Internal_Rel int_reloc2;
+
+  bfd_elf32_swap_reloc_in(reldyn_sorting_bfd, ext_reloc1, &int_reloc1);
+  bfd_elf32_swap_reloc_in(reldyn_sorting_bfd, ext_reloc2, &int_reloc2);
+
+  return (ELF32_R_SYM(int_reloc1.r_info) - ELF32_R_SYM(int_reloc2.r_info));
+}
+
 /* Returns the GOT section for ABFD.  */
 
 static asection *
@@ -7830,6 +7854,27 @@ _bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
   return true;
 }
 
+/* Copy data from a MIPS ELF indirect symbol to its direct symbol,
+   hiding the old indirect symbol.  Process additional relocation
+   information.  */
+
+void
+_bfd_mips_elf_copy_indirect_symbol (dir, ind)
+     struct elf_link_hash_entry *dir, *ind;
+{
+  struct mips_elf_link_hash_entry *dirmips, *indmips;
+
+  _bfd_elf_link_hash_copy_indirect (dir, ind);
+
+  dirmips = (struct mips_elf_link_hash_entry *) dir;
+  indmips = (struct mips_elf_link_hash_entry *) ind;
+  dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs;
+  if (dirmips->min_dyn_reloc_index == 0
+      || (indmips->min_dyn_reloc_index != 0
+          && indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
+    dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -8817,6 +8862,23 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
          }
       }
 
+    /* We need to sort the entries of the dynamic relocation section.  */
+
+    if (!ABI_64_P (output_bfd))
+      {
+            asection *reldyn;
+
+            reldyn = bfd_get_section_by_name (dynobj,
+                                     MIPS_ELF_REL_DYN_SECTION_NAME (dynobj));
+            if (reldyn != NULL && reldyn->reloc_count > 2)
+              {
+                reldyn_sorting_bfd = output_bfd;
+                qsort ((Elf32_External_Rel *) reldyn->contents + 1,
+                       (size_t) reldyn->reloc_count - 1,
+                       sizeof (Elf32_External_Rel), sort_dynamic_relocs);
+              }
+      }
+
     /* Clean up a first relocation in .rel.dyn.  */
     s = bfd_get_section_by_name (dynobj, 
                                 MIPS_ELF_REL_DYN_SECTION_NAME (dynobj));
@@ -9110,6 +9172,9 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap =
 #define elf_backend_got_header_size    (4*MIPS_RESERVED_GOTNO)
 #define elf_backend_plt_header_size    0
 
+#define elf_backend_copy_indirect_symbol \
+                                       _bfd_mips_elf_copy_indirect_symbol
+
 #define elf_backend_hide_symbol                _bfd_mips_elf_hide_symbol
 
 #define bfd_elf32_bfd_is_local_label_name \
@@ -9127,3 +9192,20 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap =
 #define bfd_elf32_bfd_print_private_bfd_data \
                                        _bfd_mips_elf_print_private_bfd_data
 #include "elf32-target.h"
+
+/* Support for traditional mips targets */
+
+#define INCLUDED_TARGET_FILE            /* More a type of flag */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
+#define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
+#define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
+#define TARGET_BIG_NAME                 "elf32-tradbigmips"
+
+/* Include the target file again for this target */
+#include "elf32-target.h"
This page took 0.026586 seconds and 4 git commands to generate.