* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index fa32640c565e58c9258630a62ac80d2f6fa7f739..8ae193041599fbb1a3e2f9c4081fb875ee307643 100644 (file)
@@ -373,26 +373,28 @@ static bfd *reldyn_sorting_bfd;
 #define ABI_N32_P(abfd) \
   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
 
-/* Nonzero if ABFD is using the 64-bit ABI. */
+/* Nonzero if ABFD is using the N64 ABI.  */
 #define ABI_64_P(abfd) \
   ((get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) != 0)
 
+/* Nonzero if ABFD is using NewABI conventions.  */
+#define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd))
+
+/* The IRIX compatibility level we are striving for.  */
 #define IRIX_COMPAT(abfd) \
   (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd))
 
-#define NEWABI_P(abfd) (ABI_N32_P(abfd) || ABI_64_P(abfd))
-
 /* Whether we are trying to be compatible with IRIX at all.  */
 #define SGI_COMPAT(abfd) \
   (IRIX_COMPAT (abfd) != ict_none)
 
 /* The name of the options section.  */
 #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
-  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.options" : ".options")
+  (ABI_64_P (abfd) ? ".MIPS.options" : ".options")
 
 /* The name of the stub section.  */
 #define MIPS_ELF_STUB_SECTION_NAME(abfd) \
-  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.stubs" : ".stub")
+  (ABI_64_P (abfd) ? ".MIPS.stubs" : ".stub")
 
 /* The size of an external REL relocation.  */
 #define MIPS_ELF_REL_SIZE(abfd) \
@@ -610,9 +612,8 @@ _bfd_mips_elf_read_ecoff_info (abfd, section, debug)
   if (ext_hdr == NULL && swap->external_hdr_size != 0)
     goto error_return;
 
-  if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
-                               swap->external_hdr_size)
-      == false)
+  if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+                                 swap->external_hdr_size))
     goto error_return;
 
   symhdr = &debug->symbolic_header;
@@ -1243,7 +1244,7 @@ mips_elf_output_extsym (h, data)
              h->esym.asym.value =
                mips_elf_hash_table (einfo->info)->procedure_count;
            }
-         else if (strcmp (name, "_gp_disp") == 0)
+         else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (einfo->abfd))
            {
              h->esym.asym.sc = scAbs;
              h->esym.asym.st = stLabel;
@@ -2474,8 +2475,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
            return bfd_reloc_outofrange;
          value
            = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
-                                             abfd,
-                                             value);
+                                             abfd, value);
          overflowed_p = mips_elf_overflow_p (value, 16);
          break;
        }
@@ -2517,8 +2517,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       if (value == MINUS_ONE)
        return bfd_reloc_outofrange;
       value = mips_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
-                                             abfd,
-                                             value);
+                                             abfd, value);
       overflowed_p = mips_elf_overflow_p (value, 16);
       break;
 
@@ -2831,8 +2830,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
 
   r_type = ELF_R_TYPE (output_bfd, rel->r_info);
   dynobj = elf_hash_table (info)->dynobj;
-  sreloc
-    = bfd_get_section_by_name (dynobj, ".rel.dyn");
+  sreloc = bfd_get_section_by_name (dynobj, ".rel.dyn");
   BFD_ASSERT (sreloc != NULL);
   BFD_ASSERT (sreloc->contents != NULL);
   BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
@@ -3642,7 +3640,8 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
      sh_offset == object size, and ld doesn't allow that.  While the check
      is arguably bogus for empty or SHT_NOBITS sections, it can easily be
      avoided by not emitting those useless sections in the first place.  */
-  if (IRIX_COMPAT (abfd) != ict_irix5 && (sec->flags & SEC_RELOC) != 0)
+  if ((IRIX_COMPAT (abfd) != ict_irix5 && (IRIX_COMPAT (abfd) != ict_irix6))
+      && (sec->flags & SEC_RELOC) != 0)
     {
       struct bfd_elf_section_data *esd;
       bfd_size_type amt = sizeof (Elf_Internal_Shdr);
@@ -4123,7 +4122,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                    && ELF_R_TYPE (abfd, r->r_info) != R_MIPS16_26)
                  break;
 
