nameless LOAD_DLL_DEBUG_EVENT causes ntdll.dll to be missing
[binutils-gdb.git] / bfd / elfxx-mips.c
index 63fb508b873ca05ad0e8c488b3712c1c3c33668a..1c64ad35d83366daf895b45613e594ed7dd18652 100644 (file)
@@ -542,6 +542,9 @@ struct mips_elf_obj_tdata
   /* Input BFD providing Tag_GNU_MIPS_ABI_FP attribute for output.  */
   bfd *abi_fp_bfd;
 
+  /* Input BFD providing Tag_GNU_MIPS_ABI_MSA attribute for output.  */
+  bfd *abi_msa_bfd;
+
   /* The GOT requirements of input bfds.  */
   struct mips_got_info *got;
 
@@ -4299,6 +4302,36 @@ mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Return true if a GOT entry for H should live in the local rather than
+   global GOT area.  */
+
+static bfd_boolean
+mips_use_local_got_p (struct bfd_link_info *info,
+                     struct mips_elf_link_hash_entry *h)
+{
+  /* Symbols that aren't in the dynamic symbol table must live in the
+     local GOT.  This includes symbols that are completely undefined
+     and which therefore don't bind locally.  We'll report undefined
+     symbols later if appropriate.  */
+  if (h->root.dynindx == -1)
+    return TRUE;
+
+  /* Symbols that bind locally can (and in the case of forced-local
+     symbols, must) live in the local GOT.  */
+  if (h->got_only_for_calls
+      ? SYMBOL_CALLS_LOCAL (info, &h->root)
+      : SYMBOL_REFERENCES_LOCAL (info, &h->root))
+    return TRUE;
+
+  /* If this is an executable that must provide a definition of the symbol,
+     either though PLTs or copy relocations, then that address should go in
+     the local rather than global GOT.  */
+  if (info->executable && h->has_static_relocs)
+    return TRUE;
+
+  return FALSE;
+}
+
 /* A mips_elf_link_hash_traverse callback for which DATA points to the
    link_info structure.  Decide whether the hash entry needs an entry in
    the global part of the primary GOT, setting global_got_area accordingly.
@@ -4318,18 +4351,8 @@ mips_elf_count_got_symbols (struct mips_elf_link_hash_entry *h, void *data)
   if (h->global_got_area != GGA_NONE)
     {
       /* Make a final decision about whether the symbol belongs in the
-        local or global GOT.  Symbols that bind locally can (and in the
-        case of forced-local symbols, must) live in the local GOT.
-        Those that are aren't in the dynamic symbol table must also
-        live in the local GOT.
-
-        Note that the former condition does not always imply the
-        latter: symbols do not bind locally if they are completely
-        undefined.  We'll report undefined symbols later if appropriate.  */
-      if (h->root.dynindx == -1
-         || (h->got_only_for_calls
-             ? SYMBOL_CALLS_LOCAL (info, &h->root)
-             : SYMBOL_REFERENCES_LOCAL (info, &h->root)))
+        local or global GOT.  */
+      if (mips_use_local_got_p (info, h))
        /* The symbol belongs in the local GOT.  We no longer need this
           entry if it was only used for relocations; those relocations
           will be against the null or section symbol instead of H.  */
@@ -5017,6 +5040,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
   h->non_elf = 0;
   h->def_regular = 1;
   h->type = STT_OBJECT;
+  h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
   elf_hash_table (info)->hgot = h;
 
   if (info->shared
@@ -5467,10 +5491,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
                                && (target_is_16_bit_code_p
                                    || target_is_micromips_code_p))));
 
-  local_p = (h == NULL
-            || (h->got_only_for_calls
-                ? SYMBOL_CALLS_LOCAL (info, &h->root)
-                : SYMBOL_REFERENCES_LOCAL (info, &h->root)));
+  local_p = (h == NULL || mips_use_local_got_p (info, h));
 
   gp0 = _bfd_get_gp_value (input_bfd);
   gp = _bfd_get_gp_value (abfd);
