Consolidate ppc64 ld/bfd communication
authorAlan Modra <amodra@gmail.com>
Mon, 17 Feb 2014 06:38:00 +0000 (17:08 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 17 Feb 2014 06:41:11 +0000 (17:11 +1030)
Moves assorted variables used to communicate between ld and bfd into
a struct, hooks it into the bfd link_hash_table early, and removes
all other places where such variables were passed piecemeal.

bfd/
* elf64-ppc.h (struct ppc64_elf_params): Define.
(ppc64_elf_init_stub_bfd, ppc64_elf_edit_opd, ppc64_elf_tls_setup,
ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
ppc64_elf_build_stubs): Update prototype.
* elf64-ppp.c (struct ppc_link_hash_table): Add params, delete other
fields now in params.  Adjust code throughout file.
(ppc64_elf_init_stub_bfd): Delete "abfd" parameter, add "params".
Save params pointer in htab.
(ppc64_elf_edit_opd, ppc64_elf_tls_setup,
ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
ppc64_elf_build_stubs): Remove parameters now in "params".
ld/
* emultemps/ppc64elf.em (params): New static struct replacing
various other static vars.  Adjust code throughout file.

bfd/ChangeLog
bfd/elf64-ppc.c
bfd/elf64-ppc.h
ld/ChangeLog
ld/emultempl/ppc64elf.em

index 86f9d849b17630ff8ce7943e76ccf38fd878f595..75cf244778f00dc81667da7df07ea59cd99d42b4 100644 (file)
@@ -1,3 +1,17 @@
+2014-02-17  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.h (struct ppc64_elf_params): Define.
+       (ppc64_elf_init_stub_bfd, ppc64_elf_edit_opd, ppc64_elf_tls_setup,
+       ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
+       ppc64_elf_build_stubs): Update prototype.
+       * elf64-ppp.c (struct ppc_link_hash_table): Add params, delete other
+       fields now in params.  Adjust code throughout file.
+       (ppc64_elf_init_stub_bfd): Delete "abfd" parameter, add "params".
+       Save params pointer in htab.
+       (ppc64_elf_edit_opd, ppc64_elf_tls_setup,
+       ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
+       ppc64_elf_build_stubs): Remove parameters now in "params".
+
 2014-02-17  Alan Modra  <amodra@gmail.com>
 
        * elf32-ppc.c (ppc_elf_relocate_section): Move relocs on insns
index 5d779616c50efa0ab2678c949e80c6ecb8a973e9..795d093469faa3d903d4ab81375ff99f9975c6ee 100644 (file)
@@ -3873,12 +3873,8 @@ struct ppc_link_hash_table
   /* Hash table for function prologue tocsave.  */
   htab_t tocsave_htab;
 
-  /* Linker stub bfd.  */
-  bfd *stub_bfd;
-
-  /* Linker call-backs.  */
-  asection * (*add_stub_section) (const char *, asection *);
-  void (*layout_sections_again) (void);
+  /* Various options and other info passed from the linker.  */
+  struct ppc64_elf_params *params;
 
   /* Array to keep track of which stub sections have been created, and
      information on stub grouping.  */
@@ -3930,24 +3926,9 @@ struct ppc_link_hash_table
   /* Number of stubs against global syms.  */
   unsigned long stub_globals;
 
-  /* Alignment of PLT call stubs.  */
-  unsigned int plt_stub_align:4;
-
   /* Set if we're linking code with function descriptors.  */
   unsigned int opd_abi:1;
 
-  /* Set if PLT call stubs should load r11.  */
-  unsigned int plt_static_chain:1;
-
-  /* Set if PLT call stubs need a read-read barrier.  */
-  unsigned int plt_thread_safe:1;
-
-  /* Set if we should emit symbols for stubs.  */
-  unsigned int emit_stub_syms:1;
-
-  /* Set if __tls_get_addr optimization should not be done.  */
-  unsigned int no_tls_get_addr_opt:1;
-
   /* Support for multiple toc sections.  */
   unsigned int do_multi_toc:1;
   unsigned int multi_toc_needed:1;
@@ -4303,11 +4284,12 @@ create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
 /* Satisfy the ELF linker by filling in some fields in our fake bfd.  */
 
 bfd_boolean
-ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
+ppc64_elf_init_stub_bfd (struct bfd_link_info *info,
+                        struct ppc64_elf_params *params)
 {
   struct ppc_link_hash_table *htab;
 
-  elf_elfheader (abfd)->e_ident[EI_CLASS] = ELFCLASS64;
+  elf_elfheader (params->stub_bfd)->e_ident[EI_CLASS] = ELFCLASS64;
 
 /* Always hook our dynamic sections into the first bfd, which is the
    linker created stub bfd.  This ensures that the GOT header is at
@@ -4315,8 +4297,8 @@ ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
   htab = ppc_hash_table (info);
   if (htab == NULL)
     return FALSE;
-  htab->stub_bfd = abfd;
-  htab->elf.dynobj = abfd;
+  htab->elf.dynobj = params->stub_bfd;
+  htab->params = params;
 
   if (info->relocatable)
     return TRUE;
@@ -4441,13 +4423,13 @@ ppc_add_stub (const char *stub_name,
 
          namelen = strlen (link_sec->name);
          len = namelen + sizeof (STUB_SUFFIX);
-         s_name = bfd_alloc (htab->stub_bfd, len);
+         s_name = bfd_alloc (htab->params->stub_bfd, len);
          if (s_name == NULL)
            return NULL;
 
          memcpy (s_name, link_sec->name, namelen);
          memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
-         stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+         stub_sec = (*htab->params->add_stub_section) (s_name, link_sec);
          if (stub_sec == NULL)
            return NULL;
          htab->stub_group[link_sec->id].stub_sec = stub_sec;
@@ -7514,11 +7496,16 @@ dec_dynrel_count (bfd_vma r_info,
    applications.  */
 
 bfd_boolean
-ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
+ppc64_elf_edit_opd (struct bfd_link_info *info)
 {
   bfd *ibfd;
   bfd_boolean some_edited = FALSE;
   asection *need_pad = NULL;
+  struct ppc_link_hash_table *htab;
+
+  htab = ppc_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
     {
@@ -7671,7 +7658,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
            goto broken_opd;
        }
 
-      add_aux_fields = non_overlapping && cnt_16b > 0;
+      add_aux_fields = htab->params->non_overlapping_opd && cnt_16b > 0;
 
       if (need_edit || add_aux_fields)
        {
@@ -7762,12 +7749,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
                  if (h != NULL
                      && h->root.root.string[0] == '.')
                    {
-                     struct ppc_link_hash_table *htab;
-
-                     htab = ppc_hash_table (info);
-                     if (htab != NULL)
-                       fdh = lookup_fdh ((struct ppc_link_hash_entry *) h,
-                                         htab);
+                     fdh = lookup_fdh ((struct ppc_link_hash_entry *) h, htab);
                      if (fdh != NULL
                          && fdh->elf.root.type != bfd_link_hash_defined
                          && fdh->elf.root.type != bfd_link_hash_defweak)
@@ -7916,9 +7898,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
 /* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
 
 asection *
-ppc64_elf_tls_setup (struct bfd_link_info *info,
-                    int no_tls_get_addr_opt,
-                    int *no_multi_toc)
+ppc64_elf_tls_setup (struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
 
@@ -7929,10 +7909,10 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
   if (abiversion (info->output_bfd) == 1)
     htab->opd_abi = 1;
 
-  if (*no_multi_toc)
+  if (htab->params->no_multi_toc)
     htab->do_multi_toc = 0;
   else if (!htab->do_multi_toc)
-    *no_multi_toc = 1;
+    htab->params->no_multi_toc = 1;
 
   htab->tls_get_addr = ((struct ppc_link_hash_entry *)
                        elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
@@ -7943,7 +7923,7 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
   htab->tls_get_addr_fd = ((struct ppc_link_hash_entry *)
                           elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
                                                 FALSE, FALSE, TRUE));
-  if (!no_tls_get_addr_opt)
+  if (!htab->params->no_tls_get_addr_opt)
     {
       struct elf_link_hash_entry *opt, *opt_fd, *tga, *tga_fd;
 
@@ -8011,9 +7991,8 @@ ppc64_elf_tls_setup (struct bfd_link_info *info,
            }
        }
       else
-       no_tls_get_addr_opt = TRUE;
+       htab->params->no_tls_get_addr_opt = TRUE;
     }
-  htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
   return _bfd_elf_tls_setup (info->output_bfd, info);
 }
 
@@ -9930,7 +9909,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
            return FALSE;
        }
 
-      tls_opt = (!htab->no_tls_get_addr_opt
+      tls_opt = (!htab->params->no_tls_get_addr_opt
                 && htab->tls_get_addr_fd != NULL
                 && htab->tls_get_addr_fd->elf.plt.plist != NULL);
       if (tls_opt || !htab->opd_abi)
@@ -10102,17 +10081,17 @@ plt_stub_size (struct ppc_link_hash_table *htab,
   if (htab->opd_abi)
     {
       size += 4;
-      if (htab->plt_static_chain)
+      if (htab->params->plt_static_chain)
        size += 4;
-      if (htab->plt_thread_safe)
+      if (htab->params->plt_thread_safe)
        size += 8;
-      if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
+      if (PPC_HA (off + 8 + 8 * htab->params->plt_static_chain) != PPC_HA (off))
        size += 4;
     }
   if (stub_entry->h != NULL
       && (stub_entry->h == htab->tls_get_addr_fd
          || stub_entry->h == htab->tls_get_addr)
-      && !htab->no_tls_get_addr_opt)
+      && !htab->params->no_tls_get_addr_opt)
     size += 13 * 4;
   return size;
 }
@@ -10124,7 +10103,7 @@ plt_stub_pad (struct ppc_link_hash_table *htab,
              struct ppc_stub_hash_entry *stub_entry,
              bfd_vma plt_off)
 {
-  int stub_align = 1 << htab->plt_stub_align;
+  int stub_align = 1 << htab->params->plt_stub_align;
   unsigned stub_size = plt_stub_size (htab, stub_entry, plt_off);
   bfd_vma stub_off = stub_entry->stub_sec->size;
 
@@ -10141,10 +10120,10 @@ build_plt_stub (struct ppc_link_hash_table *htab,
                struct ppc_stub_hash_entry *stub_entry,
                bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
 {
-  bfd *obfd = htab->stub_bfd;
+  bfd *obfd = htab->params->stub_bfd;
   bfd_boolean plt_load_toc = htab->opd_abi;
-  bfd_boolean plt_static_chain = htab->plt_static_chain;
-  bfd_boolean plt_thread_safe = htab->plt_thread_safe;
+  bfd_boolean plt_static_chain = htab->params->plt_static_chain;
+  bfd_boolean plt_thread_safe = htab->params->plt_thread_safe;
   bfd_boolean use_fake_dep = plt_thread_safe;
   bfd_vma cmp_branch_off = 0;
 
@@ -10154,7 +10133,7 @@ build_plt_stub (struct ppc_link_hash_table *htab,
       && !(stub_entry->h != NULL
           && (stub_entry->h == htab->tls_get_addr_fd
               || stub_entry->h == htab->tls_get_addr)
-          && !htab->no_tls_get_addr_opt))
+          && !htab->params->no_tls_get_addr_opt))
     {
       bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
       bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
@@ -10321,7 +10300,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
                         struct ppc_stub_hash_entry *stub_entry,
                         bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
 {
-  bfd *obfd = htab->stub_bfd;
+  bfd *obfd = htab->params->stub_bfd;
 
   bfd_put_32 (obfd, LD_R11_0R3 + 0, p),                p += 4;
   bfd_put_32 (obfd, LD_R12_0R3 + 8, p),                p += 4;
@@ -10463,20 +10442,21 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              htab->stub_error = TRUE;
              return FALSE;
            }
-         bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
+         bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
          loc += 4;
          size = 12;
          if (PPC_HA (r2off) != 0)
            {
              size = 16;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R2_R2 | PPC_HA (r2off), loc);
              loc += 4;
            }
-         bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
+         bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
          loc += 4;
          off -= size - 4;
        }
-      bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
+      bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
 
       if (off + (1 << 25) >= (bfd_vma) (1 << 26))
        {
@@ -10501,16 +10481,16 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              unsigned long symndx;
              struct ppc_link_hash_entry *h;
 
-             hashes = elf_sym_hashes (htab->stub_bfd);
+             hashes = elf_sym_hashes (htab->params->stub_bfd);
              if (hashes == NULL)
                {
                  bfd_size_type hsize;
 
                  hsize = (htab->stub_globals + 1) * sizeof (*hashes);
-                 hashes = bfd_zalloc (htab->stub_bfd, hsize);
+                 hashes = bfd_zalloc (htab->params->stub_bfd, hsize);
                  if (hashes == NULL)
                    return FALSE;
-                 elf_sym_hashes (htab->stub_bfd) = hashes;
+                 elf_sym_hashes (htab->params->stub_bfd) = hashes;
                  htab->stub_globals = 1;
                }
              symndx = htab->stub_globals++;
@@ -10637,14 +10617,17 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          if (PPC_HA (off) != 0)
            {
              size = 16;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R11_R2 | PPC_HA (off), loc);
              loc += 4;
-             bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R11 | PPC_LO (off), loc);
            }
          else
            {
              size = 12;
-             bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R2 | PPC_LO (off), loc);
            }
        }
       else
@@ -10657,36 +10640,40 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              return FALSE;
            }
 
-         bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
+         bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
          loc += 4;
          size = 16;
          if (PPC_HA (off) != 0)
            {
              size += 4;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R11_R2 | PPC_HA (off), loc);
              loc += 4;
-             bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         LD_R12_0R11 | PPC_LO (off), loc);
            }
          else
-           bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
+           bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
 
          if (PPC_HA (r2off) != 0)
            {
              size += 4;
              loc += 4;
-             bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDIS_R2_R2 | PPC_HA (r2off), loc);
            }
          if (PPC_LO (r2off) != 0)
            {
              size += 4;
              loc += 4;
-             bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
+             bfd_put_32 (htab->params->stub_bfd,
+                         ADDI_R2_R2 | PPC_LO (r2off), loc);
            }
        }
       loc += 4;
-      bfd_put_32 (htab->stub_bfd, MTCTR_R12, loc);
+      bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, loc);
       loc += 4;
-      bfd_put_32 (htab->stub_bfd, BCTR, loc);
+      bfd_put_32 (htab->params->stub_bfd, BCTR, loc);
       break;
 
     case ppc_stub_plt_call:
@@ -10760,7 +10747,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          return FALSE;
        }
 
-      if (htab->plt_stub_align != 0)
+      if (htab->params->plt_stub_align != 0)
        {
          unsigned pad = plt_stub_pad (htab, stub_entry, off);
 
@@ -10775,7 +10762,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
          r = get_relocs (stub_entry->stub_sec,
                          ((PPC_HA (off) != 0)
                           + (htab->opd_abi
-                             ? 2 + (htab->plt_static_chain
+                             ? 2 + (htab->params->plt_static_chain
                                     && PPC_HA (off + 16) == PPC_HA (off))
                              : 1)));
          if (r == NULL)
@@ -10788,7 +10775,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       if (stub_entry->h != NULL
          && (stub_entry->h == htab->tls_get_addr_fd
              || stub_entry->h == htab->tls_get_addr)
-         && !htab->no_tls_get_addr_opt)
+         && !htab->params->no_tls_get_addr_opt)
        p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r);
       else
        p = build_plt_stub (htab, stub_entry, loc, off, r);
@@ -10802,7 +10789,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 
   stub_entry->stub_sec->size += size;
 
-  if (htab->emit_stub_syms)
+  if (htab->params->emit_stub_syms)
     {
       struct elf_link_hash_entry *h;
       size_t len1, len2;
@@ -10880,14 +10867,14 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
              - htab->stub_group[stub_entry->id_sec->id].toc_off);
 
       size = plt_stub_size (htab, stub_entry, off);
-      if (htab->plt_stub_align)
+      if (htab->params->plt_stub_align)
        size += plt_stub_pad (htab, stub_entry, off);
       if (info->emitrelocations)
        {
          stub_entry->stub_sec->reloc_count
            += ((PPC_HA (off) != 0)
                + (htab->opd_abi
-                  ? 2 + (htab->plt_static_chain
+                  ? 2 + (htab->params->plt_static_chain
                          && PPC_HA (off + 16) == PPC_HA (off))
                   : 1));
          stub_entry->stub_sec->flags |= SEC_RELOC;
@@ -11010,10 +10997,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
    0 when no stubs will be needed, and 1 on success.  */
 
 int
-ppc64_elf_setup_section_lists
-  (struct bfd_link_info *info,
-   asection *(*add_stub_section) (const char *, asection *),
-   void (*layout_sections_again) (void))
+ppc64_elf_setup_section_lists (struct bfd_link_info *info)
 {
   bfd *input_bfd;
   int top_id, top_index, id;
@@ -11024,9 +11008,6 @@ ppc64_elf_setup_section_lists
 
   if (htab == NULL)
     return -1;
-  /* Stash our params away.  */
-  htab->add_stub_section = add_stub_section;
-  htab->layout_sections_again = layout_sections_again;
 
   /* Find the top input section id.  */
   for (input_bfd = info->input_bfds, top_id = 3;
@@ -11363,7 +11344,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
       }
 
   if (done_something)
-    (*htab->layout_sections_again) ();
+    (*htab->params->layout_sections_again) ();
 
   /* Set up for second pass over toc sections to recalculate elf_gp
      on input sections.  */
@@ -11850,9 +11831,7 @@ maybe_strip_output (struct bfd_link_info *info, asection *isec)
    instruction.  */
 
 bfd_boolean
-ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
-                     bfd_boolean plt_static_chain, int plt_thread_safe,
-                     int plt_stub_align)
+ppc64_elf_size_stubs (struct bfd_link_info *info)
 {
   bfd_size_type stub_group_size;
   bfd_boolean stubs_always_before_branch;
@@ -11861,13 +11840,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
   if (htab == NULL)
     return FALSE;
 
-  htab->plt_static_chain = plt_static_chain;
-  htab->plt_stub_align = plt_stub_align;
-  if (plt_thread_safe == -1 && !info->executable)
-    plt_thread_safe = 1;
+  if (htab->params->plt_thread_safe == -1 && !info->executable)
+    htab->params->plt_thread_safe = 1;
   if (!htab->opd_abi)
-    plt_thread_safe = 0;
-  else if (plt_thread_safe == -1)
+    htab->params->plt_thread_safe = 0;
+  else if (htab->params->plt_thread_safe == -1)
     {
       static const char *const thread_starter[] =
        {
@@ -11894,17 +11871,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
          struct elf_link_hash_entry *h;
          h = elf_link_hash_lookup (&htab->elf, thread_starter[i],
                                    FALSE, FALSE, TRUE);
-         plt_thread_safe = h != NULL && h->ref_regular;
-         if (plt_thread_safe)
+         htab->params->plt_thread_safe = h != NULL && h->ref_regular;
+         if (htab->params->plt_thread_safe)
            break;
        }
     }
-  htab->plt_thread_safe = plt_thread_safe;
-  stubs_always_before_branch = group_size < 0;
-  if (group_size < 0)
-    stub_group_size = -group_size;
+  stubs_always_before_branch = htab->params->group_size < 0;
+  if (htab->params->group_size < 0)
+    stub_group_size = -htab->params->group_size;
   else
-    stub_group_size = group_size;
+    stub_group_size = htab->params->group_size;
 
   group_sections (htab, stub_group_size, stubs_always_before_branch);
 
@@ -12220,7 +12196,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
 
       /* We may have added some stubs.  Find out the new size of the
         stub sections.  */
-      for (stub_sec = htab->stub_bfd->sections;
+      for (stub_sec = htab->params->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -12252,7 +12228,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
        {
          size_t size = 0, align;
 
-         for (stub_sec = htab->stub_bfd->sections;
+         for (stub_sec = htab->params->stub_bfd->sections;
               stub_sec != NULL;
               stub_sec = stub_sec->next)
            if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -12269,15 +12245,16 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
          htab->glink_eh_frame->size = size;
        }
 
-      if (htab->plt_stub_align != 0)
-       for (stub_sec = htab->stub_bfd->sections;
+      if (htab->params->plt_stub_align != 0)
+       for (stub_sec = htab->params->stub_bfd->sections;
             stub_sec != NULL;
             stub_sec = stub_sec->next)
          if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-           stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
-                             & (-1 << htab->plt_stub_align));
+           stub_sec->size = ((stub_sec->size
+                              + (1 << htab->params->plt_stub_align) - 1)
+                             & (-1 << htab->params->plt_stub_align));
 
-      for (stub_sec = htab->stub_bfd->sections;
+      for (stub_sec = htab->params->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
@@ -12292,7 +12269,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
        break;
 
       /* Ask the linker to do its stuff.  */
-      (*htab->layout_sections_again) ();
+      (*htab->params->layout_sections_again) ();
     }
 
   maybe_strip_output (info, htab->brlt);
@@ -12444,8 +12421,7 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
    hash table.  This function is called via gldelf64ppc_finish.  */
 
 bfd_boolean
-ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
-                      struct bfd_link_info *info,
+ppc64_elf_build_stubs (struct bfd_link_info *info,
                       char **stats)
 {
   struct ppc_link_hash_table *htab = ppc_hash_table (info);
@@ -12456,16 +12432,14 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
   if (htab == NULL)
     return FALSE;
 
-  htab->emit_stub_syms = emit_stub_syms;
-
   /* Allocate memory to hold the linker stubs.  */
-  for (stub_sec = htab->stub_bfd->sections;
+  for (stub_sec = htab->params->stub_bfd->sections;
        stub_sec != NULL;
        stub_sec = stub_sec->next)
     if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
        && stub_sec->size != 0)
       {
-       stub_sec->contents = bfd_zalloc (htab->stub_bfd, stub_sec->size);
+       stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
        if (stub_sec->contents == NULL)
          return FALSE;
        /* We want to check that built size is the same as calculated
@@ -12480,7 +12454,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
       bfd_vma plt0;
 
       /* Build the .glink plt call stub.  */
-      if (htab->emit_stub_syms)
+      if (htab->params->emit_stub_syms)
        {
          struct elf_link_hash_entry *h;
          h = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
@@ -12641,7 +12615,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
       bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
       p += sizeof (glink_eh_frame_cie);
 
-      for (stub_sec = htab->stub_bfd->sections;
+      for (stub_sec = htab->params->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -12737,15 +12711,16 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
   if (htab->relbrlt != NULL)
     htab->relbrlt->reloc_count = 0;
 
-  if (htab->plt_stub_align != 0)
-    for (stub_sec = htab->stub_bfd->sections;
+  if (htab->params->plt_stub_align != 0)
+    for (stub_sec = htab->params->stub_bfd->sections;
         stub_sec != NULL;
         stub_sec = stub_sec->next)
       if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
-       stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
-                         & (-1 << htab->plt_stub_align));
+       stub_sec->size = ((stub_sec->size
+                          + (1 << htab->params->plt_stub_align) - 1)
+                         & (-1 << htab->params->plt_stub_align));
 
-  for (stub_sec = htab->stub_bfd->sections;
+  for (stub_sec = htab->params->stub_bfd->sections;
        stub_sec != NULL;
        stub_sec = stub_sec->next)
     if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
@@ -12899,7 +12874,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
     return FALSE;
 
   /* Don't relocate stub sections.  */
-  if (input_section->owner == htab->stub_bfd)
+  if (input_section->owner == htab->params->stub_bfd)
     return TRUE;
 
   BFD_ASSERT (is_ppc64_elf (input_bfd));
@@ -13620,7 +13595,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                          if (h != NULL
                              && (h == htab->tls_get_addr_fd
                                  || h == htab->tls_get_addr)
-                             && !htab->no_tls_get_addr_opt)
+                             && !htab->params->no_tls_get_addr_opt)
                            {
                              /* Special stub used, leave nop alone.  */
                            }
index 06c655f746a17b81c4da2c0bb061ee9b8f16114f..3a2299ad1681628ae75da99efbdaaa2a4bc1140c 100644 (file)
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+/* Used to pass info between ld and bfd.  */
+struct ppc64_elf_params
+{
+  /* Linker stub bfd.  */
+  bfd *stub_bfd;
+
+  /* Linker call-backs.  */
+  asection * (*add_stub_section) (const char *, asection *);
+  void (*layout_sections_again) (void);
+
+  /* Maximum size of a group of input sections that can be handled by
+     one stub section.  A value of +/-1 indicates the bfd back-end
+     should use a suitable default size.  */
+  bfd_signed_vma group_size;
+
+  /* Whether to use a special call stub for __tls_get_addr.  */
+  int no_tls_get_addr_opt;
+
+  /* Whether to allow multiple toc sections.  */
+  int no_multi_toc;
+
+  /* Set if PLT call stubs should load r11.  */
+  int plt_static_chain;
+
+  /* Set if PLT call stubs need to be thread safe on power7+.  */
+  int plt_thread_safe;
+
+  /* Set if individual PLT call stubs should be aligned.  */
+  int plt_stub_align;
+
+  /* Whether to canonicalize .opd so that there are no overlapping
+     .opd entries.  */
+  int non_overlapping_opd;
+
+  /* Whether to emit symbols for stubs.  */
+  int emit_stub_syms;
+};
+
 bfd_boolean ppc64_elf_init_stub_bfd
-  (bfd *, struct bfd_link_info *);
+  (struct bfd_link_info *, struct ppc64_elf_params *);
 bfd_boolean ppc64_elf_edit_opd
-  (struct bfd_link_info *, bfd_boolean);
+  (struct bfd_link_info *);
 asection *ppc64_elf_tls_setup
-  (struct bfd_link_info *, int, int *);
+  (struct bfd_link_info *);
 bfd_boolean ppc64_elf_tls_optimize
   (struct bfd_link_info *);
 bfd_boolean ppc64_elf_edit_toc
@@ -32,10 +70,9 @@ bfd_boolean ppc64_elf_edit_toc
 bfd_boolean ppc64_elf_has_small_toc_reloc
   (asection *);
 bfd_vma ppc64_elf_set_toc
-  (struct bfd_link_info *, bfd *);
+(struct bfd_link_info *, bfd *);
 int ppc64_elf_setup_section_lists
-  (struct bfd_link_info *, asection *(*) (const char *, asection *),
-   void (*) (void));
+  (struct bfd_link_info *);
 void ppc64_elf_start_multitoc_partition
   (struct bfd_link_info *);
 bfd_boolean ppc64_elf_next_toc_section
@@ -49,8 +86,8 @@ bfd_boolean ppc64_elf_check_init_fini
 bfd_boolean ppc64_elf_next_input_section
   (struct bfd_link_info *, asection *);
 bfd_boolean ppc64_elf_size_stubs
-(struct bfd_link_info *, bfd_signed_vma, bfd_boolean, int, int);
+(struct bfd_link_info *);
 bfd_boolean ppc64_elf_build_stubs
-  (bfd_boolean, struct bfd_link_info *, char **);
+  (struct bfd_link_info *, char **);
 void ppc64_elf_restore_symbols
   (struct bfd_link_info *info);
index 38d81b095ade7f22dbda02e685189723d28f27ed..1bd1c9923cfcb59ba8c1a24be879710ab494aa3e 100644 (file)
@@ -1,3 +1,8 @@
+2014-02-17  Alan Modra  <amodra@gmail.com>
+
+       * emultemps/ppc64elf.em (params): New static struct replacing
+       various other static vars.  Adjust code throughout file.
+
 2014-02-17  Alan Modra  <amodra@gmail.com>
 
        * emultempl/ppc32elf.em (ppc_after_open_output): Really enable
index c126297883876b068d6ef6d19e1a70bfb0227feb..56cd0aff6f6e32721cf73586244285931fbec662 100644 (file)
@@ -31,6 +31,16 @@ fragment <<EOF
 #include "elf64-ppc.h"
 #include "ldlex.h"
 
+static asection *ppc_add_stub_section (const char *, asection *);
+static void ppc_layout_sections_again (void);
+
+static struct ppc64_elf_params params = { NULL,
+                                         &ppc_add_stub_section,
+                                         &ppc_layout_sections_again,
+                                         1, 0, 0,
+                                         ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 0,
+                                         0, -1};
+
 /* Fake input file for stubs.  */
 static lang_input_statement_type *stub_file;
 static int stub_added = 0;
@@ -38,17 +48,11 @@ static int stub_added = 0;
 /* Whether we need to call ppc_layout_sections_again.  */
 static int need_laying_out = 0;
 
-/* Maximum size of a group of input sections that can be handled by
-   one stub section.  A value of +/-1 indicates the bfd back-end
-   should use a suitable default size.  */
-static bfd_signed_vma group_size = 1;
-
 /* Whether to add ".foo" entries for each "foo" in a version script.  */
 static int dotsyms = 1;
 
 /* Whether to run tls optimization.  */
 static int no_tls_opt = 0;
-static int no_tls_get_addr_opt = 0;
 
 /* Whether to run opd optimization.  */
 static int no_opd_opt = 0;
@@ -56,30 +60,14 @@ static int no_opd_opt = 0;
 /* Whether to run toc optimization.  */
 static int no_toc_opt = 0;
 
-/* Whether to allow multiple toc sections.  */
-static int no_multi_toc = 0;
-
 /* Whether to sort input toc and got sections.  */
 static int no_toc_sort = 0;
 
-/* Set if PLT call stubs should load r11.  */
-static int plt_static_chain = ${DEFAULT_PLT_STATIC_CHAIN-0};
-
-/* Set if PLT call stubs need to be thread safe on power7+.  */
-static int plt_thread_safe = -1;
-
 /* Set if individual PLT call stubs should be aligned.  */
 static int plt_stub_align = 0;
 
-/* Whether to emit symbols for stubs.  */
-static int emit_stub_syms = -1;
-
 static asection *toc_section = 0;
 
-/* Whether to canonicalize .opd so that there are no overlapping
-   .opd entries.  */
-static int non_overlapping_opd = 0;
-
 /* This is called before the input files are opened.  We create a new
    fake input file to hold the stub sections.  */
 
@@ -107,7 +95,8 @@ ppc_create_output_section_statements (void)
 
   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
-  if (!ppc64_elf_init_stub_bfd (stub_file->the_bfd, &link_info))
+  params.stub_bfd = stub_file->the_bfd;
+  if (!ppc64_elf_init_stub_bfd (&link_info, &params))
     einfo ("%F%P: can not init BFD: %E\n");
 }
 
@@ -256,10 +245,10 @@ ppc_before_allocation (void)
   if (stub_file != NULL)
     {
       if (!no_opd_opt
-         && !ppc64_elf_edit_opd (&link_info, non_overlapping_opd))
+         && !ppc64_elf_edit_opd (&link_info))
        einfo ("%X%P: can not edit %s: %E\n", "opd");
 
-      if (ppc64_elf_tls_setup (&link_info, no_tls_get_addr_opt, &no_multi_toc)
+      if (ppc64_elf_tls_setup (&link_info)
          && !no_tls_opt)
        {
          /* Size the sections.  This is premature, but we want to know the
@@ -480,16 +469,14 @@ gld${EMULATION_NAME}_after_allocation (void)
      stubs.  */
   if (stub_file != NULL && !link_info.relocatable)
     {
-      int ret = ppc64_elf_setup_section_lists (&link_info,
-                                              &ppc_add_stub_section,
-                                              &ppc_layout_sections_again);
+      int ret = ppc64_elf_setup_section_lists (&link_info);
       if (ret < 0)
        einfo ("%X%P: can not size stub section: %E\n");
       else if (ret > 0)
        {
          ppc64_elf_start_multitoc_partition (&link_info);
 
-         if (!no_multi_toc)
+         if (!params.no_multi_toc)
            {
              toc_section = bfd_get_section_by_name (link_info.output_bfd,
                                                     ".got");
@@ -498,7 +485,7 @@ gld${EMULATION_NAME}_after_allocation (void)
            }
 
          if (ppc64_elf_layout_multitoc (&link_info)
-             && !no_multi_toc
+             && !params.no_multi_toc
              && toc_section != NULL)
            lang_for_each_statement (build_toc_list);
 
@@ -510,9 +497,7 @@ gld${EMULATION_NAME}_after_allocation (void)
            einfo ("%P: .init/.fini fragments use differing TOC pointers\n");
 
          /* Call into the BFD backend to do the real work.  */
-         if (!ppc64_elf_size_stubs (&link_info, group_size,
-                                    plt_static_chain, plt_thread_safe,
-                                    plt_stub_align))
+         if (!ppc64_elf_size_stubs (&link_info))
            einfo ("%X%P: can not size stub section: %E\n");
        }
     }
@@ -542,10 +527,9 @@ gld${EMULATION_NAME}_finish (void)
       char *msg = NULL;
       char *line, *endline;
 
-      if (emit_stub_syms < 0)
-       emit_stub_syms = 1;
-      if (!ppc64_elf_build_stubs (emit_stub_syms, &link_info,
-                                 config.stats ? &msg : NULL))
+      if (params.emit_stub_syms < 0)
+       params.emit_stub_syms = 1;
+      if (!ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
        einfo ("%X%P: can not build stubs: %E\n");
 
       fflush (stdout);
@@ -766,26 +750,26 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
     case OPTION_STUBGROUP_SIZE:
       {
        const char *end;
-        group_size = bfd_scan_vma (optarg, &end, 0);
+        params.group_size = bfd_scan_vma (optarg, &end, 0);
         if (*end)
          einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
       }
       break;
 
     case OPTION_PLT_STATIC_CHAIN:
-      plt_static_chain = 1;
+      params.plt_static_chain = 1;
       break;
 
     case OPTION_NO_PLT_STATIC_CHAIN:
-      plt_static_chain = 0;
+      params.plt_static_chain = 0;
       break;
 
     case OPTION_PLT_THREAD_SAFE:
-      plt_thread_safe = 1;
+      params.plt_thread_safe = 1;
       break;
 
     case OPTION_NO_PLT_THREAD_SAFE:
-      plt_thread_safe = 0;
+      params.plt_thread_safe = 0;
       break;
 
     case OPTION_PLT_ALIGN:
@@ -806,11 +790,11 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
       break;
 
     case OPTION_STUBSYMS:
-      emit_stub_syms = 1;
+      params.emit_stub_syms = 1;
       break;
 
     case OPTION_NO_STUBSYMS:
-      emit_stub_syms = 0;
+      params.emit_stub_syms = 0;
       break;
 
     case OPTION_DOTSYMS:
@@ -826,7 +810,7 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
       break;
 
     case OPTION_NO_TLS_GET_ADDR_OPT:
-      no_tls_get_addr_opt = 1;
+      params.no_tls_get_addr_opt = 1;
       break;
 
     case OPTION_NO_OPD_OPT:
@@ -838,7 +822,7 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
       break;
 
     case OPTION_NO_MULTI_TOC:
-      no_multi_toc = 1;
+      params.no_multi_toc = 1;
       break;
 
     case OPTION_NO_TOC_SORT:
@@ -846,17 +830,17 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
       break;
 
     case OPTION_NON_OVERLAPPING_OPD:
-      non_overlapping_opd = 1;
+      params.non_overlapping_opd = 1;
       break;
 
     case OPTION_TRADITIONAL_FORMAT:
       no_tls_opt = 1;
-      no_tls_get_addr_opt = 1;
+      params.no_tls_get_addr_opt = 1;
       no_opd_opt = 1;
       no_toc_opt = 1;
-      no_multi_toc = 1;
+      params.no_multi_toc = 1;
       no_toc_sort = 1;
-      plt_static_chain = 1;
+      params.plt_static_chain = 1;
       return FALSE;
 '