From 016687f8ba456b033639a2174da7a0fc35428eb8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 11 May 2007 06:39:05 +0000 Subject: [PATCH] bfd/ * 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 | 15 ++++++ bfd/elf32-ppc.c | 98 ++++++++++++++++++++++++++++------------ bfd/elf32-ppc.h | 12 ++++- ld/ChangeLog | 11 +++++ ld/emultempl/ppc32elf.em | 21 ++++++--- ld/ld.texinfo | 8 ++++ 6 files changed, 126 insertions(+), 39 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 71e7ef7f69..01234ca139 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2007-05-11 Alan Modra + + * 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 * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define. diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 43b3aab870..2f394d9213 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -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; diff --git a/bfd/elf32-ppc.h b/bfd/elf32-ppc.h index 5f8f63a38a..f5383a7bb5 100644 --- a/bfd/elf32-ppc.h +++ b/bfd/elf32-ppc.h @@ -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 *); diff --git a/ld/ChangeLog b/ld/ChangeLog index 3a7e751d8a..6951481612 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2007-05-11 Alan Modra + + * 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 * ld.h (args_type, ld_config_type): Reorder fields. diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index cee14c0c53..b0239e0b76 100644 --- a/ld/emultempl/ppc32elf.em +++ b/ld/emultempl/ppc32elf.em @@ -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: diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 788c515efc..700662eaa3 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -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 -- 2.34.1