Check unit->addr_size to read in the proper number of prologue bytes.
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 90426c437c9618817c9391082d3606c573ecb19c..f47073448a5b73a0d6928e118c07f0a9385a5f22 100644 (file)
@@ -115,6 +115,9 @@ struct mips_elf_link_hash_entry
   /* This is like the call_stub field, but it is used if the function
      being called returns a floating point value.  */
   asection *call_fp_stub;
+
+  /* Are we forced local?  .*/
+  boolean forced_local;
 };
 
 /* MIPS ELF linker hash table.  */
@@ -132,7 +135,7 @@ struct mips_elf_link_hash_table
   /* The size of the .compact_rel section (if SGI_COMPAT).  */
   bfd_size_type compact_rel_size;
   /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
-     entry is set to the address of __rld_obj_head as in Irix 5.  */
+     entry is set to the address of __rld_obj_head as in IRIX5.  */
   boolean use_rld_obj_head;
   /* This is the value of the __rld_map or __rld_obj_head symbol.  */
   bfd_vma rld_value;
@@ -151,7 +154,7 @@ struct extsym_info
   boolean failed;
 };
 
-/* The names of the runtime procedure table symbols used on Irix 5.  */
+/* The names of the runtime procedure table symbols used on IRIX5.  */
 
 static const char * const mips_elf_dynsym_rtproc_names[] =
 {
@@ -162,7 +165,7 @@ static const char * const mips_elf_dynsym_rtproc_names[] =
 };
 
 /* These structures are used to generate the .compact_rel section on
-   Irix 5.  */
+   IRIX5.  */
 
 typedef struct
 {
@@ -372,7 +375,7 @@ static bfd *reldyn_sorting_bfd;
 
 /* Nonzero if ABFD is using the 64-bit ABI. */
 #define ABI_64_P(abfd) \
-  ((elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) != 0)
+  ((get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) != 0)
 
 #define IRIX_COMPAT(abfd) \
   (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd))
@@ -581,6 +584,7 @@ mips_elf_link_hash_newfunc (entry, table, string)
       ret->need_fn_stub = false;
       ret->call_stub = NULL;
       ret->call_fp_stub = NULL;
+      ret->forced_local = false;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -606,9 +610,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;
@@ -1685,9 +1688,18 @@ mips_elf_record_global_got_symbol (h, info, g)
 {
   /* A global symbol in the GOT must also be in the dynamic symbol
      table.  */
-  if (h->dynindx == -1
-      && !bfd_elf32_link_record_dynamic_symbol (info, h))
-    return false;
+  if (h->dynindx == -1)
+    {
+      switch (ELF_ST_VISIBILITY (h->other))
+       {
+       case STV_INTERNAL:
+       case STV_HIDDEN:
+         _bfd_mips_elf_hide_symbol (info, h, true);
+         break;
+       }
+      if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+       return false;
+    }
 
   /* If we've already marked this entry as needing GOT space, we don't
      need to do it again.  */
@@ -2069,8 +2081,16 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       sec = local_sections[r_symndx];
 
       symbol = sec->output_section->vma + sec->output_offset;
-      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
+         || (sec->flags & SEC_MERGE))
        symbol += sym->st_value;
