PowerPC PLT stub tidy

This is in preparation for the next patch adding Spectre variant 2
mitigation for PowerPC and PowerPC64.  Besides tidying code involved
in stub output (to reduce the number of places where bctr is output),
the patch adds some user visible features:

1) PowerPC64 ELFv2 global entry stubs now are aligned under the
   control of --plt-align, with a default alignment of 32 bytes.
2) PowerPC64 __glink_PLTresolve is no longer padded out with nops.
3) PowerPC32 PLT stubs are aligned under the control of --plt-align,
   with the default alignment being 16 bytes as before.
4) The PowerPC32 branch/nop table emitted before __glink_PLTresolve
   is now smaller in many cases.  It was sized incorrectly when the
   __tls_get_addr_opt stub was used, and unnecessarily included space
   for local ifuncs.

bfd/
	* elf32-ppc.c (GLINK_ENTRY_SIZE): Add parameters, handle
	__tls_get_addr_opt, and alignment sizing.
	(TLS_GET_ADDR_GLINK_SIZE): Delete.
	(is_nonpic_glink_stub): Don't use GLINK_ENTRY_SIZE.
	(ppc_elf_get_synthetic_symtab): Recognize stubs spaced at 4, 6,
	or 8 insns.
	(ppc_elf_link_hash_table_create): Init new ppc_elf_params field.
	(allocate_dynrelocs): Use new GLINK_ENTRY_SIZE.
	(ppc_elf_size_dynamic_sections): Likewise.  Size branch table
	by PLT reloc count.
	(write_glink_stub): Handle __tls_get_addr_opt stub.
	Pad out to size given by GLINK_ENTRY_SIZE.
	(ppc_elf_relocate_section): Adjust write_glink_stub call.
	(ppc_elf_finish_dynamic_symbol): Likewise.
	(ppc_elf_finish_dynamic_sections): Write PLTresolve without using
	insn array since so many need rewriting.
	* elf32-ppc.h (struct ppc_elf_params): Add plt_stub_align.
	* elf64-ppc.c (GLINK_PLTRESOLVE_SIZE): Rename from
	GLINK_CALL_STUB_SIZE.  Add htab param and evaluate to size without
	nops.  Adjust all uses.
	(ppc64_elf_get_synthetic_symtab): Don't use GLINK_CALL_STUB_SIZE
	in glink_vma calculation.
	(struct ppc_link_hash_table): Add global_entry section pointer.
	(create_linkage_sections): Create separate section for global
	entry stubs.
	(PPC_LO, PPC_HI, PPC_HA): Move earlier.
	(size_global_entry_stubs): Handle sizing for aligned stubs.
	(ppc64_elf_size_dynamic_sections): Handle global_entry alloc,
	and don't stash end of glink branch table in rawsize.
	(ppc_build_one_stub): Rewrite stub size calculations.
	(build_global_entry_stubs): Use new section.
	(ppc64_elf_build_stubs): Don't pad __glink_PLTresolve with nops.
	Build lazy link stubs out to end of section.  Build global entry
	stubs in new section.
gold/
	* options.h (plt_align): Support for PowerPC32 too.
	* powerpc.cc (Stub_table::stub_align): Heed --plt-align for 32-bit.
	(Stub_table::plt_call_size, branch_stub_size): Tidy.
	(Stub_table::plt_call_align): Implement using stub_align.
	(Output_data_glink::global_entry_align): New function.
	(Output_data_glink::global_entry_off): New function.
	(Output_data_glink::global_entry_address): Use global_entry_off.
	(Output_data_glink::pltresolve_size): New function, replacing
	pltresolve_size_ constant.  Update all uses.
	(Output_data_glink::add_global_entry): Align offset.
	(Output_data_glink::set_final_data_size): Use global_entry_align.
	(Stub_table::do_write): Don't pad __glink_PLTrelsolve with nops.
	Tidy stub output.  Use global_entry_off.
ld/
	* emultempl/ppc32elf.em (params): Init new field.
	(enum ppc32_opt): New enum to define OPTION_* values.  Add
	OPTION_PLT_ALIGN and OPTION_NO_PLT_ALIGN.
	(PARSE_AND_LIST_LONGOPTS): Handle new options.
	(PARSE_AND_LIST_ARGS_CASES): Likewise.
	(PARSE_AND_LIST_OPTIONS): Likewise.  Break up help output.
	* emultempl/ppc64elf.em (ppc_add_stub_section): Init alignment
	correctly for negative --plt-stub-align.
	* testsuite/ld-powerpc/elfv2exe.d,
	* testsuite/ld-powerpc/elfv2so.d,
	* testsuite/ld-powerpc/relbrlt.d,
	* testsuite/ld-powerpc/relbrlt.s,
	* testsuite/ld-powerpc/tlsexe.d,
	* testsuite/ld-powerpc/tlsexe.r,
	* testsuite/ld-powerpc/tlsexe32.d,
	* testsuite/ld-powerpc/tlsexe32.g,
	* testsuite/ld-powerpc/tlsexe32.r,
	* testsuite/ld-powerpc/tlsexetoc.d,
	* testsuite/ld-powerpc/tlsexetoc.r,
	* testsuite/ld-powerpc/tlsopt5_32.d,
	* testsuite/ld-powerpc/tlsso.d,
	* testsuite/ld-powerpc/tlstocso.d: Update for changed stub order.
This commit is contained in:
Alan Modra 2018-01-13 18:53:41 +10:30
parent 78742b93a5
commit 9e390558ce
24 changed files with 557 additions and 435 deletions

View File

@ -1,3 +1,40 @@
2018-01-17 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (GLINK_ENTRY_SIZE): Add parameters, handle
__tls_get_addr_opt, and alignment sizing.
(TLS_GET_ADDR_GLINK_SIZE): Delete.
(is_nonpic_glink_stub): Don't use GLINK_ENTRY_SIZE.
(ppc_elf_get_synthetic_symtab): Recognize stubs spaced at 4, 6,
or 8 insns.
(ppc_elf_link_hash_table_create): Init new ppc_elf_params field.
(allocate_dynrelocs): Use new GLINK_ENTRY_SIZE.
(ppc_elf_size_dynamic_sections): Likewise. Size branch table
by PLT reloc count.
(write_glink_stub): Handle __tls_get_addr_opt stub.
Pad out to size given by GLINK_ENTRY_SIZE.
(ppc_elf_relocate_section): Adjust write_glink_stub call.
(ppc_elf_finish_dynamic_symbol): Likewise.
(ppc_elf_finish_dynamic_sections): Write PLTresolve without using
insn array since so many need rewriting.
* elf32-ppc.h (struct ppc_elf_params): Add plt_stub_align.
* elf64-ppc.c (GLINK_PLTRESOLVE_SIZE): Rename from
GLINK_CALL_STUB_SIZE. Add htab param and evaluate to size without
nops. Adjust all uses.
(ppc64_elf_get_synthetic_symtab): Don't use GLINK_CALL_STUB_SIZE
in glink_vma calculation.
(struct ppc_link_hash_table): Add global_entry section pointer.
(create_linkage_sections): Create separate section for global
entry stubs.
(PPC_LO, PPC_HI, PPC_HA): Move earlier.
(size_global_entry_stubs): Handle sizing for aligned stubs.
(ppc64_elf_size_dynamic_sections): Handle global_entry alloc,
and don't stash end of glink branch table in rawsize.
(ppc_build_one_stub): Rewrite stub size calculations.
(build_global_entry_stubs): Use new section.
(ppc64_elf_build_stubs): Don't pad __glink_PLTresolve with nops.
Build lazy link stubs out to end of section. Build global entry
stubs in new section.
2018-01-15 Nick Clifton <nickc@redhat.com> 2018-01-15 Nick Clifton <nickc@redhat.com>
* po/uk.po: Updated Ukranian translation. * po/uk.po: Updated Ukranian translation.

View File

