bfd/
authorAlan Modra <amodra@gmail.com>
Fri, 11 May 2007 06:39:05 +0000 (06:39 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 11 May 2007 06:39:05 +0000 (06:39 +0000)
* elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
(enum ppc_elf_plt_type): Move from..
* elf32-ppc.c: ..here.
(struct ppc_elf_obj_tdata): Add makes_plt_call and has_rel16.
(struct ppc_elf_link_hash_table): Reorder.  Add old_bfd.  Delete
can_use_new_plt.  Make is_vxworks a bitfield.
(ppc_elf_link_hash_table_create): Don't clear is_vxworks (again).
(ppc_elf_check_relocs): Update setting of reloc flags.  Set old_bfd.
(ppc_elf_select_plt_layout): Modify parameters.  Use bfd reloc
flags to better detect object files needing old bss-style plt.
Allow secure plt to be used without rel16 relocs being detected.
Warn if secure plt request cannot be allowed.
ld/
* emultempl/ppc32elf.em (plt_style): New variable.
(old_plt): Delete.
(ppc_after_open): Adjust ppc_elf_select_plt_layout call.
(PARSE_AND_LIST_PROLOGUE): Define OPTION_NEW_PLT, renumber
OPTION_OLD_PLT, OPTION_OLD_GOT and OPTION_STUBSYMS.
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add secure-plt.
(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_NEW_PLT.
* ld.texinfo (--secure-plt): Document.

bfd/ChangeLog
bfd/elf32-ppc.c
bfd/elf32-ppc.h
ld/ChangeLog
ld/emultempl/ppc32elf.em
ld/ld.texinfo

index 71e7ef7f692b2feab46c27d14ff3273f59f3970e..01234ca139c23d0dc3614122f2dd04c3235dd699 100644 (file)
@@ -1,3 +1,18 @@
+2007-05-11  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
+       (enum ppc_elf_plt_type): Move from..
+       * elf32-ppc.c: ..here.
+       (struct ppc_elf_obj_tdata): Add makes_plt_call and has_rel16.
+       (struct ppc_elf_link_hash_table): Reorder.  Add old_bfd.  Delete
+       can_use_new_plt.  Make is_vxworks a bitfield.
+       (ppc_elf_link_hash_table_create): Don't clear is_vxworks (again).
+       (ppc_elf_check_relocs): Update setting of reloc flags.  Set old_bfd.
+       (ppc_elf_select_plt_layout): Modify parameters.  Use bfd reloc
+       flags to better detect object files needing old bss-style plt.
+       Allow secure plt to be used without rel16 relocs being detected.
+       Warn if secure plt request cannot be allowed.
+
 2007-05-11  Alan Modra  <amodra@bigpond.net.au>
 
        * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.
index 43b3aab87071429b71ad2bb0f6f3d7561e36766c..2f394d92136c39b78363a8401182cff4cde5fae2 100644 (file)
@@ -1712,6 +1712,10 @@ struct ppc_elf_obj_tdata
   /* A mapping from local symbols to offsets into the various linker
      sections added.  This is index by the symbol index.  */
   elf_linker_section_pointers_t **linker_section_pointers;
+
+  /* Flags used to auto-detect plt type.  */
+  unsigned int makes_plt_call : 1;
+  unsigned int has_rel16 : 1;
 };
 
 #define ppc_elf_tdata(bfd) \
@@ -2381,13 +2385,6 @@ struct ppc_elf_link_hash_entry
 
 #define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
 
-enum ppc_elf_plt_type {
-  PLT_UNSET,
-  PLT_OLD,
-  PLT_NEW,
-  PLT_VXWORKS
-};
-
 /* PPC ELF linker hash table.  */
 
 struct ppc_elf_link_hash_table
@@ -2407,9 +2404,18 @@ struct ppc_elf_link_hash_table
   elf_linker_section_t sdata[2];
   asection *sbss;
 
+  /* The (unloaded but important) .rela.plt.unloaded on VxWorks.  */
+  asection *srelplt2;
+
+  /* The .got.plt section (VxWorks only)*/
+  asection *sgotplt;
+
   /* Shortcut to .__tls_get_addr.  */
   struct elf_link_hash_entry *tls_get_addr;
 
+  /* The bfd that forced an old-style PLT.  */
+  bfd *old_bfd;
   /* TLS local dynamic got entry handling.  */
   union {
     bfd_signed_vma refcount;
@@ -2427,23 +2433,11 @@ struct ppc_elf_link_hash_table
   /* The type of PLT we have chosen to use.  */
   enum ppc_elf_plt_type plt_type;
 
-  /* Whether we can use the new PLT layout.  */
-  unsigned int can_use_new_plt:1;
-
   /* Set if we should emit symbols for stubs.  */
   unsigned int emit_stub_syms:1;
 
-  /* Small local sym to section mapping cache.  */
-  struct sym_sec_cache sym_sec;
-
-  /* The (unloaded but important) .rela.plt.unloaded on VxWorks.  */
-  asection *srelplt2;
-
-  /* The .got.plt section (VxWorks only)*/
-  asection *sgotplt;
-
   /* True if the target system is VxWorks.  */
-  int is_vxworks;
+  unsigned int is_vxworks:1;
 
   /* The size of PLT entries.  */
   int plt_entry_size;
@@ -2451,6 +2445,9 @@ struct ppc_elf_link_hash_table
   int plt_slot_size;
   /* The size of the first PLT entry.  */
   int plt_initial_entry_size;
+
+  /* Small local sym to section mapping cache.  */
+  struct sym_sec_cache sym_sec;
 };
 
 /* Get the PPC ELF linker hash table from a link_info structure.  */
@@ -2522,8 +2519,6 @@ ppc_elf_link_hash_table_create (bfd *abfd)
   ret->plt_entry_size = 12;
   ret->plt_slot_size = 8;
   ret->plt_initial_entry_size = 72;
-  
-  ret->is_vxworks = 0;
 
   return &ret->elf.root;
 }
