[PowerPC64] pc-relative TLS relocations

This patch supports using pcrel instructions in TLS code sequences.  A
number of new relocations are needed, gas operand modifiers to
generate those relocations, and new TLS optimisation.  For
optimisation it turns out that the new pcrel GD and LD sequences can
be distinguished from the non-pcrel GD and LD sequences by there being
different relocations on the new sequence.  The final "add ra,rb,13"
on IE sequences similarly needs a new relocation, or as I chose, a
modification of R_PPC64_TLS.  On pcrel IE code, the R_PPC64_TLS points
one byte into the "add" instruction rather than being on the
instruction boundary.

GD:
 pla 3,z@got@tlsgd@pcrel	  # R_PPC64_GOT_TLSGD34
 bl __tls_get_addr@notoc(z@tlsgd) # R_PPC64_TLSGD and R_PPC64_REL24_NOTOC
  edited to IE
   pld 3,z@got@tprel@pcrel
   add 3,3,13
  edited to LE
   paddi 3,13,z@tprel
   nop

LD:
 pla 3,z@got@tlsld@pcrel	  # R_PPC64_GOT_TLSLD34
 bl __tls_get_addr@notoc(z@tlsld) # R_PPC64_TLSLD and R_PPC64_REL24_NOTOC
 ..
 paddi 9,3,z2@dtprel
 pld 10,z3@got@dtprel@pcrel
 add 10,10,3
  edited to LE
   paddi 3,13,0x1000
   nop

IE:
 pld 9,z@got@tprel@pcrel	  # R_PPC64_GOT_TPREL34
 add 3,9,z@tls@pcrel		  # R_PPC64_TLS at insn+1
 ldx 4,9,z@tls@pcrel
 lwax 5,9,z@tls@pcrel
 stdx 5,9,z@tls@pcrel
  edited to LE
  paddi 9,13,z@tprel
  nop
  ld 4,0(9)
  lwa 5,0(9)
  std 5,0(9)

LE:
 paddi 10,13,z@tprel

include/
	* elf/ppc64.h (R_PPC64_TPREL34, R_PPC64_DTPREL34),
	(R_PPC64_GOT_TLSGD34, R_PPC64_GOT_TLSLD34),
	(R_PPC64_GOT_TPREL34, R_PPC64_GOT_DTPREL34): Define.
	(IS_PPC64_TLS_RELOC): Include new tls relocs.
bfd/
	* reloc.c (BFD_RELOC_PPC64_TPREL34, BFD_RELOC_PPC64_DTPREL34),
	(BFD_RELOC_PPC64_GOT_TLSGD34, BFD_RELOC_PPC64_GOT_TLSLD34),
	(BFD_RELOC_PPC64_GOT_TPREL34, BFD_RELOC_PPC64_GOT_DTPREL34),
	(BFD_RELOC_PPC64_TLS_PCREL): New pcrel tls relocs.
	* elf64-ppc.c (ppc64_elf_howto_raw): Add howtos for pcrel tls relocs.
	(ppc64_elf_reloc_type_lookup): Translate pcrel tls relocs.
	(must_be_dyn_reloc, dec_dynrel_count): Add R_PPC64_TPREL64.
	(ppc64_elf_check_relocs): Support pcrel tls relocs.
	(ppc64_elf_tls_optimize, ppc64_elf_relocate_section): Likewise.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
gas/
	* config/tc-ppc.c (ppc_elf_suffix): Map "tls@pcrel", "got@tlsgd@pcrel",
	"got@tlsld@pcrel", "got@tprel@pcrel", and "got@dtprel@pcrel".
	(fixup_size, md_assemble): Handle pcrel tls relocs.
	(ppc_force_relocation, ppc_fix_adjustable): Likewise.
	(md_apply_fix, tc_gen_reloc): Likewise.
ld/
	* testsuite/ld-powerpc/tlsgd.d,
	* testsuite/ld-powerpc/tlsgd.s,
	* testsuite/ld-powerpc/tlsie.d,
	* testsuite/ld-powerpc/tlsie.s,
	* testsuite/ld-powerpc/tlsld.d,
	* testsuite/ld-powerpc/tlsld.s: New tests.
	* testsuite/ld-powerpc/powerpc.exp: Run them.
This commit is contained in:
Alan Modra 2019-07-19 15:36:58 +09:30
parent 7a70898417
commit c213164ad2
17 changed files with 634 additions and 35 deletions

View file

@ -1,3 +1,17 @@
2019-07-19 Alan Modra <amodra@gmail.com>
* reloc.c (BFD_RELOC_PPC64_TPREL34, BFD_RELOC_PPC64_DTPREL34),
(BFD_RELOC_PPC64_GOT_TLSGD34, BFD_RELOC_PPC64_GOT_TLSLD34),
(BFD_RELOC_PPC64_GOT_TPREL34, BFD_RELOC_PPC64_GOT_DTPREL34),
(BFD_RELOC_PPC64_TLS_PCREL): New pcrel tls relocs.
* elf64-ppc.c (ppc64_elf_howto_raw): Add howtos for pcrel tls relocs.
(ppc64_elf_reloc_type_lookup): Translate pcrel tls relocs.
(must_be_dyn_reloc, dec_dynrel_count): Add R_PPC64_TPREL64.
(ppc64_elf_check_relocs): Support pcrel tls relocs.
(ppc64_elf_tls_optimize, ppc64_elf_relocate_section): Likewise.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
2019-07-18 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_relocate_section): Don't bother selecting

View file