@ -68,8 +68,13 @@ static bfd_reloc_status_type ppc_elf_unhandled_reloc
/* For new-style .glink and .plt. */ /* For new-style .glink and .plt. */
#define GLINK_PLTRESOLVE 16*4 #define GLINK_PLTRESOLVE 16*4
#define GLINK_ENTRY_SIZE 4*4 #define GLINK_ENTRY_SIZE(htab, h) \
#define TLS_GET_ADDR_GLINK_SIZE 12*4 ((4*4 \
+ (h != NULL \
&& h == htab->tls_get_addr \
&& !htab->params->no_tls_get_addr_opt ? 8*4 : 0) \
+ (1u << htab->params->plt_stub_align) - 1) \
& -(1u << htab->params->plt_stub_align))
/* VxWorks uses its own plt layout, filled in by the static linker. */ /* VxWorks uses its own plt layout, filled in by the static linker. */
@ -2873,9 +2878,9 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
static bfd_boolean static bfd_boolean
is_nonpic_glink_stub (bfd *abfd, asection *glink, bfd_vma off) is_nonpic_glink_stub (bfd *abfd, asection *glink, bfd_vma off)
{ {
bfd_byte buf[GLINK_ENTRY_SIZE]; bfd_byte buf[4 * 4];
if (!bfd_get_section_contents (abfd, glink, buf, off, GLINK_ENTRY_SIZE)) if (!bfd_get_section_contents (abfd, glink, buf, off, sizeof buf))
return FALSE; return FALSE;
return ((bfd_get_32 (abfd, buf + 0) & 0xffff0000) == LIS_11 return ((bfd_get_32 (abfd, buf + 0) & 0xffff0000) == LIS_11
@ -2902,10 +2907,10 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
asection *plt, *relplt, *dynamic, *glink; asection *plt, *relplt, *dynamic, *glink;
bfd_vma glink_vma = 0; bfd_vma glink_vma = 0;
bfd_vma resolv_vma = 0; bfd_vma resolv_vma = 0;
bfd_vma stub_vma; bfd_vma stub_off;
asymbol *s; asymbol *s;
arelent *p; arelent *p;
long count, i; long count, i, stub_delta;
size_t size; size_t size;
char *names; char *names;
bfd_byte buf[4]; bfd_byte buf[4];
@ -3016,9 +3021,14 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
/* If the stubs are those for -shared/-pie then we might have /* If the stubs are those for -shared/-pie then we might have
multiple stubs for each plt entry. If that is the case then multiple stubs for each plt entry. If that is the case then
there is no way to associate stubs with their plt entries short there is no way to associate stubs with their plt entries short
of figuring out the GOT pointer value used in the stub. */ of figuring out the GOT pointer value used in the stub.
if (!is_nonpic_glink_stub (abfd, glink, The offsets tested here need to cover all possible values of
glink_vma - GLINK_ENTRY_SIZE - glink->vma)) GLINK_ENTRY_SIZE for other than __tls_get_addr_opt. */
stub_off = glink_vma - glink->vma;
for (stub_delta = 16; stub_delta <= 32; stub_delta += 8)
if (is_nonpic_glink_stub (abfd, glink, stub_off - stub_delta))
break;
if (stub_delta > 32)
return 0; return 0;
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
@ -3043,13 +3053,16 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
if (s == NULL) if (s == NULL)
return -1; return -1;
stub_vma = glink_vma; stub_off = glink_vma - glink->vma;
names = (char *) (s + count + 1 + (resolv_vma != 0)); names = (char *) (s + count + 1 + (resolv_vma != 0));
p = relplt->relocation + count - 1; p = relplt->relocation + count - 1;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
size_t len; size_t len;
stub_off -= stub_delta;
if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
stub_off -= 32;
*s = **p->sym_ptr_ptr; *s = **p->sym_ptr_ptr;
/* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
we are defining a symbol, ensure one of them is set. */ we are defining a symbol, ensure one of them is set. */
@ -3057,10 +3070,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
s->flags |= BSF_GLOBAL; s->flags |= BSF_GLOBAL;
s->flags |= BSF_SYNTHETIC; s->flags |= BSF_SYNTHETIC;
s->section = glink; s->section = glink;
stub_vma -= 16; s->value = stub_off;
if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
stub_vma -= 32;
s->value = stub_vma - glink->vma;
s->name = names; s->name = names;
s->udata.p = NULL; s->udata.p = NULL;
len = strlen ((*p->sym_ptr_ptr)->name); len = strlen ((*p->sym_ptr_ptr)->name);
@ -3355,7 +3365,7 @@ ppc_elf_link_hash_table_create (bfd *abfd)
{ {
struct ppc_elf_link_hash_table *ret; struct ppc_elf_link_hash_table *ret;
static struct ppc_elf_params default_params static struct ppc_elf_params default_params
= { PLT_OLD, 0, 1, 0, 0, 12, 0, 0, 0 }; = { PLT_OLD, 0, 0, 1, 0, 0, 12, 0, 0, 0 };
ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table)); ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
if (ret == NULL) if (ret == NULL)
@ -6015,10 +6025,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (!doneone || bfd_link_pic (info)) if (!doneone || bfd_link_pic (info))
{ {
glink_offset = s->size; glink_offset = s->size;
s->size += GLINK_ENTRY_SIZE; s->size += GLINK_ENTRY_SIZE (htab, h);
if (h == htab->tls_get_addr
&& !htab->params->no_tls_get_addr_opt)
s->size += TLS_GET_ADDR_GLINK_SIZE - GLINK_ENTRY_SIZE;
} }
if (!doneone if (!doneone
&& !bfd_link_pic (info) && !bfd_link_pic (info)
@ -6333,7 +6340,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
if (!doneone || bfd_link_pic (info)) if (!doneone || bfd_link_pic (info))
{ {
glink_offset = s->size; glink_offset = s->size;
s->size += GLINK_ENTRY_SIZE; s->size += GLINK_ENTRY_SIZE (htab, NULL);
} }
ent->glink_offset = glink_offset; ent->glink_offset = glink_offset;
@ -6401,10 +6408,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
&& htab->elf.dynamic_sections_created) && htab->elf.dynamic_sections_created)
{ {
htab->glink_pltresolve = htab->glink->size; htab->glink_pltresolve = htab->glink->size;
/* Space for the branch table. ??? We don't need entries for /* Space for the branch table. */
non-dynamic symbols in this table. This case can arise with htab->glink->size
static ifuncs or forced local ifuncs. */ += htab->elf.srelplt->size / (sizeof (Elf32_External_Rela) / 4) - 4;
htab->glink->size += htab->glink->size / (GLINK_ENTRY_SIZE / 4) - 4;
/* Pad out to align the start of PLTresolve. */ /* Pad out to align the start of PLTresolve. */
htab->glink->size += -htab->glink->size & (htab->params->ppc476_workaround htab->glink->size += -htab->glink->size & (htab->params->ppc476_workaround
? 63 : 15); ? 63 : 15);
@ -7443,12 +7449,36 @@ elf_finish_pointer_linker_section (bfd *input_bfd,
#define PPC_HA(v) PPC_HI ((v) + 0x8000) #define PPC_HA(v) PPC_HI ((v) + 0x8000)
static void static void
write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p, write_glink_stub (struct elf_link_hash_entry *h, struct plt_entry *ent,
asection *plt_sec, unsigned char *p,
struct bfd_link_info *info) struct bfd_link_info *info)
{ {
struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info); struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
bfd *output_bfd = info->output_bfd; bfd *output_bfd = info->output_bfd;
bfd_vma plt; bfd_vma plt;
unsigned char *end = p + GLINK_ENTRY_SIZE (htab, h);
if (h != NULL
&& h == htab->tls_get_addr
&& !htab->params->no_tls_get_addr_opt)
{
bfd_put_32 (output_bfd, LWZ_11_3, p);
p += 4;
bfd_put_32 (output_bfd, LWZ_12_3 + 4, p);
p += 4;
bfd_put_32 (output_bfd, MR_0_3, p);
p += 4;
bfd_put_32 (output_bfd, CMPWI_11_0, p);
p += 4;
bfd_put_32 (output_bfd, ADD_3_12_2, p);
p += 4;
bfd_put_32 (output_bfd, BEQLR, p);
p += 4;
bfd_put_32 (output_bfd, MR_3_0, p);
p += 4;
bfd_put_32 (output_bfd, NOP, p);
p += 4;
}
plt = ((ent->plt.offset & ~1) plt = ((ent->plt.offset & ~1)
+ plt_sec->output_section->vma + plt_sec->output_section->vma
@ -7468,26 +7498,12 @@ write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p,
plt -= got; plt -= got;
if (plt + 0x8000 < 0x10000) if (plt + 0x8000 < 0x10000)
{ bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);
bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);
p += 4;
bfd_put_32 (output_bfd, MTCTR_11, p);
p += 4;
bfd_put_32 (output_bfd, BCTR, p);
p += 4;
bfd_put_32 (output_bfd, htab->params->ppc476_workaround ? BA : NOP, p);
p += 4;
}
else else
{ {
bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p); bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p);
p += 4; p += 4;
bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p); bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
p += 4;
bfd_put_32 (output_bfd, MTCTR_11, p);
p += 4;
bfd_put_32 (output_bfd, BCTR, p);
p += 4;
} }
} }
else else
@ -7495,10 +7511,15 @@ write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p,
bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p); bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p);
p += 4; p += 4;
bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p); bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
p += 4; }
bfd_put_32 (output_bfd, MTCTR_11, p); p += 4;
p += 4; bfd_put_32 (output_bfd, MTCTR_11, p);
bfd_put_32 (output_bfd, BCTR, p); p += 4;
bfd_put_32 (output_bfd, BCTR, p);
p += 4;
while (p < end)
{
bfd_put_32 (output_bfd, htab->params->ppc476_workaround ? BA : NOP, p);
p += 4; p += 4;
} }
} }
@ -8253,7 +8274,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
{ {
unsigned char *p = ((unsigned char *) htab->glink->contents unsigned char *p = ((unsigned char *) htab->glink->contents
+ ent->glink_offset); + ent->glink_offset);
write_glink_stub (ent, htab->elf.iplt, p, info);
write_glink_stub (NULL, ent, htab->elf.iplt, p, info);
ent->glink_offset |= 1; ent->glink_offset |= 1;
} }
@ -10191,33 +10213,13 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
{ {
unsigned char *p; unsigned char *p;
asection *splt = htab->elf.splt; asection *splt = htab->elf.splt;
if (!htab->elf.dynamic_sections_created if (!htab->elf.dynamic_sections_created
|| h->dynindx == -1) || h->dynindx == -1)
splt = htab->elf.iplt; splt = htab->elf.iplt;
p = (unsigned char *) htab->glink->contents + ent->glink_offset; p = (unsigned char *) htab->glink->contents + ent->glink_offset;
write_glink_stub (h, ent, splt, p, info);
if (h == htab->tls_get_addr && !htab->params->no_tls_get_addr_opt)
{
bfd_put_32 (output_bfd, LWZ_11_3, p);
p += 4;
bfd_put_32 (output_bfd, LWZ_12_3 + 4, p);
p += 4;
bfd_put_32 (output_bfd, MR_0_3, p);
p += 4;
bfd_put_32 (output_bfd, CMPWI_11_0, p);
p += 4;
bfd_put_32 (output_bfd, ADD_3_12_2, p);
p += 4;
bfd_put_32 (output_bfd, BEQLR, p);
p += 4;
bfd_put_32 (output_bfd, MR_3_0, p);
p += 4;
bfd_put_32 (output_bfd, NOP, p);
p += 4;
}
write_glink_stub (ent, splt, p, info);
if (!bfd_link_pic (info)) if (!bfd_link_pic (info))
/* We only need one non-PIC glink stub. */ /* We only need one non-PIC glink stub. */
@ -10502,7 +10504,6 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
unsigned char *p; unsigned char *p;
unsigned char *endp; unsigned char *endp;
bfd_vma res0; bfd_vma res0;
unsigned int i;
/* /*
* PIC glink code is the following: * PIC glink code is the following:
@ -10539,28 +10540,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
* add 0,11,11 * add 0,11,11
* add 11,0,11 # r11 = index * 12 = reloc offset. * add 11,0,11 # r11 = index * 12 = reloc offset.
* bctr * bctr
*/ *
static const unsigned int pic_plt_resolve[] =
{
ADDIS_11_11,
MFLR_0,
BCL_20_31,
ADDI_11_11,
MFLR_12,
MTLR_0,
SUB_11_11_12,
ADDIS_12_12,
LWZ_0_12,
LWZ_12_12,
MTCTR_0,
ADD_0_11_11,
ADD_11_0_11,
BCTR,
NOP,
NOP
};
/*
* Non-PIC glink code is a little simpler. * Non-PIC glink code is a little simpler.
* *
* # ith PLT code stub. * # ith PLT code stub.
@ -10582,30 +10562,6 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
* add 11,0,11 # r11 = index * 12 = reloc offset. * add 11,0,11 # r11 = index * 12 = reloc offset.
* bctr * bctr
*/ */
static const unsigned int plt_resolve[] =
{
LIS_12,
ADDIS_11_11,
LWZ_0_12,
ADDI_11_11,
MTCTR_0,
ADD_0_11_11,
LWZ_12_12,
ADD_11_0_11,
BCTR,
NOP,
NOP,
NOP,
NOP,
NOP,
NOP,
NOP
};
if (ARRAY_SIZE (pic_plt_resolve) != GLINK_PLTRESOLVE / 4)
abort ();
if (ARRAY_SIZE (plt_resolve) != GLINK_PLTRESOLVE / 4)
abort ();
/* Build the branch table, one for each plt entry (less one), /* Build the branch table, one for each plt entry (less one),
and perhaps some padding. */ and perhaps some padding. */
@ -10662,80 +10618,83 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
} }
/* Last comes the PLTresolve stub. */ /* Last comes the PLTresolve stub. */
endp = p + GLINK_PLTRESOLVE;
if (bfd_link_pic (info)) if (bfd_link_pic (info))
{ {
bfd_vma bcl; bfd_vma bcl;
for (i = 0; i < ARRAY_SIZE (pic_plt_resolve); i++)
{
unsigned int insn = pic_plt_resolve[i];
if (htab->params->ppc476_workaround && insn == NOP)
insn = BA + 0;
bfd_put_32 (output_bfd, insn, p);
p += 4;
}
p -= 4 * ARRAY_SIZE (pic_plt_resolve);
bcl = (htab->glink->size - GLINK_PLTRESOLVE + 3*4 bcl = (htab->glink->size - GLINK_PLTRESOLVE + 3*4
+ htab->glink->output_section->vma + htab->glink->output_section->vma
+ htab->glink->output_offset); + htab->glink->output_offset);
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, ADDIS_11_11 + PPC_HA (bcl - res0), p);
ADDIS_11_11 + PPC_HA (bcl - res0), p + 0*4); p += 4;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, MFLR_0, p);
ADDI_11_11 + PPC_LO (bcl - res0), p + 3*4); p += 4;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, BCL_20_31, p);
ADDIS_12_12 + PPC_HA (got + 4 - bcl), p + 7*4); p += 4;
bfd_put_32 (output_bfd, ADDI_11_11 + PPC_LO (bcl - res0), p);
p += 4;
bfd_put_32 (output_bfd, MFLR_12, p);
p += 4;
bfd_put_32 (output_bfd, MTLR_0, p);
p += 4;
bfd_put_32 (output_bfd, SUB_11_11_12, p);
p += 4;
bfd_put_32 (output_bfd, ADDIS_12_12 + PPC_HA (got + 4 - bcl), p);
p += 4;
if (PPC_HA (got + 4 - bcl) == PPC_HA (got + 8 - bcl)) if (PPC_HA (got + 4 - bcl) == PPC_HA (got + 8 - bcl))
{ {
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, LWZ_0_12 + PPC_LO (got + 4 - bcl), p);
LWZ_0_12 + PPC_LO (got + 4 - bcl), p + 8*4); p += 4;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, LWZ_12_12 + PPC_LO (got + 8 - bcl), p);
LWZ_12_12 + PPC_LO (got + 8 - bcl), p + 9*4); p += 4;
} }
else else
{ {
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, LWZU_0_12 + PPC_LO (got + 4 - bcl), p);
LWZU_0_12 + PPC_LO (got + 4 - bcl), p + 8*4); p += 4;
bfd_put_32 (output_bfd, bfd_put_32 (output_bfd, LWZ_12_12 + 4, p);
LWZ_12_12 + 4, p + 9*4); p += 4;
} }
bfd_put_32 (output_bfd, MTCTR_0, p);
p += 4;
bfd_put_32 (output_bfd, ADD_0_11_11, p);
} }
else else
{ {
for (i = 0; i < ARRAY_SIZE (plt_resolve); i++) bfd_put_32 (output_bfd, LIS_12 + PPC_HA (got + 4), p);
{ p += 4;
unsigned int insn = plt_resolve[i]; bfd_put_32 (output_bfd, ADDIS_11_11 + PPC_HA (-res0), p);
p += 4;
if (htab->params->ppc476_workaround && insn == NOP)
insn = BA + 0;
bfd_put_32 (output_bfd, insn, p);
p += 4;
}
p -= 4 * ARRAY_SIZE (plt_resolve);
bfd_put_32 (output_bfd,
LIS_12 + PPC_HA (got + 4), p + 0*4);
bfd_put_32 (output_bfd,
ADDIS_11_11 + PPC_HA (-res0), p + 1*4);
bfd_put_32 (output_bfd,
ADDI_11_11 + PPC_LO (-res0), p + 3*4);
if (PPC_HA (got + 4) == PPC_HA (got + 8)) if (PPC_HA (got + 4) == PPC_HA (got + 8))
{ bfd_put_32 (output_bfd, LWZ_0_12 + PPC_LO (got + 4), p);
bfd_put_32 (output_bfd,
LWZ_0_12 + PPC_LO (got + 4), p + 2*4);
bfd_put_32 (output_bfd,
LWZ_12_12 + PPC_LO (got + 8), p + 6*4);
}
else else
{ bfd_put_32 (output_bfd, LWZU_0_12 + PPC_LO (got + 4), p);
bfd_put_32 (output_bfd, p += 4;
LWZU_0_12 + PPC_LO (got + 4), p + 2*4); bfd_put_32 (output_bfd, ADDI_11_11 + PPC_LO (-res0), p);
bfd_put_32 (output_bfd, p += 4;
LWZ_12_12 + 4, p + 6*4); bfd_put_32 (output_bfd, MTCTR_0, p);
} p += 4;
bfd_put_32 (output_bfd, ADD_0_11_11, p);
p += 4;
if (PPC_HA (got + 4) == PPC_HA (got + 8))
bfd_put_32 (output_bfd, LWZ_12_12 + PPC_LO (got + 8), p);
else
bfd_put_32 (output_bfd, LWZ_12_12 + 4, p);
} }
p += 4;
bfd_put_32 (output_bfd, ADD_11_0_11, p);
p += 4;
bfd_put_32 (output_bfd, BCTR, p);
p += 4;
while (p < endp)
{
bfd_put_32 (output_bfd,
htab->params->ppc476_workaround ? BA : NOP, p);
p += 4;
}
BFD_ASSERT (p == endp);
} }
if (htab->glink_eh_frame != NULL if (htab->glink_eh_frame != NULL

View File

@ -32,6 +32,9 @@ struct ppc_elf_params
/* Chooses the type of .plt. */ /* Chooses the type of .plt. */
enum ppc_elf_plt_type plt_style; enum ppc_elf_plt_type plt_style;
/* Set if individual PLT call stubs should be aligned. */
int plt_stub_align;
/* Whether to emit symbols for stubs. */ /* Whether to emit symbols for stubs. */
int emit_stub_syms; int emit_stub_syms;

View File

@ -187,8 +187,9 @@ static bfd_vma opd_entry_value
#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */ #define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */
#define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */ #define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */
/* glink call stub instructions. We enter with the index in R0. */ /* __glink_PLTresolve stub instructions. We enter with the index in R0. */
#define GLINK_CALL_STUB_SIZE (16*4) #define GLINK_PLTRESOLVE_SIZE(htab) \
(8u + (htab->opd_abi ? 11 * 4 : 14 * 4))
/* 0: */ /* 0: */
/* .quad plt0-1f */ /* .quad plt0-1f */
/* __glink: */ /* __glink: */
@ -3515,9 +3516,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
if (dyn.d_tag == DT_PPC64_GLINK) if (dyn.d_tag == DT_PPC64_GLINK)
{ {
/* The first glink stub starts at offset 32; see /* The first glink stub starts at DT_PPC64_GLINK plus 32.
comment in ppc64_elf_finish_dynamic_sections. */ See comment in ppc64_elf_finish_dynamic_sections. */
glink_vma = dyn.d_un.d_val + GLINK_CALL_STUB_SIZE - 8 * 4; glink_vma = dyn.d_un.d_val + 8 * 4;
/* The .glink section usually does not survive the final /* The .glink section usually does not survive the final
link; search for the section (usually .text) where the link; search for the section (usually .text) where the
glink stubs now reside. */ glink stubs now reside. */
@ -4092,6 +4093,7 @@ struct ppc_link_hash_table
/* Shortcuts to get to dynamic linker sections. */ /* Shortcuts to get to dynamic linker sections. */
asection *glink; asection *glink;
asection *global_entry;
asection *sfpr; asection *sfpr;
asection *brlt; asection *brlt;
asection *relbrlt; asection *relbrlt;
@ -4431,6 +4433,14 @@ create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
|| ! bfd_set_section_alignment (dynobj, htab->glink, 3)) || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
return FALSE; return FALSE;
/* The part of .glink used by global entry stubs, separate so that
it can be aligned appropriately without affecting htab->glink. */
htab->global_entry = bfd_make_section_anyway_with_flags (dynobj, ".glink",
flags);
if (htab->global_entry == NULL
|| ! bfd_set_section_alignment (dynobj, htab->global_entry, 2))
return FALSE;
if (!info->no_ld_generated_unwind_info) if (!info->no_ld_generated_unwind_info)
{ {
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
@ -9793,11 +9803,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* Make room for the .glink code. */ /* Make room for the .glink code. */
s = htab->glink; s = htab->glink;
if (s->size == 0) if (s->size == 0)
s->size += GLINK_CALL_STUB_SIZE; s->size += GLINK_PLTRESOLVE_SIZE (htab);
if (htab->opd_abi) if (htab->opd_abi)
{ {
/* We need bigger stubs past index 32767. */ /* We need bigger stubs past index 32767. */
if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4) if (s->size >= GLINK_PLTRESOLVE_SIZE (htab) + 32768*2*4)
s->size += 4; s->size += 4;
s->size += 2*4; s->size += 2*4;
} }
@ -9827,6 +9837,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
return TRUE; return TRUE;
} }
#define PPC_LO(v) ((v) & 0xffff)
#define PPC_HI(v) (((v) >> 16) & 0xffff)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
/* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections /* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections
to set up space for global entry stubs. These are put in glink, to set up space for global entry stubs. These are put in glink,
after the branch table. */ after the branch table. */
@ -9837,7 +9851,7 @@ size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct ppc_link_hash_table *htab; struct ppc_link_hash_table *htab;
struct plt_entry *pent; struct plt_entry *pent;
asection *s; asection *s, *plt;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -9853,7 +9867,8 @@ size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
if (htab == NULL) if (htab == NULL)
return FALSE; return FALSE;
s = htab->glink; s = htab->global_entry;
plt = htab->elf.splt;
for (pent = h->plt.plist; pent != NULL; pent = pent->next) for (pent = h->plt.plist; pent != NULL; pent = pent->next)
if (pent->plt.offset != (bfd_vma) -1 if (pent->plt.offset != (bfd_vma) -1
&& pent->addend == 0) && pent->addend == 0)
@ -9862,11 +9877,39 @@ size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
and we are not generating a shared library or pie, then we and we are not generating a shared library or pie, then we
need to define the symbol in the executable on a call stub. need to define the symbol in the executable on a call stub.
This is to avoid text relocations. */ This is to avoid text relocations. */
s->size = (s->size + 15) & -16; bfd_vma off, stub_align, stub_off, stub_size;
unsigned int align_power;
stub_size = 16;
stub_off = s->size;
if (htab->params->plt_stub_align >= 0)
align_power = htab->params->plt_stub_align;
else
align_power = -htab->params->plt_stub_align;
/* Setting section alignment is delayed until we know it is
non-empty. Otherwise the .text output section will be
aligned at least to plt_stub_align even when no global
entry stubs are needed. */
if (s->alignment_power < align_power)
s->alignment_power = align_power;
stub_align = (bfd_vma) 1 << align_power;
if (htab->params->plt_stub_align >= 0
|| ((((stub_off + stub_size - 1) & -stub_align)
- (stub_off & -stub_align))
> ((stub_size - 1) & -stub_align)))
stub_off = (stub_off + stub_align - 1) & -stub_align;
off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
off -= stub_off + s->output_offset + s->output_section->vma;
/* Note that for --plt-stub-align negative we have a possible
dependency between stub offset and size. Break that
dependency by assuming the max stub size when calculating
the stub offset. */
if (PPC_HA (off) == 0)
stub_size -= 4;
h->root.type = bfd_link_hash_defined; h->root.type = bfd_link_hash_defined;
h->root.u.def.section = s; h->root.u.def.section = s;
h->root.u.def.value = s->size; h->root.u.def.value = stub_off;
s->size += 16; s->size = stub_off + stub_size;
break; break;
} }
return TRUE; return TRUE;
@ -10051,9 +10094,6 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
/* Allocate global sym .plt and .got entries, and space for global /* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */ sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
/* Stash the end of glink branch table. */
if (htab->glink != NULL)
htab->glink->rawsize = htab->glink->size;
if (!htab->opd_abi && !bfd_link_pic (info)) if (!htab->opd_abi && !bfd_link_pic (info))
elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info); elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info);
@ -10108,6 +10148,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
|| s == htab->elf.splt || s == htab->elf.splt
|| s == htab->elf.iplt || s == htab->elf.iplt
|| s == htab->glink || s == htab->glink
|| s == htab->global_entry
|| s == htab->elf.sdynbss || s == htab->elf.sdynbss
|| s == htab->elf.sdynrelro) || s == htab->elf.sdynrelro)
{ {
@ -10393,10 +10434,6 @@ ppc_type_of_stub (asection *input_sec,
#define ALWAYS_USE_FAKE_DEP 0 #define ALWAYS_USE_FAKE_DEP 0
#define ALWAYS_EMIT_R2SAVE 0 #define ALWAYS_EMIT_R2SAVE 0
#define PPC_LO(v) ((v) & 0xffff)
#define PPC_HI(v) (((v) >> 16) & 0xffff)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
static inline unsigned int static inline unsigned int
plt_stub_size (struct ppc_link_hash_table *htab, plt_stub_size (struct ppc_link_hash_table *htab,
struct ppc_stub_hash_entry *stub_entry, struct ppc_stub_hash_entry *stub_entry,
@ -10492,7 +10529,7 @@ build_plt_stub (struct ppc_link_hash_table *htab,
bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1; bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab)) bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
/ PLT_ENTRY_SIZE (htab)); / PLT_ENTRY_SIZE (htab));
bfd_vma glinkoff = GLINK_CALL_STUB_SIZE + pltindex * 8; bfd_vma glinkoff = GLINK_PLTRESOLVE_SIZE (htab) + pltindex * 8;
bfd_vma to, from; bfd_vma to, from;
if (pltindex > 32768) if (pltindex > 32768)
@ -10767,7 +10804,6 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
bfd_byte *loc; bfd_byte *loc;
bfd_byte *p; bfd_byte *p;
bfd_vma dest, off; bfd_vma dest, off;
int size;
Elf_Internal_Rela *r; Elf_Internal_Rela *r;
asection *plt; asection *plt;
@ -10800,7 +10836,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+ stub_entry->group->stub_sec->output_offset + stub_entry->group->stub_sec->output_offset
+ stub_entry->group->stub_sec->output_section->vma); + stub_entry->group->stub_sec->output_section->vma);
size = 4; p = loc;
if (stub_entry->stub_type == ppc_stub_long_branch_r2off) if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
{ {
bfd_vma r2off = get_r2off (info, stub_entry); bfd_vma r2off = get_r2off (info, stub_entry);
@ -10810,26 +10846,24 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
htab->stub_error = TRUE; htab->stub_error = TRUE;
return FALSE; return FALSE;
} }
bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc); bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), p);
loc += 4; p += 4;
size = 8;
if (PPC_HA (r2off) != 0) if (PPC_HA (r2off) != 0)
{ {
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDIS_R2_R2 | PPC_HA (r2off), loc); ADDIS_R2_R2 | PPC_HA (r2off), p);
loc += 4; p += 4;
size += 4;
} }
if (PPC_LO (r2off) != 0) if (PPC_LO (r2off) != 0)
{ {
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDI_R2_R2 | PPC_LO (r2off), loc); ADDI_R2_R2 | PPC_LO (r2off), p);
loc += 4; p += 4;
size += 4;
} }
off -= size - 4; off -= p - loc;
} }
bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc); bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), p);
p += 4;
if (off + (1 << 25) >= (bfd_vma) (1 << 26)) if (off + (1 << 25) >= (bfd_vma) (1 << 26))
{ {
@ -10845,7 +10879,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
r = get_relocs (stub_entry->group->stub_sec, 1); r = get_relocs (stub_entry->group->stub_sec, 1);
if (r == NULL) if (r == NULL)
return FALSE; return FALSE;
r->r_offset = loc - stub_entry->group->stub_sec->contents; r->r_offset = p - 4 - stub_entry->group->stub_sec->contents;
r->r_info = ELF64_R_INFO (0, R_PPC64_REL24); r->r_info = ELF64_R_INFO (0, R_PPC64_REL24);
r->r_addend = dest; r->r_addend = dest;
if (stub_entry->h != NULL) if (stub_entry->h != NULL)
@ -10985,23 +11019,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
} }
} }
p = loc;
if (stub_entry->stub_type != ppc_stub_plt_branch_r2off) if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
{ {
if (PPC_HA (off) != 0) if (PPC_HA (off) != 0)
{ {
size = 16;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDIS_R12_R2 | PPC_HA (off), loc); ADDIS_R12_R2 | PPC_HA (off), p);
loc += 4; p += 4;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
LD_R12_0R12 | PPC_LO (off), loc); LD_R12_0R12 | PPC_LO (off), p);
} }
else else
{ bfd_put_32 (htab->params->stub_bfd,
size = 12; LD_R12_0R2 | PPC_LO (off), p);
bfd_put_32 (htab->params->stub_bfd,
LD_R12_0R2 | PPC_LO (off), loc);
}
} }
else else
{ {
@ -11013,40 +11044,37 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
return FALSE; return FALSE;
} }
bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc); bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), p);
loc += 4; p += 4;
size = 16;
if (PPC_HA (off) != 0) if (PPC_HA (off) != 0)
{ {
size += 4;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDIS_R12_R2 | PPC_HA (off), loc); ADDIS_R12_R2 | PPC_HA (off), p);
loc += 4; p += 4;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
LD_R12_0R12 | PPC_LO (off), loc); LD_R12_0R12 | PPC_LO (off), p);
} }
else else
bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc); bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), p);
if (PPC_HA (r2off) != 0) if (PPC_HA (r2off) != 0)
{ {
size += 4; p += 4;
loc += 4;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDIS_R2_R2 | PPC_HA (r2off), loc); ADDIS_R2_R2 | PPC_HA (r2off), p);
} }
if (PPC_LO (r2off) != 0) if (PPC_LO (r2off) != 0)
{ {
size += 4; p += 4;
loc += 4;
bfd_put_32 (htab->params->stub_bfd, bfd_put_32 (htab->params->stub_bfd,
ADDI_R2_R2 | PPC_LO (r2off), loc); ADDI_R2_R2 | PPC_LO (r2off), p);
} }
} }
loc += 4; p += 4;
bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, loc); bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, p);
loc += 4; p += 4;
bfd_put_32 (htab->params->stub_bfd, BCTR, loc); bfd_put_32 (htab->params->stub_bfd, BCTR, p);
p += 4;
break; break;
case ppc_stub_plt_call: case ppc_stub_plt_call:
@ -11150,7 +11178,6 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r); p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r);
else else
p = build_plt_stub (htab, stub_entry, loc, off, r); p = build_plt_stub (htab, stub_entry, loc, off, r);
size = p - loc;
break; break;
case ppc_stub_save_res: case ppc_stub_save_res:
@ -11161,7 +11188,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
return FALSE; return FALSE;
} }
stub_entry->group->stub_sec->size += size; stub_entry->group->stub_sec->size += p - loc;
if (htab->params->emit_stub_syms) if (htab->params->emit_stub_syms)
{ {
@ -12951,7 +12978,7 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
if (htab == NULL) if (htab == NULL)
return FALSE; return FALSE;
s = htab->glink; s = htab->global_entry;
for (pent = h->plt.plist; pent != NULL; pent = pent->next) for (pent = h->plt.plist; pent != NULL; pent = pent->next)
if (pent->plt.offset != (bfd_vma) -1 if (pent->plt.offset != (bfd_vma) -1
&& pent->addend == 0) && pent->addend == 0)
@ -13144,15 +13171,11 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
} }
bfd_put_32 (htab->glink->owner, BCTR, p); bfd_put_32 (htab->glink->owner, BCTR, p);
p += 4; p += 4;
while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE) BFD_ASSERT (p - htab->glink->contents == GLINK_PLTRESOLVE_SIZE (htab));
{
bfd_put_32 (htab->glink->owner, NOP, p);
p += 4;
}
/* Build the .glink lazy link call stubs. */ /* Build the .glink lazy link call stubs. */
indx = 0; indx = 0;
while (p < htab->glink->contents + htab->glink->rawsize) while (p < htab->glink->contents + htab->glink->size)
{ {
if (htab->opd_abi) if (htab->opd_abi)
{ {
@ -13175,12 +13198,12 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
indx++; indx++;
p += 4; p += 4;
} }
/* Build .glink global entry stubs. */
if (htab->glink->size > htab->glink->rawsize)
elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
} }
/* Build .glink global entry stubs. */
if (htab->global_entry != NULL && htab->global_entry->size != 0)
elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
if (htab->brlt != NULL && htab->brlt->size != 0) if (htab->brlt != NULL && htab->brlt->size != 0)
{ {
htab->brlt->contents = bfd_zalloc (htab->brlt->owner, htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
@ -15557,7 +15580,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
of glink rather than the first entry point, which is of glink rather than the first entry point, which is
what ld.so needs, and now have a bigger stub to what ld.so needs, and now have a bigger stub to
support automatic multiple TOCs. */ support automatic multiple TOCs. */
dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 8 * 4; dyn.d_un.d_ptr += GLINK_PLTRESOLVE_SIZE (htab) - 8 * 4;
break; break;
case DT_PPC64_OPD: case DT_PPC64_OPD:

View File

@ -1,3 +1,19 @@
2018-01-17 Alan Modra <amodra@gmail.com>
* options.h (plt_align): Support for PowerPC32 too.
* powerpc.cc (Stub_table::stub_align): Heed --plt-align for 32-bit.
(Stub_table::plt_call_size, branch_stub_size): Tidy.
(Stub_table::plt_call_align): Implement using stub_align.
(Output_data_glink::global_entry_align): New function.
(Output_data_glink::global_entry_off): New function.
(Output_data_glink::global_entry_address): Use global_entry_off.
(Output_data_glink::pltresolve_size): New function, replacing
pltresolve_size_ constant. Update all uses.
(Output_data_glink::add_global_entry): Align offset.
(Output_data_glink::set_final_data_size): Use global_entry_align.
(Stub_table::do_write): Don't pad __glink_PLTrelsolve with nops.
Tidy stub output. Use global_entry_off.
2018-01-15 Cary Coutant <ccoutant@gmail.com> 2018-01-15 Cary Coutant <ccoutant@gmail.com>
PR gold/22694 PR gold/22694

View File

@ -1101,7 +1101,7 @@ class General_options
NULL, N_("(ARM only) Ignore for backward compatibility")); NULL, N_("(ARM only) Ignore for backward compatibility"));
DEFINE_var(plt_align, options::TWO_DASHES, '\0', 0, "5", DEFINE_var(plt_align, options::TWO_DASHES, '\0', 0, "5",
N_("(PowerPC64 only) Align PLT call stubs to fit cache lines"), N_("(PowerPC only) Align PLT call stubs to fit cache lines"),
N_("[=P2ALIGN]"), true, int, int, options::parse_uint, false); N_("[=P2ALIGN]"), true, int, int, options::parse_uint, false);
DEFINE_bool(plt_localentry, options::TWO_DASHES, '\0', false, DEFINE_bool(plt_localentry, options::TWO_DASHES, '\0', false,

View File

@ -3524,7 +3524,7 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
if (this->glink_ != NULL) if (this->glink_ != NULL)
{ {
int stub_size = this->glink_->pltresolve_size; int stub_size = this->glink_->pltresolve_size();
Address value = -stub_size; Address value = -stub_size;
if (size == 64) if (size == 64)
{ {
@ -3580,7 +3580,7 @@ Target_powerpc<size, big_endian>::do_plt_fde_location(const Output_data* plt,
// There are two FDEs for a position independent glink. // There are two FDEs for a position independent glink.
// The first covers the branch table, the second // The first covers the branch table, the second
// __glink_PLTresolve at the end of glink. // __glink_PLTresolve at the end of glink.
off_t resolve_size = this->glink_->pltresolve_size; off_t resolve_size = this->glink_->pltresolve_size();
if (oview[9] == elfcpp::DW_CFA_nop) if (oview[9] == elfcpp::DW_CFA_nop)
len -= resolve_size; len -= resolve_size;
else else
@ -4391,9 +4391,9 @@ class Stub_table : public Output_relaxed_input_section
unsigned int unsigned int
stub_align() const stub_align() const
{ {
if (size == 32) unsigned int min_align = 4;
return 16; if (!parameters->options().user_set_plt_align())
unsigned int min_align = 32; return size == 64 ? 32 : min_align;
unsigned int user_align = 1 << parameters->options().plt_align(); unsigned int user_align = 1 << parameters->options().plt_align();
return std::max(user_align, min_align); return std::max(user_align, min_align);
} }
@ -4425,9 +4425,8 @@ class Stub_table : public Output_relaxed_input_section
if (size == 32) if (size == 32)
{ {
const Symbol* gsym = p->first.sym_; const Symbol* gsym = p->first.sym_;
if (this->targ_->is_tls_get_addr_opt(gsym)) return (4 * 4
return 12 * 4; + (this->targ_->is_tls_get_addr_opt(gsym) ? 8 * 4 : 0));
return 4 * 4;
} }
bool is_iplt; bool is_iplt;
@ -4460,10 +4459,8 @@ class Stub_table : public Output_relaxed_input_section
unsigned int unsigned int
plt_call_align(unsigned int bytes) const plt_call_align(unsigned int bytes) const
{ {
unsigned int align = 1 << parameters->options().plt_align(); unsigned int align = this->stub_align();
if (align > 1) return (bytes + align - 1) & -align;
bytes = (bytes + align - 1) & -align;
return bytes;
} }
// Return long branch stub size. // Return long branch stub size.
@ -4473,9 +4470,10 @@ class Stub_table : public Output_relaxed_input_section
Address loc = this->stub_address() + this->last_plt_size_ + p->second; Address loc = this->stub_address() + this->last_plt_size_ + p->second;
if (p->first.dest_ - loc + (1 << 25) < 2 << 25) if (p->first.dest_ - loc + (1 << 25) < 2 << 25)
return 4; return 4;
if (size == 64 || !parameters->options().output_is_position_independent()) unsigned int bytes = 16;
return 16; if (size == 32 && parameters->options().output_is_position_independent())
return 32; bytes += 16;
return bytes;
} }
// Write out stubs. // Write out stubs.
@ -4884,7 +4882,6 @@ class Output_data_glink : public Output_section_data
public: public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
static const Address invalid_address = static_cast<Address>(0) - 1; static const Address invalid_address = static_cast<Address>(0) - 1;
static const int pltresolve_size = 16*4;
Output_data_glink(Target_powerpc<size, big_endian>* targ) Output_data_glink(Target_powerpc<size, big_endian>* targ)
: Output_section_data(16), targ_(targ), global_entry_stubs_(), : Output_section_data(16), targ_(targ), global_entry_stubs_(),
@ -4900,12 +4897,35 @@ class Output_data_glink : public Output_section_data
Address Address
find_global_entry(const Symbol*) const; find_global_entry(const Symbol*) const;
unsigned int
global_entry_align(unsigned int off) const
{
unsigned int align = 1 << parameters->options().plt_align();
if (!parameters->options().user_set_plt_align())
align = size == 64 ? 32 : 4;
return (off + align - 1) & -align;
}
unsigned int
global_entry_off() const
{
return this->global_entry_align(this->end_branch_table_);
}
Address Address
global_entry_address() const global_entry_address() const
{ {
gold_assert(this->is_data_size_valid()); gold_assert(this->is_data_size_valid());
unsigned int global_entry_off = (this->end_branch_table_ + 15) & -16; return this->address() + this->global_entry_off();
return this->address() + global_entry_off; }
int
pltresolve_size() const
{
if (size == 64)
return (8
+ (this->targ_->abiversion() < 2 ? 11 * 4 : 14 * 4));
return 16 * 4;
} }
protected: protected:
@ -4977,10 +4997,11 @@ template<int size, bool big_endian>
void void
Output_data_glink<size, big_endian>::add_global_entry(const Symbol* gsym) Output_data_glink<size, big_endian>::add_global_entry(const Symbol* gsym)
{ {
unsigned int off = this->global_entry_align(this->ge_size_);
std::pair<typename Global_entry_stub_entries::iterator, bool> p std::pair<typename Global_entry_stub_entries::iterator, bool> p
= this->global_entry_stubs_.insert(std::make_pair(gsym, this->ge_size_)); = this->global_entry_stubs_.insert(std::make_pair(gsym, off));
if (p.second) if (p.second)
this->ge_size_ += 16; this->ge_size_ = off + 16;
} }
template<int size, bool big_endian> template<int size, bool big_endian>
@ -5007,11 +5028,11 @@ Output_data_glink<size, big_endian>::set_final_data_size()
total += 4 * (count - 1); total += 4 * (count - 1);
total += -total & 15; total += -total & 15;
total += this->pltresolve_size; total += this->pltresolve_size();
} }
else else
{ {
total += this->pltresolve_size; total += this->pltresolve_size();
// space for branch table // space for branch table
total += 4 * count; total += 4 * count;
@ -5024,7 +5045,7 @@ Output_data_glink<size, big_endian>::set_final_data_size()
} }
} }
this->end_branch_table_ = total; this->end_branch_table_ = total;
total = (total + 15) & -16; total = this->global_entry_align(total);
total += this->ge_size_; total += this->ge_size_;
this->set_data_size(total); this->set_data_size(total);
@ -5175,7 +5196,7 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
= ((pltoff - this->targ_->first_plt_entry_offset()) = ((pltoff - this->targ_->first_plt_entry_offset())
/ this->targ_->plt_entry_size()); / this->targ_->plt_entry_size());
Address glinkoff Address glinkoff
= (this->targ_->glink_section()->pltresolve_size = (this->targ_->glink_section()->pltresolve_size()
+ pltindex * 8); + pltindex * 8);
if (pltindex > 32768) if (pltindex > 32768)
glinkoff += (pltindex - 32768) * 4; glinkoff += (pltindex - 32768) * 4;
@ -5441,26 +5462,24 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
Address off = plt_addr - got_addr; Address off = plt_addr - got_addr;
if (ha(off) == 0) if (ha(off) == 0)
{ write_insn<big_endian>(p, lwz_11_30 + l(off));
write_insn<big_endian>(p + 0, lwz_11_30 + l(off));
write_insn<big_endian>(p + 4, mtctr_11);
write_insn<big_endian>(p + 8, bctr);
}
else else
{ {
write_insn<big_endian>(p + 0, addis_11_30 + ha(off)); write_insn<big_endian>(p, addis_11_30 + ha(off));
write_insn<big_endian>(p + 4, lwz_11_11 + l(off)); p += 4;
write_insn<big_endian>(p + 8, mtctr_11); write_insn<big_endian>(p, lwz_11_11 + l(off));
write_insn<big_endian>(p + 12, bctr);
} }
} }
else else
{ {
write_insn<big_endian>(p + 0, lis_11 + ha(plt_addr)); write_insn<big_endian>(p, lis_11 + ha(plt_addr));
write_insn<big_endian>(p + 4, lwz_11_11 + l(plt_addr)); p += 4;
write_insn<big_endian>(p + 8, mtctr_11); write_insn<big_endian>(p, lwz_11_11 + l(plt_addr));
write_insn<big_endian>(p + 12, bctr);
} }
p += 4;
write_insn<big_endian>(p, mtctr_11);
p += 4;
write_insn<big_endian>(p, bctr);
} }
} }
@ -5479,23 +5498,29 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
write_insn<big_endian>(p, b | (delta & 0x3fffffc)); write_insn<big_endian>(p, b | (delta & 0x3fffffc));
else if (!parameters->options().output_is_position_independent()) else if (!parameters->options().output_is_position_independent())
{ {
write_insn<big_endian>(p + 0, lis_12 + ha(bs->first.dest_)); write_insn<big_endian>(p, lis_12 + ha(bs->first.dest_));
write_insn<big_endian>(p + 4, addi_12_12 + l(bs->first.dest_)); p += 4;
write_insn<big_endian>(p + 8, mtctr_12); write_insn<big_endian>(p, addi_12_12 + l(bs->first.dest_));
write_insn<big_endian>(p + 12, bctr);
} }
else else
{ {
delta -= 8; delta -= 8;
write_insn<big_endian>(p + 0, mflr_0); write_insn<big_endian>(p, mflr_0);
write_insn<big_endian>(p + 4, bcl_20_31); p += 4;
write_insn<big_endian>(p + 8, mflr_12); write_insn<big_endian>(p, bcl_20_31);
write_insn<big_endian>(p + 12, addis_12_12 + ha(delta)); p += 4;
write_insn<big_endian>(p + 16, addi_12_12 + l(delta)); write_insn<big_endian>(p, mflr_12);
write_insn<big_endian>(p + 20, mtlr_0); p += 4;
write_insn<big_endian>(p + 24, mtctr_12); write_insn<big_endian>(p, addis_12_12 + ha(delta));
write_insn<big_endian>(p + 28, bctr); p += 4;
write_insn<big_endian>(p, addi_12_12 + l(delta));
p += 4;
write_insn<big_endian>(p, mtlr_0);
} }
p += 4;
write_insn<big_endian>(p, mtctr_12);
p += 4;
write_insn<big_endian>(p, bctr);
} }
} }
if (this->need_save_res_) if (this->need_save_res_)
@ -5563,8 +5588,7 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
write_insn<big_endian>(p, ld_11_11 + 8), p += 4; write_insn<big_endian>(p, ld_11_11 + 8), p += 4;
} }
write_insn<big_endian>(p, bctr), p += 4; write_insn<big_endian>(p, bctr), p += 4;
while (p < oview + this->pltresolve_size) gold_assert(p == oview + this->pltresolve_size());
write_insn<big_endian>(p, nop), p += 4;
// Write lazy link call stubs. // Write lazy link call stubs.
uint32_t indx = 0; uint32_t indx = 0;
@ -5590,7 +5614,7 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
Address plt_base = this->targ_->plt_section()->address(); Address plt_base = this->targ_->plt_section()->address();
Address iplt_base = invalid_address; Address iplt_base = invalid_address;
unsigned int global_entry_off = (this->end_branch_table_ + 15) & -16; unsigned int global_entry_off = this->global_entry_off();
Address global_entry_base = this->address() + global_entry_off; Address global_entry_base = this->address() + global_entry_off;
typename Global_entry_stub_entries::const_iterator ge; typename Global_entry_stub_entries::const_iterator ge;
for (ge = this->global_entry_stubs_.begin(); for (ge = this->global_entry_stubs_.begin();
@ -5631,7 +5655,7 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
// Write out pltresolve branch table. // Write out pltresolve branch table.
p = oview; p = oview;
unsigned int the_end = oview_size - this->pltresolve_size; unsigned int the_end = oview_size - this->pltresolve_size();
unsigned char* end_p = oview + the_end; unsigned char* end_p = oview + the_end;
while (p < end_p - 8 * 4) while (p < end_p - 8 * 4)
write_insn<big_endian>(p, b + end_p - p), p += 4; write_insn<big_endian>(p, b + end_p - p), p += 4;
@ -5639,68 +5663,85 @@ Output_data_glink<size, big_endian>::do_write(Output_file* of)
write_insn<big_endian>(p, nop), p += 4; write_insn<big_endian>(p, nop), p += 4;
// Write out pltresolve call stub. // Write out pltresolve call stub.
end_p = oview + oview_size;
if (parameters->options().output_is_position_independent()) if (parameters->options().output_is_position_independent())
{ {
Address res0_off = 0; Address res0_off = 0;
Address after_bcl_off = the_end + 12; Address after_bcl_off = the_end + 12;
Address bcl_res0 = after_bcl_off - res0_off; Address bcl_res0 = after_bcl_off - res0_off;
write_insn<big_endian>(p + 0, addis_11_11 + ha(bcl_res0)); write_insn<big_endian>(p, addis_11_11 + ha(bcl_res0));
write_insn<big_endian>(p + 4, mflr_0); p += 4;
write_insn<big_endian>(p + 8, bcl_20_31); write_insn<big_endian>(p, mflr_0);
write_insn<big_endian>(p + 12, addi_11_11 + l(bcl_res0)); p += 4;
write_insn<big_endian>(p + 16, mflr_12); write_insn<big_endian>(p, bcl_20_31);
write_insn<big_endian>(p + 20, mtlr_0); p += 4;
write_insn<big_endian>(p + 24, sub_11_11_12); write_insn<big_endian>(p, addi_11_11 + l(bcl_res0));
p += 4;
write_insn<big_endian>(p, mflr_12);
p += 4;
write_insn<big_endian>(p, mtlr_0);
p += 4;
write_insn<big_endian>(p, sub_11_11_12);
p += 4;
Address got_bcl = g_o_t + 4 - (after_bcl_off + this->address()); Address got_bcl = g_o_t + 4 - (after_bcl_off + this->address());
write_insn<big_endian>(p + 28, addis_12_12 + ha(got_bcl)); write_insn<big_endian>(p, addis_12_12 + ha(got_bcl));
p += 4;
if (ha(got_bcl) == ha(got_bcl + 4)) if (ha(got_bcl) == ha(got_bcl + 4))
{ {
write_insn<big_endian>(p + 32, lwz_0_12 + l(got_bcl)); write_insn<big_endian>(p, lwz_0_12 + l(got_bcl));
write_insn<big_endian>(p + 36, lwz_12_12 + l(got_bcl + 4)); p += 4;
write_insn<big_endian>(p, lwz_12_12 + l(got_bcl + 4));
} }
else else
{ {
write_insn<big_endian>(p + 32, lwzu_0_12 + l(got_bcl)); write_insn<big_endian>(p, lwzu_0_12 + l(got_bcl));
write_insn<big_endian>(p + 36, lwz_12_12 + 4); p += 4;
write_insn<big_endian>(p, lwz_12_12 + 4);
} }
write_insn<big_endian>(p + 40, mtctr_0); p += 4;
write_insn<big_endian>(p + 44, add_0_11_11); write_insn<big_endian>(p, mtctr_0);
write_insn<big_endian>(p + 48, add_11_0_11); p += 4;
write_insn<big_endian>(p + 52, bctr); write_insn<big_endian>(p, add_0_11_11);
write_insn<big_endian>(p + 56, nop); p += 4;
write_insn<big_endian>(p + 60, nop); write_insn<big_endian>(p, add_11_0_11);
} }
else else
{ {
Address res0 = this->address(); Address res0 = this->address();
write_insn<big_endian>(p + 0, lis_12 + ha(g_o_t + 4)); write_insn<big_endian>(p, lis_12 + ha(g_o_t + 4));
write_insn<big_endian>(p + 4, addis_11_11 + ha(-res0)); p += 4;
write_insn<big_endian>(p, addis_11_11 + ha(-res0));
p += 4;
if (ha(g_o_t + 4) == ha(g_o_t + 8)) if (ha(g_o_t + 4) == ha(g_o_t + 8))
write_insn<big_endian>(p + 8, lwz_0_12 + l(g_o_t + 4)); write_insn<big_endian>(p, lwz_0_12 + l(g_o_t + 4));
else else
write_insn<big_endian>(p + 8, lwzu_0_12 + l(g_o_t + 4)); write_insn<big_endian>(p, lwzu_0_12 + l(g_o_t + 4));
write_insn<big_endian>(p + 12, addi_11_11 + l(-res0)); p += 4;
write_insn<big_endian>(p + 16, mtctr_0); write_insn<big_endian>(p, addi_11_11 + l(-res0));
write_insn<big_endian>(p + 20, add_0_11_11); p += 4;
write_insn<big_endian>(p, mtctr_0);
p += 4;
write_insn<big_endian>(p, add_0_11_11);
p += 4;
if (ha(g_o_t + 4) == ha(g_o_t + 8)) if (ha(g_o_t + 4) == ha(g_o_t + 8))
write_insn<big_endian>(p + 24, lwz_12_12 + l(g_o_t + 8)); write_insn<big_endian>(p, lwz_12_12 + l(g_o_t + 8));
else else
write_insn<big_endian>(p + 24, lwz_12_12 + 4); write_insn<big_endian>(p, lwz_12_12 + 4);
write_insn<big_endian>(p + 28, add_11_0_11); p += 4;
write_insn<big_endian>(p + 32, bctr); write_insn<big_endian>(p, add_11_0_11);
write_insn<big_endian>(p + 36, nop); }
write_insn<big_endian>(p + 40, nop); p += 4;
write_insn<big_endian>(p + 44, nop); write_insn<big_endian>(p, bctr);
write_insn<big_endian>(p + 48, nop); p += 4;
write_insn<big_endian>(p + 52, nop); while (p < end_p)
write_insn<big_endian>(p + 56, nop); {
write_insn<big_endian>(p + 60, nop); write_insn<big_endian>(p, nop);
p += 4;
} }
p += 64;
} }
of->write_output_view(off, oview_size, oview); of->write_output_view(off, oview_size, oview);
@ -8161,7 +8202,7 @@ Target_powerpc<size, big_endian>::do_finalize_sections(
this->glink_->finalize_data_size(); this->glink_->finalize_data_size();
odyn->add_section_plus_offset(elfcpp::DT_PPC64_GLINK, odyn->add_section_plus_offset(elfcpp::DT_PPC64_GLINK,
this->glink_, this->glink_,
(this->glink_->pltresolve_size (this->glink_->pltresolve_size()
- 32)); - 32));
} }
if (this->has_localentry0_ || this->has_tls_get_addr_opt_) if (this->has_localentry0_ || this->has_tls_get_addr_opt_)
@ -10187,8 +10228,6 @@ Target_selector_powerpc<64, false> target_selector_ppc64le;
// Instantiate these constants for -O0 // Instantiate these constants for -O0
template<int size, bool big_endian> template<int size, bool big_endian>
const int Output_data_glink<size, big_endian>::pltresolve_size;
template<int size, bool big_endian>
const typename Output_data_glink<size, big_endian>::Address const typename Output_data_glink<size, big_endian>::Address
Output_data_glink<size, big_endian>::invalid_address; Output_data_glink<size, big_endian>::invalid_address;
template<int size, bool big_endian> template<int size, bool big_endian>