@@ -7954,6 +7975,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       unsigned int r_type;
       struct elf_link_hash_entry *h;
       bfd_boolean can_make_dynamic_p;
+      bfd_boolean call_reloc_p;
+      bfd_boolean constrain_symbol_p;
 
       r_symndx = ELF_R_SYM (abfd, rel->r_info);
       r_type = ELF_R_TYPE (abfd, rel->r_info);
@@ -7986,12 +8009,30 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       /* Set CAN_MAKE_DYNAMIC_P to true if we can convert this
         relocation into a dynamic one.  */
       can_make_dynamic_p = FALSE;
+
+      /* Set CALL_RELOC_P to true if the relocation is for a call,
+        and if pointer equality therefore doesn't matter.  */
+      call_reloc_p = FALSE;
+
+      /* Set CONSTRAIN_SYMBOL_P if we need to take the relocation
+        into account when deciding how to define the symbol.
+        Relocations in nonallocatable sections such as .pdr and
+        .debug* should have no effect.  */
+      constrain_symbol_p = ((sec->flags & SEC_ALLOC) != 0);
+
       switch (r_type)
        {
-       case R_MIPS_GOT16:
        case R_MIPS_CALL16:
        case R_MIPS_CALL_HI16:
        case R_MIPS_CALL_LO16:
+       case R_MIPS16_CALL16:
+       case R_MICROMIPS_CALL16:
+       case R_MICROMIPS_CALL_HI16:
+       case R_MICROMIPS_CALL_LO16:
+         call_reloc_p = TRUE;
+         /* Fall through.  */
+
+       case R_MIPS_GOT16:
        case R_MIPS_GOT_HI16:
        case R_MIPS_GOT_LO16:
        case R_MIPS_GOT_PAGE:
@@ -8001,14 +8042,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_MIPS_TLS_GD:
        case R_MIPS_TLS_LDM:
        case R_MIPS16_GOT16:
-       case R_MIPS16_CALL16:
        case R_MIPS16_TLS_GOTTPREL:
        case R_MIPS16_TLS_GD:
        case R_MIPS16_TLS_LDM:
        case R_MICROMIPS_GOT16:
-       case R_MICROMIPS_CALL16:
-       case R_MICROMIPS_CALL_HI16:
-       case R_MICROMIPS_CALL_LO16:
        case R_MICROMIPS_GOT_HI16:
        case R_MICROMIPS_GOT_LO16:
        case R_MICROMIPS_GOT_PAGE:
@@ -8029,12 +8066,27 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
+         can_make_dynamic_p = TRUE;
          break;
 
-         /* This is just a hint; it can safely be ignored.  Don't set
-            has_static_relocs for the corresponding symbol.  */
+       case R_MIPS_NONE:
        case R_MIPS_JALR:
        case R_MICROMIPS_JALR:
+         /* These relocations have empty fields and are purely there to
+            provide link information.  The symbol value doesn't matter.  */
+         constrain_symbol_p = FALSE;
+         break;
+
+       case R_MIPS_GPREL16:
+       case R_MIPS_GPREL32:
+       case R_MIPS16_GPREL:
+       case R_MICROMIPS_GPREL16:
+         /* GP-relative relocations always resolve to a definition in a
+            regular input file, ignoring the one-definition rule.  This is
+            important for the GP setup sequence in NewABI code, which
+            always resolves to a local function even if other relocations
+            against the symbol wouldn't.  */
+         constrain_symbol_p = FALSE;
          break;
 
        case R_MIPS_32:
@@ -8061,35 +8113,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              can_make_dynamic_p = TRUE;
              if (dynobj == NULL)
                elf_hash_table (info)->dynobj = dynobj = abfd;
-             break;
            }