+      if ((sec->flags & SEC_MERGE)
+         && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+       {
+         addend = _bfd_elf_rel_local_sym (abfd, sym, &sec, addend);
+         addend -= symbol;
+         addend += sec->output_section->vma + sec->output_offset;
+       }
 
       /* MIPS16 text labels should be treated as odd.  */
       if (sym->st_other == STO_MIPS16)
@@ -2398,7 +2418,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
        {
          value = addend + gp - p + 4;
          /* The MIPS ABI requires checking the R_MIPS_LO16 relocation
-            for overflow.  But, on, say, Irix 5, relocations against
+            for overflow.  But, on, say, IRIX5, relocations against
             _gp_disp are normally generated from the .cpload
             pseudo-op.  It generates code that normally looks like
             this:
@@ -3338,7 +3358,7 @@ boolean
 _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
      bfd *abfd;
      Elf_Internal_Shdr *hdr;
-     char *name;
+     const char *name;
 {
   flagword flags = 0;
 
@@ -3529,7 +3549,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
   else if (strcmp (name, ".mdebug") == 0)
     {
       hdr->sh_type = SHT_MIPS_DEBUG;
-      /* In a shared object on Irix 5.3, the .mdebug section has an
+      /* In a shared object on IRIX 5.3, the .mdebug section has an
          entsize of 0.  FIXME: Does this matter?  */
       if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
        hdr->sh_entsize = 0;
@@ -3539,7 +3559,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
   else if (strcmp (name, ".reginfo") == 0)
     {
       hdr->sh_type = SHT_MIPS_REGINFO;
-      /* In a shared object on Irix 5.3, the .reginfo section has an
+      /* In a shared object on IRIX 5.3, the .reginfo section has an
          entsize of 0x18.  FIXME: Does this matter?  */
       if (SGI_COMPAT (abfd))
        {
@@ -3559,7 +3579,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
       if (SGI_COMPAT (abfd))
        hdr->sh_entsize = 0;
 #if 0
-      /* This isn't how the Irix 6 linker behaves.  */
+      /* This isn't how the IRIX6 linker behaves.  */
       hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
 #endif
     }
@@ -3680,7 +3700,7 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
       && (abfd->flags & DYNAMIC) != 0
       && strcmp (*namep, "_rld_new_interface") == 0)
     {
-      /* Skip Irix 5 rld entry name.  */
+      /* Skip IRIX5 rld entry name.  */
       *namep = NULL;
       return true;
     }
@@ -4777,7 +4797,7 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
        }
       else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
        {
-         /* Irix rld assumes that the function stub isn't at the end
+         /* IRIX rld assumes that the function stub isn't at the end
             of .text section. So put a dummy. XXX  */
          s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
        }
@@ -4992,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.  */
@@ -5028,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
@@ -5060,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;
@@ -5123,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;
@@ -5137,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.
@@ -5166,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
@@ -5229,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,
@@ -5772,7 +5785,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
 
   /* The first entry of the global offset table will be filled at
      runtime. The second entry will be used by some runtime loaders.
-     This isn't the case of Irix rld.  */
+     This isn't the case of IRIX rld.  */
   if (sgot != NULL && sgot->_raw_size > 0)
     {
       MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents);
@@ -6017,7 +6030,7 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
     }
 }
 \f
-/* When creating an Irix 5 executable, we need REGINFO and RTPROC
+/* When creating an IRIX5 executable, we need REGINFO and RTPROC
    segments.  */
 
 int
@@ -6047,7 +6060,7 @@ _bfd_mips_elf_additional_program_headers (abfd)
   return ret;
 }
 
-/* Modify the segment map for an Irix 5 executable.  */
+/* Modify the segment map for an IRIX5 executable.  */
 
 boolean
 _bfd_mips_elf_modify_segment_map (abfd)
@@ -6170,7 +6183,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
                }
            }
        }
-      /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic,
+      /* On IRIX5, the PT_DYNAMIC segment includes the .dynamic,
         .dynstr, .dynsym, and .hash sections, and everything in
         between.  */
       for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL;
@@ -6384,7 +6397,12 @@ _bfd_mips_elf_hide_symbol (info, entry, force_local)
   asection *got;
   struct mips_got_info *g;
   struct mips_elf_link_hash_entry *h;
+
   h = (struct mips_elf_link_hash_entry *) entry;
+  if (h->forced_local)
+    return;
+  h->forced_local = true;
+
   dynobj = elf_hash_table (info)->dynobj;
   got = bfd_get_section_by_name (dynobj, ".got");
   g = (struct mips_got_info *) elf_section_data (got)->tdata;
@@ -6396,6 +6414,15 @@ _bfd_mips_elf_hide_symbol (info, entry, force_local)
   got->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
 }
 \f
+boolean
+_bfd_mips_elf_ignore_discarded_relocs (sec)
+     asection *sec;
+{
+  if (strcmp (sec->name, ".pdr") == 0)
+    return true;
+  return false;
+}
+\f
 /* MIPS ELF uses a special find_nearest_line routine in order the
    handle the ECOFF debugging information.  */
 
@@ -7519,7 +7546,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
@@ -7761,6 +7788,12 @@ _bfd_mips_elf_print_private_bfd_data (abfd, ptr)
   else
     fprintf (file, _(" [unknown ISA]"));
 
+  if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MDMX)
+    fprintf (file, _(" [mdmx]"));
+
+  if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_M16)
+    fprintf (file, _(" [mips16]"));
+
   if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
     fprintf (file, _(" [32bitmode]"));
   else
This page took 0.029311 seconds and 4 git commands to generate.