View File

@ -1,3 +1,28 @@
2018-01-17 Alan Modra <amodra@gmail.com>
* emultempl/ppc32elf.em (params): Init new field.
(enum ppc32_opt): New enum to define OPTION_* values. Add
OPTION_PLT_ALIGN and OPTION_NO_PLT_ALIGN.
(PARSE_AND_LIST_LONGOPTS): Handle new options.
(PARSE_AND_LIST_ARGS_CASES): Likewise.
(PARSE_AND_LIST_OPTIONS): Likewise. Break up help output.
* emultempl/ppc64elf.em (ppc_add_stub_section): Init alignment
correctly for negative --plt-stub-align.
* testsuite/ld-powerpc/elfv2exe.d,
* testsuite/ld-powerpc/elfv2so.d,
* testsuite/ld-powerpc/relbrlt.d,
* testsuite/ld-powerpc/relbrlt.s,
* testsuite/ld-powerpc/tlsexe.d,
* testsuite/ld-powerpc/tlsexe.r,
* testsuite/ld-powerpc/tlsexe32.d,
* testsuite/ld-powerpc/tlsexe32.g,
* testsuite/ld-powerpc/tlsexe32.r,
* testsuite/ld-powerpc/tlsexetoc.d,
* testsuite/ld-powerpc/tlsexetoc.r,
* testsuite/ld-powerpc/tlsopt5_32.d,
* testsuite/ld-powerpc/tlsso.d,
* testsuite/ld-powerpc/tlstocso.d: Update for changed stub order.
2018-01-16 Nick Clifton <nickc@redhat.com> 2018-01-16 Nick Clifton <nickc@redhat.com>
* po/pt_BR.po: Updated Brazilian Portugese translation. * po/pt_BR.po: Updated Brazilian Portugese translation.

