daily update
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 466a471675b209735decc680edbfc73698759204..cdc81a229d5bf770c1d998a5d4c207e120dd193d 100644 (file)
@@ -3583,9 +3583,12 @@ mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
                          const Elf_Internal_Rela *relocation,
                          const Elf_Internal_Rela *relend)
 {
+  unsigned long r_symndx = ELF_R_SYM (abfd, relocation->r_info);
+
   while (relocation < relend)
     {
-      if (ELF_R_TYPE (abfd, relocation->r_info) == r_type)
+      if (ELF_R_TYPE (abfd, relocation->r_info) == r_type
+         && ELF_R_SYM (abfd, relocation->r_info) == r_symndx)
        return relocation;
 
       ++relocation;
@@ -4471,7 +4474,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     case R_MIPS_GNU_REL16_S2:
       value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
       overflowed_p = mips_elf_overflow_p (value, 18);
-      value = (value >> 2) & howto->dst_mask;
+      value >>= howto->rightshift;
+      value &= howto->dst_mask;
       break;
 
     case R_MIPS_GOT_HI16:
@@ -5091,6 +5095,7 @@ _bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
       /* Common symbols less than the GP size are automatically
         treated as SHN_MIPS_SCOMMON symbols on IRIX5.  */
       if (asym->value > elf_gp_size (abfd)
+         || ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_TLS
          || IRIX_COMPAT (abfd) == ict_irix6)
        break;
       /* Fall through.  */
@@ -5731,6 +5736,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
       /* Common symbols less than the GP size are automatically
         treated as SHN_MIPS_SCOMMON symbols.  */
       if (sym->st_size > elf_gp_size (abfd)
+         || ELF_ST_TYPE (sym->st_info) == STT_TLS
          || IRIX_COMPAT (abfd) == ict_irix6)
        break;
       /* Fall through.  */
@@ -8785,11 +8791,10 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
          MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0x80000000,
                             sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
        }
-    }
 
-  if (sgot != NULL)
-    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
-      = MIPS_ELF_GOT_SIZE (output_bfd);
+      elf_section_data (sgot->output_section)->this_hdr.sh_entsize
+        = MIPS_ELF_GOT_SIZE (output_bfd);
+    }
 
   /* Generate dynamic relocations for the non-primary gots.  */
   if (gg != NULL && gg->next)
@@ -9138,7 +9143,8 @@ _bfd_mips_elf_final_write_processing (bfd *abfd,
    segments.  */
 
 int
-_bfd_mips_elf_additional_program_headers (bfd *abfd)
+_bfd_mips_elf_additional_program_headers (bfd *abfd,
+                                         struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   asection *s;
   int ret = 0;
@@ -9229,15 +9235,18 @@ _bfd_mips_elf_modify_segment_map (bfd *abfd,
                     || (*pm)->p_type == PT_INTERP))
            pm = &(*pm)->next;
 
-         amt = sizeof (struct elf_segment_map);
-         options_segment = bfd_zalloc (abfd, amt);
-         options_segment->next = *pm;
-         options_segment->p_type = PT_MIPS_OPTIONS;
-         options_segment->p_flags = PF_R;
-         options_segment->p_flags_valid = TRUE;
-         options_segment->count = 1;
-         options_segment->sections[0] = s;
-         *pm = options_segment;
+         if (*pm == NULL || (*pm)->p_type != PT_MIPS_OPTIONS)
+           {
+             amt = sizeof (struct elf_segment_map);
+             options_segment = bfd_zalloc (abfd, amt);
+             options_segment->next = *pm;
+             options_segment->p_type = PT_MIPS_OPTIONS;
+             options_segment->p_flags = PF_R;
+             options_segment->p_flags_valid = TRUE;
+             options_segment->count = 1;
+             options_segment->sections[0] = s;
+             *pm = options_segment;
+           }
        }
     }
   else
@@ -10846,7 +10855,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
        = elf_elfheader (ibfd)->e_ident[EI_CLASS];
 
       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
-         && bfd_get_arch_info (obfd)->the_default)
+         && (bfd_get_arch_info (obfd)->the_default
+             || mips_mach_extends_p (bfd_get_mach (obfd), 
+                                     bfd_get_mach (ibfd))))
        {
          if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
                                   bfd_get_mach (ibfd)))
@@ -11104,15 +11115,25 @@ const struct bfd_elf_special_section _bfd_mips_elf_special_sections[] =
   { NULL,      0,  0, 0,              0 }
 };
 
-/* Ensure that the STO_OPTIONAL flag is copied into h->other,
-   even if this is not a defintion of the symbol.  */
+/* Merge non visibility st_other attributes.  Ensure that the
+   STO_OPTIONAL flag is copied into h->other, even if this is not a
+   definiton of the symbol.  */
 void
 _bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
                                      const Elf_Internal_Sym *isym,
                                      bfd_boolean definition,
                                      bfd_boolean dynamic ATTRIBUTE_UNUSED)
 {
-  if (! definition
+  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
+    {
+      unsigned char other;
+
+      other = (definition ? isym->st_other : h->other);
+      other &= ~ELF_ST_VISIBILITY (-1);
+      h->other = other | ELF_ST_VISIBILITY (h->other);
+    }
+
+  if (!definition
       && ELF_MIPS_IS_OPTIONAL (isym->st_other))
     h->other |= STO_OPTIONAL;
 }
@@ -11124,3 +11145,11 @@ _bfd_mips_elf_ignore_undef_symbol (struct elf_link_hash_entry *h)
 {
   return ELF_MIPS_IS_OPTIONAL (h->other) ? TRUE : FALSE;
 }
+
+bfd_boolean
+_bfd_mips_elf_common_definition (Elf_Internal_Sym *sym)
+{
+  return (sym->st_shndx == SHN_COMMON
+         || sym->st_shndx == SHN_MIPS_ACOMMON
+         || sym->st_shndx == SHN_MIPS_SCOMMON);
+}
This page took 0.029297 seconds and 4 git commands to generate.