-         /* For sections that are not SEC_ALLOC a copy reloc would be
-            output if possible (implying questionable semantics for
-            read-only data objects) or otherwise the final link would
-            fail as ld.so will not process them and could not therefore
-            handle any outstanding dynamic relocations.
-
-            For such sections that are also SEC_DEBUGGING, we can avoid
-            these problems by simply ignoring any relocs as these
-            sections have a predefined use and we know it is safe to do
-            so.
-
-            This is needed in cases such as a global symbol definition
-            in a shared library causing a common symbol from an object
-            file to be converted to an undefined reference.  If that
-            happens, then all the relocations against this symbol from
-            SEC_DEBUGGING sections in the object file will resolve to
-            nil.  */
-         if ((sec->flags & SEC_DEBUGGING) != 0)
-           break;
-         /* Fall through.  */
-
-       default:
-         /* Most static relocations require pointer equality, except
-            for branches.  */
-         if (h)
-           h->pointer_equality_needed = TRUE;
-         /* Fall through.  */
+         break;
 
        case R_MIPS_26:
        case R_MIPS_PC16:
@@ -8099,13 +8124,28 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_MICROMIPS_PC10_S1:
        case R_MICROMIPS_PC16_S1:
        case R_MICROMIPS_PC23_S2:
-         if (h)
-           ((struct mips_elf_link_hash_entry *) h)->has_static_relocs = TRUE;
+         call_reloc_p = TRUE;
          break;
        }
 
       if (h)
        {
+         if (constrain_symbol_p)
+           {
+             if (!can_make_dynamic_p)
+               ((struct mips_elf_link_hash_entry *) h)->has_static_relocs = 1;
+
+             if (!call_reloc_p)
+               h->pointer_equality_needed = 1;
+
+             /* We must not create a stub for a symbol that has
+                relocations related to taking the function's address.
+                This doesn't apply to VxWorks, where CALL relocs refer
+                to a .got.plt entry instead of a normal .got entry.  */
+             if (!htab->is_vxworks && (!can_make_dynamic_p || !call_reloc_p))
+               ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE;
+           }
+
          /* Relocations against the special VxWorks __GOTT_BASE__ and
             __GOTT_INDEX__ symbols must be left to the loader.  Allocate
             room for them in .rela.dyn.  */
@@ -8386,28 +8426,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            h->plt.plist->need_comp = TRUE;
        }
 
-      /* We must not create a stub for a symbol that has relocations
-        related to taking the function's address.  This doesn't apply to
-        VxWorks, where CALL relocs refer to a .got.plt entry instead of
-        a normal .got entry.  */
-      if (!htab->is_vxworks && h != NULL)
-       switch (r_type)
-         {
-         default:
-           ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE;
-           break;
-         case R_MIPS16_CALL16:
-         case R_MIPS_CALL16:
-         case R_MIPS_CALL_HI16:
-         case R_MIPS_CALL_LO16:
-         case R_MIPS_JALR:
-         case R_MICROMIPS_CALL16:
-         case R_MICROMIPS_CALL_HI16:
-         case R_MICROMIPS_CALL_LO16:
-         case R_MICROMIPS_JALR:
-           break;
-         }
-
       /* See if this reloc would need to refer to a MIPS16 hard-float stub,
         if there is one.  We only need to handle global symbols here;
         we decide whether to keep or delete stubs for local symbols
@@ -14313,12 +14331,18 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
   obj_attribute *in_attr;
   obj_attribute *out_attr;
   bfd *abi_fp_bfd;
+  bfd *abi_msa_bfd;
 
   abi_fp_bfd = mips_elf_tdata (obfd)->abi_fp_bfd;
   in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
-  if (!abi_fp_bfd && in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
+  if (!abi_fp_bfd && in_attr[Tag_GNU_MIPS_ABI_FP].i != Val_GNU_MIPS_ABI_FP_ANY)
     mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
 
+  abi_msa_bfd = mips_elf_tdata (obfd)->abi_msa_bfd;
+  if (!abi_msa_bfd
+      && in_attr[Tag_GNU_MIPS_ABI_MSA].i != Val_GNU_MIPS_ABI_MSA_ANY)
+    mips_elf_tdata (obfd)->abi_msa_bfd = ibfd;
+
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
       /* This is the first object.  Copy the attributes.  */