View File

@ -38,7 +38,8 @@ static int notlsopt = 0;
/* Choose the correct place for .got. */ /* Choose the correct place for .got. */
static int old_got = 0; static int old_got = 0;
static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0, 0, 0, 0 }; static struct ppc_elf_params params = { PLT_UNSET, 0, -1,
0, 0, 0, 0, 0, 0, 0 };
static void static void
ppc_after_open_output (void) ppc_after_open_output (void)
@ -239,17 +240,22 @@ fi
# parse_args and list_options functions. # parse_args and list_options functions.
# #
PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}' PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
#define OPTION_NO_TLS_OPT 321 enum ppc32_opt
#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1) {
#define OPTION_NEW_PLT (OPTION_NO_TLS_GET_ADDR_OPT + 1) OPTION_NO_TLS_OPT = 321,
#define OPTION_OLD_PLT (OPTION_NEW_PLT + 1) OPTION_NO_TLS_GET_ADDR_OPT,
#define OPTION_OLD_GOT (OPTION_OLD_PLT + 1) OPTION_NEW_PLT,
#define OPTION_STUBSYMS (OPTION_OLD_GOT + 1) OPTION_OLD_PLT,
#define OPTION_NO_STUBSYMS (OPTION_STUBSYMS + 1) OPTION_PLT_ALIGN,
#define OPTION_PPC476_WORKAROUND (OPTION_NO_STUBSYMS + 1) OPTION_NO_PLT_ALIGN,
#define OPTION_NO_PPC476_WORKAROUND (OPTION_PPC476_WORKAROUND + 1) OPTION_OLD_GOT,
#define OPTION_NO_PICFIXUP (OPTION_NO_PPC476_WORKAROUND + 1) OPTION_STUBSYMS,
#define OPTION_VLE_RELOC_FIXUP (OPTION_NO_PICFIXUP + 1) OPTION_NO_STUBSYMS,
OPTION_PPC476_WORKAROUND,
OPTION_NO_PPC476_WORKAROUND,
OPTION_NO_PICFIXUP,
OPTION_VLE_RELOC_FIXUP
};
' '
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
@ -261,6 +267,8 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "secure-plt", no_argument, NULL, OPTION_NEW_PLT }, { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT }, { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
{ "plt-align", no_argument, NULL, OPTION_PLT_ALIGN },
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },' { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
fi fi
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
@ -272,21 +280,47 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}' PARSE_AND_LIST_OPTIONS=${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-emit-stub-syms Don'\''t label linker stubs with a symbol.\n\ ));
--no-tls-optimize Don'\''t try to optimize TLS accesses.\n\ fprintf (file, _("\
--no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n' --no-emit-stub-syms Don'\''t label linker stubs with a symbol.\n"
));
fprintf (file, _("\
--no-tls-optimize Don'\''t try to optimize TLS accesses.\n"
));
fprintf (file, _("\
--no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n"
));'
if test -z "$VXWORKS_BASE_EM_FILE" ; then if test -z "$VXWORKS_BASE_EM_FILE" ; then
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
--secure-plt Use new-style PLT if possible.\n\ fprintf (file, _("\
--bss-plt Force old-style BSS PLT.\n\ --secure-plt Use new-style PLT if possible.\n"
--sdata-got Force GOT location just before .sdata.\n' ));
fprintf (file, _("\
--bss-plt Force old-style BSS PLT.\n"
));
fprintf (file, _("\
--plt-align Align PLT call stubs to fit cache lines.\n"
));
fprintf (file, _("\
--no-plt-align Dont'\''t align individual PLT call stubs.\n"
));
fprintf (file, _("\
--sdata-got Force GOT location just before .sdata.\n"
));'
fi fi
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
fprintf (file, _("\
--ppc476-workaround [=pagesize]\n\ --ppc476-workaround [=pagesize]\n\
Avoid a cache bug on ppc476.\n\ Avoid a cache bug on ppc476.\n"
--no-ppc476-workaround Disable workaround.\n\ ));
--no-pic-fixup Don'\''t edit non-pic to pic.\n\ fprintf (file, _("\
--no-ppc476-workaround Disable workaround.\n"
));
fprintf (file, _("\
--no-pic-fixup Don'\''t edit non-pic to pic.\n"
));
fprintf (file, _("\
--vle-reloc-fixup Correct old object file 16A/16D relocation.\n" --vle-reloc-fixup Correct old object file 16A/16D relocation.\n"
)); ));
' '
@ -316,6 +350,14 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
params.plt_style = PLT_OLD; params.plt_style = PLT_OLD;
break; break;
case OPTION_PLT_ALIGN:
params.plt_stub_align = 5;
break;
case OPTION_NO_PLT_ALIGN:
params.plt_stub_align = 0;
break;
case OPTION_OLD_GOT: case OPTION_OLD_GOT:
old_got = 1; old_got = 1;
break; break;

