This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: powerpc __tls_get_addr call optimization
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Mon, 21 Sep 2009 20:59:54 +0930
- Subject: Re: powerpc __tls_get_addr call optimization
- References: <20090330075029.GL30645@bubble.grove.modra.org>
On Mon, Mar 30, 2009 at 06:20:29PM +1030, Alan Modra wrote:
> This patch is the ld support for a PowerPC TLS optimization, inspired
[snip http://sourceware.org/ml/binutils/2009-03/msg00498.html]
> I don't intend to commit this immediately as the patch isn't useful
> until glibc support is available.
Well the glibc patch was totally ignored, but I don't want to miss the
binutils release so I'm committing linker support. This patch differs
slightly from the previous one in that ld now detects whether glibc
has the necessary support before using the new call stub.
include/elf/
* ppc.h (DT_PPC_TLSOPT): Define.
* ppc64.h (DT_PPC64_TLSOPT): Define.
bfd/
* elf32-ppc.c (TLS_GET_ADDR_GLINK_SIZE): Define.
(ADD_3_12_2, BEQLR, CMPWI_11_0, LWZ_11_3, LWZ_12_3): Define.
(MR_0_3, MR_3_0): Define.
(struct ppc_elf_link_hash_table): Add no_tls_get_addr_opt.
(ppc_elf_select_plt_layout): Save emit_stub_syms param earlier.
(ppc_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
table. Check for presense of __tls_get_addr_opt
(allocate_dynrelocs): Increase glink entry size for __tls_get_addr.
(ppc_elf_size_dynamic_sections): Add DT_PPC_TLS_OPT tag.
(write_glink_stub): Add param p.
(ppc_elf_relocate_section): Adjust write_glink_stub call.
(ppc_elf_finish_dynamic_symbol): Emit special glink call stub for
__tls_get_addr.
* elf32-ppc.h (ppc_elf_tls_setup): Update prototype.
* elf64-ppc.c (struct ppc_link_hash_table): Add no_tls_get_addr_opt.
(ppc64_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
table. Check for presense of __tls_get_addr_opt.
(ppc64_elf_size_dynamic_sections): Add DT_PPC64_TLS_OPT tag.
(LD_R11_0R3, LD_R12_0R3, MR_R0_R3, CMPDI_R11_0, ADD_R3_R12_R13,
BEQLR, MR_R3_R0, MFLR_R11, STD_R11_0R1, BCTRL, LD_R11_0R1,
LD_R2_0R1, MTLR_R11): Define.
(build_tls_get_addr_stub): New function.
(ppc_build_one_stub): Call it.
(ppc_size_one_stub): Add extra size for __tls_get_addr stub.
(ppc64_elf_relocate_section): Don't change nop to ld 2,40(1) for
__tls_get_addr plt call.
* elf64-ppc.h (ppc64_elf_tls_setup): Update prototype.
binutils/
* readelf.c (get_ppc_dynamic_type): Add TLSOPT.
(get_ppc64_dynamic_type): Likewise.
ld/
* emultempl/ppc32elf.em (no_tls_get_addr_opt): New var.
(ppc_before_allocation): Pass to ppc_elf_tls_setup.
(OPTION_NO_TLS_GET_ADDR_OPT): Define. Redefine other options in
terms of previous option.
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add
--no-tls-get-addr-optimize.
(PARSE_AND_LIST_ARGS_CASES): Handle it.
* emultempl/ppc64elf.em (no_tls_get_addr_opt): New var.
(ppc_before_allocation): Pass to ppc64_elf_tls_setup.
(OPTION_NO_TLS_GET_ADDR_OPT): Define.
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add
--no-tls-get-addr-optimize.
(PARSE_AND_LIST_ARGS_CASES): Handle it.
ld/testsuite/
* ld-powerpc/tlslib.s: Delete dot-symbol entry syms. Add
__tls_get_addr_opt.
* ld-powerpc/tlslib32.s: Add __tls_get_addr_opt.
* ld-powerpc/oldtlslib.s: New file, old-abi version of tlslib.s.
* ld-powerpc/powerpc.exp: Build old-abi library and use it in
two new link tests.
* ld-powerpc/tlsexe.d: Update for new __tls_get_addr stub.
* ld-powerpc/tlsexe.g, * ld-powerpc/tlsexe.r, *ld-powerpc/tlsexe32.d,
* ld-powerpc/tlsexe32.g, * ld-powerpc/tlsexe32.r,
* ld-powerpc/tlsexetoc.d, * ld-powerpc/tlsexetoc.g,
* ld-powerpc/tlsexetoc.r: Likewise.
Index: include/elf/ppc.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc.h,v
retrieving revision 1.25
diff -u -p -r1.25 ppc.h
--- include/elf/ppc.h 10 Jul 2009 12:19:55 -0000 1.25
+++ include/elf/ppc.h 20 Sep 2009 11:12:19 -0000
@@ -153,7 +153,10 @@ END_RELOC_NUMBERS (R_PPC_max)
((R) >= R_PPC_TLS && (R) <= R_PPC_GOT_DTPREL16_HA)
/* Specify the value of _GLOBAL_OFFSET_TABLE_. */
-#define DT_PPC_GOT DT_LOPROC
+#define DT_PPC_GOT (DT_LOPROC)
+
+/* Specify that tls descriptors should be optimized. */
+#define DT_PPC_TLSOPT (DT_LOPROC + 1)
/* Processor specific flags for the ELF header e_flags field. */
Index: include/elf/ppc64.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc64.h,v
retrieving revision 1.7
diff -u -p -r1.7 ppc64.h
--- include/elf/ppc64.h 29 Jul 2009 14:55:20 -0000 1.7
+++ include/elf/ppc64.h 20 Sep 2009 11:12:19 -0000
@@ -165,4 +165,7 @@ END_RELOC_NUMBERS (R_PPC64_max)
#define DT_PPC64_OPD (DT_LOPROC + 1)
#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+/* Specify that tls descriptors should be optimized. */
+#define DT_PPC64_TLSOPT (DT_LOPROC + 3)
+
#endif /* _ELF_PPC64_H */
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.268
diff -u -p -r1.268 elf32-ppc.c
--- bfd/elf32-ppc.c 18 Sep 2009 12:41:52 -0000 1.268
+++ bfd/elf32-ppc.c 20 Sep 2009 11:11:20 -0000
@@ -61,6 +61,7 @@ static bfd_reloc_status_type ppc_elf_unh
/* For new-style .glink and .plt. */
#define GLINK_PLTRESOLVE 16*4
#define GLINK_ENTRY_SIZE 4*4
+#define TLS_GET_ADDR_GLINK_SIZE 12*4
/* VxWorks uses its own plt layout, filled in by the static linker. */
@@ -135,17 +136,24 @@ static const bfd_vma ppc_elf_vxworks_pic
#define ADDIS_12_12 0x3d8c0000
#define ADDI_11_11 0x396b0000
#define ADD_0_11_11 0x7c0b5a14
+#define ADD_3_12_2 0x7c6c1214
#define ADD_11_0_11 0x7d605a14
#define B 0x48000000
#define BCL_20_31 0x429f0005
#define BCTR 0x4e800420
+#define BEQLR 0x4d820020
+#define CMPWI_11_0 0x2c0b0000
#define LIS_11 0x3d600000
#define LIS_12 0x3d800000
#define LWZU_0_12 0x840c0000
#define LWZ_0_12 0x800c0000
+#define LWZ_11_3 0x81630000
#define LWZ_11_11 0x816b0000
#define LWZ_11_30 0x817e0000
+#define LWZ_12_3 0x81830000
#define LWZ_12_12 0x818c0000
+#define MR_0_3 0x7c601b78
+#define MR_3_0 0x7c030378
#define MFLR_0 0x7c0802a6
#define MFLR_12 0x7d8802a6
#define MTCTR_0 0x7c0903a6
@@ -2754,6 +2762,9 @@ struct ppc_elf_link_hash_table
/* Set if we should emit symbols for stubs. */
unsigned int emit_stub_syms:1;
+ /* Set if __tls_get_addr optimization should not be done. */
+ unsigned int no_tls_get_addr_opt:1;
+
/* True if the target system is VxWorks. */
unsigned int is_vxworks:1;
@@ -4277,6 +4288,8 @@ ppc_elf_select_plt_layout (bfd *output_b
htab = ppc_elf_hash_table (info);
+ htab->emit_stub_syms = emit_stub_syms;
+
if (htab->plt_type == PLT_UNSET)
{
if (plt_style == PLT_OLD)
@@ -4310,8 +4323,6 @@ ppc_elf_select_plt_layout (bfd *output_b
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;
-
BFD_ASSERT (htab->plt_type != PLT_VXWORKS);
if (htab->plt_type == PLT_NEW)
@@ -4539,11 +4550,62 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
generic ELF tls_setup function. */
asection *
-ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+ppc_elf_tls_setup (bfd *obfd,
+ struct bfd_link_info *info,
+ int no_tls_get_addr_opt)
{
struct ppc_elf_link_hash_table *htab;
htab = ppc_elf_hash_table (info);
+ htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ if (!no_tls_get_addr_opt)
+ {
+ struct elf_link_hash_entry *opt, *tga;
+ opt = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt != NULL
+ && (opt->root.type == bfd_link_hash_defined
+ || opt->root.type == bfd_link_hash_defweak))
+ {
+ /* If glibc supports an optimized __tls_get_addr call stub,
+ signalled by the presence of __tls_get_addr_opt, and we'll
+ be calling __tls_get_addr via a plt call stub, then
+ make __tls_get_addr point to __tls_get_addr_opt. */
+ tga = htab->tls_get_addr;
+ if (htab->elf.dynamic_sections_created
+ && tga != NULL
+ && (tga->type == STT_FUNC
+ || tga->needs_plt)
+ && !(SYMBOL_CALLS_LOCAL (info, tga)
+ || (ELF_ST_VISIBILITY (tga->other) != STV_DEFAULT
+ && tga->root.type == bfd_link_hash_undefweak)))
+ {
+ struct plt_entry *ent;
+ ent = find_plt_ent (&tga->plt.plist, NULL, 0);
+ if (ent != NULL
+ && ent->plt.refcount > 0)
+ {
+ tga->root.type = bfd_link_hash_indirect;
+ tga->root.u.i.link = &opt->root;
+ ppc_elf_copy_indirect_symbol (info, opt, tga);
+ if (opt->dynindx != -1)
+ {
+ /* Use __tls_get_addr_opt in dynamic relocations. */
+ opt->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ opt->dynstr_index);
+ if (!bfd_elf_link_record_dynamic_symbol (info, opt))
+ return FALSE;
+ }
+ htab->tls_get_addr = opt;
+ }
+ }
+ }
+ else
+ no_tls_get_addr_opt = TRUE;
+ }
+ htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
if (htab->plt_type == PLT_NEW
&& htab->plt != NULL
&& htab->plt->output_section != NULL)
@@ -4552,8 +4614,6 @@ ppc_elf_tls_setup (bfd *obfd, struct bfd
elf_section_flags (htab->plt->output_section) = SHF_ALLOC + SHF_WRITE;
}
- htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
- FALSE, FALSE, TRUE);
return _bfd_elf_tls_setup (obfd, info);
}
@@ -5144,6 +5204,9 @@ allocate_dynrelocs (struct elf_link_hash
{
glink_offset = s->size;
s->size += GLINK_ENTRY_SIZE;
+ if (h == htab->tls_get_addr
+ && !htab->no_tls_get_addr_opt)
+ s->size += TLS_GET_ADDR_GLINK_SIZE - GLINK_ENTRY_SIZE;
}
if (!doneone
&& !info->shared
@@ -5820,6 +5883,11 @@ ppc_elf_size_dynamic_sections (bfd *outp
{
if (!add_dynamic_entry (DT_PPC_GOT, 0))
return FALSE;
+ if (!htab->no_tls_get_addr_opt
+ && htab->tls_get_addr != NULL
+ && htab->tls_get_addr->plt.plist != NULL
+ && !add_dynamic_entry (DT_PPC_TLSOPT, 0))
+ return FALSE;
}
if (relocs)
@@ -6474,18 +6542,16 @@ elf_finish_pointer_linker_section (bfd *
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
static void
-write_glink_stub (struct plt_entry *ent, asection *plt_sec,
+write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p,
struct bfd_link_info *info)
{
struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
bfd *output_bfd = info->output_bfd;
bfd_vma plt;
- unsigned char *p;
plt = ((ent->plt.offset & ~1)
+ plt_sec->output_section->vma
+ plt_sec->output_offset);
- p = (unsigned char *) htab->glink->contents + ent->glink_offset;
if (info->shared)
{
@@ -7045,7 +7111,9 @@ ppc_elf_relocate_section (bfd *output_bf
}
if (h == NULL && (ent->glink_offset & 1) == 0)
{
- write_glink_stub (ent, htab->iplt, info);
+ unsigned char *p = ((unsigned char *) htab->glink->contents
+ + ent->glink_offset);
+ write_glink_stub (ent, htab->iplt, p, info);
ent->glink_offset |= 1;
}
@@ -8274,12 +8342,35 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
|| !htab->elf.dynamic_sections_created
|| h->dynindx == -1)
{
+ unsigned char *p;
asection *splt = htab->plt;
if (!htab->elf.dynamic_sections_created
|| h->dynindx == -1)
splt = htab->iplt;
- write_glink_stub (ent, splt, info);
+ p = (unsigned char *) htab->glink->contents + ent->glink_offset;
+
+ if (h == htab->tls_get_addr && !htab->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 (!info->shared)
/* We only need one non-PIC glink stub. */
Index: bfd/elf32-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.h,v
retrieving revision 1.11
diff -u -p -r1.11 elf32-ppc.h
--- bfd/elf32-ppc.h 3 Jul 2007 14:26:41 -0000 1.11
+++ bfd/elf32-ppc.h 20 Sep 2009 11:11:20 -0000
@@ -28,6 +28,6 @@ enum ppc_elf_plt_type
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 *, int);
bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.300
diff -u -p -r1.300 elf64-ppc.c
--- bfd/elf64-ppc.c 18 Sep 2009 03:30:33 -0000 1.300
+++ bfd/elf64-ppc.c 20 Sep 2009 11:11:29 -0000
@@ -3771,6 +3771,9 @@ struct ppc_link_hash_table
/* Set if we should emit symbols for stubs. */
unsigned int emit_stub_syms:1;
+ /* Set if __tls_get_addr optimization should not be done. */
+ unsigned int no_tls_get_addr_opt:1;
+
/* Support for multiple toc sections. */
unsigned int no_multi_toc:1;
unsigned int multi_toc_needed:1;
@@ -7218,7 +7221,9 @@ ppc64_elf_edit_opd (bfd *obfd, struct bf
/* Set htab->tls_get_addr and call the generic ELF tls_setup function. */
asection *
-ppc64_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+ppc64_elf_tls_setup (bfd *obfd,
+ struct bfd_link_info *info,
+ int no_tls_get_addr_opt)
{
struct ppc_link_hash_table *htab;
@@ -7226,9 +7231,83 @@ ppc64_elf_tls_setup (bfd *obfd, struct b
htab->tls_get_addr = ((struct ppc_link_hash_entry *)
elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
FALSE, FALSE, TRUE));
+ /* Move dynamic linking info to the function descriptor sym. */
+ if (htab->tls_get_addr != NULL)
+ func_desc_adjust (&htab->tls_get_addr->elf, info);
htab->tls_get_addr_fd = ((struct ppc_link_hash_entry *)
elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
FALSE, FALSE, TRUE));
+ if (!no_tls_get_addr_opt)
+ {
+ struct elf_link_hash_entry *opt, *opt_fd, *tga, *tga_fd;
+
+ opt = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt != NULL)
+ func_desc_adjust (opt, info);
+ opt_fd = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt_fd != NULL
+ && (opt_fd->root.type == bfd_link_hash_defined
+ || opt_fd->root.type == bfd_link_hash_defweak))
+ {
+ /* If glibc supports an optimized __tls_get_addr call stub,
+ signalled by the presence of __tls_get_addr_opt, and we'll
+ be calling __tls_get_addr via a plt call stub, then
+ make __tls_get_addr point to __tls_get_addr_opt. */
+ tga_fd = &htab->tls_get_addr_fd->elf;
+ if (htab->elf.dynamic_sections_created
+ && tga_fd != NULL
+ && (tga_fd->type == STT_FUNC
+ || tga_fd->needs_plt)
+ && !(SYMBOL_CALLS_LOCAL (info, tga_fd)
+ || (ELF_ST_VISIBILITY (tga_fd->other) != STV_DEFAULT
+ && tga_fd->root.type == bfd_link_hash_undefweak)))
+ {
+ struct plt_entry *ent;
+
+ for (ent = tga_fd->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent != NULL)
+ {
+ tga_fd->root.type = bfd_link_hash_indirect;
+ tga_fd->root.u.i.link = &opt_fd->root;
+ ppc64_elf_copy_indirect_symbol (info, opt_fd, tga_fd);
+ if (opt_fd->dynindx != -1)
+ {
+ /* Use __tls_get_addr_opt in dynamic relocations. */
+ opt_fd->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ opt_fd->dynstr_index);
+ if (!bfd_elf_link_record_dynamic_symbol (info, opt_fd))
+ return FALSE;
+ }
+ htab->tls_get_addr_fd = (struct ppc_link_hash_entry *) opt_fd;
+ tga = &htab->tls_get_addr->elf;
+ if (opt != NULL && tga != NULL)
+ {
+ tga->root.type = bfd_link_hash_indirect;
+ tga->root.u.i.link = &opt->root;
+ ppc64_elf_copy_indirect_symbol (info, opt, tga);
+ _bfd_elf_link_hash_hide_symbol (info, opt,
+ tga->forced_local);
+ htab->tls_get_addr = (struct ppc_link_hash_entry *) opt;
+ }
+ htab->tls_get_addr_fd->oh = htab->tls_get_addr;
+ htab->tls_get_addr_fd->is_func_descriptor = 1;
+ if (htab->tls_get_addr != NULL)
+ {
+ htab->tls_get_addr->oh = htab->tls_get_addr_fd;
+ htab->tls_get_addr->is_func = 1;
+ }
+ }
+ }
+ }
+ else
+ no_tls_get_addr_opt = TRUE;
+ }
+ htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
return _bfd_elf_tls_setup (obfd, info);
}
@@ -8666,6 +8745,12 @@ ppc64_elf_size_dynamic_sections (bfd *ou
return FALSE;
}
+ if (!htab->no_tls_get_addr_opt
+ && htab->tls_get_addr_fd != NULL
+ && htab->tls_get_addr_fd->elf.plt.plist != NULL
+ && !add_dynamic_entry (DT_PPC64_TLSOPT, 0))
+ return FALSE;
+
if (relocs)
{
if (!add_dynamic_entry (DT_RELA, 0)
@@ -8859,6 +8944,49 @@ build_plt_stub (bfd *obfd, bfd_byte *p,
return p;
}
+/* Build a special .plt call stub for __tls_get_addr. */
+
+#define LD_R11_0R3 0xe9630000
+#define LD_R12_0R3 0xe9830000
+#define MR_R0_R3 0x7c601b78
+#define CMPDI_R11_0 0x2c2b0000
+#define ADD_R3_R12_R13 0x7c6c6a14
+#define BEQLR 0x4d820020
+#define MR_R3_R0 0x7c030378
+#define MFLR_R11 0x7d6802a6
+#define STD_R11_0R1 0xf9610000
+#define BCTRL 0x4e800421
+#define LD_R11_0R1 0xe9610000
+#define LD_R2_0R1 0xe8410000
+#define MTLR_R11 0x7d6803a6
+
+static inline bfd_byte *
+build_tls_get_addr_stub (bfd *obfd, bfd_byte *p, int offset,
+ Elf_Internal_Rela *r)
+{
+ bfd_put_32 (obfd, LD_R11_0R3 + 0, p), p += 4;
+ bfd_put_32 (obfd, LD_R12_0R3 + 8, p), p += 4;
+ bfd_put_32 (obfd, MR_R0_R3, p), p += 4;
+ bfd_put_32 (obfd, CMPDI_R11_0, p), p += 4;
+ bfd_put_32 (obfd, ADD_R3_R12_R13, p), p += 4;
+ bfd_put_32 (obfd, BEQLR, p), p += 4;
+ bfd_put_32 (obfd, MR_R3_R0, p), p += 4;
+ bfd_put_32 (obfd, MFLR_R11, p), p += 4;
+ bfd_put_32 (obfd, STD_R11_0R1 + 32, p), p += 4;
+
+ if (r != NULL)
+ r[0].r_offset += 9 * 4;
+ p = build_plt_stub (obfd, p, offset, r);
+ bfd_put_32 (obfd, BCTRL, p - 4);
+
+ bfd_put_32 (obfd, LD_R11_0R1 + 32, p), p += 4;
+ bfd_put_32 (obfd, LD_R2_0R1 + 40, p), p += 4;
+ bfd_put_32 (obfd, MTLR_R11, p), p += 4;
+ bfd_put_32 (obfd, BLR, p), p += 4;
+
+ return p;
+}
+
static Elf_Internal_Rela *
get_relocs (asection *sec, int count)
{
@@ -9227,7 +9355,13 @@ ppc_build_one_stub (struct bfd_hash_entr
r[0].r_offset += 2;
r[0].r_addend = dest;
}
- p = build_plt_stub (htab->stub_bfd, loc, off, r);
+ if (stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && !htab->no_tls_get_addr_opt)
+ p = build_tls_get_addr_stub (htab->stub_bfd, loc, off, r);
+ else
+ p = build_plt_stub (htab->stub_bfd, loc, off, r);
size = p - loc;
break;
@@ -9316,6 +9450,11 @@ ppc_size_one_stub (struct bfd_hash_entry
size -= 4;
if (PPC_HA (off + 16) != PPC_HA (off))
size += 4;
+ if (stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && !htab->no_tls_get_addr_opt)
+ size += 13 * 4;
if (info->emitrelocations)
{
stub_entry->stub_sec->reloc_count
@@ -11255,8 +11394,16 @@ ppc64_elf_relocate_section (bfd *output_
if (nop == NOP
|| nop == CROR_151515 || nop == CROR_313131)
{
- bfd_put_32 (input_bfd, LD_R2_40R1,
- contents + rel->r_offset + 4);
+ if (h != NULL
+ && (h == htab->tls_get_addr_fd
+ || h == htab->tls_get_addr)
+ && !htab->no_tls_get_addr_opt)
+ {
+ /* Special stub used, leave nop alone. */
+ }
+ else
+ bfd_put_32 (input_bfd, LD_R2_40R1,
+ contents + rel->r_offset + 4);
can_plt_call = TRUE;
}
}
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.25
diff -u -p -r1.25 elf64-ppc.h
--- bfd/elf64-ppc.h 15 Jan 2008 07:25:49 -0000 1.25
+++ bfd/elf64-ppc.h 20 Sep 2009 11:11:29 -0000
@@ -24,7 +24,7 @@ void ppc64_elf_init_stub_bfd
bfd_boolean ppc64_elf_edit_opd
(bfd *, struct bfd_link_info *, bfd_boolean);
asection *ppc64_elf_tls_setup
- (bfd *, struct bfd_link_info *);
+(bfd *, struct bfd_link_info *, int);
bfd_boolean ppc64_elf_tls_optimize
(bfd *, struct bfd_link_info *);
bfd_boolean ppc64_elf_edit_toc
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.459
diff -u -p -r1.459 readelf.c
--- binutils/readelf.c 14 Sep 2009 12:29:50 -0000 1.459
+++ binutils/readelf.c 21 Sep 2009 03:12:04 -0000
@@ -1470,7 +1470,8 @@ get_ppc_dynamic_type (unsigned long type
{
switch (type)
{
- case DT_PPC_GOT: return "PPC_GOT";
+ case DT_PPC_GOT: return "PPC_GOT";
+ case DT_PPC_TLSOPT: return "PPC_TLSOPT";
default:
return NULL;
}
@@ -1481,9 +1482,10 @@ get_ppc64_dynamic_type (unsigned long ty
{
switch (type)
{
- case DT_PPC64_GLINK: return "PPC64_GLINK";
- case DT_PPC64_OPD: return "PPC64_OPD";
- case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
+ case DT_PPC64_GLINK: return "PPC64_GLINK";
+ case DT_PPC64_OPD: return "PPC64_OPD";
+ case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
+ case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
default:
return NULL;
}
Index: ld/emultempl/ppc32elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc32elf.em,v
retrieving revision 1.21
diff -u -p -r1.21 ppc32elf.em
--- ld/emultempl/ppc32elf.em 2 Sep 2009 07:25:35 -0000 1.21
+++ ld/emultempl/ppc32elf.em 20 Sep 2009 11:12:26 -0000
@@ -33,6 +33,7 @@ fragment <<EOF
/* Whether to run tls optimization. */
static int notlsopt = 0;
+static int no_tls_get_addr_opt = 0;
/* Whether to emit symbols for stubs. */
static int emit_stub_syms = 0;
@@ -103,7 +104,9 @@ ppc_before_allocation (void)
{
if (is_ppc_elf (link_info.output_bfd))
{
- if (ppc_elf_tls_setup (link_info.output_bfd, &link_info) && !notlsopt)
+ if (ppc_elf_tls_setup (link_info.output_bfd, &link_info,
+ no_tls_get_addr_opt)
+ && !notlsopt)
{
if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
{
@@ -174,15 +177,17 @@ fi
#
PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_TLS_OPT 301
-#define OPTION_NEW_PLT 302
-#define OPTION_OLD_PLT 303
-#define OPTION_OLD_GOT 304
-#define OPTION_STUBSYMS 305
+#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1)
+#define OPTION_NEW_PLT (OPTION_NO_TLS_GET_ADDR_OPT + 1)
+#define OPTION_OLD_PLT (OPTION_NEW_PLT + 1)
+#define OPTION_OLD_GOT (OPTION_OLD_PLT + 1)
+#define OPTION_STUBSYMS (OPTION_OLD_GOT + 1)
'
PARSE_AND_LIST_LONGOPTS='
{ "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+ { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_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 },
@@ -192,6 +197,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\
+ --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\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"
@@ -207,6 +213,10 @@ PARSE_AND_LIST_ARGS_CASES='
notlsopt = 1;
break;
+ case OPTION_NO_TLS_GET_ADDR_OPT:
+ no_tls_get_addr_opt = 1;
+ break;
+
case OPTION_NEW_PLT:
plt_style = PLT_NEW;
break;
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.63
diff -u -p -r1.63 ppc64elf.em
--- ld/emultempl/ppc64elf.em 2 Sep 2009 07:25:35 -0000 1.63
+++ ld/emultempl/ppc64elf.em 20 Sep 2009 11:12:26 -0000
@@ -47,6 +47,7 @@ static int dotsyms = 1;
/* Whether to run tls optimization. */
static int no_tls_opt = 0;
+static int no_tls_get_addr_opt = 0;
/* Whether to run opd optimization. */
static int no_opd_opt = 0;
@@ -106,7 +107,8 @@ ppc_before_allocation (void)
non_overlapping_opd))
einfo ("%X%P: can not edit %s %E\n", "opd");
- if (ppc64_elf_tls_setup (link_info.output_bfd, &link_info)
+ if (ppc64_elf_tls_setup (link_info.output_bfd, &link_info,
+ no_tls_get_addr_opt)
&& !no_tls_opt)
{
/* Size the sections. This is premature, but we want to know the
@@ -488,7 +490,8 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_DOTSYMS (OPTION_STUBSYMS + 1)
#define OPTION_NO_DOTSYMS (OPTION_DOTSYMS + 1)
#define OPTION_NO_TLS_OPT (OPTION_NO_DOTSYMS + 1)
-#define OPTION_NO_OPD_OPT (OPTION_NO_TLS_OPT + 1)
+#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1)
+#define OPTION_NO_OPD_OPT (OPTION_NO_TLS_GET_ADDR_OPT + 1)
#define OPTION_NO_TOC_OPT (OPTION_NO_OPD_OPT + 1)
#define OPTION_NO_MULTI_TOC (OPTION_NO_TOC_OPT + 1)
#define OPTION_NON_OVERLAPPING_OPD (OPTION_NO_MULTI_TOC + 1)
@@ -500,6 +503,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
{ "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+ { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
{ "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
{ "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
{ "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
@@ -533,6 +537,9 @@ PARSE_AND_LIST_OPTIONS='
--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"
+ ));
+ fprintf (file, _("\
--no-opd-optimize Don'\''t optimize the OPD section.\n"
));
fprintf (file, _("\
@@ -573,6 +580,10 @@ PARSE_AND_LIST_ARGS_CASES='
no_tls_opt = 1;
break;
+ case OPTION_NO_TLS_GET_ADDR_OPT:
+ no_tls_get_addr_opt = 1;
+ break;
+
case OPTION_NO_OPD_OPT:
no_opd_opt = 1;
break;
Index: ld/testsuite/ld-powerpc/powerpc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v
retrieving revision 1.28
diff -u -p -r1.28 powerpc.exp
--- ld/testsuite/ld-powerpc/powerpc.exp 23 Aug 2009 14:38:31 -0000 1.28
+++ ld/testsuite/ld-powerpc/powerpc.exp 20 Sep 2009 11:12:29 -0000
@@ -138,10 +138,16 @@ set ppc64elftests {
"tls"}
{"TLS helper shared library" "-shared -melf64ppc tmpdir/tlslib.o" "" {}
{} "libtlslib.so"}
+ {"TLS helper old shared lib" "-shared -melf64ppc" "-a64" {oldtlslib.s}
+ {} "liboldlib.so"}
{"TLS dynamic exec" "-melf64ppc tmpdir/tls.o tmpdir/libtlslib.so" "" {}
{{readelf -WSsrl tlsexe.r} {objdump -dr tlsexe.d}
{objdump -sj.got tlsexe.g} {objdump -sj.tdata tlsexe.t}}
"tlsexe"}
+ {"TLS dynamic old" "-melf64ppc tmpdir/tls.o tmpdir/liboldlib.so" "" {}
+ {{readelf -WSsrl tlsexe.r} {objdump -dr tlsexe.d}
+ {objdump -sj.got tlsexe.g} {objdump -sj.tdata tlsexe.t}}
+ "tlsexeold"}
{"TLS shared" "-shared -melf64ppc tmpdir/tls.o" "" {}
{{readelf -WSsrl tlsso.r} {objdump -dr tlsso.d}
{objdump -sj.got tlsso.g} {objdump -sj.tdata tlsso.t}}
@@ -155,6 +161,11 @@ set ppc64elftests {
{{readelf -WSsrl tlsexetoc.r} {objdump -dr tlsexetoc.d}
{objdump -sj.got tlsexetoc.g} {objdump -sj.tdata tlsexetoc.t}}
"tlsexetoc"}
+ {"TLSTOC dynamic old" "-melf64ppc tmpdir/tlstoc.o tmpdir/liboldlib.so"
+ "" {}
+ {{readelf -WSsrl tlsexetoc.r} {objdump -dr tlsexetoc.d}
+ {objdump -sj.got tlsexetoc.g} {objdump -sj.tdata tlsexetoc.t}}
+ "tlsexetocold"}
{"TLSTOC shared" "-shared -melf64ppc tmpdir/tlstoc.o" "" {}
{{readelf -WSsrl tlstocso.r} {objdump -dr tlstocso.d}
{objdump -sj.got tlstocso.g} {objdump -sj.tdata tlstocso.t}}
Index: ld/testsuite/ld-powerpc/tlsexe.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.d,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.d
--- ld/testsuite/ld-powerpc/tlsexe.d 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexe.d 20 Sep 2009 11:12:29 -0000
@@ -8,21 +8,34 @@
Disassembly of section \.text:
-.* <_start-0x18>:
+.* <_start-0x4c>:
+.* e9 63 00 00 ld r11,0\(r3\)
+.* e9 83 00 08 ld r12,8\(r3\)
+.* 7c 60 1b 78 mr r0,r3
+.* 2c 2b 00 00 cmpdi r11,0
+.* 7c 6c 6a 14 add r3,r12,r13
+.* 4d 82 00 20 beqlr
+.* 7c 03 03 78 mr r3,r0
+.* 7d 68 02 a6 mflr r11
+.* f9 61 00 20 std r11,32\(r1\)
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 48 ld r11,-32696\(r2\)
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 58 ld r11,-32680\(r2\)
.* e8 42 80 50 ld r2,-32688\(r2\)
-.* 4e 80 04 20 bctr
+.* 4e 80 04 21 bctrl
+.* e9 61 00 20 ld r11,32\(r1\)
+.* e8 41 00 28 ld r2,40\(r1\)
+.* 7d 68 03 a6 mtlr r11
+.* 4e 80 00 20 blr
.* <_start>:
.* e8 62 80 10 ld r3,-32752\(r2\)
.* 60 00 00 00 nop
.* 7c 63 6a 14 add r3,r3,r13
.* 38 62 80 18 addi r3,r2,-32744
-.* 4b ff ff d9 bl .*
-.* e8 41 00 28 ld r2,40\(r1\)
+.* 4b ff ff a5 bl .*
+.* 60 00 00 00 nop
.* 3c 6d 00 00 addis r3,r13,0
.* 60 00 00 00 nop
.* 38 63 90 38 addi r3,r3,-28616
@@ -55,8 +68,9 @@ Disassembly of section \.text:
.* e9 4d 90 2a lwa r10,-28632\(r13\)
.* 3d 2d 00 00 addis r9,r13,0
.* a9 49 90 30 lha r10,-28624\(r9\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
-.* 00 01 01 f0 .*
+.* 00 01 02 00 .*
.* 7d 88 02 a6 mflr r12
.* 42 9f 00 05 bcl- 20,4\*cr7\+so,.*
.* 7d 68 02 a6 mflr r11
Index: ld/testsuite/ld-powerpc/tlsexe.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.g
--- ld/testsuite/ld-powerpc/tlsexe.g 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexe.g 20 Sep 2009 11:12:29 -0000
@@ -7,6 +7,6 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 100185c8 ffffffff ffff8018 .*
+.* 00000000 10018618 ffffffff ffff8018 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
Index: ld/testsuite/ld-powerpc/tlsexe.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.r,v
retrieving revision 1.21
diff -u -p -r1.21 tlsexe.r
--- ld/testsuite/ld-powerpc/tlsexe.r 30 Sep 2007 01:33:15 -0000 1.21
+++ ld/testsuite/ld-powerpc/tlsexe.r 20 Sep 2009 11:12:29 -0000
@@ -16,10 +16,10 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+f8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+130 0+ +AX +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]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
+\[[ 0-9]+\] \.branch_lt + PROGBITS .* 0+ 0+ +WA +0 +0 +8
+\[[ 0-9]+\] \.got +PROGBITS .* 0+30 08 +WA +0 +0 +8
+\[[ 0-9]+\] \.plt +.*
@@ -59,16 +59,16 @@ Relocation section '\.rela\.dyn' at offs
Relocation section '\.rela\.plt' at offset .* contains 1 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
-[0-9a-f ]+R_PPC64_JMP_SLOT +0+ __tls_get_addr \+ 0
+[0-9a-f ]+R_PPC64_JMP_SLOT +0+ __tls_get_addr_opt \+ 0
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size Type +Bind +Vis +Ndx Name
.* NOTYPE +LOCAL +DEFAULT +UND
.* TLS +GLOBAL DEFAULT +UND gd
-.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr
.* TLS +GLOBAL DEFAULT +UND ld
.* TLS +GLOBAL DEFAULT +9 ld2
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
@@ -96,10 +96,9 @@ Symbol table '\.symtab' contains [0-9]+
.* TLS +LOCAL +DEFAULT +8 le4
.* TLS +LOCAL +DEFAULT +8 le5
.* OBJECT +LOCAL +HIDDEN +10 _DYNAMIC
-.* FUNC +LOCAL +DEFAULT +UND \.__tls_get_addr
+.* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
.* GLOBAL DEFAULT +UND gd
.* GLOBAL DEFAULT +9 le0
-.* GLOBAL DEFAULT +UND __tls_get_addr
.* GLOBAL DEFAULT +9 ld0
.* GLOBAL DEFAULT +9 le1
.* GLOBAL DEFAULT +UND ld
@@ -107,6 +106,7 @@ Symbol table '\.symtab' contains [0-9]+
.* TLS +GLOBAL DEFAULT +9 ld2
.* TLS +GLOBAL DEFAULT +9 ld1
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL +DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
.* TLS +GLOBAL DEFAULT +9 gd0
Index: ld/testsuite/ld-powerpc/tlsexe32.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe32.d,v
retrieving revision 1.9
diff -u -p -r1.9 tlsexe32.d
--- ld/testsuite/ld-powerpc/tlsexe32.d 15 Aug 2005 15:39:47 -0000 1.9
+++ ld/testsuite/ld-powerpc/tlsexe32.d 20 Sep 2009 11:12:29 -0000
@@ -12,7 +12,7 @@ Disassembly of section \.text:
.*: 80 7f ff f0 lwz r3,-16\(r31\)
.*: 7c 63 12 14 add r3,r3,r2
.*: 38 7f ff f4 addi r3,r31,-12
-.*: 48 01 01 85 bl .*<__tls_get_addr@plt>
+.*: 48 01 01 85 bl .*<__tls_get_addr_opt@plt>
.*: 3c 62 00 00 addis r3,r2,0
.*: 38 63 90 1c addi r3,r3,-28644
.*: 3c 62 00 00 addis r3,r2,0
@@ -44,4 +44,4 @@ Disassembly of section \.got:
.*: 4e 80 00 21 blrl
.* <_GLOBAL_OFFSET_TABLE_>:
-.*: 01 81 02 b4 00 00 00 00 00 00 00 00 .*
+.*: 01 81 02 b8 00 00 00 00 00 00 00 00 .*
Index: ld/testsuite/ld-powerpc/tlsexe32.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe32.g,v
retrieving revision 1.5
diff -u -p -r1.5 tlsexe32.g
--- ld/testsuite/ld-powerpc/tlsexe32.g 15 Aug 2005 15:39:47 -0000 1.5
+++ ld/testsuite/ld-powerpc/tlsexe32.g 20 Sep 2009 11:12:29 -0000
@@ -8,4 +8,4 @@
Contents of section \.got:
.* 00000000 00000000 00000000 4e800021 .*
-.* 018102b4 00000000 00000000 .*
+.* 018102b8 00000000 00000000 .*
Index: ld/testsuite/ld-powerpc/tlsexe32.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe32.r,v
retrieving revision 1.15
diff -u -p -r1.15 tlsexe32.r
--- ld/testsuite/ld-powerpc/tlsexe32.r 30 Sep 2007 01:33:15 -0000 1.15
+++ ld/testsuite/ld-powerpc/tlsexe32.r 20 Sep 2009 11:12:29 -0000
@@ -57,16 +57,16 @@ Relocation section '\.rela\.dyn' at offs
Relocation section '\.rela\.plt' at offset .* contains 1 entries:
Offset +Info +Type +Sym\. Value +Symbol's Name \+ Addend
-[0-9a-f ]+R_PPC_JMP_SLOT[0-9a-f ]+__tls_get_addr \+ 0
+[0-9a-f ]+R_PPC_JMP_SLOT[0-9a-f ]+__tls_get_addr_opt \+ 0
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size Type +Bind +Vis +Ndx Name
.* NOTYPE +LOCAL +DEFAULT +UND
.* TLS +GLOBAL DEFAULT +UND gd
-.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr
.* TLS +GLOBAL DEFAULT +UND ld
.* NOTYPE +GLOBAL DEFAULT +ABS __end
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
@@ -96,7 +96,6 @@ Symbol table '\.symtab' contains [0-9]+
.* OBJECT +LOCAL +HIDDEN +11 _GLOBAL_OFFSET_TABLE_
.* TLS +GLOBAL DEFAULT +UND gd
.* TLS +GLOBAL DEFAULT +9 le0
-.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr
.* TLS +GLOBAL DEFAULT +9 ld0
.* TLS +GLOBAL DEFAULT +9 le1
.* TLS +GLOBAL DEFAULT +UND ld
@@ -105,6 +104,7 @@ Symbol table '\.symtab' contains [0-9]+
.* TLS +GLOBAL DEFAULT +9 ld2
.* TLS +GLOBAL DEFAULT +9 ld1
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
.* TLS +GLOBAL DEFAULT +9 gd0
Index: ld/testsuite/ld-powerpc/tlsexetoc.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.d,v
retrieving revision 1.8
diff -u -p -r1.8 tlsexetoc.d
--- ld/testsuite/ld-powerpc/tlsexetoc.d 13 Aug 2007 00:20:59 -0000 1.8
+++ ld/testsuite/ld-powerpc/tlsexetoc.d 20 Sep 2009 11:12:29 -0000
@@ -8,21 +8,34 @@
Disassembly of section \.text:
-.* <_start-0x18>:
+.* <_start-0x4c>:
+.* e9 63 00 00 ld r11,0\(r3\)
+.* e9 83 00 08 ld r12,8\(r3\)
+.* 7c 60 1b 78 mr r0,r3
+.* 2c 2b 00 00 cmpdi r11,0
+.* 7c 6c 6a 14 add r3,r12,r13
+.* 4d 82 00 20 beqlr
+.* 7c 03 03 78 mr r3,r0
+.* 7d 68 02 a6 mflr r11
+.* f9 61 00 20 std r11,32\(r1\)
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 70 ld r11,-32656\(r2\)
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 80 ld r11,-32640\(r2\)
.* e8 42 80 78 ld r2,-32648\(r2\)
-.* 4e 80 04 20 bctr
+.* 4e 80 04 21 bctrl
+.* e9 61 00 20 ld r11,32\(r1\)
+.* e8 41 00 28 ld r2,40\(r1\)
+.* 7d 68 03 a6 mtlr r11
+.* 4e 80 00 20 blr
.* <_start>:
.* 38 62 80 08 addi r3,r2,-32760
-.* 4b ff ff e5 bl .*
-.* e8 41 00 28 ld r2,40\(r1\)
+.* 4b ff ff b1 bl .*
+.* 60 00 00 00 nop
.* 38 62 80 18 addi r3,r2,-32744
-.* 4b ff ff d9 bl .*
-.* e8 41 00 28 ld r2,40\(r1\)
+.* 4b ff ff a5 bl .*
+.* 60 00 00 00 nop
.* 3c 6d 00 00 addis r3,r13,0
.* 60 00 00 00 nop
.* 38 63 90 38 addi r3,r3,-28616
@@ -39,8 +52,9 @@ Disassembly of section \.text:
.* 89 4d 90 60 lbz r10,-28576\(r13\)
.* 3d 2d 00 00 addis r9,r13,0
.* 99 49 90 68 stb r10,-28568\(r9\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
-.* 00 01 02 18 .*
+.* 00 01 02 28 .*
.* 7d 88 02 a6 mflr r12
.* 42 9f 00 05 bcl- 20,4\*cr7\+so,.*
.* 7d 68 02 a6 mflr r11
Index: ld/testsuite/ld-powerpc/tlsexetoc.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexetoc.g
--- ld/testsuite/ld-powerpc/tlsexetoc.g 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexetoc.g 20 Sep 2009 11:12:29 -0000
@@ -7,7 +7,7 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 10018568 00000000 00000000 .*
+.* 00000000 100185b0 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000001 .*
.* 00000000 00000000 00000000 00000001 .*
Index: ld/testsuite/ld-powerpc/tlsexetoc.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.r,v
retrieving revision 1.22
diff -u -p -r1.22 tlsexetoc.r
--- ld/testsuite/ld-powerpc/tlsexetoc.r 30 Sep 2007 01:33:15 -0000 1.22
+++ ld/testsuite/ld-powerpc/tlsexetoc.r 20 Sep 2009 11:12:29 -0000
@@ -16,10 +16,10 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+b8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+f0 0+ +AX +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]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
+\[[ 0-9]+\] \.branch_lt +PROGBITS .* 0+ 0+ +WA +0 +0 +8
+\[[ 0-9]+\] \.got +PROGBITS .* 0+58 08 +WA +0 +0 +8
+\[[ 0-9]+\] \.plt +.*
@@ -59,15 +59,15 @@ Relocation section '\.rela\.dyn' at offs
Relocation section '\.rela\.plt' at offset .* contains 1 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
-[0-9a-f ]+R_PPC64_JMP_SLOT +0+ __tls_get_addr \+ 0
+[0-9a-f ]+R_PPC64_JMP_SLOT +0+ __tls_get_addr_opt \+ 0
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size Type +Bind +Vis +Ndx Name
.* NOTYPE +LOCAL +DEFAULT +UND
.* TLS +GLOBAL DEFAULT +UND gd
-.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr
.* TLS +GLOBAL DEFAULT +UND ld
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
@@ -96,10 +96,9 @@ Symbol table '\.symtab' contains [0-9]+
.* TLS +LOCAL +DEFAULT +8 le5
.* NOTYPE +LOCAL +DEFAULT +12 \.Lie0
.* OBJECT +LOCAL +HIDDEN +10 _DYNAMIC
-.* FUNC +LOCAL +DEFAULT +UND \.__tls_get_addr
+.* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
.* TLS +GLOBAL DEFAULT +UND gd
.* TLS +GLOBAL DEFAULT +9 le0
-.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr
.* TLS +GLOBAL DEFAULT +9 ld0
.* TLS +GLOBAL DEFAULT +9 le1
.* TLS +GLOBAL DEFAULT +UND ld
@@ -107,6 +106,7 @@ Symbol table '\.symtab' contains [0-9]+
.* TLS +GLOBAL DEFAULT +9 ld2
.* TLS +GLOBAL DEFAULT +9 ld1
.* NOTYPE +GLOBAL DEFAULT +ABS __bss_start
+.* FUNC +GLOBAL DEFAULT +UND __tls_get_addr_opt
.* NOTYPE +GLOBAL DEFAULT +ABS _edata
.* NOTYPE +GLOBAL DEFAULT +ABS _end
.* TLS +GLOBAL DEFAULT +9 gd0
Index: ld/testsuite/ld-powerpc/tlslib.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlslib.s,v
retrieving revision 1.2
diff -u -p -r1.2 tlslib.s
--- ld/testsuite/ld-powerpc/tlslib.s 9 Feb 2003 04:37:04 -0000 1.2
+++ ld/testsuite/ld-powerpc/tlslib.s 20 Sep 2009 11:12:29 -0000
@@ -1,10 +1,12 @@
- .global .__tls_get_addr,__tls_get_addr,gd,ld
- .type .__tls_get_addr,@function
+ .global __tls_get_addr,__tls_get_addr_opt,gd,ld
+ .type __tls_get_addr,@function
+ .type __tls_get_addr_opt,@function
.section ".opd","aw",@progbits
__tls_get_addr:
+__tls_get_addr_opt:
.align 3
- .quad .__tls_get_addr
+ .quad .L.__tls_get_addr
.quad .TOC.@tocbase
.quad 0
@@ -17,5 +19,6 @@ gd: .space 8
ld: .long 0xc0ffee
.text
-.__tls_get_addr:
+.L.__tls_get_addr:
blr
+ .size __tls_get_addr,. - .L.__tls_get_addr
Index: ld/testsuite/ld-powerpc/tlslib32.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlslib32.s,v
retrieving revision 1.1
diff -u -p -r1.1 tlslib32.s
--- ld/testsuite/ld-powerpc/tlslib32.s 18 Feb 2003 06:11:32 -0000 1.1
+++ ld/testsuite/ld-powerpc/tlslib32.s 20 Sep 2009 11:12:29 -0000
@@ -1,5 +1,6 @@
- .global __tls_get_addr,gd,ld
+ .global __tls_get_addr,__tls_get_addr_opt,gd,ld
.type __tls_get_addr,@function
+ .type __tls_get_addr_opt,@function
.section ".tbss","awT",@nobits
.align 2
@@ -11,4 +12,5 @@ ld: .long 0xc0ffee
.text
__tls_get_addr:
+__tls_get_addr_opt:
blr
Index: ld/testsuite/ld-powerpc/oldtlslib.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/oldtlslib.s
diff -N ld/testsuite/ld-powerpc/oldtlslib.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/oldtlslib.s 21 Sep 2009 00:52:55 -0000
@@ -0,0 +1,29 @@
+ .global __tls_get_addr,__tls_get_addr_opt,gd,ld
+ .global .__tls_get_addr,.__tls_get_addr_opt
+ .type .__tls_get_addr,@function
+ .type .__tls_get_addr_opt,@function
+
+ .section ".opd","aw",@progbits
+__tls_get_addr:
+__tls_get_addr_opt:
+ .align 3
+ .quad .__tls_get_addr
+ .quad .TOC.@tocbase
+ .quad 0
+ .size __tls_get_addr,24
+ .size __tls_get_addr_opt,24
+
+ .section ".tbss","awT",@nobits
+ .align 3
+gd: .space 8
+
+ .section ".tdata","awT",@progbits
+ .align 2
+ld: .long 0xc0ffee
+
+ .text
+.__tls_get_addr:
+.__tls_get_addr_opt:
+ blr
+ .size .__tls_get_addr,. - .__tls_get_addr
+ .size .__tls_get_addr_opt,. - .__tls_get_addr_opt
--
Alan Modra
Australia Development Lab, IBM