* 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.
This commit is contained in:
Alan Modra
2007-05-11 06:39:05 +00:00
parent ece5ef6079
commit 016687f8ba
6 changed files with 126 additions and 39 deletions

View 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> 2007-05-11 Alan Modra <amodra@bigpond.net.au>
* reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define. * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.

View File

@ -1712,6 +1712,10 @@ struct ppc_elf_obj_tdata
/* A mapping from local symbols to offsets into the various linker /* A mapping from local symbols to offsets into the various linker
sections added. This is index by the symbol index. */ sections added. This is index by the symbol index. */
elf_linker_section_pointers_t **linker_section_pointers; 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) \ #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)) #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. */ /* PPC ELF linker hash table. */
struct ppc_elf_link_hash_table struct ppc_elf_link_hash_table
@ -2407,9 +2404,18 @@ struct ppc_elf_link_hash_table
elf_linker_section_t sdata[2]; elf_linker_section_t sdata[2];
asection *sbss; 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. */ /* Shortcut to .__tls_get_addr. */
struct elf_link_hash_entry *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. */ /* TLS local dynamic got entry handling. */
union { union {
bfd_signed_vma refcount; bfd_signed_vma refcount;
@ -2427,23 +2433,11 @@ struct ppc_elf_link_hash_table
/* The type of PLT we have chosen to use. */ /* The type of PLT we have chosen to use. */
enum ppc_elf_plt_type plt_type; 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. */ /* Set if we should emit symbols for stubs. */
unsigned int emit_stub_syms:1; 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. */ /* True if the target system is VxWorks. */
int is_vxworks; unsigned int is_vxworks:1;
/* The size of PLT entries. */ /* The size of PLT entries. */
int plt_entry_size; int plt_entry_size;
@ -2451,6 +2445,9 @@ struct ppc_elf_link_hash_table
int plt_slot_size; int plt_slot_size;
/* The size of the first PLT entry. */ /* The size of the first PLT entry. */
int plt_initial_entry_size; 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. */ /* 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_entry_size = 12;
ret->plt_slot_size = 8; ret->plt_slot_size = 8;
ret->plt_initial_entry_size = 72; ret->plt_initial_entry_size = 72;
ret->is_vxworks = 0;
return &ret->elf.root; return &ret->elf.root;
} }
@ -3293,8 +3288,13 @@ ppc_elf_check_relocs (bfd *abfd,
} }
else 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; h->needs_plt = 1;
if (!update_plt_info (abfd, h, got2, addend)) if (!update_plt_info (abfd, h, got2, addend))
return FALSE; return FALSE;
@ -3319,7 +3319,7 @@ ppc_elf_check_relocs (bfd *abfd,
case R_PPC_REL16_LO: case R_PPC_REL16_LO:
case R_PPC_REL16_HI: case R_PPC_REL16_HI:
case R_PPC_REL16_HA: case R_PPC_REL16_HA:
htab->can_use_new_plt = 1; ppc_elf_tdata (abfd)->has_rel16 = 1;
break; break;
/* These are just markers. */ /* These are just markers. */
@ -3348,7 +3348,10 @@ ppc_elf_check_relocs (bfd *abfd,
/* This refers only to functions defined in the shared library. */ /* This refers only to functions defined in the shared library. */
case R_PPC_LOCAL24PC: case R_PPC_LOCAL24PC:
if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET) 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; break;
/* This relocation describes the C++ object vtable hierarchy. /* 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, s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
r_symndx); r_symndx);
if (s == got2) if (s == got2)
htab->plt_type = PLT_OLD; {
htab->plt_type = PLT_OLD;
htab->old_bfd = abfd;
}
} }
if (h == NULL || h == htab->elf.hgot) if (h == NULL || h == htab->elf.hgot)
break; break;
@ -3417,7 +3423,10 @@ ppc_elf_check_relocs (bfd *abfd,
if (h == htab->elf.hgot) if (h == htab->elf.hgot)
{ {
if (htab->plt_type == PLT_UNSET) if (htab->plt_type == PLT_UNSET)
htab->plt_type = PLT_OLD; {
htab->plt_type = PLT_OLD;
htab->old_bfd = abfd;
}
break; break;
} }
/* fall through */ /* fall through */
@ -3671,7 +3680,7 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
int int
ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED, ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info, struct bfd_link_info *info,
int force_old_plt, enum ppc_elf_plt_type plt_style,
int emit_stub_syms) int emit_stub_syms)
{ {
struct ppc_elf_link_hash_table *htab; 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); htab = ppc_elf_hash_table (info);
if (htab->plt_type == PLT_UNSET) 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; htab->emit_stub_syms = emit_stub_syms;

View File

@ -1,5 +1,5 @@
/* PowerPC-specific support for 64-bit ELF. /* 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. 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 along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 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 *); asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
bfd_boolean ppc_elf_tls_optimize (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 *); void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);

View 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> 2007-05-08 Alan Modra <amodra@bigpond.net.au>
* ld.h (args_type, ld_config_type): Reorder fields. * ld.h (args_type, ld_config_type): Reorder fields.

View File

@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*- # 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. # This file is part of GLD, the Gnu Linker.
# #
@ -45,7 +45,7 @@ static int notlsopt = 0;
static int emit_stub_syms = 0; static int emit_stub_syms = 0;
/* Chooses the correct place for .plt and .got. */ /* 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 int old_got = 0;
static void static void
@ -62,7 +62,7 @@ ppc_after_open (void)
lang_output_section_statement_type *got_os[2]; lang_output_section_statement_type *got_os[2];
emit_stub_syms |= link_info.emitrelocations; 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); emit_stub_syms);
if (new_plt < 0) if (new_plt < 0)
einfo ("%X%P: select_plt_layout problem %E\n"); einfo ("%X%P: select_plt_layout problem %E\n");
@ -148,14 +148,16 @@ fi
# #
PARSE_AND_LIST_PROLOGUE=' PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_TLS_OPT 301 #define OPTION_NO_TLS_OPT 301
#define OPTION_OLD_PLT 302 #define OPTION_NEW_PLT 302
#define OPTION_OLD_GOT 303 #define OPTION_OLD_PLT 303
#define OPTION_STUBSYMS 304 #define OPTION_OLD_GOT 304
#define OPTION_STUBSYMS 305
' '
PARSE_AND_LIST_LONGOPTS=' PARSE_AND_LIST_LONGOPTS='
{ "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS }, { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT }, { "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 }, { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT }, { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
' '
@ -164,6 +166,7 @@ PARSE_AND_LIST_OPTIONS='
fprintf (file, _("\ fprintf (file, _("\
--emit-stub-syms Label linker stubs with a symbol.\n\ --emit-stub-syms Label linker stubs with a symbol.\n\
--no-tls-optimize Don'\''t try to optimize TLS accesses.\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\ --bss-plt Force old-style BSS PLT.\n\
--sdata-got Force GOT location just before .sdata.\n" --sdata-got Force GOT location just before .sdata.\n"
)); ));
@ -178,8 +181,12 @@ PARSE_AND_LIST_ARGS_CASES='
notlsopt = 1; notlsopt = 1;
break; break;
case OPTION_NEW_PLT:
plt_style = PLT_NEW;
break;
case OPTION_OLD_PLT: case OPTION_OLD_PLT:
old_plt = 1; plt_style = PLT_OLD;
break; break;
case OPTION_OLD_GOT: case OPTION_OLD_GOT:

View 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 compiled with @samp{-msecure-plt}. @samp{--bss-plt} forces the old
BSS PLT (and GOT layout) which can give slightly better performance. 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 @cindex PowerPC GOT
@kindex --sdata-got @kindex --sdata-got
@item --sdata-got @item --sdata-got