View File

@ -412,6 +412,8 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
|| !bfd_set_section_alignment (stub_file->the_bfd, stub_sec, || !bfd_set_section_alignment (stub_file->the_bfd, stub_sec,
(params.plt_stub_align > 5 (params.plt_stub_align > 5
? params.plt_stub_align ? params.plt_stub_align
: params.plt_stub_align < -5
? -params.plt_stub_align
: 5))) : 5)))
goto err_ret; goto err_ret;

View File

@ -7,13 +7,13 @@
Disassembly of section \.text: Disassembly of section \.text:
0+100000c0 <.*\.plt_branch\.f2>: 0+100000c0 <.*\.plt_branch\.f4>:
.*: (3d 82 ff ff|ff ff 82 3d) addis r12,r2,-1 .*: (3d 82 ff ff|ff ff 82 3d) addis r12,r2,-1
.*: (e9 8c 7f 28|28 7f 8c e9) ld r12,32552\(r12\) .*: (e9 8c 7f 28|28 7f 8c e9) ld r12,32552\(r12\)
.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12 .*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
.*: (4e 80 04 20|20 04 80 4e) bctr .*: (4e 80 04 20|20 04 80 4e) bctr
0+100000d0 <.*\.plt_branch\.f4>: 0+100000d0 <.*\.plt_branch\.f2>:
.*: (3d 82 ff ff|ff ff 82 3d) addis r12,r2,-1 .*: (3d 82 ff ff|ff ff 82 3d) addis r12,r2,-1
.*: (e9 8c 7f 30|30 7f 8c e9) ld r12,32560\(r12\) .*: (e9 8c 7f 30|30 7f 8c e9) ld r12,32560\(r12\)
.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12 .*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
@ -27,12 +27,12 @@ Disassembly of section \.text:
.*: (f8 01 00 30|30 00 01 f8) std r0,48\(r1\) .*: (f8 01 00 30|30 00 01 f8) std r0,48\(r1\)
.*: (4b ff ff f5|f5 ff ff 4b) bl .* <(f1|_start)\+0x8> .*: (4b ff ff f5|f5 ff ff 4b) bl .* <(f1|_start)\+0x8>
.*: (e8 62 80 08|08 80 62 e8) ld r3,-32760\(r2\) .*: (e8 62 80 08|08 80 62 e8) ld r3,-32760\(r2\)
.*: (4b ff ff c5|c5 ff ff 4b) bl .*\.plt_branch\.f2> .*: (4b ff ff d5|d5 ff ff 4b) bl .*\.plt_branch\.f2>
.*: (60 00 00 00|00 00 00 60) nop .*: (60 00 00 00|00 00 00 60) nop
.*: (e8 62 80 10|10 80 62 e8) ld r3,-32752\(r2\) .*: (e8 62 80 10|10 80 62 e8) ld r3,-32752\(r2\)
.*: (48 00 87 81|81 87 00 48) bl 10008888 <f3> .*: (48 00 87 81|81 87 00 48) bl 10008888 <f3>
.*: (60 00 00 00|00 00 00 60) nop .*: (60 00 00 00|00 00 00 60) nop
.*: (4b ff ff c1|c1 ff ff 4b) bl .*\.plt_branch\.f4> .*: (4b ff ff b1|b1 ff ff 4b) bl .*\.plt_branch\.f4>
.*: (60 00 00 00|00 00 00 60) nop .*: (60 00 00 00|00 00 00 60) nop
.*: (e8 01 00 30|30 00 01 e8) ld r0,48\(r1\) .*: (e8 01 00 30|30 00 01 e8) ld r0,48\(r1\)
.*: (38 21 00 20|20 00 21 38) addi r1,r1,32 .*: (38 21 00 20|20 00 21 38) addi r1,r1,32