-             if (! info->keep_memory)
+             if (elf_section_data (o)->relocs != sec_relocs)
                free (sec_relocs);
 
              if (r < rend)
@@ -4770,7 +4769,7 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
          /* Assume there are two loadable segments consisting of
             contiguous sections.  Is 5 enough?  */
          local_gotno = (loadable_size >> 16) + 5;
-         if (IRIX_COMPAT (output_bfd) == ict_irix6)
+         if (NEWABI_P (output_bfd))
            /* It's possible we will need GOT_PAGE entries as well as
               GOT16 entries.  Often, these will be able to share GOT
               entries, but not always.  */
@@ -5005,7 +5004,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       const char * msg = (const char *) NULL;
 
       /* Find the relocation howto for this relocation.  */
-      if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
+      if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
        {
          /* Some 32-bit code uses R_MIPS_64.  In particular, people use
             64-bit code, but make sure all their addresses are in the
@@ -5013,8 +5012,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
             space.  Thus, when they use an R_MIPS_64 they mean what is
             usually meant by R_MIPS_32, with the exception that the
             stored value is sign-extended to 64 bits.  */
-         howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32,
-                                          NEWABI_P (input_bfd));
+         howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32, false);
 
          /* On big-endian systems, we need to lie about the position
             of the reloc.  */
@@ -5049,6 +5047,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              addend = mips_elf_obtain_contents (howto, rel, input_bfd,
                                                 contents);
              addend &= howto->src_mask;
+             addend <<= howto->rightshift;
 
              /* For some kinds of relocations, the ADDEND is a
                 combination of the addend stored in two different
@@ -5081,11 +5080,11 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                    return false;
 
                  /* Obtain the addend kept there.  */
-                 lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, lo,
-                                                       rela_relocation_p);
+                 lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, lo, false);
                  l = mips_elf_obtain_contents (lo16_howto, lo16_relocation,
                                                input_bfd, contents);
                  l &= lo16_howto->src_mask;
+                 l <<= lo16_howto->rightshift;
                  l = mips_elf_sign_extend (l, 16);
 
                  addend <<= 16;
@@ -5122,7 +5121,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          Elf_Internal_Sym *sym;
          unsigned long r_symndx;
 
-         if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd)
+         if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)
              && bfd_big_endian (input_bfd))
            rel->r_offset -= 4;
 
@@ -5144,13 +5143,6 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              || r_type == R_MIPS_LITERAL)
            addend -= (_bfd_get_gp_value (output_bfd)
                       - _bfd_get_gp_value (input_bfd));
-         else if (r_type == R_MIPS_26 || r_type == R_MIPS16_26
-                  || r_type == R_MIPS_GNU_REL16_S2)
-           /* The addend is stored without its two least
-              significant bits (which are always zero.)  In a
-              non-relocateable link, calculate_relocation will do
-              this shift; here, we must do it ourselves.  */
-           addend <<= 2;
 
          r_symndx = ELF_R_SYM (output_bfd, rel->r_info);
          sym = local_syms + r_symndx;
@@ -5158,23 +5150,20 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            /* Adjust the addend appropriately.  */
            addend += local_sections[r_symndx]->output_offset;
 