@@ -14337,27 +14361,27 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
   if (in_attr[Tag_GNU_MIPS_ABI_FP].i != out_attr[Tag_GNU_MIPS_ABI_FP].i)
     {
       out_attr[Tag_GNU_MIPS_ABI_FP].type = 1;
-      if (out_attr[Tag_GNU_MIPS_ABI_FP].i == 0)
+      if (out_attr[Tag_GNU_MIPS_ABI_FP].i == Val_GNU_MIPS_ABI_FP_ANY)
        out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
-      else if (in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
+      else if (in_attr[Tag_GNU_MIPS_ABI_FP].i != Val_GNU_MIPS_ABI_FP_ANY)
        switch (out_attr[Tag_GNU_MIPS_ABI_FP].i)
          {
-         case 1:
+         case Val_GNU_MIPS_ABI_FP_DOUBLE:
            switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
              {
-             case 2:
+             case Val_GNU_MIPS_ABI_FP_SINGLE:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-mdouble-float", "-msingle-float");
                break;
 
-             case 3:
+             case Val_GNU_MIPS_ABI_FP_SOFT:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
                break;
 
-             case 4:
+             case Val_GNU_MIPS_ABI_FP_64:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd,
@@ -14374,22 +14398,22 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              }
            break;
 
-         case 2:
+         case Val_GNU_MIPS_ABI_FP_SINGLE:
            switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
              {
-             case 1:
+             case Val_GNU_MIPS_ABI_FP_DOUBLE:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-msingle-float", "-mdouble-float");
                break;
 
-             case 3:
+             case Val_GNU_MIPS_ABI_FP_SOFT:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
                break;
 
-             case 4:
+             case Val_GNU_MIPS_ABI_FP_64:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd,
@@ -14406,12 +14430,12 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              }
            break;
 
-         case 3:
+         case Val_GNU_MIPS_ABI_FP_SOFT:
            switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
              {
-             case 1:
-             case 2:
-             case 4:
+             case Val_GNU_MIPS_ABI_FP_DOUBLE:
+             case Val_GNU_MIPS_ABI_FP_SINGLE:
+             case Val_GNU_MIPS_ABI_FP_64:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-msoft-float", "-mhard-float");
@@ -14427,24 +14451,24 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              }
            break;
 
-         case 4:
+         case Val_GNU_MIPS_ABI_FP_64:
            switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
              {
-             case 1:
+             case Val_GNU_MIPS_ABI_FP_DOUBLE:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd,
                   "-mips32r2 -mfp64", "-mdouble-float");
                break;
 
-             case 2:
+             case Val_GNU_MIPS_ABI_FP_SINGLE:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd,
                   "-mips32r2 -mfp64", "-msingle-float");
                break;
 
-             case 3:
+             case Val_GNU_MIPS_ABI_FP_SOFT:
                _bfd_error_handler
                  (_("Warning: %B uses %s (set by %B), %B uses %s"),
                   obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
@@ -14463,7 +14487,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
          default:
            switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
              {
-             case 1:
+             case Val_GNU_MIPS_ABI_FP_DOUBLE:
                _bfd_error_handler
                  (_("Warning: %B uses unknown floating point ABI %d "
                     "(set by %B), %B uses %s"),
@@ -14471,7 +14495,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
                   out_attr[Tag_GNU_MIPS_ABI_FP].i, "-mdouble-float");
                break;
 
-             case 2:
+             case Val_GNU_MIPS_ABI_FP_SINGLE:
                _bfd_error_handler
                  (_("Warning: %B uses unknown floating point ABI %d "
                     "(set by %B), %B uses %s"),
@@ -14479,7 +14503,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
                   out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msingle-float");
                break;
 
-             case 3:
+             case Val_GNU_MIPS_ABI_FP_SOFT:
                _bfd_error_handler
                  (_("Warning: %B uses unknown floating point ABI %d "
                     "(set by %B), %B uses %s"),
@@ -14487,7 +14511,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
                   out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msoft-float");
                break;
 
-             case 4:
+             case Val_GNU_MIPS_ABI_FP_64:
                _bfd_error_handler
                  (_("Warning: %B uses unknown floating point ABI %d "
                     "(set by %B), %B uses %s"),
@@ -14508,6 +14532,47 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
          }
     }
 
+  /* Check for conflicting Tag_GNU_MIPS_ABI_MSA attributes and merge
+     non-conflicting ones.  */
+  if (in_attr[Tag_GNU_MIPS_ABI_MSA].i != out_attr[Tag_GNU_MIPS_ABI_MSA].i)
+    {
+      out_attr[Tag_GNU_MIPS_ABI_MSA].type = 1;
+      if (out_attr[Tag_GNU_MIPS_ABI_MSA].i == Val_GNU_MIPS_ABI_MSA_ANY)
+       out_attr[Tag_GNU_MIPS_ABI_MSA].i = in_attr[Tag_GNU_MIPS_ABI_MSA].i;
+      else if (in_attr[Tag_GNU_MIPS_ABI_MSA].i != Val_GNU_MIPS_ABI_MSA_ANY)
+       switch (out_attr[Tag_GNU_MIPS_ABI_MSA].i)
+         {
+         case Val_GNU_MIPS_ABI_MSA_128:
+           _bfd_error_handler
+             (_("Warning: %B uses %s (set by %B), "
+                "%B uses unknown MSA ABI %d"),
+              obfd, abi_msa_bfd, ibfd,
+              "-mmsa", in_attr[Tag_GNU_MIPS_ABI_MSA].i);
+           break;
+
+         default:
+           switch (in_attr[Tag_GNU_MIPS_ABI_MSA].i)
+             {
+             case Val_GNU_MIPS_ABI_MSA_128:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown MSA ABI %d "
+                    "(set by %B), %B uses %s"),
+                    obfd, abi_msa_bfd, ibfd,
+                    out_attr[Tag_GNU_MIPS_ABI_MSA].i, "-mmsa");
+                 break;
+
+             default:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown MSA ABI %d "
+                    "(set by %B), %B uses unknown MSA ABI %d"),
+                  obfd, abi_msa_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_MSA].i,
+                  in_attr[Tag_GNU_MIPS_ABI_MSA].i);
+               break;
+             }
+         }
+    }
+
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
   _bfd_elf_merge_object_attributes (ibfd, obfd);
 