View File

@ -14,6 +14,13 @@ Disassembly of section \.text:
.*: (4e 80 04 20|20 04 80 4e) bctr .*: (4e 80 04 20|20 04 80 4e) bctr
\.\.\. \.\.\.
.* <.*\.plt_call\.f1>:
.*: (f8 41 00 18|18 00 41 f8) std r2,24\(r1\)
.*: (e9 82 80 40|40 80 82 e9) ld r12,-32704\(r2\)
.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
.*: (4e 80 04 20|20 04 80 4e) bctr
\.\.\.
.* <.*\.plt_call\.f3>: .* <.*\.plt_call\.f3>:
.*: (f8 41 00 18|18 00 41 f8) std r2,24\(r1\) .*: (f8 41 00 18|18 00 41 f8) std r2,24\(r1\)
.*: (e9 82 80 28|28 80 82 e9) ld r12,-32728\(r2\) .*: (e9 82 80 28|28 80 82 e9) ld r12,-32728\(r2\)
@ -28,25 +35,18 @@ Disassembly of section \.text:
.*: (4e 80 04 20|20 04 80 4e) bctr .*: (4e 80 04 20|20 04 80 4e) bctr
\.\.\. \.\.\.
.* <.*\.plt_call\.f1>:
.*: (f8 41 00 18|18 00 41 f8) std r2,24\(r1\)
.*: (e9 82 80 40|40 80 82 e9) ld r12,-32704\(r2\)
.*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
.*: (4e 80 04 20|20 04 80 4e) bctr
\.\.\.
.* <f1>: .* <f1>:
.*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2 .*: (3c 4c 00 02|02 00 4c 3c) addis r2,r12,2
.*: (38 42 .. ..|.. .. 42 38) addi r2,r2,.* .*: (38 42 .. ..|.. .. 42 38) addi r2,r2,.*
.*: (7c 08 02 a6|a6 02 08 7c) mflr r0 .*: (7c 08 02 a6|a6 02 08 7c) mflr r0
.*: (f8 21 ff e1|e1 ff 21 f8) stdu r1,-32\(r1\) .*: (f8 21 ff e1|e1 ff 21 f8) stdu r1,-32\(r1\)
.*: (f8 01 00 30|30 00 01 f8) std r0,48\(r1\) .*: (f8 01 00 30|30 00 01 f8) std r0,48\(r1\)
.*: (4b ff ff cd|cd ff ff 4b) bl .*\.plt_call\.f1> .*: (4b ff ff 8d|8d ff ff 4b) bl .*\.plt_call\.f1>
.*: (e8 62 80 08|08 80 62 e8) ld r3,-32760\(r2\) .*: (e8 62 80 08|08 80 62 e8) ld r3,-32760\(r2\)
.*: (4b ff ff a5|a5 ff ff 4b) bl .*\.plt_call\.f2> .*: (4b ff ff c5|c5 ff ff 4b) bl .*\.plt_call\.f2>
.*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\) .*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\)
.*: (e8 62 80 10|10 80 62 e8) ld r3,-32752\(r2\) .*: (e8 62 80 10|10 80 62 e8) ld r3,-32752\(r2\)
.*: (4b ff ff 79|79 ff ff 4b) bl .*\.plt_call\.f3> .*: (4b ff ff 99|99 ff ff 4b) bl .*\.plt_call\.f3>
.*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\) .*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\)
.*: (4b ff ff 51|51 ff ff 4b) bl .*\.plt_call\.f4> .*: (4b ff ff 51|51 ff ff 4b) bl .*\.plt_call\.f4>
.*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\) .*: (e8 41 00 18|18 00 41 e8) ld r2,24\(r1\)