@ -3563,6 +3563,13 @@ instruction. */
BFD_RELOC_PPC64_DTPREL16_HIGHERA,
BFD_RELOC_PPC64_DTPREL16_HIGHEST,
BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
BFD_RELOC_PPC64_TPREL34,
BFD_RELOC_PPC64_DTPREL34,
BFD_RELOC_PPC64_GOT_TLSGD34,
BFD_RELOC_PPC64_GOT_TLSLD34,
BFD_RELOC_PPC64_GOT_TPREL34,
BFD_RELOC_PPC64_GOT_DTPREL34,
BFD_RELOC_PPC64_TLS_PCREL,
/* IBM 370/390 relocations */
BFD_RELOC_I370_D12,

View file

@ -920,6 +920,24 @@ static reloc_howto_type ppc64_elf_howto_raw[] =
HOW (R_PPC64_PLT_PCREL34_NOTOC, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_TPREL34, 4, 34, 0x3ffff0000ffffULL, 0, FALSE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_DTPREL34, 4, 34, 0x3ffff0000ffffULL, 0, FALSE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_GOT_TLSGD34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_GOT_TLSLD34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_GOT_TPREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_GOT_DTPREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_ADDR16_HIGHER34, 1, 16, 0xffff, 34, FALSE, dont,
bfd_elf_generic_reloc),
@ -1119,6 +1137,7 @@ ppc64_elf_reloc_type_lookup (bfd *abfd,
break;
case BFD_RELOC_PPC64_PLTGOT16_LO_DS: r = R_PPC64_PLTGOT16_LO_DS;
break;
case BFD_RELOC_PPC64_TLS_PCREL:
case BFD_RELOC_PPC_TLS: r = R_PPC64_TLS;
break;
case BFD_RELOC_PPC_TLSGD: r = R_PPC64_TLSGD;
@ -1253,6 +1272,18 @@ ppc64_elf_reloc_type_lookup (bfd *abfd,
break;
case BFD_RELOC_PPC64_PLT_PCREL34: r = R_PPC64_PLT_PCREL34;
break;
case BFD_RELOC_PPC64_TPREL34: r = R_PPC64_TPREL34;
break;
case BFD_RELOC_PPC64_DTPREL34: r = R_PPC64_DTPREL34;
break;
case BFD_RELOC_PPC64_GOT_TLSGD34: r = R_PPC64_GOT_TLSGD34;
break;
case BFD_RELOC_PPC64_GOT_TLSLD34: r = R_PPC64_GOT_TLSLD34;
break;
case BFD_RELOC_PPC64_GOT_TPREL34: r = R_PPC64_GOT_TPREL34;
break;
case BFD_RELOC_PPC64_GOT_DTPREL34: r = R_PPC64_GOT_DTPREL34;
break;
case BFD_RELOC_PPC64_ADDR16_HIGHER34: r = R_PPC64_ADDR16_HIGHER34;
break;
case BFD_RELOC_PPC64_ADDR16_HIGHERA34: r = R_PPC64_ADDR16_HIGHERA34;
@ -2727,6 +2758,7 @@ must_be_dyn_reloc (struct bfd_link_info *info,
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_TPREL16_HIGHESTA:
case R_PPC64_TPREL64:
case R_PPC64_TPREL34:
/* These relocations are relative but in a shared library the
linker doesn't know the thread pointer base. */
return bfd_link_dll (info);
@ -4514,6 +4546,8 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_D34_HI30:
case R_PPC64_D34_HA30:
case R_PPC64_D28:
case R_PPC64_TPREL34:
case R_PPC64_DTPREL34:
htab->powerxx_stubs = 1;
/* Fall through. */
default:
@ -4528,6 +4562,10 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_PCREL34:
case R_PPC64_GOT_PCREL34:
case R_PPC64_GOT_TLSGD34:
case R_PPC64_GOT_TLSLD34:
case R_PPC64_GOT_TPREL34:
case R_PPC64_GOT_DTPREL34:
case R_PPC64_PLT_PCREL34:
case R_PPC64_PLT_PCREL34_NOTOC:
case R_PPC64_PCREL28:
@ -4580,6 +4618,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_GOT_TLSLD16_HI:
case R_PPC64_GOT_TLSLD16_HA:
case R_PPC64_GOT_TLSLD34:
tls_type = TLS_TLS | TLS_LD;
goto dogottls;
@ -4587,6 +4626,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSGD16_HA:
case R_PPC64_GOT_TLSGD34:
tls_type = TLS_TLS | TLS_GD;
goto dogottls;
@ -4594,6 +4634,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_TPREL16_HA:
case R_PPC64_GOT_TPREL34:
if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS;
tls_type = TLS_TLS | TLS_TPREL;
@ -4603,6 +4644,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_GOT_DTPREL16_LO_DS:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_GOT_DTPREL16_HA:
case R_PPC64_GOT_DTPREL34:
tls_type = TLS_TLS | TLS_DTPREL;
dogottls:
sec->has_tls_reloc = 1;
@ -4949,6 +4991,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_PPC64_TPREL16_HIGHERA:
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_TPREL16_HIGHESTA:
case R_PPC64_TPREL34:
if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS;
goto dodyn;
@ -6769,6 +6812,7 @@ dec_dynrel_count (bfd_vma r_info,
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_TPREL16_HIGHESTA:
case R_PPC64_TPREL64:
case R_PPC64_TPREL34:
case R_PPC64_DTPMOD64:
case R_PPC64_DTPREL64:
case R_PPC64_ADDR64:
@ -7733,6 +7777,12 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
value += sym_sec->output_offset;
value += sym_sec->output_section->vma;
value -= htab->elf.tls_sec->vma + TP_OFFSET;
/* Note that even though the prefix insns
allow a 1<<33 offset we use the same test
as for addis;addi. There may be a mix of
pcrel and non-pcrel code and the decision
to optimise is per symbol, not per TLS
sequence. */
ok_tprel = value + 0x80008000ULL < 1ULL << 32;
}
}
@ -7764,6 +7814,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
{
case R_PPC64_GOT_TLSLD16:
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_GOT_TLSLD34:
expecting_tls_get_addr = 1;
found_tls_get_addr_arg = 1;
/* Fall through. */
@ -7784,6 +7835,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
case R_PPC64_GOT_TLSGD16:
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSGD34:
expecting_tls_get_addr = 1;
found_tls_get_addr_arg = 1;
/* Fall through. */
@ -7800,6 +7852,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
tls_type = TLS_TLS | TLS_GD;
break;
case R_PPC64_GOT_TPREL34:
case R_PPC64_GOT_TPREL16_DS:
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
@ -14436,14 +14489,35 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
break;
case R_PPC64_GOT_TPREL34:
if ((tls_mask & TLS_TLS) != 0
&& (tls_mask & TLS_TPREL) == 0)
{
/* pld ra,sym@got@tprel@pcrel -> paddi ra,r13,sym@tprel */
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
pinsn <<= 32;
pinsn |= bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
pinsn += ((2ULL << 56) + (-1ULL << 52)
+ (14ULL << 26) - (57ULL << 26) + (13ULL << 16));
bfd_put_32 (input_bfd, pinsn >> 32,
contents + rel->r_offset);
bfd_put_32 (input_bfd, pinsn & 0xffffffff,
contents + rel->r_offset + 4);
r_type = R_PPC64_TPREL34;
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
}
break;
case R_PPC64_TLS:
if ((tls_mask & TLS_TLS) != 0
&& (tls_mask & TLS_TPREL) == 0)
{
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
insn = _bfd_elf_ppc_at_tls_transform (insn, 13);
if (insn == 0)
abort ();
break;
if ((rel->r_offset & 3) == 0)
{
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
/* Was PPC64_TLS which sits on insn boundary, now
PPC64_TPREL16_LO which is at low-order half-word. */
@ -14460,6 +14534,28 @@ ppc64_elf_relocate_section (bfd *output_bfd,
else
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
}
else if ((rel->r_offset & 3) == 1)
{
/* For pcrel IE to LE we already have the full
offset and thus don't need an addi here. A nop
or mr will do. */
if ((insn & (0x3f << 26)) == 14 << 26)
{
/* Extract regs from addi rt,ra,si. */
unsigned int rt = (insn >> 21) & 0x1f;
unsigned int ra = (insn >> 16) & 0x1f;
if (rt == ra)
insn = NOP;
else
{
/* Build or ra,rs,rb with rb==rs, ie. mr ra,rs. */
insn = (rt << 16) | (ra << 21) | (ra << 11);
insn |= (31u << 26) | (444u << 1);
}
}
bfd_put_32 (input_bfd, insn, contents + rel->r_offset - 1);
}
}
break;
case R_PPC64_GOT_TLSGD16_HI:
@ -14584,6 +14680,51 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
break;
case R_PPC64_GOT_TLSGD34:
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
{
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
pinsn <<= 32;
pinsn |= bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
if ((tls_mask & TLS_GDIE) != 0)
{
/* IE, pla -> pld */
pinsn += (-2ULL << 56) + (57ULL << 26) - (14ULL << 26);
r_type = R_PPC64_GOT_TPREL34;
}
else
{
/* LE, pla pcrel -> paddi r13 */
pinsn += (-1ULL << 52) + (13ULL << 16);
r_type = R_PPC64_TPREL34;
}
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
bfd_put_32 (input_bfd, pinsn >> 32,
contents + rel->r_offset);
bfd_put_32 (input_bfd, pinsn & 0xffffffff,
contents + rel->r_offset + 4);
}
break;
case R_PPC64_GOT_TLSLD34:
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
{
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
pinsn <<= 32;
pinsn |= bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
pinsn += (-1ULL << 52) + (13ULL << 16);
bfd_put_32 (input_bfd, pinsn >> 32,
contents + rel->r_offset);
bfd_put_32 (input_bfd, pinsn & 0xffffffff,
contents + rel->r_offset + 4);
rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
r_symndx = STN_UNDEF;
r_type = R_PPC64_TPREL34;
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
goto again;
}
break;
case R_PPC64_TLSGD:
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
&& rel + 1 < relend)
@ -14619,16 +14760,27 @@ ppc64_elf_relocate_section (bfd *output_bfd,
r_symndx = toc_symndx;
rel->r_addend = toc_addend;
}
r_type = R_PPC64_TPREL16_LO;
if (r_type1 == R_PPC64_REL24_NOTOC
|| r_type1 == R_PPC64_PLTCALL_NOTOC)
{
r_type = R_PPC64_NONE;
insn2 = NOP;
}
else
{
rel->r_offset = offset + d_offset;
r_type = R_PPC64_TPREL16_LO;
insn2 = 0x38630000; /* addi 3,3,0 */
}
}
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
/* Zap the reloc on the _tls_get_addr call too. */
BFD_ASSERT (offset == rel[1].r_offset);
rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
bfd_put_32 (input_bfd, insn2, contents + offset);
if ((tls_mask & TLS_GDIE) == 0 && toc_symndx != 0)
if ((tls_mask & TLS_GDIE) == 0
&& toc_symndx != 0
&& r_type != R_PPC64_NONE)
goto again;
}
break;
@ -14654,17 +14806,26 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (ELF64_R_TYPE (rel[1].r_info) == R_PPC64_PLTCALL)
bfd_put_32 (output_bfd, NOP, contents + offset + 4);
if (r_type1 == R_PPC64_REL24_NOTOC
|| r_type1 == R_PPC64_PLTCALL_NOTOC)
{
r_type = R_PPC64_NONE;
insn2 = NOP;
}
else
{
rel->r_offset = offset + d_offset;
r_symndx = STN_UNDEF;
r_type = R_PPC64_TPREL16_LO;
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
insn2 = 0x38630000; /* addi 3,3,0 */
}
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
/* Zap the reloc on the _tls_get_addr call too. */
BFD_ASSERT (offset == rel[1].r_offset);
rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
insn2 = 0x38630000; /* addi 3,3,0 */
bfd_put_32 (input_bfd, insn2, contents + offset);
if (r_type != R_PPC64_NONE)
goto again;
}
break;
@ -15267,6 +15428,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSGD16_HA:
case R_PPC64_GOT_TLSGD34:
tls_type = TLS_TLS | TLS_GD;
goto dogot;
@ -15274,6 +15436,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_GOT_TLSLD16_HI:
case R_PPC64_GOT_TLSLD16_HA:
case R_PPC64_GOT_TLSLD34:
tls_type = TLS_TLS | TLS_LD;
goto dogot;
@ -15281,6 +15444,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_TPREL16_HA:
case R_PPC64_GOT_TPREL34:
tls_type = TLS_TLS | TLS_TPREL;
goto dogot;
@ -15288,6 +15452,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT_DTPREL16_LO_DS:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_GOT_DTPREL16_HA:
case R_PPC64_GOT_DTPREL34:
tls_type = TLS_TLS | TLS_DTPREL;
goto dogot;
@ -15309,7 +15474,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
struct got_entry *ent;
bfd_vma sym_addend = orig_rel.r_addend;
if (r_type == R_PPC64_GOT_PCREL34)
if (r_type == R_PPC64_GOT_PCREL34
|| r_type == R_PPC64_GOT_TLSGD34
|| r_type == R_PPC64_GOT_TLSLD34
|| r_type == R_PPC64_GOT_TPREL34
|| r_type == R_PPC64_GOT_DTPREL34)
sym_addend = 0;
if (tls_type == (TLS_TLS | TLS_LD)
@ -15491,7 +15660,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
abort ();
relocation = got->output_section->vma + got->output_offset + off;
if (r_type != R_PPC64_GOT_PCREL34)
if (!(r_type == R_PPC64_GOT_PCREL34
|| r_type == R_PPC64_GOT_TLSGD34
|| r_type == R_PPC64_GOT_TLSLD34
|| r_type == R_PPC64_GOT_TPREL34
|| r_type == R_PPC64_GOT_DTPREL34))
addend = -(TOCstart + htab->sec_info[input_section->id].toc_off);
}
break;
@ -15644,6 +15817,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_TPREL16_HIGHERA:
case R_PPC64_TPREL16_HIGHEST:
case R_PPC64_TPREL16_HIGHESTA:
case R_PPC64_TPREL34:
if (h != NULL
&& h->elf.root.type == bfd_link_hash_undefweak
&& h->elf.dynindx == -1)
@ -15679,6 +15853,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_DTPREL16_HIGHERA:
case R_PPC64_DTPREL16_HIGHEST:
case R_PPC64_DTPREL16_HIGHESTA:
case R_PPC64_DTPREL34:
if (htab->elf.tls_sec != NULL)
addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
break;
@ -16301,6 +16476,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_D34_HA30:
case R_PPC64_PCREL34:
case R_PPC64_GOT_PCREL34:
case R_PPC64_TPREL34:
case R_PPC64_DTPREL34:
case R_PPC64_GOT_TLSGD34:
case R_PPC64_GOT_TLSLD34:
case R_PPC64_GOT_TPREL34:
case R_PPC64_GOT_DTPREL34:
case R_PPC64_PLT_PCREL34:
case R_PPC64_PLT_PCREL34_NOTOC:
case R_PPC64_D28:

View file

@ -1539,6 +1539,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC64_DTPREL16_HIGHERA",
"BFD_RELOC_PPC64_DTPREL16_HIGHEST",
"BFD_RELOC_PPC64_DTPREL16_HIGHESTA",
"BFD_RELOC_PPC64_TPREL34",
"BFD_RELOC_PPC64_DTPREL34",
"BFD_RELOC_PPC64_GOT_TLSGD34",
"BFD_RELOC_PPC64_GOT_TLSLD34",
"BFD_RELOC_PPC64_GOT_TPREL34",
"BFD_RELOC_PPC64_GOT_DTPREL34",
"BFD_RELOC_PPC64_TLS_PCREL",
"BFD_RELOC_I370_D12",
"BFD_RELOC_CTOR",
"BFD_RELOC_ARM_PCREL_BRANCH",

View file

@ -3007,6 +3007,20 @@ ENUMX
BFD_RELOC_PPC64_DTPREL16_HIGHEST
ENUMX
BFD_RELOC_PPC64_DTPREL16_HIGHESTA
ENUMX
BFD_RELOC_PPC64_TPREL34
ENUMX
BFD_RELOC_PPC64_DTPREL34
ENUMX
BFD_RELOC_PPC64_GOT_TLSGD34
ENUMX
BFD_RELOC_PPC64_GOT_TLSLD34
ENUMX
BFD_RELOC_PPC64_GOT_TPREL34
ENUMX
BFD_RELOC_PPC64_GOT_DTPREL34
ENUMX
BFD_RELOC_PPC64_TLS_PCREL
ENUMDOC
PowerPC and PowerPC64 thread-local storage relocations.