@@ -14730,6 +14795,20 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       old_flags &= ~ EF_MIPS_ARCH_ASE;
     }
 
+  /* Compare NaN encodings.  */
+  if ((new_flags & EF_MIPS_NAN2008) != (old_flags & EF_MIPS_NAN2008))
+    {
+      _bfd_error_handler (_("%B: linking %s module with previous %s modules"),
+                         ibfd,
+                         (new_flags & EF_MIPS_NAN2008
+                          ? "-mnan=2008" : "-mnan=legacy"),
+                         (old_flags & EF_MIPS_NAN2008
+                          ? "-mnan=2008" : "-mnan=legacy"));
+      ok = FALSE;
+      new_flags &= ~EF_MIPS_NAN2008;
+      old_flags &= ~EF_MIPS_NAN2008;
+    }
+
   /* Warn about any other mismatches */
   if (new_flags != old_flags)
     {
@@ -14921,6 +15000,12 @@ _bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
   if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
     fprintf (file, " [micromips]");
 
+  if (elf_elfheader (abfd)->e_flags & EF_MIPS_NAN2008)
+    fprintf (file, " [nan2008]");
+
+  if (elf_elfheader (abfd)->e_flags & EF_MIPS_FP64)
+    fprintf (file, " [fp64]");
+
   if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
     fprintf (file, " [32bitmode]");
   else