Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf64-ppc.c
index 1b4404cecb492343db0ffb9b937c73bcc7319f83..f8b6629d2d99ce150ce0cee44d7d3f681e975141 100644 (file)
@@ -161,10 +161,6 @@ static bfd_vma opd_entry_value
 #define LD_R11_0R11    0xe96b0000      /* ld    %r11,xxx+16@l(%r11) */
 #define BCTR           0x4e800420      /* bctr                      */
 
-#define CRSETEQ                0x4c421242      /* crset 4*%cr0+%eq      */
-#define BEQCTRM                0x4dc20420      /* beqctr-               */
-#define BEQCTRLM       0x4dc20421      /* beqctrl-              */
-
 #define ADDI_R11_R11   0x396b0000      /* addi %r11,%r11,off@l  */
 #define ADDIS_R2_R2    0x3c420000      /* addis %r2,%r2,off@ha  */
 #define ADDI_R2_R2     0x38420000      /* addi  %r2,%r2,off@l   */
@@ -193,8 +189,7 @@ static bfd_vma opd_entry_value
 
 /* __glink_PLTresolve stub instructions.  We enter with the index in R0.  */
 #define GLINK_PLTRESOLVE_SIZE(htab)                    \
-  (8u + (htab->opd_abi ? 11 * 4 : 14 * 4)              \
-   + (!htab->params->speculate_indirect_jumps ? 2 * 4 : 0))
+  (8u + (htab->opd_abi ? 11 * 4 : 14 * 4))
                                        /* 0:                           */
                                        /*  .quad plt0-1f               */
                                        /* __glink:                     */