@@ -3293,8 +3288,13 @@ ppc_elf_check_relocs (bfd *abfd,
            }
          else
            {
-             bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
+             bfd_vma addend = 0;
 
+             if (r_type == R_PPC_PLTREL24)
+               {
+                 ppc_elf_tdata (abfd)->makes_plt_call = 1;
+                 addend = rel->r_addend;
+               }
              h->needs_plt = 1;
              if (!update_plt_info (abfd, h, got2, addend))
                return FALSE;
@@ -3319,7 +3319,7 @@ ppc_elf_check_relocs (bfd *abfd,
        case R_PPC_REL16_LO:
        case R_PPC_REL16_HI:
        case R_PPC_REL16_HA:
-         htab->can_use_new_plt = 1;
+         ppc_elf_tdata (abfd)->has_rel16 = 1;
          break;
 
          /* These are just markers.  */
@@ -3348,7 +3348,10 @@ ppc_elf_check_relocs (bfd *abfd,
          /* This refers only to functions defined in the shared library.  */
        case R_PPC_LOCAL24PC:
          if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
-           htab->plt_type = PLT_OLD;
+           {
+             htab->plt_type = PLT_OLD;
+             htab->old_bfd = abfd;
+           }
          break;
 
          /* This relocation describes the C++ object vtable hierarchy.
@@ -3402,7 +3405,10 @@ ppc_elf_check_relocs (bfd *abfd,
              s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
                                             r_symndx);
              if (s == got2)
-               htab->plt_type = PLT_OLD;
+               {
+                 htab->plt_type = PLT_OLD;
+                 htab->old_bfd = abfd;
+               }
            }
          if (h == NULL || h == htab->elf.hgot)
            break;
@@ -3417,7 +3423,10 @@ ppc_elf_check_relocs (bfd *abfd,
          if (h == htab->elf.hgot)
            {
              if (htab->plt_type == PLT_UNSET)
-               htab->plt_type = PLT_OLD;
+               {
+                 htab->plt_type = PLT_OLD;
+                 htab->old_bfd = abfd;
+               }
              break;
            }
          /* fall through */
@@ -3671,7 +3680,7 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 int
 ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
                           struct bfd_link_info *info,
-                          int force_old_plt,
+                          enum ppc_elf_plt_type plt_style,
                           int emit_stub_syms)
 {
   struct ppc_elf_link_hash_table *htab;
@@ -3680,8 +3689,37 @@ ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
   htab = ppc_elf_hash_table (info);
 
   if (htab->plt_type == PLT_UNSET)
-    htab->plt_type = (force_old_plt || !htab->can_use_new_plt
-                     ? PLT_OLD : PLT_NEW);
+    {
+      if (plt_style == PLT_OLD)
+       htab->plt_type = PLT_OLD;
+      else
+       {
+         bfd *ibfd;
+         enum ppc_elf_plt_type plt_type = plt_style;
+
+         /* Look through the reloc flags left by ppc_elf_check_relocs.
+            Use the old style bss plt if a file makes plt calls
+            without using the new relocs, and if ld isn't given
+            --secure-plt and we never see REL16 relocs.  */
+         if (plt_type == PLT_UNSET)
+           plt_type = PLT_OLD;
+         for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->next)
+           if (is_ppc_elf_target (ibfd->xvec))
+             {
+               if (ppc_elf_tdata (ibfd)->has_rel16)
+                 plt_type = PLT_NEW;
+               else if (ppc_elf_tdata (ibfd)->makes_plt_call)
+                 {
+                   plt_type = PLT_OLD;
+                   htab->old_bfd = ibfd;
+                   break;
+                 }
+             }
+         htab->plt_type = plt_type;
+       }
+    }
+  if (htab->plt_type == PLT_OLD && plt_style == PLT_NEW)
+    info->callbacks->info (_("Using bss-plt due to %B"), htab->old_bfd);
 
   htab->emit_stub_syms = emit_stub_syms;
 
index 5f8f63a38a59605b29c53110add822b7d210023e..f5383a7bb5875598166fe3c44dec3d86e56e2a20 100644 (file)
@@ -1,5 +1,5 @@
 /* PowerPC-specific support for 64-bit ELF.
-   Copyright 2003, 2005 Free Software Foundation, Inc.
+   Copyright 2003, 2005, 2007 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -17,7 +17,15 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, int, int);
+enum ppc_elf_plt_type {
+  PLT_UNSET,
+  PLT_OLD,
+  PLT_NEW,
+  PLT_VXWORKS
+};
+
+int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *,
+                              enum ppc_elf_plt_type, int);
 asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
 bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
 void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);
index 3a7e751d8a8dc7d6f56158677b68cc05aeb16917..6951481612ffa6b9874c552ae70e0c3efe68602b 100644 (file)
@@ -1,3 +1,14 @@
+2007-05-11  Alan Modra  <amodra@bigpond.net.au>
+
+       * emultempl/ppc32elf.em (plt_style): New variable.
+       (old_plt): Delete.
+       (ppc_after_open): Adjust ppc_elf_select_plt_layout call.
+       (PARSE_AND_LIST_PROLOGUE): Define OPTION_NEW_PLT, renumber
+       OPTION_OLD_PLT, OPTION_OLD_GOT and OPTION_STUBSYMS.
+       (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add secure-plt.
+       (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_NEW_PLT.
+       * ld.texinfo (--secure-plt): Document.
+
 2007-05-08  Alan Modra  <amodra@bigpond.net.au>
 
        * ld.h (args_type, ld_config_type): Reorder fields.
index cee14c0c53d1bf27f154b949c2f2b9355d81502c..b0239e0b76a5eb8e02ed54dabab385191cd1f4a5 100644 (file)
@@ -1,5 +1,5 @@
 # This shell script emits a C file. -*- C -*-
-#   Copyright 2003, 2005 Free Software Foundation, Inc.
+#   Copyright 2003, 2005, 2007 Free Software Foundation, Inc.
 #
 # This file is part of GLD, the Gnu Linker.
 #
@@ -45,7 +45,7 @@ static int notlsopt = 0;
 static int emit_stub_syms = 0;
 
 /* Chooses the correct place for .plt and .got.  */
-static int old_plt = 0;
+static enum ppc_elf_plt_type plt_style = PLT_UNSET;
 static int old_got = 0;
 
 static void
@@ -62,7 +62,7 @@ ppc_after_open (void)
       lang_output_section_statement_type *got_os[2];
 
       emit_stub_syms |= link_info.emitrelocations;
-      new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt,
+      new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, plt_style,
                                           emit_stub_syms);
       if (new_plt < 0)
        einfo ("%X%P: select_plt_layout problem %E\n");
@@ -148,14 +148,16 @@ fi
 #
 PARSE_AND_LIST_PROLOGUE='
 #define OPTION_NO_TLS_OPT              301
-#define OPTION_OLD_PLT                 302
-#define OPTION_OLD_GOT                 303
-#define OPTION_STUBSYMS                        304
+#define OPTION_NEW_PLT                 302
+#define OPTION_OLD_PLT                 303
+#define OPTION_OLD_GOT                 304
+#define OPTION_STUBSYMS                        305
 '
 
 PARSE_AND_LIST_LONGOPTS='
   { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+  { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
   { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
   { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
 '
@@ -164,6 +166,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("\
   --emit-stub-syms      Label linker stubs with a symbol.\n\
   --no-tls-optimize     Don'\''t try to optimize TLS accesses.\n\
+  --secure-plt          Use new-style PLT if possible.\n\
   --bss-plt             Force old-style BSS PLT.\n\
   --sdata-got           Force GOT location just before .sdata.\n"
                   ));
@@ -178,8 +181,12 @@ PARSE_AND_LIST_ARGS_CASES='
       notlsopt = 1;
       break;
 
+    case OPTION_NEW_PLT:
+      plt_style = PLT_NEW;
+      break;
+
     case OPTION_OLD_PLT:
-      old_plt = 1;
+      plt_style = PLT_OLD;
       break;
 
     case OPTION_OLD_GOT:
index 788c515efcf7650365e801c1bc5765fd082c1d8a..700662eaa3a456dad5f280c65e4e982952c80512 100644 (file)
@@ -5699,6 +5699,14 @@ PLT, if all input files (including startup and static libraries) were
 compiled with @samp{-msecure-plt}.  @samp{--bss-plt} forces the old
 BSS PLT (and GOT layout) which can give slightly better performance.
 
+@kindex --secure-plt
+@item --secure-plt
+@command{ld} will use the new PLT and GOT layout if it is linking new
+@samp{-fpic} or @samp{-fPIC} code, but does not do so automatically
+when linking non-PIC code.  This option requests the new PLT and GOT
+layout.  A warning will be given if some object file requires the old
+style BSS PLT.
+
 @cindex PowerPC GOT
 @kindex --sdata-got
 @item --sdata-got