-         /* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16,
-            then we only want to write out the high-order 16 bits.
-            The subsequent R_MIPS_LO16 will handle the low-order bits.  */
-         if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16
-             || r_type == R_MIPS_GNU_REL_HI16)
-           addend = mips_elf_high (addend);
-         else if (r_type == R_MIPS_HIGHER)
-           addend = mips_elf_higher (addend);
-         else if (r_type == R_MIPS_HIGHEST)
-           addend = mips_elf_highest (addend);
-
-         /* If the relocation is for an R_MIPS_26 relocation, then
-            the two low-order bits are not stored in the object file;
-            they are implicitly zero.  */
-         else if (r_type == R_MIPS_26 || r_type == R_MIPS16_26
-                  || r_type == R_MIPS_GNU_REL16_S2)
-           addend >>= 2;
+         if (howto->partial_inplace)
+           {
+             /* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16,
+                then we only want to write out the high-order 16 bits.
+                The subsequent R_MIPS_LO16 will handle the low-order bits.
+              */
+             if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16
+                 || r_type == R_MIPS_GNU_REL_HI16)
+               addend = mips_elf_high (addend);
+             else if (r_type == R_MIPS_HIGHER)
+               addend = mips_elf_higher (addend);
+             else if (r_type == R_MIPS_HIGHEST)
+               addend = mips_elf_highest (addend);
+           }
 
          if (rela_relocation_p)
            /* If this is a RELA relocation, just update the addend.
@@ -5187,9 +5176,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                 destination mask because the place to which we are
                 writing will be source of the addend in the final
                 link.  */
+             addend >>= howto->rightshift;
              addend &= howto->src_mask;
 
-             if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
+             if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
                /* See the comment above about using R_MIPS_64 in the 32-bit
                   ABI.  Here, we need to update the addend.  It would be
                   possible to get away with just using the R_MIPS_32 reloc
@@ -5250,6 +5240,8 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       else
        use_saved_addend_p = false;
 
+      addend >>= howto->rightshift;
+
       /* Figure out what value we are supposed to relocate.  */
       switch (mips_elf_calculate_relocation (output_bfd, input_bfd,
                                             input_section, info, rel,
@@ -5305,7 +5297,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          continue;
        }
 
-      if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
+      if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
        /* See the comment above about using R_MIPS_64 in the 32-bit
           ABI.  Until now, we've been using the HOWTO for R_MIPS_32;
           that calculated the right value.  Now, however, we
@@ -5533,7 +5525,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
       sym->st_value = 1;
     }
-  else if (strcmp (name, "_gp_disp") == 0)
+  else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (output_bfd))
     {
       sym->st_shndx = SHN_ABS;
       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
@@ -6113,7 +6105,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
      .dynamic end up in PT_DYNAMIC.  However, we do have to insert a
      PT_OPTIONS segement immediately following the program header
      table.  */
-  if (IRIX_COMPAT (abfd) == ict_irix6)
+  if (ABI_64_P (abfd))
     {
       for (s = abfd->sections; s; s = s->next)
        if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
@@ -6282,8 +6274,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
    relocation.  */
 
 asection *
-_bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
-     bfd *abfd;
+_bfd_mips_elf_gc_mark_hook (sec, info, rel, h, sym)
+     asection *sec;
      struct bfd_link_info *info ATTRIBUTE_UNUSED;
      Elf_Internal_Rela *rel;
      struct elf_link_hash_entry *h;
@@ -6293,7 +6285,7 @@ _bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
 
   if (h != NULL)
     {
-      switch (ELF_R_TYPE (abfd, rel->r_info))
+      switch (ELF_R_TYPE (sec->owner, rel->r_info))
        {
        case R_MIPS_GNU_VTINHERIT:
        case R_MIPS_GNU_VTENTRY:
@@ -6315,9 +6307,7 @@ _bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
        }
     }
   else
-    {
-      return bfd_section_from_elf_index (abfd, sym->st_shndx);
-    }
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
   return NULL;
 }
@@ -6353,6 +6343,9 @@ _bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
       case R_MIPS_CALL_LO16:
       case R_MIPS_GOT_HI16:
       case R_MIPS_GOT_LO16:
+      case R_MIPS_GOT_DISP:
+      case R_MIPS_GOT_PAGE:
+      case R_MIPS_GOT_OFST:
        /* ??? It would seem that the existing MIPS code does no sort
           of reference counting or whatnot on its GOT and PLT entries,
           so it is not possible to garbage collect them at this time.  */
@@ -7554,7 +7547,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
   asection *sec;
 
   /* Check if we have the same endianess */
-  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
     return false;
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
This page took 0.134533 seconds and 4 git commands to generate.