* 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>
* 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
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;

View 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 *);

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>
* ld.h (args_type, ld_config_type): Reorder fields.

View 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:

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
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