* elflink.c (_bfd_elf_link_create_dynamic_sections): Move from
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index d2ba1cf8c2317205921759cc37e469d483a4a8a1..72516f71f1c3743de350754cb231be5d077581d0 100644 (file)
@@ -408,6 +408,7 @@ static asection * mips_elf_rel_dyn_section PARAMS ((bfd *, bfd_boolean));
 static asection * mips_elf_got_section PARAMS ((bfd *, bfd_boolean));
 static struct mips_got_info *mips_elf_got_info
   PARAMS ((bfd *, asection **));
+static long mips_elf_get_global_gotsym_index PARAMS ((bfd *abfd));
 static bfd_vma mips_elf_local_got_index
   PARAMS ((bfd *, bfd *, struct bfd_link_info *, bfd_vma));
 static bfd_vma mips_elf_global_got_index
@@ -541,7 +542,7 @@ static bfd *reldyn_sorting_bfd;
 
 /* The default alignment for sections, as a power of two.  */
 #define MIPS_ELF_LOG_FILE_ALIGN(abfd)                          \
-  (get_elf_backend_data (abfd)->s->file_align == 8 ? 3 : 2)
+  (get_elf_backend_data (abfd)->s->log_file_align)
 
 /* Get word-sized data.  */
 #define MIPS_ELF_GET_WORD(abfd, ptr) \
@@ -1707,6 +1708,29 @@ mips_elf_got_info (abfd, sgotp)
   return g;
 }
 
+/* Obtain the lowest dynamic index of a symbol that was assigned a
+   global GOT entry.  */
+static long
+mips_elf_get_global_gotsym_index (abfd)
+     bfd *abfd;
+{
+  asection *sgot;
+  struct mips_got_info *g;
+
+  if (abfd == NULL)
+    return 0;
+  
+  sgot = mips_elf_got_section (abfd, TRUE);
+  if (sgot == NULL || mips_elf_section_data (sgot) == NULL)
+    return 0;
+  
+  g = mips_elf_section_data (sgot)->u.got_info;
+  if (g == NULL || g->global_gotsym == NULL)
+    return 0;
+    
+  return g->global_gotsym->dynindx;
+}
+
 /* Returns the GOT offset at which the indicated address can be found.
    If there is not yet a GOT entry for this value, create one.  Returns
    -1 if no satisfactory GOT offset can be found.  */
@@ -3197,9 +3221,14 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
   switch (r_type)
     {
     case R_MIPS_GOT_PAGE:
-      /* If we didn't create a dynamic index for this symbol, it can
-        be regarded as local.  */
-      if (local_p || ! h || h->root.dynindx < 0)
+    case R_MIPS_GOT_OFST:
+      /* If this symbol got a global GOT entry, we have to decay
+        GOT_PAGE/GOT_OFST to GOT_DISP/addend.  */
+      local_p = local_p || ! h
+       || (h->root.dynindx
+           < mips_elf_get_global_gotsym_index (elf_hash_table (info)
+                                               ->dynobj));
+      if (local_p || r_type == R_MIPS_GOT_OFST)
        break;
       /* Fall through.  */
 
@@ -3485,7 +3514,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       /* GOT_PAGE relocations that reference non-local symbols decay
         to GOT_DISP.  The corresponding GOT_OFST relocation decays to
         0.  */
-      if (! (local_p || ! h || h->root.dynindx < 0))
+      if (! local_p)
        goto got_disp;
       value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL);
       if (value == MINUS_ONE)
@@ -3496,7 +3525,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       break;
 
     case R_MIPS_GOT_OFST:
-      if (local_p || ! h || h->root.dynindx < 0)
+      if (local_p)
        mips_elf_got_page (abfd, input_bfd, info, symbol + addend, &value);
       else
        value = addend;
@@ -5077,10 +5106,10 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                              sizeof CALL_FP_STUB - 1) == 0)
                continue;
 
-             sec_relocs = (MNAME(abfd,_bfd_elf,link_read_relocs)
-                           (abfd, o, (PTR) NULL,
-                            (Elf_Internal_Rela *) NULL,
-                            info->keep_memory));
+             sec_relocs
+               = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL,
+                                            (Elf_Internal_Rela *) NULL,
+                                            info->keep_memory);
              if (sec_relocs == NULL)
                return FALSE;
 
@@ -5532,9 +5561,9 @@ _bfd_mips_relax_section (abfd, sec, link_info, again)
   if (link_info->relocateable)
     return TRUE;
 
-  internal_relocs = (MNAME(abfd,_bfd_elf,link_read_relocs)
-                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
-                      link_info->keep_memory));
+  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, (PTR) NULL,
+                                              (Elf_Internal_Rela *) NULL,
+                                              link_info->keep_memory);
   if (internal_relocs == NULL)
     return TRUE;
 
@@ -7858,10 +7887,9 @@ _bfd_mips_elf_discard_info (abfd, cookie, info)
   if (! tdata)
     return FALSE;
 
-  cookie->rels = (MNAME(abfd,_bfd_elf,link_read_relocs)
-                 (abfd, o, (PTR) NULL,
-                  (Elf_Internal_Rela *) NULL,
-                  info->keep_memory));
+  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL,
+                                           (Elf_Internal_Rela *) NULL,
+                                           info->keep_memory);
   if (!cookie->rels)
     {
       free (tdata);
@@ -9145,12 +9173,25 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
 
   /* Check if we have the same endianess */
   if (! _bfd_generic_verify_endian_match (ibfd, obfd))
-    return FALSE;
+    {
+      (*_bfd_error_handler)
+       (_("%s: endianness incompatible with that of the selected emulation"),
+        bfd_archive_filename (ibfd));
+      return FALSE;
+    }
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
+  if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
+    {
+      (*_bfd_error_handler)
+       (_("%s: ABI is incompatible with that of the selected emulation"),
+        bfd_archive_filename (ibfd));
+      return FALSE;
+    }
+
   new_flags = elf_elfheader (ibfd)->e_flags;
   elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
   old_flags = elf_elfheader (obfd)->e_flags;
This page took 0.026134 seconds and 4 git commands to generate.