@@ -2519,7 +2514,7 @@ ppc64_elf_info_to_howto (bfd *abfd, arelent *cache_ptr,
   if (type >= ARRAY_SIZE (ppc64_elf_howto_table))
     {
       /* xgettext:c-format */
-      _bfd_error_handler (_("%B: invalid relocation type %d"),
+      _bfd_error_handler (_("%pB: invalid relocation type %d"),
                          abfd, (int) type);
       type = R_PPC64_NONE;
     }
@@ -4652,7 +4647,7 @@ ppc_add_stub (const char *stub_name,
   if (stub_entry == NULL)
     {
       /* xgettext:c-format */
-      info->callbacks->einfo (_("%P: %B: cannot create stub entry %s\n"),
+      info->callbacks->einfo (_("%P: %pB: cannot create stub entry %s\n"),
                              section->owner, stub_name);
       return NULL;
     }
@@ -5051,7 +5046,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   dot_name = bfd_alloc (abfd, len + 2);
   if (dot_name == NULL)
-    return (struct elf_link_hash_entry *) 0 - 1;
+    return (struct elf_link_hash_entry *) -1;
   dot_name[0] = '.';
   memcpy (dot_name + 1, name, len + 1);
   h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
@@ -5158,7 +5153,7 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
       else if (abiversion (ibfd) >= 2)
        {
          /* xgettext:c-format */
-         info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
+         info->callbacks->einfo (_("%P: %pB .opd not allowed in ABI"
                                    " version %d\n"),
                                  ibfd, abiversion (ibfd));
          bfd_set_error (bfd_error_bad_value);
@@ -6047,7 +6042,7 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
     {
       _bfd_error_handler
        /* xgettext:c-format */
-       (_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
+       (_("%pB uses unknown e_flags 0x%lx"), ibfd, iflags);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -6055,7 +6050,7 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
     {
       _bfd_error_handler
        /* xgettext:c-format */
-       (_("%B: ABI version %ld is not compatible with ABI version %ld output"),
+       (_("%pB: ABI version %ld is not compatible with ABI version %ld output"),
         ibfd, iflags, oflags);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
@@ -7267,7 +7262,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
         sections.  Allow them to proceed, but warn that this might
         break at runtime.  */
       info->callbacks->einfo
-       (_("%P: copy reloc against `%T' requires lazy plt linking; "
+       (_("%P: copy reloc against `%pT' requires lazy plt linking; "
           "avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
         h->root.root.string);
     }
@@ -7534,7 +7529,7 @@ tocsave_find (struct ppc_link_hash_table *htab,
   if (ent.sec == NULL || ent.sec->output_section == NULL)
     {
       _bfd_error_handler
-       (_("%B: undefined symbol on R_PPC64_TOCSAVE relocation"), ibfd);
+       (_("%pB: undefined symbol on R_PPC64_TOCSAVE relocation"), ibfd);
       return NULL;
     }
 
@@ -7761,7 +7756,7 @@ dec_dynrel_count (bfd_vma r_info,
     }
 
   /* xgettext:c-format */
-  info->callbacks->einfo (_("%P: dynreloc miscount for %B, section %A\n"),
+  info->callbacks->einfo (_("%P: dynreloc miscount for %pB, section %pA\n"),
                          sec->owner, sec);
   bfd_set_error (bfd_error_bad_value);
   return FALSE;
@@ -7850,7 +7845,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
                 optimization for them!  */
            broken_opd:
              _bfd_error_handler
-               (_("%B: .opd is not a regular array of opd entries"), ibfd);
+               (_("%pB: .opd is not a regular array of opd entries"), ibfd);
              broken = TRUE;
              break;
            }
@@ -7860,7 +7855,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
            {
              _bfd_error_handler
                /* xgettext:c-format */
-               (_("%B: unexpected reloc type %u in .opd section"),
+               (_("%pB: unexpected reloc type %u in .opd section"),
                 ibfd, r_type);
              broken = TRUE;
              break;
@@ -7882,7 +7877,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
 
              _bfd_error_handler
                /* xgettext:c-format */
-               (_("%B: undefined sym `%s' in .opd section"),
+               (_("%pB: undefined sym `%s' in .opd section"),
                 ibfd, sym_name);
              broken = TRUE;
              break;
@@ -9886,8 +9881,6 @@ size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
        unsigned int align_power;
 
        stub_size = 16;
-       if (!htab->params->speculate_indirect_jumps)
-         stub_size += 8;
        stub_off = s->size;
        if (htab->params->plt_stub_align >= 0)
          align_power = htab->params->plt_stub_align;
@@ -9940,7 +9933,7 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-       (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+       (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
         sec->owner, h->root.root.string, sec);
 
       /* Not an error, just cut short the traversal.  */
@@ -10453,8 +10446,6 @@ plt_stub_size (struct ppc_link_hash_table *htab,
     size += 4;
   if (PPC_HA (off) != 0)
     size += 4;
-  if (!htab->params->speculate_indirect_jumps)
-    size += 8;
   if (htab->opd_abi)
     {
       size += 4;
@@ -10476,11 +10467,7 @@ plt_stub_size (struct ppc_link_hash_table *htab,
       size += 7 * 4;
       if (ALWAYS_EMIT_R2SAVE
          || stub_entry->stub_type == ppc_stub_plt_call_r2save)
-       {
-         size += 6 * 4;
-         if (!htab->params->speculate_indirect_jumps)
-           size -= 4;
-       }
+       size += 6 * 4;
     }
   return size;
 }
@@ -10515,26 +10502,6 @@ plt_stub_pad (struct ppc_link_hash_table *htab,
   return 0;
 }
 
-static inline bfd_byte *
-output_bctr (struct ppc_link_hash_table *htab, bfd *obfd, bfd_byte *p)
-{
-  if (!htab->params->speculate_indirect_jumps)
-    {
-      bfd_put_32 (obfd, CRSETEQ, p);
-      p += 4;
-      bfd_put_32 (obfd, BEQCTRM, p);
-      p += 4;
-      bfd_put_32 (obfd, B_DOT, p);
-      p += 4;
-    }
-  else
-    {
-      bfd_put_32 (obfd, BCTR, p);
-      p += 4;
-    }
-  return p;
-}
-
 /* Build a .plt call stub.  */
 
 static inline bfd_byte *
@@ -10555,7 +10522,6 @@ build_plt_stub (struct ppc_link_hash_table *htab,
   if (!ALWAYS_USE_FAKE_DEP
       && plt_load_toc
       && plt_thread_safe
-      && htab->params->speculate_indirect_jumps
       && !((stub_entry->h == htab->tls_get_addr_fd
            || stub_entry->h == htab->tls_get_addr)
           && htab->params->tls_get_addr_opt))
@@ -10710,7 +10676,7 @@ build_plt_stub (struct ppc_link_hash_table *htab,
       bfd_put_32 (obfd, B_DOT | (cmp_branch_off & 0x3fffffc), p), p += 4;
     }
   else
-    p = output_bctr (htab, obfd, p);
+    bfd_put_32 (obfd, BCTR, p),                                        p += 4;
   return p;
 }
 
@@ -10754,13 +10720,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
   if (r != NULL)
     r[0].r_offset += 2 * 4;
   p = build_plt_stub (htab, stub_entry, p, offset, r);
-  if (!htab->params->speculate_indirect_jumps)
-    {
-      p -= 4;
-      bfd_put_32 (obfd, BEQCTRLM, p - 4);
-    }
-  else
-    bfd_put_32 (obfd, BCTRL, p - 4);
+  bfd_put_32 (obfd, BCTRL, p - 4);
 
   bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p),    p += 4;
   bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p),        p += 4;
@@ -10820,7 +10780,7 @@ get_r2off (struct bfd_link_info *info,
       if (strcmp (opd->name, ".opd") != 0
          || opd->reloc_count != 0)
        {
-         info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
+         info->callbacks->einfo (_("%P: cannot find opd entry toc for `%pT'\n"),
                                  stub_entry->h->elf.root.root.string);
          bfd_set_error (bfd_error_bad_value);
          return (bfd_vma) -1;
@@ -11031,7 +10991,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
        {
          info->callbacks->einfo
-           (_("%P: linkage table error against `%T'\n"),
+           (_("%P: linkage table error against `%pT'\n"),
             stub_entry->root.string);
          bfd_set_error (bfd_error_bad_value);
          htab->stub_error = TRUE;
@@ -11113,7 +11073,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       p += 4;
       bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, p);
       p += 4;
-      p = output_bctr (htab, htab->params->stub_bfd, p);
+      bfd_put_32 (htab->params->stub_bfd, BCTR, p);
+      p += 4;
       break;
 
     case ppc_stub_plt_call:
@@ -11176,7 +11137,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
        {
          info->callbacks->einfo
            /* xgettext:c-format */
-           (_("%P: linkage table error against `%T'\n"),
+           (_("%P: linkage table error against `%pT'\n"),
             stub_entry->h != NULL
             ? stub_entry->h->elf.root.root.string
             : "<local sym>");
@@ -11446,8 +11407,6 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              if (PPC_LO (r2off) != 0)
                size += 4;
            }
-         if (!htab->params->speculate_indirect_jumps)
-           size += 8;
        }
       else if (info->emitrelocations)
        {
@@ -12169,7 +12128,7 @@ group_sections (struct bfd_link_info *info,
          big_sec = total > group_size;
          if (big_sec && !suppress_size_errors)
            /* xgettext:c-format */
-           _bfd_error_handler (_("%B section %A exceeds stub group size"),
+           _bfd_error_handler (_("%pB section %pA exceeds stub group size"),
                                tail->owner, tail);
          curr_toc = htab->sec_info[tail->id].toc_off;
 
@@ -12702,6 +12661,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
            stub_sec->flags &= ~SEC_RELOC;
          }
 
+      if (htab->stub_iteration <= STUB_SHRINK_ITER
+         || htab->brlt->rawsize < htab->brlt->size)
+       htab->brlt->rawsize = htab->brlt->size;
       htab->brlt->size = 0;
       htab->brlt->reloc_count = 0;
       htab->brlt->flags &= ~SEC_RELOC;
@@ -12743,9 +12705,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
       if (htab->params->plt_stub_align != 0)
        for (group = htab->group; group != NULL; group = group->next)
          if (group->stub_sec != NULL)
-           group->stub_sec->size = ((group->stub_sec->size
-                                     + (1 << htab->params->plt_stub_align) - 1)
-                                    & -(1 << htab->params->plt_stub_align));
+           {
+             int align = abs (htab->params->plt_stub_align);
+             group->stub_sec->size
+               = (group->stub_sec->size + (1 << align) - 1) & -(1 << align);
+           }
 
       for (group = htab->group; group != NULL; group = group->next)
        if (group->stub_sec != NULL
@@ -12755,6 +12719,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
          break;
 
       if (group == NULL
+         && (htab->brlt->rawsize == htab->brlt->size
+             || (htab->stub_iteration > STUB_SHRINK_ITER
+                 && htab->brlt->rawsize > htab->brlt->size))
          && (htab->glink_eh_frame == NULL
              || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
        break;
@@ -13039,7 +13006,7 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
        if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
          {
            info->callbacks->einfo
-             (_("%P: linkage table error against `%T'\n"),
+             (_("%P: linkage table error against `%pT'\n"),
               h->root.root.string);
            bfd_set_error (bfd_error_bad_value);
            htab->stub_error = TRUE;
@@ -13081,7 +13048,7 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
        p += 4;
        bfd_put_32 (s->owner, MTCTR_R12, p);
        p += 4;
-       output_bctr (htab, s->owner, p);
+       bfd_put_32 (s->owner, BCTR, p);
        break;
       }
   return TRUE;
@@ -13210,8 +13177,9 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
          bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 8, p);
          p += 4;
        }
-      p = output_bctr (htab, htab->glink->owner, p);
-      BFD_ASSERT (p - htab->glink->contents == GLINK_PLTRESOLVE_SIZE (htab));
+      bfd_put_32 (htab->glink->owner, BCTR, p);
+      p += 4;
+      BFD_ASSERT (p == htab->glink->contents + GLINK_PLTRESOLVE_SIZE (htab));
 
       /* Build the .glink lazy link call stubs.  */
       indx = 0;
@@ -13285,9 +13253,10 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
   if (htab->params->plt_stub_align != 0)
     for (group = htab->group; group != NULL; group = group->next)
       if ((stub_sec = group->stub_sec) != NULL)
-       stub_sec->size = ((stub_sec->size
-                          + (1 << htab->params->plt_stub_align) - 1)
-                         & -(1 << htab->params->plt_stub_align));
+       {
+         int align = abs (htab->params->plt_stub_align);
+         stub_sec->size = (stub_sec->size + (1 << align) - 1) & -(1 << align);
+       }
 
   for (group = htab->group; group != NULL; group = group->next)
     if ((stub_sec = group->stub_sec) != NULL)
@@ -13639,9 +13608,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            info->callbacks->einfo
              (!IS_PPC64_TLS_RELOC (r_type)
               /* xgettext:c-format */
-              ? _("%H: %s used with TLS symbol `%T'\n")
+              ? _("%H: %s used with TLS symbol `%pT'\n")
               /* xgettext:c-format */
-              : _("%H: %s used with non-TLS symbol `%T'\n"),
+              : _("%H: %s used with non-TLS symbol `%pT'\n"),
               input_bfd, input_section, rel->r_offset,
               ppc64_elf_howto_table[r_type]->name,
               sym_name);
@@ -14251,13 +14220,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                      || stub_entry->stub_type == ppc_stub_plt_call_r2save)
                    info->callbacks->einfo
                      /* xgettext:c-format */
-                     (_("%H: call to `%T' lacks nop, can't restore toc; "
+                     (_("%H: call to `%pT' lacks nop, can't restore toc; "
                         "recompile with -fPIC\n"),
                       input_bfd, input_section, rel->r_offset, sym_name);
                  else
                    info->callbacks->einfo
                      /* xgettext:c-format */
-                     (_("%H: call to `%T' lacks nop, can't restore toc; "
+                     (_("%H: call to `%pT' lacks nop, can't restore toc; "
                         "(-mcmodel=small toc adjust stub)\n"),
                       input_bfd, input_section, rel->r_offset, sym_name);
 
@@ -14385,7 +14354,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        default:
          info->callbacks->einfo
            /* xgettext:c-format */
-           (_("%P: %B: unknown relocation type %d for `%T'\n"),
+           (_("%P: %pB: unknown relocation type %d for `%pT'\n"),
             input_bfd, (int) r_type, sym_name);
 
          bfd_set_error (bfd_error_bad_value);
@@ -14935,7 +14904,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                          info->callbacks->einfo
                            /* xgettext:c-format */
                            (_("%H: %s for indirect "
-                              "function `%T' unsupported\n"),
+                              "function `%pT' unsupported\n"),
                             input_bfd, input_section, rel->r_offset,
                             ppc64_elf_howto_table[r_type]->name,
                             sym_name);
@@ -15046,7 +15015,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
          info->callbacks->einfo
            /* xgettext:c-format */
-           (_("%P: %B: %s is not supported for `%T'\n"),
+           (_("%P: %pB: %s is not supported for `%pT'\n"),
             input_bfd,
             ppc64_elf_howto_table[r_type]->name, sym_name);
 
@@ -15058,7 +15027,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       /* Multi-instruction sequences that access the TOC can be
         optimized, eg. addis ra,r2,0; addi rb,ra,x;
         to             nop;           addi rb,r2,x;  */
-      howto = ppc64_elf_howto_table[(int) r_type];
       switch (r_type)
        {
        default:
@@ -15090,6 +15058,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            {
              bfd_byte *p = contents + (rel->r_offset & ~3);
              bfd_put_32 (input_bfd, NOP, p);
+             goto copy_reloc;
            }
          break;
 
@@ -15131,9 +15100,13 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                /* xgettext:c-format */
                info->callbacks->minfo
                  (_("%H: warning: %s unexpected insn %#x.\n"),
-                  input_bfd, input_section, rel->r_offset, howto->name, insn);
+                  input_bfd, input_section, rel->r_offset,
+                  ppc64_elf_howto_table[r_type]->name, insn);
              else
-               bfd_put_32 (input_bfd, NOP, p);
+               {
+                 bfd_put_32 (input_bfd, NOP, p);
+                 goto copy_reloc;
+               }
            }
          break;
 
@@ -15231,7 +15204,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                /* xgettext:c-format */
                (_("%H: error: %s not a multiple of %u\n"),
                 input_bfd, input_section, rel->r_offset,
-                howto->name,
+                ppc64_elf_howto_table[r_type]->name,
                 mask + 1);
              bfd_set_error (bfd_error_bad_value);
              ret = FALSE;
@@ -15243,6 +15216,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
         because such sections are not SEC_ALLOC and thus ld.so will
         not process them.  */
+      howto = ppc64_elf_howto_table[(int) r_type];
       if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
               && h->elf.def_dynamic)
@@ -15251,7 +15225,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        {
          info->callbacks->einfo
            /* xgettext:c-format */
-           (_("%H: unresolvable %s against `%T'\n"),
+           (_("%H: unresolvable %s against `%pT'\n"),
             input_bfd, input_section, rel->r_offset,
             howto->name,
             h->elf.root.root.string);
@@ -15348,7 +15322,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
            {
              info->callbacks->einfo
                /* xgettext:c-format */
-               (_("%H: %s against `%T': error %d\n"),
+               (_("%H: %s against `%pT': error %d\n"),
                 input_bfd, input_section, rel->r_offset,
                 reloc_name, sym_name, (int) r);
              ret = FALSE;
This page took 0.034101 seconds and 4 git commands to generate.