* elf32-m68k.c (elf_m68k_copy_indirect_symbol): Propagate non_got_ref
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 5a345f4482a5ab253dbf9fd582851c6dacdab5e9..ec712fac74d0873f1516592a226668d937b2781e 100644 (file)
@@ -662,6 +662,23 @@ static struct mips_got_info *mips_elf_got_for_ibfd
 /* This will be used when we sort the dynamic relocation records.  */
 static bfd *reldyn_sorting_bfd;
 
+/* True if ABFD is for CPUs with load interlocking that include
+   non-MIPS1 CPUs and R3900.  */
+#define LOAD_INTERLOCKS_P(abfd) \
+  (   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) != E_MIPS_ARCH_1) \
+   || ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == E_MIPS_MACH_3900))
+
+/* True if ABFD is for CPUs that are faster if JAL is converted to BAL.
+   This should be safe for all architectures.  We enable this predicate
+   for RM9000 for now.  */
+#define JAL_TO_BAL_P(abfd) \
+  ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == E_MIPS_MACH_9000)
+
+/* True if ABFD is for CPUs that are faster if JALR is converted to BAL.
+   This should be safe for all architectures.  We enable this predicate for
+   all CPUs.  */
+#define JALR_TO_BAL_P(abfd) 1
+
 /* True if ABFD is a PIC object.  */
 #define PIC_OBJECT_P(abfd) \
   ((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
@@ -878,7 +895,8 @@ static bfd *reldyn_sorting_bfd;
 #define CALL_FP_STUB_P(name) CONST_STRNEQ (name, CALL_FP_STUB)
 \f
 /* The format of the first PLT entry in an O32 executable.  */
-static const bfd_vma mips_o32_exec_plt0_entry[] = {
+static const bfd_vma mips_o32_exec_plt0_entry[] =
+{
   0x3c1c0000,  /* lui $28, %hi(&GOTPLT[0])                             */
   0x8f990000,  /* lw $25, %lo(&GOTPLT[0])($28)                         */
   0x279c0000,  /* addiu $28, $28, %lo(&GOTPLT[0])                      */
@@ -891,7 +909,8 @@ static const bfd_vma mips_o32_exec_plt0_entry[] = {
 
 /* The format of the first PLT entry in an N32 executable.  Different
    because gp ($28) is not available; we use t2 ($14) instead.  */
-static const bfd_vma mips_n32_exec_plt0_entry[] = {
+static const bfd_vma mips_n32_exec_plt0_entry[] =
+{
   0x3c0e0000,  /* lui $14, %hi(&GOTPLT[0])                             */
   0x8dd90000,  /* lw $25, %lo(&GOTPLT[0])($14)                         */
   0x25ce0000,  /* addiu $14, $14, %lo(&GOTPLT[0])                      */
@@ -904,7 +923,8 @@ static const bfd_vma mips_n32_exec_plt0_entry[] = {
 
 /* The format of the first PLT entry in an N64 executable.  Different
    from N32 because of the increased size of GOT entries.  */
-static const bfd_vma mips_n64_exec_plt0_entry[] = {
+static const bfd_vma mips_n64_exec_plt0_entry[] =
+{
   0x3c0e0000,  /* lui $14, %hi(&GOTPLT[0])                             */
   0xddd90000,  /* ld $25, %lo(&GOTPLT[0])($14)                         */
   0x25ce0000,  /* addiu $14, $14, %lo(&GOTPLT[0])                      */
@@ -916,7 +936,8 @@ static const bfd_vma mips_n64_exec_plt0_entry[] = {
 };
 
 /* The format of subsequent PLT entries.  */
-static const bfd_vma mips_exec_plt_entry[] = {
+static const bfd_vma mips_exec_plt_entry[] =
+{
   0x3c0f0000,  /* lui $15, %hi(.got.plt entry)                 */
   0x01f90000,  /* l[wd] $25, %lo(.got.plt entry)($15)          */
   0x25f80000,  /* addiu $24, $15, %lo(.got.plt entry)          */
@@ -924,7 +945,8 @@ static const bfd_vma mips_exec_plt_entry[] = {
 };
 
 /* The format of the first PLT entry in a VxWorks executable.  */
-static const bfd_vma mips_vxworks_exec_plt0_entry[] = {
+static const bfd_vma mips_vxworks_exec_plt0_entry[] =
+{
   0x3c190000,  /* lui t9, %hi(_GLOBAL_OFFSET_TABLE_)           */
   0x27390000,  /* addiu t9, t9, %lo(_GLOBAL_OFFSET_TABLE_)     */
   0x8f390008,  /* lw t9, 8(t9)                                 */
@@ -934,7 +956,8 @@ static const bfd_vma mips_vxworks_exec_plt0_entry[] = {
 };
 
 /* The format of subsequent PLT entries.  */
-static const bfd_vma mips_vxworks_exec_plt_entry[] = {
+static const bfd_vma mips_vxworks_exec_plt_entry[] =
+{
   0x10000000,  /* b .PLT_resolver                      */
   0x24180000,  /* li t8, <pltindex>                    */
   0x3c190000,  /* lui t9, %hi(<.got.plt slot>)         */
@@ -946,7 +969,8 @@ static const bfd_vma mips_vxworks_exec_plt_entry[] = {
 };
 
 /* The format of the first PLT entry in a VxWorks shared object.  */
-static const bfd_vma mips_vxworks_shared_plt0_entry[] = {
+static const bfd_vma mips_vxworks_shared_plt0_entry[] =
+{
   0x8f990008,  /* lw t9, 8(gp)         */
   0x00000000,  /* nop                  */
   0x03200008,  /* jr t9                */
@@ -956,7 +980,8 @@ static const bfd_vma mips_vxworks_shared_plt0_entry[] = {
 };
 
 /* The format of subsequent PLT entries.  */
-static const bfd_vma mips_vxworks_shared_plt_entry[] = {
+static const bfd_vma mips_vxworks_shared_plt_entry[] =
+{
   0x10000000,  /* b .PLT_resolver      */
   0x24180000   /* li t8, <pltindex>    */
 };
@@ -5572,15 +5597,15 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
       x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
     }
 
-  /* On the RM9000, bal is faster than jal, because bal uses branch
-     prediction hardware.  If we are linking for the RM9000, and we
-     see jal, and bal fits, use it instead.  Note that this
-     transformation should be safe for all architectures.  */
-  if (bfd_get_mach (input_bfd) == bfd_mach_mips9000
-      && !info->relocatable
+  /* Try converting JAL and JALR to BAL, if the target is in range.  */
+  if (!info->relocatable
       && !require_jalx
-      && ((r_type == R_MIPS_26 && (x >> 26) == 0x3)        /* jal addr */
-         || (r_type == R_MIPS_JALR && x == 0x0320f809)))   /* jalr t9 */
+      && ((JAL_TO_BAL_P (input_bfd)
+          && r_type == R_MIPS_26
+          && (x >> 26) == 0x3)         /* jal addr */
+         || (JALR_TO_BAL_P (input_bfd)
+             && r_type == R_MIPS_JALR
+             && x == 0x0320f809)))     /* jalr t9 */
     {
       bfd_vma addr;
       bfd_vma dest;
@@ -6249,6 +6274,13 @@ _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
     {
       const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
 
+      /* .sbss is not handled specially here because the GNU/Linux
+        prelinker can convert .sbss from NOBITS to PROGBITS and
+        changing it back to NOBITS breaks the binary.  The entry in
+        _bfd_mips_elf_special_sections will ensure the correct flags
+        are set on .sbss if BFD creates it without reading it from an
+        input file, and without special handling here the flags set
+        on it in an input file will be followed.  */
       if (strcmp (name, ".sdata") == 0
          || strcmp (name, ".lit8") == 0
          || strcmp (name, ".lit4") == 0)
@@ -6256,11 +6288,6 @@ _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
          hdr->sh_type = SHT_PROGBITS;
        }
-      else if (strcmp (name, ".sbss") == 0)
-       {
-         hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
-         hdr->sh_type = SHT_NOBITS;
-       }
       else if (strcmp (name, ".srdata") == 0)
        {
          hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
@@ -6783,7 +6810,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
    symbol.  We mark symbols as small common if appropriate.  This is
    also where we undo the increment of the value for a mips16 symbol.  */
 
-bfd_boolean
+int
 _bfd_mips_elf_link_output_symbol_hook
   (struct bfd_link_info *info ATTRIBUTE_UNUSED,
    const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym,
@@ -6799,7 +6826,7 @@ _bfd_mips_elf_link_output_symbol_hook
   if (ELF_ST_IS_MIPS16 (sym->st_other))
     sym->st_value &= ~1;
 
-  return TRUE;
+  return 1;
 }
 \f
 /* Functions for the dynamic linker.  */
@@ -8629,8 +8656,10 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
       else if (s == htab->splt)
        {
          /* If the last PLT entry has a branch delay slot, allocate
-            room for an extra nop to fill the delay slot.  */
-         if (!htab->is_vxworks && s->size > 0)
+            room for an extra nop to fill the delay slot.  This is
+            for CPUs without load interlocking.  */
+         if (! LOAD_INTERLOCKS_P (output_bfd)
+             && ! htab->is_vxworks && s->size > 0)
            s->size += 4;
        }
       else if (! CONST_STRNEQ (name, ".init")
@@ -9353,8 +9382,17 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
       plt_entry = mips_exec_plt_entry;
       bfd_put_32 (output_bfd, plt_entry[0] | got_address_high, loc);
       bfd_put_32 (output_bfd, plt_entry[1] | got_address_low | load, loc + 4);
-      bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
-      bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+
+      if (! LOAD_INTERLOCKS_P (output_bfd))
+       {
+         bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
+         bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+       }
+      else
+       {
+         bfd_put_32 (output_bfd, plt_entry[3], loc + 8);
+         bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 12);
+       }
 
       /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry.  */
       mips_elf_output_dynamic_relocation (output_bfd, htab->srelplt,
This page took 0.027577 seconds and 4 git commands to generate.