View File

@ -8,32 +8,32 @@
Disassembly of section \.text: Disassembly of section \.text:
0*100000c0 <_start>: 0*100000c0 <_start>:
[0-9a-f ]*: (49 bf 00 2d|2d 00 bf 49) bl .* [0-9a-f ]*: (49 bf 00 21|21 00 bf 49) bl .*
[0-9a-f ]*: R_PPC64_REL24 \.text\+0x37e003c [0-9a-f ]*: R_PPC64_REL24 \.text\+0x37e003c
[0-9a-f ]*: (60 00 00 00|00 00 00 60) nop [0-9a-f ]*: (60 00 00 00|00 00 00 60) nop
[0-9a-f ]*: (49 bf 00 19|19 00 bf 49) bl .* [0-9a-f ]*: (49 bf 00 1d|1d 00 bf 49) bl .*
[0-9a-f ]*: R_PPC64_REL24 \.text\+0x3bf0020 [0-9a-f ]*: R_PPC64_REL24 \.text\+0x3bf002c
[0-9a-f ]*: (60 00 00 00|00 00 00 60) nop [0-9a-f ]*: (60 00 00 00|00 00 00 60) nop
[0-9a-f ]*: (49 bf 00 21|21 00 bf 49) bl .* [0-9a-f ]*: (49 bf 00 21|21 00 bf 49) bl .*
[0-9a-f ]*: R_PPC64_REL24 \.text\+0x57e0024 [0-9a-f ]*: R_PPC64_REL24 \.text\+0x57e0030
[0-9a-f ]*: (60 00 00 00|00 00 00 60) nop [0-9a-f ]*: (60 00 00 00|00 00 00 60) nop
[0-9a-f ]*: 00 00 00 00 \.long 0x0 [0-9a-f ]*: 00 00 00 00 \.long 0x0
[0-9a-f ]*: (4b ff ff e4|e4 ff ff 4b) b .* <_start> [0-9a-f ]*: (4b ff ff e4|e4 ff ff 4b) b .* <_start>
\.\.\. \.\.\.
[0-9a-f ]*<.*plt_branch.*>:
[0-9a-f ]*: (e9 82 80 e8|e8 80 82 e9) ld r12,-32536\(r2\)
[0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f00e8
[0-9a-f ]*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
[0-9a-f ]*: (4e 80 04 20|20 04 80 4e) bctr
[0-9a-f ]*<.*long_branch.*>: [0-9a-f ]*<.*long_branch.*>:
[0-9a-f ]*: (49 bf 00 10|10 00 bf 49) b .* <far> [0-9a-f ]*: (49 bf 00 1c|1c 00 bf 49) b .* <far>
[0-9a-f ]*: R_PPC64_REL24 \*ABS\*\+0x137e00fc [0-9a-f ]*: R_PPC64_REL24 \*ABS\*\+0x137e00fc
[0-9a-f ]*<.*plt_branch.*>: [0-9a-f ]*<.*plt_branch.*>:
[0-9a-f ]*: (e9 82 80 f0|f0 80 82 e9) ld r12,-32528\(r2\) [0-9a-f ]*: (e9 82 80 f8|f8 80 82 e9) ld r12,-32520\(r2\)
[0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f00f0 [0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f00f8
[0-9a-f ]*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
[0-9a-f ]*: (4e 80 04 20|20 04 80 4e) bctr
[0-9a-f ]*<.*plt_branch.*>:
[0-9a-f ]*: (e9 82 81 00|00 81 82 e9) ld r12,-32512\(r2\)
[0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f0100
[0-9a-f ]*: (7d 89 03 a6|a6 03 89 7d) mtctr r12 [0-9a-f ]*: (7d 89 03 a6|a6 03 89 7d) mtctr r12
[0-9a-f ]*: (4e 80 04 20|20 04 80 4e) bctr [0-9a-f ]*: (4e 80 04 20|20 04 80 4e) bctr
\.\.\. \.\.\.
@ -42,19 +42,19 @@ Disassembly of section \.text:
[0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr [0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr
\.\.\. \.\.\.
0*13bf00e0 <far2far>: 0*13bf00ec <far2far>:
[0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr [0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr
\.\.\. \.\.\.
0*157e00e4 <huge>: 0*157e00f0 <huge>:
[0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr [0-9a-f ]*: (4e 80 00 20|20 00 80 4e) blr
Disassembly of section \.branch_lt: Disassembly of section \.branch_lt:
0*157f00e8 .*: 0*157f00f8 .*:
[0-9a-f ]*: (00 00 00 00|e0 00 bf 13) .* [0-9a-f ]*: (00 00 00 00|ec 00 bf 13) .*
[0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x13bf00e0 [0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x13bf00ec
[0-9a-f ]*: (13 bf 00 e0|00 00 00 00) .* [0-9a-f ]*: (13 bf 00 ec|00 00 00 00) .*
[0-9a-f ]*: (00 00 00 00|e4 00 7e 15) .* [0-9a-f ]*: (00 00 00 00|f0 00 7e 15) .*
[0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x157e00e4 [0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x157e00f0
[0-9a-f ]*: (15 7e 00 e4|00 00 00 00) .* [0-9a-f ]*: (15 7e 00 f0|00 00 00 00) .*

View File

@ -20,7 +20,7 @@ far:
blr blr
.section .text.pad2,"ax" .section .text.pad2,"ax"
.space 0x40ffe0 .space 0x40ffec
.section .text.far2far,"ax" .section .text.far2far,"ax"
far2far: far2far:

View File

@ -81,9 +81,6 @@ Disassembly of section \.text:
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12 .* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\) .* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
.* (4e 80 04 20|20 04 80 4e) bctr .* (4e 80 04 20|20 04 80 4e) bctr
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* <__tls_get_addr_opt@plt>: .* <__tls_get_addr_opt@plt>:
.* (38 00 00 00|00 00 00 38) li r0,0 .* (38 00 00 00|00 00 00 38) li r0,0
.* (4b ff ff c4|c4 ff ff 4b) b .* .* (4b ff ff d0|d0 ff ff 4b) b .*

View File

@ -16,7 +16,7 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.* +\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.* +\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.* +\[[ 0-9]+\] \.rela\.plt +.*
+\[[ 0-9]+\] \.text +PROGBITS .* 0+128 0+ +AX +0 +0 +32 +\[[ 0-9]+\] \.text +PROGBITS .* 0+11c 0+ +AX +0 +0 +32
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8 +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8 +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8 +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8

View File

@ -12,7 +12,7 @@ Disassembly of section \.text:
.*: (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.* <_start\+0x4> .*: (42 9f 00 05|05 00 9f 42) bcl 20,4\*cr7\+so,.* <_start\+0x4>
.*: (7f c8 02 a6|a6 02 c8 7f) mflr r30 .*: (7f c8 02 a6|a6 02 c8 7f) mflr r30
.*: (3f de 00 02|02 00 de 3f) addis r30,r30,2 .*: (3f de 00 02|02 00 de 3f) addis r30,r30,2
.*: (3b de 81 18|18 81 de 3b) addi r30,r30,-32488 .*: (3b de 81 08|08 81 de 3b) addi r30,r30,-32504
.*: (80 7f ff f4|f4 ff 7f 80) lwz r3,-12\(r31\) .*: (80 7f ff f4|f4 ff 7f 80) lwz r3,-12\(r31\)
.*: (7c 63 12 14|14 12 63 7c) add r3,r3,r2 .*: (7c 63 12 14|14 12 63 7c) add r3,r3,r2
.*: (38 7f ff f8|f8 ff 7f 38) addi r3,r31,-8 .*: (38 7f ff f8|f8 ff 7f 38) addi r3,r31,-8
@ -52,24 +52,18 @@ Disassembly of section \.text:
.*: (7c 03 03 78|78 03 03 7c) mr r3,r0 .*: (7c 03 03 78|78 03 03 7c) mr r3,r0
.*: (60 00 00 00|00 00 00 60) nop .*: (60 00 00 00|00 00 00 60) nop
.*: (3d 60 01 81|81 01 60 3d) lis r11,385 .*: (3d 60 01 81|81 01 60 3d) lis r11,385
.*: (81 6b 04 14|14 04 6b 81) lwz r11,1044\(r11\) .*: (81 6b 04 04|04 04 6b 81) lwz r11,1028\(r11\)
.*: (7d 69 03 a6|a6 03 69 7d) mtctr r11 .*: (7d 69 03 a6|a6 03 69 7d) mtctr r11
.*: (4e 80 04 20|20 04 80 4e) bctr .*: (4e 80 04 20|20 04 80 4e) bctr
.* <__glink>: .* <__glink(_PLTresolve)?>:
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.* <__glink_PLTresolve>:
.*: (3d 80 01 81|81 01 80 3d) lis r12,385 .*: (3d 80 01 81|81 01 80 3d) lis r12,385
.*: (3d 6b fe 80|80 fe 6b 3d) addis r11,r11,-384 .*: (3d 6b fe 80|80 fe 6b 3d) addis r11,r11,-384
.*: (80 0c 04 0c|0c 04 0c 80) lwz r0,1036\(r12\) .*: (80 0c 03 fc|fc 03 0c 80) lwz r0,1020\(r12\)
.*: (39 6b fd 20|20 fd 6b 39) addi r11,r11,-736 .*: (39 6b fd 20|20 fd 6b 39) addi r11,r11,-736
.*: (7c 09 03 a6|a6 03 09 7c) mtctr r0 .*: (7c 09 03 a6|a6 03 09 7c) mtctr r0
.*: (7c 0b 5a 14|14 5a 0b 7c) add r0,r11,r11 .*: (7c 0b 5a 14|14 5a 0b 7c) add r0,r11,r11
.*: (81 8c 04 10|10 04 8c 81) lwz r12,1040\(r12\) .*: (81 8c 04 00|00 04 8c 81) lwz r12,1024\(r12\)
.*: (7d 60 5a 14|14 5a 60 7d) add r11,r0,r11 .*: (7d 60 5a 14|14 5a 60 7d) add r11,r0,r11
.*: (4e 80 04 20|20 04 80 4e) bctr .*: (4e 80 04 20|20 04 80 4e) bctr
.*: (60 00 00 00|00 00 00 60) nop .*: (60 00 00 00|00 00 00 60) nop

View File

@ -7,5 +7,5 @@
.* .*
Contents of section \.got: Contents of section \.got:
.* 00000000 00000000 00000000 (0181034c|4c038101) .* .* 00000000 00000000 00000000 (0181033c|3c038101) .*
.* 00000000 00000000 .* .* 00000000 00000000 .*

View File

@ -16,7 +16,7 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.* +\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.* +\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.* +\[[ 0-9]+\] \.rela\.plt +.*
+\[[ 0-9]+\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000100 00 +AX +0 +0 +16 +\[[ 0-9]+\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0000f0 00 +AX +0 +0 +16
+\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 00001c 00 WAT +0 +0 +4 +\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 00001c 00 WAT +0 +0 +4
+\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 00001c 00 WAT +0 +0 +4 +\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 00001c 00 WAT +0 +0 +4
+\[[ 0-9]+\] \.dynamic +DYNAMIC +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 08 +WA +4 +0 +4 +\[[ 0-9]+\] \.dynamic +DYNAMIC +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 08 +WA +4 +0 +4

View File

@ -65,9 +65,6 @@ Disassembly of section \.text:
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12 .* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\) .* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
.* (4e 80 04 20|20 04 80 4e) bctr .* (4e 80 04 20|20 04 80 4e) bctr
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* <__tls_get_addr_opt@plt>: .* <__tls_get_addr_opt@plt>:
.* (38 00 00 00|00 00 00 38) li r0,0 .* (38 00 00 00|00 00 00 38) li r0,0
.* (4b ff ff c4|c4 ff ff 4b) b .* .* (4b ff ff d0|d0 ff ff 4b) b .*

View File

@ -16,7 +16,7 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.* +\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.* +\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.* +\[[ 0-9]+\] \.rela\.plt +.*
+\[[ 0-9]+\] \.text +PROGBITS .* 0+e8 0+ +AX +0 +0 +32 +\[[ 0-9]+\] \.text +PROGBITS .* 0+dc 0+ +AX +0 +0 +32
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8 +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8 +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8 +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8

View File

@ -40,17 +40,11 @@ Disassembly of section \.text:
.*: (20 04 80 4e|4e 80 04 20) bctr .*: (20 04 80 4e|4e 80 04 20) bctr
.*: (00 00 00 60|60 00 00 00) nop .*: (00 00 00 60|60 00 00 00) nop
.* <__glink>: .* <__glink(_PLTresolve)?>:
.*: (00 00 00 60|60 00 00 00) nop
.*: (00 00 00 60|60 00 00 00) nop
.*: (00 00 00 60|60 00 00 00) nop
.*: (00 00 00 60|60 00 00 00) nop
.* <__glink_PLTresolve>:
.*: (00 00 6b 3d|3d 6b 00 00) addis r11,r11,0 .*: (00 00 6b 3d|3d 6b 00 00) addis r11,r11,0
.*: (a6 02 08 7c|7c 08 02 a6) mflr r0 .*: (a6 02 08 7c|7c 08 02 a6) mflr r0
.*: (05 00 9f 42|42 9f 00 05) bcl .* .*: (05 00 9f 42|42 9f 00 05) bcl .*
.*: (1c 00 6b 39|39 6b 00 1c) addi r11,r11,28 .*: (0c 00 6b 39|39 6b 00 0c) addi r11,r11,12
.*: (a6 02 88 7d|7d 88 02 a6) mflr r12 .*: (a6 02 88 7d|7d 88 02 a6) mflr r12
.*: (a6 03 08 7c|7c 08 03 a6) mtlr r0 .*: (a6 03 08 7c|7c 08 03 a6) mtlr r0
.*: (50 58 6c 7d|7d 6c 58 50) subf r11,r12,r11 .*: (50 58 6c 7d|7d 6c 58 50) subf r11,r12,r11

View File

@ -71,9 +71,6 @@ Disassembly of section \.text:
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12 .* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\) .* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
.* (4e 80 04 20|20 04 80 4e) bctr .* (4e 80 04 20|20 04 80 4e) bctr
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* <__tls_get_addr@plt>: .* <__tls_get_addr@plt>:
.* (38 00 00 00|00 00 00 38) li r0,0 .* (38 00 00 00|00 00 00 38) li r0,0
.* (4b ff ff c4|c4 ff ff 4b) b .* .* (4b ff ff d0|d0 ff ff 4b) b .*

View File

@ -55,9 +55,6 @@ Disassembly of section \.text:
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12 .* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\) .* (e9 6b 00 10|10 00 6b e9) ld r11,16\(r11\)
.* (4e 80 04 20|20 04 80 4e) bctr .* (4e 80 04 20|20 04 80 4e) bctr
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* (60 00 00 00|00 00 00 60) nop
.* <__tls_get_addr@plt>: .* <__tls_get_addr@plt>:
.* (38 00 00 00|00 00 00 38) li r0,0 .* (38 00 00 00|00 00 00 38) li r0,0
.* (4b ff ff c4|c4 ff ff 4b) b .* .* (4b ff ff d0|d0 ff ff 4b) b .*