View file

@ -1,3 +1,11 @@
2019-07-19 Alan Modra <amodra@gmail.com>
* config/tc-ppc.c (ppc_elf_suffix): Map "tls@pcrel", "got@tlsgd@pcrel",
"got@tlsld@pcrel", "got@tprel@pcrel", and "got@dtprel@pcrel".
(fixup_size, md_assemble): Handle pcrel tls relocs.
(ppc_force_relocation, ppc_fix_adjustable): Likewise.
(md_apply_fix, tc_gen_reloc): Likewise.
2019-07-17 Jose E. Marchesi <jose.marchesi@oracle.com>
* config/tc-bpf.c: Make .lcomm to get a third argument with the

View file

@ -2224,6 +2224,11 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP64 ("pcrel", BFD_RELOC_PPC64_PCREL34),
MAP64 ("got@pcrel", BFD_RELOC_PPC64_GOT_PCREL34),
MAP64 ("plt@pcrel", BFD_RELOC_PPC64_PLT_PCREL34),
MAP64 ("tls@pcrel", BFD_RELOC_PPC64_TLS_PCREL),
MAP64 ("got@tlsgd@pcrel", BFD_RELOC_PPC64_GOT_TLSGD34),
MAP64 ("got@tlsld@pcrel", BFD_RELOC_PPC64_GOT_TLSLD34),
MAP64 ("got@tprel@pcrel", BFD_RELOC_PPC64_GOT_TPREL34),
MAP64 ("got@dtprel@pcrel", BFD_RELOC_PPC64_GOT_DTPREL34),
MAP64 ("higher34", BFD_RELOC_PPC64_ADDR16_HIGHER34),
MAP64 ("highera34", BFD_RELOC_PPC64_ADDR16_HIGHERA34),
MAP64 ("highest34", BFD_RELOC_PPC64_ADDR16_HIGHEST34),
@ -3155,6 +3160,7 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
case BFD_RELOC_PPC64_TLS_PCREL:
case BFD_RELOC_RVA:
size = 4;
break;
@ -3196,6 +3202,8 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
case BFD_RELOC_PPC64_D34_LO:
case BFD_RELOC_PPC64_D34_HI30:
case BFD_RELOC_PPC64_D34_HA30:
case BFD_RELOC_PPC64_TPREL34:
case BFD_RELOC_PPC64_DTPREL34:
case BFD_RELOC_PPC64_TOC:
size = 8;
break;
@ -3203,6 +3211,10 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
case BFD_RELOC_64_PCREL:
case BFD_RELOC_64_PLT_PCREL:
case BFD_RELOC_PPC64_GOT_PCREL34:
case BFD_RELOC_PPC64_GOT_TLSGD34:
case BFD_RELOC_PPC64_GOT_TLSLD34:
case BFD_RELOC_PPC64_GOT_TPREL34:
case BFD_RELOC_PPC64_GOT_DTPREL34:
case BFD_RELOC_PPC64_PCREL28:
case BFD_RELOC_PPC64_PCREL34:
case BFD_RELOC_PPC64_PLT_PCREL34:
@ -3744,6 +3756,7 @@ md_assemble (char *str)
break;
case BFD_RELOC_PPC_TLS:
case BFD_RELOC_PPC64_TLS_PCREL:
if (!_bfd_elf_ppc_at_tls_transform (opcode->opcode, 0))
as_bad (_("@tls may not be used with \"%s\" operands"),
opcode->name);
@ -3756,12 +3769,18 @@ md_assemble (char *str)
break;
/* We'll only use the 32 (or 64) bit form of these relocations
in constants. Instructions get the 16 bit form. */
in constants. Instructions get the 16 or 34 bit form. */
case BFD_RELOC_PPC_DTPREL:
if (operand->bitm == 0x3ffffffffULL)
reloc = BFD_RELOC_PPC64_DTPREL34;
else
reloc = BFD_RELOC_PPC_DTPREL16;
break;
case BFD_RELOC_PPC_TPREL:
if (operand->bitm == 0x3ffffffffULL)
reloc = BFD_RELOC_PPC64_TPREL34;
else
reloc = BFD_RELOC_PPC_TPREL16;
break;
@ -3774,6 +3793,10 @@ md_assemble (char *str)
/* Fall through. */
case BFD_RELOC_PPC64_GOT_PCREL34:
case BFD_RELOC_PPC64_PLT_PCREL34:
case BFD_RELOC_PPC64_GOT_TLSGD34:
case BFD_RELOC_PPC64_GOT_TLSLD34:
case BFD_RELOC_PPC64_GOT_TPREL34:
case BFD_RELOC_PPC64_GOT_DTPREL34:
if (operand->bitm != 0x3ffffffffULL
|| (operand->flags & PPC_OPERAND_NEGATIVE) != 0)
as_warn (_("%s unsupported on this instruction"), "@pcrel");
@ -7003,7 +7026,7 @@ ppc_force_relocation (fixS *fix)
}
if (fix->fx_r_type >= BFD_RELOC_PPC_TLS
&& fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA)
&& fix->fx_r_type <= BFD_RELOC_PPC64_TLS_PCREL)
return 1;
return generic_force_reloc (fix);
@ -7071,7 +7094,7 @@ ppc_fix_adjustable (fixS *fix)
&& fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
&& fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
&& !(fix->fx_r_type >= BFD_RELOC_PPC_TLS
&& fix->fx_r_type <= BFD_RELOC_PPC64_DTPREL16_HIGHESTA));
&& fix->fx_r_type <= BFD_RELOC_PPC64_TLS_PCREL));
}
#endif
@ -7503,6 +7526,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_PPC64_DTPREL16_HIGHERA:
case BFD_RELOC_PPC64_DTPREL16_HIGHEST:
case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:
case BFD_RELOC_PPC64_TPREL34:
case BFD_RELOC_PPC64_DTPREL34:
case BFD_RELOC_PPC64_GOT_TLSGD34:
case BFD_RELOC_PPC64_GOT_TLSLD34:
case BFD_RELOC_PPC64_GOT_TPREL34:
case BFD_RELOC_PPC64_GOT_DTPREL34:
gas_assert (fixP->fx_addsy != NULL);
S_SET_THREAD_LOCAL (fixP->fx_addsy);
fieldval = 0;
@ -7573,6 +7602,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_PPC_TLS:
case BFD_RELOC_PPC_TLSGD:
case BFD_RELOC_PPC_TLSLD:
case BFD_RELOC_PPC64_TLS_PCREL:
fieldval = 0;
break;
#endif
@ -7826,6 +7856,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_PPC64_TPREL16_HIGHERA:
case BFD_RELOC_PPC64_TPREL16_HIGHEST:
case BFD_RELOC_PPC64_TPREL16_HIGHESTA:
case BFD_RELOC_PPC64_TLS_PCREL:
fixP->fx_done = 0;
break;
#endif
@ -7918,6 +7949,9 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
/* BFD_RELOC_PPC64_TLS_PCREL generates R_PPC64_TLS with an odd r_offset. */
if (fixp->fx_r_type == BFD_RELOC_PPC64_TLS_PCREL)
reloc->address++;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)
{

View file

@ -1,3 +1,10 @@
2019-07-19 Alan Modra <amodra@gmail.com>
* elf/ppc64.h (R_PPC64_TPREL34, R_PPC64_DTPREL34),
(R_PPC64_GOT_TLSGD34, R_PPC64_GOT_TLSLD34),
(R_PPC64_GOT_TPREL34, R_PPC64_GOT_DTPREL34): Define.
(IS_PPC64_TLS_RELOC): Include new tls relocs.
2019-07-18 Nick Alcock <nick.alcock@oracle.com>
* ctf-api.h (ECTF_NOTFUNC): Fix description.

View file

@ -181,6 +181,12 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
RELOC_NUMBER (R_PPC64_REL16_HIGHESTA34, 143)
RELOC_NUMBER (R_PPC64_D28, 144)
RELOC_NUMBER (R_PPC64_PCREL28, 145)
RELOC_NUMBER (R_PPC64_TPREL34, 146)
RELOC_NUMBER (R_PPC64_DTPREL34, 147)
RELOC_NUMBER (R_PPC64_GOT_TLSGD34, 148)
RELOC_NUMBER (R_PPC64_GOT_TLSLD34, 149)
RELOC_NUMBER (R_PPC64_GOT_TPREL34, 150)
RELOC_NUMBER (R_PPC64_GOT_DTPREL34, 151)
#ifndef RELOC_MACROS_GEN_FUNC
/* Relocation only used internally by gas or ld. If you need to use
@ -218,8 +224,8 @@ END_RELOC_NUMBERS (R_PPC64_max)
#define IS_PPC64_TLS_RELOC(R) \
(((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) \
|| ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
|| ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA) \
|| ((R) >= R_PPC64_TPREL34 && (R) <= R_PPC64_GOT_DTPREL34))
/* e_flags bits specifying ABI.
1 for original function descriptor using ABI,

View file

@ -1,3 +1,13 @@
2019-07-19 Alan Modra <amodra@gmail.com>
* testsuite/ld-powerpc/tlsgd.d,
* testsuite/ld-powerpc/tlsgd.s,
* testsuite/ld-powerpc/tlsie.d,
* testsuite/ld-powerpc/tlsie.s,
* testsuite/ld-powerpc/tlsld.d,
* testsuite/ld-powerpc/tlsld.s: New tests.
* testsuite/ld-powerpc/powerpc.exp: Run them.
2019-07-19 Alan Modra <amodra@gmail.com>
* testsuite/ld-powerpc/tlsldopt.d: Rename from tlsld.d.

View file

@ -343,6 +343,9 @@ if [ supports_ppc64 ] then {
run_dump_test "pr23937"
run_dump_test "callstub-1"
run_dump_test "callstub-2"
run_dump_test "tlsgd"
run_dump_test "tlsld"
run_dump_test "tlsie"
}
run_dump_test "tlsldopt32"

View file

@ -0,0 +1,31 @@
#source: tlsgd.s
#as: -a64 -mfuture
#ld: -melf64ppc
#objdump: -dr -Mfuture
.*: file format .*
Disassembly of section \.text:
.*:
.*: (60 00 00 00|00 00 00 60) nop
.*: (38 6d 90 08|08 90 6d 38) addi r3,r13,-28664
.*: (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
.*: (38 6d 90 10|10 90 6d 38) addi r3,r13,-28656
.*: (60 00 00 00|00 00 00 60) nop
.*: (06 03 ff ff|ff ff 03 06) paddi r3,r13,-28648
.*: (38 6d 90 18|18 90 6d 38)
.*: (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
.*: (38 6d 90 20|20 90 6d 38) addi r3,r13,-28640
.*: (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
.*: (38 6d 90 20|20 90 6d 38) addi r3,r13,-28640
.*: (60 00 00 00|00 00 00 60) nop
.*: (06 03 ff ff|ff ff 03 06) paddi r3,r13,-28640
.*: (38 6d 90 20|20 90 6d 38)
.*: (60 00 00 00|00 00 00 60) nop

View file

@ -0,0 +1,52 @@
.section ".tbss","awT",@nobits
.p2align 3
pad: .space 8
.global a
a: .space 8
.global b
b: .space 8
.global c
c: .space 8
.global d
d: .space 8
.text
.globl _start
_start:
#Small model OpenPower
addi 3,2,.La@toc
bl __tls_get_addr(.La@tlsgd)
nop
.section .toc,"aw",@progbits
.p2align 3
.La:
.quad a@dtpmod
.quad a@dtprel
.text
#Medium mode ELF
addis 3,2,b@got@tlsgd@ha
addi 3,3,b@got@tlsgd@l
bl __tls_get_addr(b@tlsgd)
nop
#PCrel
pla 3,c@got@tlsgd@pcrel
bl __tls_get_addr@notoc(c@tlsgd)
#All of the above using the same symbol
addis 3,2,.Ld@toc@ha
addi 3,3,.Ld@toc@l
bl __tls_get_addr(.Ld@tlsgd)
nop
.section .toc,"aw",@progbits
.Ld:
.quad d@dtpmod
.quad d@dtprel
.text
addis 3,2,d@got@tlsgd@ha
addi 3,3,d@got@tlsgd@l
bl __tls_get_addr(d@tlsgd)
nop
pla 3,d@got@tlsgd@pcrel
bl __tls_get_addr@notoc(d@tlsgd)

View file

@ -0,0 +1,54 @@
#source: tlsie.s
#as: -a64 -mfuture
#ld: -melf64ppc
#objdump: -dr -Mfuture
.*: file format .*
Disassembly of section \.text:
.*:
.*: (60 00 00 00|00 00 00 60) nop
.*: (39 4d 90 08|08 90 4d 39) addi r10,r13,-28664
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.*: (38 6d 90 10|10 90 6d 38) addi r3,r13,-28656
.*: (06 03 ff ff|ff ff 03 06) paddi r4,r13,-28648
.*: (38 8d 90 18|18 90 8d 38)
.*: (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
.*: (39 4d 90 20|20 90 4d 39) addi r10,r13,-28640
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.*: (38 6d 90 20|20 90 6d 38) addi r3,r13,-28640
.*: (06 03 ff ff|ff ff 03 06) paddi r30,r13,-28640
.*: (3b cd 90 20|20 90 cd 3b)
.*: (7f c3 f3 78|78 f3 c3 7f) mr r3,r30
.*: (80 9e 00 00|00 00 9e 80) lwz r4,0\(r30\)
.*: (84 9e 00 00|00 00 9e 84) lwzu r4,0\(r30\)
.*: (88 be 00 00|00 00 be 88) lbz r5,0\(r30\)
.*: (8c be 00 00|00 00 be 8c) lbzu r5,0\(r30\)
.*: (90 de 00 00|00 00 de 90) stw r6,0\(r30\)
.*: (94 de 00 00|00 00 de 94) stwu r6,0\(r30\)
.*: (98 fe 00 00|00 00 fe 98) stb r7,0\(r30\)
.*: (9c fe 00 00|00 00 fe 9c) stbu r7,0\(r30\)
.*: (a1 1e 00 00|00 00 1e a1) lhz r8,0\(r30\)
.*: (a5 1e 00 00|00 00 1e a5) lhzu r8,0\(r30\)
.*: (a9 3e 00 00|00 00 3e a9) lha r9,0\(r30\)
.*: (ad 3e 00 00|00 00 3e ad) lhau r9,0\(r30\)
.*: (b1 5e 00 00|00 00 5e b1) sth r10,0\(r30\)
.*: (b5 5e 00 00|00 00 5e b5) sthu r10,0\(r30\)
.*: (c1 7e 00 00|00 00 7e c1) lfs f11,0\(r30\)
.*: (c5 7e 00 00|00 00 7e c5) lfsu f11,0\(r30\)
.*: (c9 9e 00 00|00 00 9e c9) lfd f12,0\(r30\)
.*: (cd 9e 00 00|00 00 9e cd) lfdu f12,0\(r30\)
.*: (d1 be 00 00|00 00 be d1) stfs f13,0\(r30\)
.*: (d5 be 00 00|00 00 be d5) stfsu f13,0\(r30\)
.*: (d9 de 00 00|00 00 de d9) stfd f14,0\(r30\)
.*: (dd de 00 00|00 00 de dd) stfdu f14,0\(r30\)
.*: (e9 fe 00 00|00 00 fe e9) ld r15,0\(r30\)
.*: (e9 fe 00 01|01 00 fe e9) ldu r15,0\(r30\)
.*: (fa 1e 00 00|00 00 1e fa) std r16,0\(r30\)
.*: (fa 1e 00 01|01 00 1e fa) stdu r16,0\(r30\)
.*: (ea 3e 00 02|02 00 3e ea) lwa r17,0\(r30\)

View file

@ -0,0 +1,77 @@
.section ".tbss","awT",@nobits
.p2align 3
pad: .space 8
.global a
a: .space 8
.global b
b: .space 8
.global c
c: .space 8
.global d
d: .space 8
.text
.globl _start
_start:
#Small model OpenPower
ld 9,.La@toc(2)
add 10,9,.La@tls
.section .toc,"aw",@progbits
.La:
.quad a@tprel
.text
#Medium model ELF
addi 9,2,b@got@tprel@ha
ld 10,b@got@tprel@l(9)
add 3,10,b@tls
#PCrel
pld 4,c@got@tprel@pcrel
add 4,4,c@tls@pcrel
#All of the above using the same symbol
addis 9,2,.Ld@toc@ha
ld 9,.Ld@toc@l(9)
add 10,9,.Ld@tls
.section .toc,"aw",@progbits
.Ld:
.quad d@tprel
.text
addi 9,2,d@got@tprel@ha
ld 31,d@got@tprel@l(9)
add 3,31,d@tls
pld 30,d@got@tprel@pcrel
add 3,30,d@tls@pcrel
#Note that after optimisation r31 and r30 above have a different value to
#what they would have without optimisation. r31 may not even be written.
#Here are all the other insns that gas/ld accept as the final insn of an
#IE sequence. The r30 value below will be different after optimisation
#for the non-update forms.
lwzx 4,30,d@tls@pcrel
lwzux 4,30,d@tls@pcrel
lbzx 5,30,d@tls@pcrel
lbzux 5,30,d@tls@pcrel
stwx 6,30,d@tls@pcrel
stwux 6,30,d@tls@pcrel
stbx 7,30,d@tls@pcrel
stbux 7,30,d@tls@pcrel
lhzx 8,30,d@tls@pcrel
lhzux 8,30,d@tls@pcrel
lhax 9,30,d@tls@pcrel
lhaux 9,30,d@tls@pcrel
sthx 10,30,d@tls@pcrel
sthux 10,30,d@tls@pcrel
lfsx 11,30,d@tls@pcrel
lfsux 11,30,d@tls@pcrel
lfdx 12,30,d@tls@pcrel
lfdux 12,30,d@tls@pcrel
stfsx 13,30,d@tls@pcrel
stfsux 13,30,d@tls@pcrel
stfdx 14,30,d@tls@pcrel
stfdux 14,30,d@tls@pcrel
ldx 15,30,d@tls@pcrel
ldux 15,30,d@tls@pcrel
stdx 16,30,d@tls@pcrel
stdux 16,30,d@tls@pcrel
lwax 17,30,d@tls@pcrel

View file

@ -0,0 +1,36 @@
#source: tlsld.s
#as: -a64 -mfuture
#ld: -melf64ppc
#objdump: -dr -Mfuture
.*: file format .*
Disassembly of section \.text:
.*:
.*: (60 00 00 00|00 00 00 60) nop
.*: (38 6d 10 00|00 10 6d 38) addi r3,r13,4096
.*: (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
.*: (38 6d 10 00|00 10 6d 38) addi r3,r13,4096
.*: (60 00 00 00|00 00 00 60) nop
.*: (06 00 00 00|00 00 00 06) paddi r3,r13,4096
.*: (38 6d 10 00|00 10 6d 38)
.*: (60 00 00 00|00 00 00 60) nop
.*: (06 03 ff ff|ff ff 03 06) paddi r9,r3,-32728
.*: (39 23 80 28|28 80 23 39)
.*: (04 10 00 01|01 00 10 04) pld r10,65784
.*: (e5 40 00 f8|f8 00 40 e5)
.*: (7d 4a 1a 14|14 1a 4a 7d) add r10,r10,r3
.*: (60 00 00 00|00 00 00 60) nop
.*: (60 00 00 00|00 00 00 60) nop
.*: (38 6d 10 00|00 10 6d 38) addi r3,r13,4096
.*: (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
.*: (38 6d 10 00|00 10 6d 38) addi r3,r13,4096
.*: (60 00 00 00|00 00 00 60) nop
.*: (06 00 00 00|00 00 00 06) paddi r3,r13,4096
.*: (38 6d 10 00|00 10 6d 38)
.*: (60 00 00 00|00 00 00 60) nop

View file

@ -0,0 +1,58 @@
.section ".tbss","awT",@nobits
.p2align 3
pad: .space 8
.global a
a: .space 8
.global b
b: .space 8
.global c
c: .space 8
.global d
d: .space 8
z2: .space 8
z3: .space 8
.text
.globl _start
_start:
#Small model OpenPower
addi 3,2,.La@toc
bl __tls_get_addr(.La@tlsld)
nop
.section .toc,"aw",@progbits
.p2align 3
.La:
.quad a@dtpmod
.quad 0
.text
#Medium mode ELF
addis 3,2,b@got@tlsld@ha
addi 3,3,b@got@tlsld@l
bl __tls_get_addr(b@tlsld)
nop
#PCrel, with dtprel access to vars
pla 3,c@got@tlsld@pcrel
bl __tls_get_addr@notoc(c@tlsld)
paddi 9,3,z2@dtprel
pld 10,z3@got@dtprel@pcrel
add 10,10,3
#All of the above using the same symbol
addis 3,2,.Ld@toc@ha
addi 3,3,.Ld@toc@l
bl __tls_get_addr(.Ld@tlsld)
nop
.section .toc,"aw",@progbits
.p2align 3
.Ld:
.quad d@dtpmod
.quad 0
.text
addis 3,2,d@got@tlsld@ha
addi 3,3,d@got@tlsld@l
bl __tls_get_addr(d@tlsld)
nop
pla 3,d@got@tlsld@pcrel
bl __tls_get_addr@notoc(d@tlsld)