include/elf/
* ppc.h (R_PPC_TLSGD, R_PPC_TLSLD): Add new relocs. * ppc64.h (R_PPC64_TLSGD, R_PPC64_TLSLD): Add new relocs. bfd/ * reloc.c (BFD_RELOC_PPC_TLSGD, BFD_RELOC_PPC_TLSLD): New. * section.c (struct bfd_section): Add has_tls_get_addr_call. (BFD_FAKE_SECTION): Init new flag. * ecoff.c (bfd_debug_section): Likewise. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_TLSGD and R_PPC_TLSLD. (ppc_elf_reloc_type_lookup): Handle new relocs. (ppc_elf_check_relocs): Set has_tls_get_addr_call on finding such without marker relocs. (ppc_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs if section has no old-style calls. (ppc_elf_relocate_section): Set tls_mask for non-tls relocs too. Don't try to optimize new-style __tls_get_addr call when handling arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD relocs. * elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_TLSGD, R_PPC64_TLSLD. (ppc64_elf_reloc_type_lookup): Handle new relocs. (ppc64_elf_check_relocs): Set has_tls_get_addr_call on finding such without marker relocs. (ppc64_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs if section has no old-style calls. Set toc_ref for new relocs as appropriate. (ppc64_elf_relocate_section): Set tls_mask for non-tls relocs too. Don't try to optimize new-style __tls_get_addr call when handling arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD relocs. gas/ * config/tc-ppc.c (ppc_elf_suffix): Error if ppc32 tls got relocs have non-zero addend. (md_assemble): Parse args of __tls_get_addr calls. (md_apply_fix): Handle BFD_RELOC_PPC_TLSGD and BFD_RELOC_PPC_TLSLD. ld/testsuite/ * ld-powerpc/tlsmark.s, * ld-powerpc/tlsmark.d: New test. * ld-powerpc/tlsmark32.s, * ld-powerpc/tlsmark32.d: New test. * ld-powerpc/powerpc.exp: Run them.
This commit is contained in:
parent
51dec22749
commit
727fc41e07
|
@ -1,3 +1,33 @@
|
|||
2009-03-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* reloc.c (BFD_RELOC_PPC_TLSGD, BFD_RELOC_PPC_TLSLD): New.
|
||||
* section.c (struct bfd_section): Add has_tls_get_addr_call.
|
||||
(BFD_FAKE_SECTION): Init new flag.
|
||||
* ecoff.c (bfd_debug_section): Likewise.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* libbfd.h: Regenerate.
|
||||
* elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_TLSGD and R_PPC_TLSLD.
|
||||
(ppc_elf_reloc_type_lookup): Handle new relocs.
|
||||
(ppc_elf_check_relocs): Set has_tls_get_addr_call on finding such
|
||||
without marker relocs.
|
||||
(ppc_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs
|
||||
if section has no old-style calls.
|
||||
(ppc_elf_relocate_section): Set tls_mask for non-tls relocs too.
|
||||
Don't try to optimize new-style __tls_get_addr call when handling
|
||||
arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD
|
||||
relocs.
|
||||
* elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_TLSGD, R_PPC64_TLSLD.
|
||||
(ppc64_elf_reloc_type_lookup): Handle new relocs.
|
||||
(ppc64_elf_check_relocs): Set has_tls_get_addr_call on finding such
|
||||
without marker relocs.
|
||||
(ppc64_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs
|
||||
if section has no old-style calls. Set toc_ref for new relocs as
|
||||
appropriate.
|
||||
(ppc64_elf_relocate_section): Set tls_mask for non-tls relocs too.
|
||||
Don't try to optimize new-style __tls_get_addr call when handling
|
||||
arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD
|
||||
relocs.
|
||||
|
||||
2009-03-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR 6768
|
||||
|
|
|
@ -1343,6 +1343,9 @@ typedef struct bfd_section
|
|||
/* Nonzero if this section has TLS related relocations. */
|
||||
unsigned int has_tls_reloc:1;
|
||||
|
||||
/* Nonzero if this section has a call to __tls_get_addr. */
|
||||
unsigned int has_tls_get_addr_call:1;
|
||||
|
||||
/* Nonzero if this section has a gp reloc. */
|
||||
unsigned int has_gp_reloc:1;
|
||||
|
||||
|
@ -1603,11 +1606,11 @@ extern asection bfd_ind_section;
|
|||
/* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */ \
|
||||
0, 0, 0, 0, \
|
||||
\
|
||||
/* has_gp_reloc, need_finalize_relax, reloc_done, */ \
|
||||
0, 0, 0, \
|
||||
/* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax, */ \
|
||||
0, 0, 0, \
|
||||
\
|
||||
/* vma, lma, size, rawsize */ \
|
||||
0, 0, 0, 0, \
|
||||
/* reloc_done, vma, lma, size, rawsize */ \
|
||||
0, 0, 0, 0, 0, \
|
||||
\
|
||||
/* output_offset, output_section, alignment_power, */ \
|
||||
0, (struct bfd_section *) &SEC, 0, \
|
||||
|
@ -2928,6 +2931,8 @@ relaxation. */
|
|||
|
||||
/* PowerPC and PowerPC64 thread-local storage relocations. */
|
||||
BFD_RELOC_PPC_TLS,
|
||||
BFD_RELOC_PPC_TLSGD,
|
||||
BFD_RELOC_PPC_TLSLD,
|
||||
BFD_RELOC_PPC_DTPMOD,
|
||||
BFD_RELOC_PPC_TPREL16,
|
||||
BFD_RELOC_PPC_TPREL16_LO,
|
||||
|
|
11
bfd/ecoff.c
11
bfd/ecoff.c
|
@ -1,6 +1,7 @@
|
|||
/* Generic ECOFF (Extended-COFF) routines.
|
||||
Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Free Software Foundation, Inc.
|
||||
Original version by Per Bothner.
|
||||
Full support added by Ian Lance Taylor, ian@cygnus.com.
|
||||
|
||||
|
@ -59,10 +60,10 @@ static asection bfd_debug_section =
|
|||
0, 0, 1,
|
||||
/* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */
|
||||
0, 0, 0, 0,
|
||||
/* has_gp_reloc, need_finalize_relax, reloc_done, */
|
||||
0, 0, 0,
|
||||
/* vma, lma, size, rawsize, */
|
||||
0, 0, 0, 0,
|
||||
/* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax, */
|
||||
0, 0, 0,
|
||||
/* reloc_done, vma, lma, size, rawsize, */
|
||||
0, 0, 0, 0, 0,
|
||||
/* output_offset, output_section, alignment_power, */
|
||||
0, NULL, 0,
|
||||
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */
|
||||
|
|
192
bfd/elf32-ppc.c
192
bfd/elf32-ppc.c
|
@ -753,7 +753,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
|
|||
0xffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* Marker reloc for TLS. */
|
||||
/* Marker relocs for TLS. */
|
||||
HOWTO (R_PPC_TLS,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
|
@ -768,6 +768,34 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
|
|||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_PPC_TLSGD,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC_TLSGD", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_PPC_TLSLD,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC_TLSLD", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* Computes the load module index of the load module that contains the
|
||||
definition of its TLS sym. */
|
||||
HOWTO (R_PPC_DTPMOD32,
|
||||
|
@ -1531,6 +1559,8 @@ ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|||
case BFD_RELOC_CTOR: r = R_PPC_ADDR32; break;
|
||||
case BFD_RELOC_PPC_TOC16: r = R_PPC_TOC16; break;
|
||||
case BFD_RELOC_PPC_TLS: r = R_PPC_TLS; break;
|
||||
case BFD_RELOC_PPC_TLSGD: r = R_PPC_TLSGD; break;
|
||||
case BFD_RELOC_PPC_TLSLD: r = R_PPC_TLSLD; break;
|
||||
case BFD_RELOC_PPC_DTPMOD: r = R_PPC_DTPMOD32; break;
|
||||
case BFD_RELOC_PPC_TPREL16: r = R_PPC_TPREL16; break;
|
||||
case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC_TPREL16_LO; break;
|
||||
|
@ -3288,6 +3318,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||
const Elf_Internal_Rela *rel;
|
||||
const Elf_Internal_Rela *rel_end;
|
||||
asection *got2, *sreloc;
|
||||
struct elf_link_hash_entry *tga;
|
||||
|
||||
if (info->relocatable)
|
||||
return TRUE;
|
||||
|
@ -3313,6 +3344,8 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||
ppc_elf_howto_init ();
|
||||
|
||||
htab = ppc_elf_hash_table (info);
|
||||
tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
|
||||
FALSE, FALSE, TRUE);
|
||||
symtab_hdr = &elf_symtab_hdr (abfd);
|
||||
sym_hashes = elf_sym_hashes (abfd);
|
||||
got2 = bfd_get_section_by_name (abfd, ".got2");
|
||||
|
@ -3324,7 +3357,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||
unsigned long r_symndx;
|
||||
enum elf_ppc_reloc_type r_type;
|
||||
struct elf_link_hash_entry *h;
|
||||
int tls_type = 0;
|
||||
int tls_type;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
|
@ -3351,9 +3384,44 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||
BFD_ASSERT (h == htab->elf.hgot);
|
||||
}
|
||||
|
||||
tls_type = 0;
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
if (h != NULL && h == tga)
|
||||
switch (r_type)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case R_PPC_PLTREL24:
|
||||
case R_PPC_LOCAL24PC:
|
||||
case R_PPC_REL24:
|
||||
case R_PPC_REL14:
|
||||
case R_PPC_REL14_BRTAKEN:
|
||||
case R_PPC_REL14_BRNTAKEN:
|
||||
case R_PPC_ADDR24:
|
||||
case R_PPC_ADDR14:
|
||||
case R_PPC_ADDR14_BRTAKEN:
|
||||
case R_PPC_ADDR14_BRNTAKEN:
|
||||
if (rel != relocs
|
||||
&& (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
|
||||
|| ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
|
||||
/* We have a new-style __tls_get_addr call with a marker
|
||||
reloc. */
|
||||
;
|
||||
else
|
||||
/* Mark this section as having an old-style call. */
|
||||
sec->has_tls_get_addr_call = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_PPC_TLSGD:
|
||||
case R_PPC_TLSLD:
|
||||
/* These special tls relocs tie a call to __tls_get_addr with
|
||||
its parameter symbol. */
|
||||
break;
|
||||
|
||||
case R_PPC_GOT_TLSLD16:
|
||||
case R_PPC_GOT_TLSLD16_LO:
|
||||
case R_PPC_GOT_TLSLD16_HI:
|
||||
|
@ -3607,7 +3675,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||
|
||||
/* This refers only to functions defined in the shared library. */
|
||||
case R_PPC_LOCAL24PC:
|
||||
if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
|
||||
if (h != NULL && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
|
||||
{
|
||||
htab->plt_type = PLT_OLD;
|
||||
htab->old_bfd = abfd;
|
||||
|
@ -4484,7 +4552,8 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
|
|||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (!expecting_tls_get_addr)
|
||||
if (!expecting_tls_get_addr
|
||||
|| !sec->has_tls_get_addr_call)
|
||||
continue;
|
||||
|
||||
if (rel + 1 < relend
|
||||
|
@ -6234,16 +6303,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
for the final instruction stream. */
|
||||
tls_mask = 0;
|
||||
tls_gd = 0;
|
||||
if (IS_PPC_TLS_RELOC (r_type))
|
||||
if (h != NULL)
|
||||
tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
|
||||
else if (local_got_offsets != NULL)
|
||||
{
|
||||
if (h != NULL)
|
||||
tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
|
||||
else if (local_got_offsets != NULL)
|
||||
{
|
||||
char *lgot_masks;
|
||||
lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);
|
||||
tls_mask = lgot_masks[r_symndx];
|
||||
}
|
||||
char *lgot_masks;
|
||||
lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);
|
||||
tls_mask = lgot_masks[r_symndx];
|
||||
}
|
||||
|
||||
/* Ensure reloc mapping code below stays sane. */
|
||||
|
@ -6361,7 +6427,17 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
bfd_vma offset;
|
||||
|
||||
tls_ldgd_opt:
|
||||
offset = rel[1].r_offset;
|
||||
offset = (bfd_vma) -1;
|
||||
/* If not using the newer R_PPC_TLSGD/LD to mark
|
||||
__tls_get_addr calls, we must trust that the call
|
||||
stays with its arg setup insns, ie. that the next
|
||||
reloc is the __tls_get_addr call associated with
|
||||
the current reloc. Edit both insns. */
|
||||
if (input_section->has_tls_get_addr_call
|
||||
&& rel + 1 < relend
|
||||
&& branch_reloc_hash_match (input_bfd, rel + 1,
|
||||
htab->tls_get_addr))
|
||||
offset = rel[1].r_offset;
|
||||
if ((tls_mask & tls_gd) != 0)
|
||||
{
|
||||
/* IE */
|
||||
|
@ -6369,9 +6445,14 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
contents + rel->r_offset - d_offset);
|
||||
insn1 &= (1 << 26) - 1;
|
||||
insn1 |= 32 << 26; /* lwz */
|
||||
insn2 = 0x7c631214; /* add 3,3,2 */
|
||||
rel[1].r_info
|
||||
= ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info), R_PPC_NONE);
|
||||
if (offset != (bfd_vma) -1)
|
||||
{
|
||||
rel[1].r_info
|
||||
= ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
|
||||
R_PPC_NONE);
|
||||
insn2 = 0x7c631214; /* add 3,3,2 */
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
}
|
||||
r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
|
||||
+ R_PPC_GOT_TPREL16);
|
||||
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
|
||||
|
@ -6380,7 +6461,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
{
|
||||
/* LE */
|
||||
insn1 = 0x3c620000; /* addis 3,2,0 */
|
||||
insn2 = 0x38630000; /* addi 3,3,0 */
|
||||
if (tls_gd == 0)
|
||||
{
|
||||
/* Was an LD reloc. */
|
||||
|
@ -6399,14 +6479,17 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
r_type = R_PPC_TPREL16_HA;
|
||||
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
|
||||
rel[1].r_info = ELF32_R_INFO (r_symndx,
|
||||
R_PPC_TPREL16_LO);
|
||||
rel[1].r_offset += d_offset;
|
||||
rel[1].r_addend = rel->r_addend;
|
||||
if (offset != (bfd_vma) -1)
|
||||
{
|
||||
rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
|
||||
rel[1].r_offset = offset + d_offset;
|
||||
rel[1].r_addend = rel->r_addend;
|
||||
insn2 = 0x38630000; /* addi 3,3,0 */
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
}
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn1,
|
||||
contents + rel->r_offset - d_offset);
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
if (tls_gd == 0)
|
||||
{
|
||||
/* We changed the symbol on an LD reloc. Start over
|
||||
|
@ -6416,6 +6499,66 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PPC_TLSGD:
|
||||
if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
|
||||
{
|
||||
unsigned int insn2;
|
||||
bfd_vma offset = rel->r_offset;
|
||||
|
||||
if ((tls_mask & TLS_TPRELGD) != 0)
|
||||
{
|
||||
/* IE */
|
||||
r_type = R_PPC_NONE;
|
||||
insn2 = 0x7c631214; /* add 3,3,2 */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* LE */
|
||||
r_type = R_PPC_TPREL16_LO;
|
||||
rel->r_offset += d_offset;
|
||||
insn2 = 0x38630000; /* addi 3,3,0 */
|
||||
}
|
||||
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
/* Zap the reloc on the _tls_get_addr call too. */
|
||||
BFD_ASSERT (offset == rel[1].r_offset);
|
||||
rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
|
||||
R_PPC_NONE);
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PPC_TLSLD:
|
||||
if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
|
||||
{
|
||||
unsigned int insn2;
|
||||
|
||||
for (r_symndx = 0;
|
||||
r_symndx < symtab_hdr->sh_info;
|
||||
r_symndx++)
|
||||
if (local_sections[r_symndx] == sec)
|
||||
break;
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
r_symndx = 0;
|
||||
rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
|
||||
if (r_symndx != 0)
|
||||
rel->r_addend -= (local_syms[r_symndx].st_value
|
||||
+ sec->output_offset
|
||||
+ sec->output_section->vma);
|
||||
|
||||
rel->r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
|
||||
rel->r_offset += d_offset;
|
||||
insn2 = 0x38630000; /* addi 3,3,0 */
|
||||
bfd_put_32 (output_bfd, insn2,
|
||||
contents + rel->r_offset - d_offset);
|
||||
/* Zap the reloc on the _tls_get_addr call too. */
|
||||
BFD_ASSERT (rel->r_offset - d_offset == rel[1].r_offset);
|
||||
rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
|
||||
R_PPC_NONE);
|
||||
rel--;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle other relocations that tweak non-addend part of insn. */
|
||||
|
@ -6468,6 +6611,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
|
||||
case R_PPC_NONE:
|
||||
case R_PPC_TLS:
|
||||
case R_PPC_TLSGD:
|
||||
case R_PPC_TLSLD:
|
||||
case R_PPC_EMB_MRKREF:
|
||||
case R_PPC_GNU_VTINHERIT:
|
||||
case R_PPC_GNU_VTENTRY:
|
||||
|
@ -6509,6 +6654,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
case R_PPC_GOT16_LO:
|
||||
case R_PPC_GOT16_HI:
|
||||
case R_PPC_GOT16_HA:
|
||||
tls_mask = 0;
|
||||
dogot:
|
||||
{
|
||||
/* Relocation is to the entry for this symbol in the global
|
||||
|
|
286
bfd/elf64-ppc.c
286
bfd/elf64-ppc.c
|
@ -1235,7 +1235,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|||
0xfffc, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* Marker reloc for TLS. */
|
||||
/* Marker relocs for TLS. */
|
||||
HOWTO (R_PPC64_TLS,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
|
@ -1250,6 +1250,34 @@ static reloc_howto_type ppc64_elf_howto_raw[] = {
|
|||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_PPC64_TLSGD,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC64_TLSGD", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_PPC64_TLSLD,
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_PPC64_TLSLD", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* Computes the load module index of the load module that contains the
|
||||
definition of its TLS sym. */
|
||||
HOWTO (R_PPC64_DTPMOD64,
|
||||
|
@ -2031,6 +2059,10 @@ ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|||
break;
|
||||
case BFD_RELOC_PPC_TLS: r = R_PPC64_TLS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TLSGD: r = R_PPC64_TLSGD;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TLSLD: r = R_PPC64_TLSLD;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPMOD: r = R_PPC64_DTPMOD64;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16: r = R_PPC64_TPREL16;
|
||||
|
@ -4644,7 +4676,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
unsigned long r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
enum elf_ppc64_reloc_type r_type;
|
||||
int tls_type = 0;
|
||||
int tls_type;
|
||||
struct _ppc64_elf_section_data *ppc64_sec;
|
||||
|
||||
r_symndx = ELF64_R_SYM (rel->r_info);
|
||||
|
@ -4658,9 +4690,42 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
}
|
||||
|
||||
tls_type = 0;
|
||||
r_type = ELF64_R_TYPE (rel->r_info);
|
||||
if (h != NULL && (h == tga || h == dottga))
|
||||
switch (r_type)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case R_PPC64_REL24:
|
||||
case R_PPC64_REL14:
|
||||
case R_PPC64_REL14_BRTAKEN:
|
||||
case R_PPC64_REL14_BRNTAKEN:
|
||||
case R_PPC64_ADDR24:
|
||||
case R_PPC64_ADDR14:
|
||||
case R_PPC64_ADDR14_BRTAKEN:
|
||||
case R_PPC64_ADDR14_BRNTAKEN:
|
||||
if (rel != relocs
|
||||
&& (ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_TLSGD
|
||||
|| ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_TLSLD))
|
||||
/* We have a new-style __tls_get_addr call with a marker
|
||||
reloc. */
|
||||
;
|
||||
else
|
||||
/* Mark this section as having an old-style call. */
|
||||
sec->has_tls_get_addr_call = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
/* These special tls relocs tie a call to __tls_get_addr with
|
||||
its parameter symbol. */
|
||||
break;
|
||||
|
||||
case R_PPC64_GOT_TLSLD16:
|
||||
case R_PPC64_GOT_TLSLD16_LO:
|
||||
case R_PPC64_GOT_TLSLD16_HI:
|
||||
|
@ -7072,6 +7137,8 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||
case R_PPC64_TOC16:
|
||||
case R_PPC64_TOC16_LO:
|
||||
case R_PPC64_TLS:
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
if (sym_sec == NULL || sym_sec != toc)
|
||||
continue;
|
||||
|
||||
|
@ -7092,7 +7159,9 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||
value += rel->r_addend;
|
||||
BFD_ASSERT (value < toc->size && value % 8 == 0);
|
||||
toc_ref_index = value / 8;
|
||||
if (r_type == R_PPC64_TLS)
|
||||
if (r_type == R_PPC64_TLS
|
||||
|| r_type == R_PPC64_TLSGD
|
||||
|| r_type == R_PPC64_TLSLD)
|
||||
{
|
||||
toc_ref[toc_ref_index] = 1;
|
||||
continue;
|
||||
|
@ -7157,7 +7226,8 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (!expecting_tls_get_addr)
|
||||
if (!expecting_tls_get_addr
|
||||
|| !sec->has_tls_get_addr_call)
|
||||
continue;
|
||||
|
||||
if (rel + 1 < relend
|
||||
|
@ -7276,18 +7346,18 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||
free (relstart);
|
||||
}
|
||||
|
||||
if (toc_ref != NULL)
|
||||
free (toc_ref);
|
||||
if (toc_ref != NULL)
|
||||
free (toc_ref);
|
||||
|
||||
if (locsyms != NULL
|
||||
&& (elf_symtab_hdr (ibfd).contents != (unsigned char *) locsyms))
|
||||
{
|
||||
if (!info->keep_memory)
|
||||
free (locsyms);
|
||||
else
|
||||
elf_symtab_hdr (ibfd).contents = (unsigned char *) locsyms;
|
||||
}
|
||||
}
|
||||
if (locsyms != NULL
|
||||
&& (elf_symtab_hdr (ibfd).contents != (unsigned char *) locsyms))
|
||||
{
|
||||
if (!info->keep_memory)
|
||||
free (locsyms);
|
||||
else
|
||||
elf_symtab_hdr (ibfd).contents = (unsigned char *) locsyms;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -10288,28 +10358,28 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
tls_mask = 0;
|
||||
tls_gd = 0;
|
||||
toc_symndx = 0;
|
||||
if (IS_PPC64_TLS_RELOC (r_type))
|
||||
if (h != NULL)
|
||||
tls_mask = h->tls_mask;
|
||||
else if (local_got_ents != NULL)
|
||||
{
|
||||
if (h != NULL)
|
||||
tls_mask = h->tls_mask;
|
||||
else if (local_got_ents != NULL)
|
||||
{
|
||||
char *lgot_masks;
|
||||
lgot_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
|
||||
tls_mask = lgot_masks[r_symndx];
|
||||
}
|
||||
if (tls_mask == 0 && r_type == R_PPC64_TLS)
|
||||
{
|
||||
/* Check for toc tls entries. */
|
||||
char *toc_tls;
|
||||
char *lgot_masks;
|
||||
lgot_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
|
||||
tls_mask = lgot_masks[r_symndx];
|
||||
}
|
||||
if (tls_mask == 0
|
||||
&& (r_type == R_PPC64_TLS
|
||||
|| r_type == R_PPC64_TLSGD
|
||||
|| r_type == R_PPC64_TLSLD))
|
||||
{
|
||||
/* Check for toc tls entries. */
|
||||
char *toc_tls;
|
||||
|
||||
if (!get_tls_mask (&toc_tls, &toc_symndx, &toc_addend,
|
||||
&local_syms, rel, input_bfd))
|
||||
return FALSE;
|
||||
if (!get_tls_mask (&toc_tls, &toc_symndx, &toc_addend,
|
||||
&local_syms, rel, input_bfd))
|
||||
return FALSE;
|
||||
|
||||
if (toc_tls)
|
||||
tls_mask = *toc_tls;
|
||||
}
|
||||
if (toc_tls)
|
||||
tls_mask = *toc_tls;
|
||||
}
|
||||
|
||||
/* Check that tls relocs are used with tls syms, and non-tls
|
||||
|
@ -10324,7 +10394,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
|| (sym_type == STT_SECTION
|
||||
&& (sec->flags & SEC_THREAD_LOCAL) != 0))))
|
||||
{
|
||||
if (r_type == R_PPC64_TLS && tls_mask != 0)
|
||||
if (tls_mask != 0
|
||||
&& (r_type == R_PPC64_TLS
|
||||
|| r_type == R_PPC64_TLSGD
|
||||
|| r_type == R_PPC64_TLSLD))
|
||||
/* R_PPC64_TLS is OK against a symbol in the TOC. */
|
||||
;
|
||||
else
|
||||
|
@ -10520,9 +10593,18 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
bfd_vma offset;
|
||||
|
||||
tls_ldgd_opt:
|
||||
/* We know that the next reloc is on a tls_get_addr
|
||||
call, since ppc64_elf_tls_optimize checks this. */
|
||||
offset = rel[1].r_offset;
|
||||
offset = (bfd_vma) -1;
|
||||
/* If not using the newer R_PPC64_TLSGD/LD to mark
|
||||
__tls_get_addr calls, we must trust that the call
|
||||
stays with its arg setup insns, ie. that the next
|
||||
reloc is the __tls_get_addr call associated with
|
||||
the current reloc. Edit both insns. */
|
||||
if (input_section->has_tls_get_addr_call
|
||||
&& rel + 1 < relend
|
||||
&& branch_reloc_hash_match (input_bfd, rel + 1,
|
||||
htab->tls_get_addr,
|
||||
htab->tls_get_addr_fd))
|
||||
offset = rel[1].r_offset;
|
||||
if ((tls_mask & tls_gd) != 0)
|
||||
{
|
||||
/* IE */
|
||||
|
@ -10531,8 +10613,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
insn1 &= (1 << 26) - (1 << 2);
|
||||
insn1 |= 58 << 26; /* ld */
|
||||
insn2 = 0x7c636a14; /* add 3,3,13 */
|
||||
rel[1].r_info = ELF64_R_INFO (ELF64_R_SYM (rel[1].r_info),
|
||||
R_PPC64_NONE);
|
||||
if (offset != (bfd_vma) -1)
|
||||
rel[1].r_info = ELF64_R_INFO (ELF64_R_SYM (rel[1].r_info),
|
||||
R_PPC64_NONE);
|
||||
if ((tls_mask & TLS_EXPLICIT) == 0)
|
||||
r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
|
||||
+ R_PPC64_GOT_TPREL16_DS);
|
||||
|
@ -10570,23 +10653,29 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
r_type = R_PPC64_TPREL16_HA;
|
||||
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
||||
rel[1].r_info = ELF64_R_INFO (r_symndx,
|
||||
R_PPC64_TPREL16_LO);
|
||||
rel[1].r_offset += d_offset;
|
||||
rel[1].r_addend = rel->r_addend;
|
||||
if (offset != (bfd_vma) -1)
|
||||
{
|
||||
rel[1].r_info = ELF64_R_INFO (r_symndx,
|
||||
R_PPC64_TPREL16_LO);
|
||||
rel[1].r_offset = offset + d_offset;
|
||||
rel[1].r_addend = rel->r_addend;
|
||||
}
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn1,
|
||||
contents + rel->r_offset - d_offset);
|
||||
insn3 = bfd_get_32 (output_bfd,
|
||||
contents + offset + 4);
|
||||
if (insn3 == NOP
|
||||
|| insn3 == CROR_151515 || insn3 == CROR_313131)
|
||||
if (offset != (bfd_vma) -1)
|
||||
{
|
||||
rel[1].r_offset += 4;
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset + 4);
|
||||
insn2 = NOP;
|
||||
insn3 = bfd_get_32 (output_bfd,
|
||||
contents + offset + 4);
|
||||
if (insn3 == NOP
|
||||
|| insn3 == CROR_151515 || insn3 == CROR_313131)
|
||||
{
|
||||
rel[1].r_offset += 4;
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset + 4);
|
||||
insn2 = NOP;
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
if ((tls_mask & tls_gd) == 0
|
||||
&& (tls_gd == 0 || toc_symndx != 0))
|
||||
{
|
||||
|
@ -10598,6 +10687,97 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
}
|
||||
break;
|
||||
|
||||
case R_PPC64_TLSGD:
|
||||
if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
|
||||
{
|
||||
unsigned int insn2, insn3;
|
||||
bfd_vma offset = rel->r_offset;
|
||||
|
||||
if ((tls_mask & TLS_TPRELGD) != 0)
|
||||
{
|
||||
/* IE */
|
||||
r_type = R_PPC64_NONE;
|
||||
insn2 = 0x7c636a14; /* add 3,3,13 */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* LE */
|
||||
if (toc_symndx != 0)
|
||||
{
|
||||
r_symndx = toc_symndx;
|
||||
rel->r_addend = toc_addend;
|
||||
}
|
||||
r_type = R_PPC64_TPREL16_LO;
|
||||
rel->r_offset = offset + d_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 (ELF64_R_SYM (rel[1].r_info),
|
||||
R_PPC64_NONE);
|
||||
insn3 = bfd_get_32 (output_bfd,
|
||||
contents + offset + 4);
|
||||
if (insn3 == NOP
|
||||
|| insn3 == CROR_151515 || insn3 == CROR_313131)
|
||||
{
|
||||
rel->r_offset += 4;
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset + 4);
|
||||
insn2 = NOP;
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
if ((tls_mask & TLS_TPRELGD) == 0 && toc_symndx != 0)
|
||||
{
|
||||
rel--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PPC64_TLSLD:
|
||||
if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
|
||||
{
|
||||
unsigned int insn2, insn3;
|
||||
bfd_vma offset = rel->r_offset;
|
||||
|
||||
if (toc_symndx)
|
||||
sec = local_sections[toc_symndx];
|
||||
for (r_symndx = 0;
|
||||
r_symndx < symtab_hdr->sh_info;
|
||||
r_symndx++)
|
||||
if (local_sections[r_symndx] == sec)
|
||||
break;
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
r_symndx = 0;
|
||||
rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
|
||||
if (r_symndx != 0)
|
||||
rel->r_addend -= (local_syms[r_symndx].st_value
|
||||
+ sec->output_offset
|
||||
+ sec->output_section->vma);
|
||||
|
||||
r_type = R_PPC64_TPREL16_LO;
|
||||
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
||||
rel->r_offset = offset + d_offset;
|
||||
/* Zap the reloc on the _tls_get_addr call too. */
|
||||
BFD_ASSERT (offset == rel[1].r_offset);
|
||||
rel[1].r_info = ELF64_R_INFO (ELF64_R_SYM (rel[1].r_info),
|
||||
R_PPC64_NONE);
|
||||
insn2 = 0x38630000; /* addi 3,3,0 */
|
||||
insn3 = bfd_get_32 (output_bfd,
|
||||
contents + offset + 4);
|
||||
if (insn3 == NOP
|
||||
|| insn3 == CROR_151515 || insn3 == CROR_313131)
|
||||
{
|
||||
rel->r_offset += 4;
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset + 4);
|
||||
insn2 = NOP;
|
||||
}
|
||||
bfd_put_32 (output_bfd, insn2, contents + offset);
|
||||
rel--;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PPC64_DTPMOD64:
|
||||
if (rel + 1 < relend
|
||||
&& rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
|
||||
|
@ -10851,6 +11031,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
|
||||
case R_PPC64_NONE:
|
||||
case R_PPC64_TLS:
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
case R_PPC64_GNU_VTINHERIT:
|
||||
case R_PPC64_GNU_VTENTRY:
|
||||
continue;
|
||||
|
|
|
@ -1201,6 +1201,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||
"BFD_RELOC_PPC64_PLTGOT16_DS",
|
||||
"BFD_RELOC_PPC64_PLTGOT16_LO_DS",
|
||||
"BFD_RELOC_PPC_TLS",
|
||||
"BFD_RELOC_PPC_TLSGD",
|
||||
"BFD_RELOC_PPC_TLSLD",
|
||||
"BFD_RELOC_PPC_DTPMOD",
|
||||
"BFD_RELOC_PPC_TPREL16",
|
||||
"BFD_RELOC_PPC_TPREL16_LO",
|
||||
|
|
|
@ -2710,6 +2710,10 @@ ENUMDOC
|
|||
|
||||
ENUM
|
||||
BFD_RELOC_PPC_TLS
|
||||
ENUMX
|
||||
BFD_RELOC_PPC_TLSGD
|
||||
ENUMX
|
||||
BFD_RELOC_PPC_TLSLD
|
||||
ENUMX
|
||||
BFD_RELOC_PPC_DTPMOD
|
||||
ENUMX
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Object file "section" support for the BFD library.
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
|
@ -382,6 +382,9 @@ CODE_FRAGMENT
|
|||
. {* Nonzero if this section has TLS related relocations. *}
|
||||
. unsigned int has_tls_reloc:1;
|
||||
.
|
||||
. {* Nonzero if this section has a call to __tls_get_addr. *}
|
||||
. unsigned int has_tls_get_addr_call:1;
|
||||
.
|
||||
. {* Nonzero if this section has a gp reloc. *}
|
||||
. unsigned int has_gp_reloc:1;
|
||||
.
|
||||
|
@ -642,11 +645,11 @@ CODE_FRAGMENT
|
|||
. {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, *} \
|
||||
. 0, 0, 0, 0, \
|
||||
. \
|
||||
. {* has_gp_reloc, need_finalize_relax, reloc_done, *} \
|
||||
. 0, 0, 0, \
|
||||
. {* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax, *} \
|
||||
. 0, 0, 0, \
|
||||
. \
|
||||
. {* vma, lma, size, rawsize *} \
|
||||
. 0, 0, 0, 0, \
|
||||
. {* reloc_done, vma, lma, size, rawsize *} \
|
||||
. 0, 0, 0, 0, 0, \
|
||||
. \
|
||||
. {* output_offset, output_section, alignment_power, *} \
|
||||
. 0, (struct bfd_section *) &SEC, 0, \
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2009-03-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/tc-ppc.c (ppc_elf_suffix): Error if ppc32 tls got relocs
|
||||
have non-zero addend.
|
||||
(md_assemble): Parse args of __tls_get_addr calls.
|
||||
(md_apply_fix): Handle BFD_RELOC_PPC_TLSGD and BFD_RELOC_PPC_TLSLD.
|
||||
|
||||
2009-03-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
binutils/3807
|
||||
|
|
|
@ -1974,13 +1974,38 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
|
|||
{
|
||||
int reloc = ptr->reloc;
|
||||
|
||||
if (!ppc_obj64)
|
||||
if (exp_p->X_add_number != 0
|
||||
&& (reloc == (int) BFD_RELOC_16_GOTOFF
|
||||
|| reloc == (int) BFD_RELOC_LO16_GOTOFF
|
||||
|| reloc == (int) BFD_RELOC_HI16_GOTOFF
|
||||
|| reloc == (int) BFD_RELOC_HI16_S_GOTOFF))
|
||||
as_warn (_("identifier+constant@got means identifier@got+constant"));
|
||||
if (!ppc_obj64 && exp_p->X_add_number != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_16_GOTOFF:
|
||||
case BFD_RELOC_LO16_GOTOFF:
|
||||
case BFD_RELOC_HI16_GOTOFF:
|
||||
case BFD_RELOC_HI16_S_GOTOFF:
|
||||
as_warn (_("identifier+constant@got means "
|
||||
"identifier@got+constant"));
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_GOT_TLSGD16:
|
||||
case BFD_RELOC_PPC_GOT_TLSGD16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TLSGD16_HI:
|
||||
case BFD_RELOC_PPC_GOT_TLSGD16_HA:
|
||||
case BFD_RELOC_PPC_GOT_TLSLD16:
|
||||
case BFD_RELOC_PPC_GOT_TLSLD16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TLSLD16_HI:
|
||||
case BFD_RELOC_PPC_GOT_TLSLD16_HA:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_HI:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_HA:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_HI:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_HA:
|
||||
as_bad (_("symbol+offset not supported for got tls"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now check for identifier@suffix+constant. */
|
||||
if (*str == '-' || *str == '+')
|
||||
|
@ -2797,108 +2822,156 @@ md_assemble (char *str)
|
|||
ppc_cpu, (char *) NULL, 0);
|
||||
}
|
||||
#ifdef OBJ_ELF
|
||||
else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
|
||||
else
|
||||
{
|
||||
/* Some TLS tweaks. */
|
||||
switch (reloc)
|
||||
if (ex.X_op == O_symbol && str[0] == '(')
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
|
||||
ppc_cpu, (char *) NULL, 0);
|
||||
break;
|
||||
/* We'll only use the 32 (or 64) bit form of these relocations
|
||||
in constants. Instructions get the 16 bit form. */
|
||||
case BFD_RELOC_PPC_DTPREL:
|
||||
reloc = BFD_RELOC_PPC_DTPREL16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL:
|
||||
reloc = BFD_RELOC_PPC_TPREL16;
|
||||
break;
|
||||
}
|
||||
const char *sym_name = S_GET_NAME (ex.X_add_symbol);
|
||||
if (sym_name[0] == '.')
|
||||
++sym_name;
|
||||
|
||||
/* For the absolute forms of branches, convert the PC
|
||||
relative form back into the absolute. */
|
||||
if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
if (strcasecmp (sym_name, "__tls_get_addr") == 0)
|
||||
{
|
||||
case BFD_RELOC_PPC_B26:
|
||||
reloc = BFD_RELOC_PPC_BA26;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16:
|
||||
reloc = BFD_RELOC_PPC_BA16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRNTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
expressionS tls_exp;
|
||||
|
||||
hold = input_line_pointer;
|
||||
input_line_pointer = str + 1;
|
||||
expression (&tls_exp);
|
||||
if (tls_exp.X_op == O_symbol)
|
||||
{
|
||||
reloc = BFD_RELOC_UNUSED;
|
||||
if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
|
||||
{
|
||||
reloc = BFD_RELOC_PPC_TLSGD;
|
||||
input_line_pointer += 7;
|
||||
}
|
||||
else if (strncasecmp (input_line_pointer, "@tlsld)", 7) == 0)
|
||||
{
|
||||
reloc = BFD_RELOC_PPC_TLSLD;
|
||||
input_line_pointer += 7;
|
||||
}
|
||||
if (reloc != BFD_RELOC_UNUSED)
|
||||
{
|
||||
SKIP_WHITESPACE ();
|
||||
str = input_line_pointer;
|
||||
|
||||
if (fc >= MAX_INSN_FIXUPS)
|
||||
as_fatal (_("too many fixups"));
|
||||
fixups[fc].exp = tls_exp;
|
||||
fixups[fc].opindex = *opindex_ptr;
|
||||
fixups[fc].reloc = reloc;
|
||||
++fc;
|
||||
}
|
||||
}
|
||||
input_line_pointer = hold;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppc_obj64
|
||||
&& (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
|
||||
if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
|
||||
{
|
||||
/* Some TLS tweaks. */
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_PLTOFF:
|
||||
reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TOC16:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_TOC16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16_LO:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_LO:
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported relocation for DS offset field"));
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
insn = ppc_insert_operand (insn, operand, ppc_obj64 ? 13 : 2,
|
||||
ppc_cpu, (char *) NULL, 0);
|
||||
break;
|
||||
|
||||
/* We'll only use the 32 (or 64) bit form of these relocations
|
||||
in constants. Instructions get the 16 bit form. */
|
||||
case BFD_RELOC_PPC_DTPREL:
|
||||
reloc = BFD_RELOC_PPC_DTPREL16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL:
|
||||
reloc = BFD_RELOC_PPC_TPREL16;
|
||||
break;
|
||||
}
|
||||
|
||||
/* For the absolute forms of branches, convert the PC
|
||||
relative form back into the absolute. */
|
||||
if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_PPC_B26:
|
||||
reloc = BFD_RELOC_PPC_BA26;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16:
|
||||
reloc = BFD_RELOC_PPC_BA16;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
|
||||
break;
|
||||
case BFD_RELOC_PPC_B16_BRNTAKEN:
|
||||
reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppc_obj64
|
||||
&& (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
|
||||
{
|
||||
switch (reloc)
|
||||
{
|
||||
case BFD_RELOC_16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16:
|
||||
reloc = BFD_RELOC_PPC64_ADDR16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_GOTOFF:
|
||||
reloc = BFD_RELOC_PPC64_GOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_PLTOFF:
|
||||
reloc = BFD_RELOC_PPC64_PLT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_DS;
|
||||
break;
|
||||
case BFD_RELOC_LO16_BASEREL:
|
||||
reloc = BFD_RELOC_PPC64_SECTOFF_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TOC16:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_TOC16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TOC16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC64_PLTGOT16_LO:
|
||||
reloc = BFD_RELOC_PPC64_PLTGOT16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_DTPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_DTPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_TPREL16_LO:
|
||||
reloc = BFD_RELOC_PPC64_TPREL16_LO_DS;
|
||||
break;
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16:
|
||||
case BFD_RELOC_PPC_GOT_DTPREL16_LO:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16:
|
||||
case BFD_RELOC_PPC_GOT_TPREL16_LO:
|
||||
break;
|
||||
default:
|
||||
as_bad (_("unsupported relocation for DS offset field"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2906,12 +2979,11 @@ md_assemble (char *str)
|
|||
if (fc >= MAX_INSN_FIXUPS)
|
||||
as_fatal (_("too many fixups"));
|
||||
fixups[fc].exp = ex;
|
||||
fixups[fc].opindex = 0;
|
||||
fixups[fc].opindex = *opindex_ptr;
|
||||
fixups[fc].reloc = reloc;
|
||||
++fc;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
#else /* OBJ_ELF */
|
||||
else
|
||||
{
|
||||
/* We need to generate a fixup for this expression. */
|
||||
|
@ -2922,6 +2994,7 @@ md_assemble (char *str)
|
|||
fixups[fc].reloc = BFD_RELOC_UNUSED;
|
||||
++fc;
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
if (need_paren)
|
||||
{
|
||||
|
@ -3006,9 +3079,6 @@ md_assemble (char *str)
|
|||
md_apply_fix. */
|
||||
for (i = 0; i < fc; i++)
|
||||
{
|
||||
const struct powerpc_operand *operand;
|
||||
|
||||
operand = &powerpc_operands[fixups[i].opindex];
|
||||
if (fixups[i].reloc != BFD_RELOC_UNUSED)
|
||||
{
|
||||
reloc_howto_type *reloc_howto;
|
||||
|
@ -3055,13 +3125,18 @@ md_assemble (char *str)
|
|||
}
|
||||
}
|
||||
else
|
||||
fix_new_exp (frag_now,
|
||||
f - frag_now->fr_literal,
|
||||
4,
|
||||
&fixups[i].exp,
|
||||
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
|
||||
((bfd_reloc_code_real_type)
|
||||
(fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
|
||||
{
|
||||
const struct powerpc_operand *operand;
|
||||
|
||||
operand = &powerpc_operands[fixups[i].opindex];
|
||||
fix_new_exp (frag_now,
|
||||
f - frag_now->fr_literal,
|
||||
4,
|
||||
&fixups[i].exp,
|
||||
(operand->flags & PPC_OPERAND_RELATIVE) != 0,
|
||||
((bfd_reloc_code_real_type)
|
||||
(fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6155,6 +6230,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
|||
break;
|
||||
|
||||
case BFD_RELOC_PPC_TLS:
|
||||
case BFD_RELOC_PPC_TLSGD:
|
||||
case BFD_RELOC_PPC_TLSLD:
|
||||
break;
|
||||
|
||||
case BFD_RELOC_PPC_DTPMOD:
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-03-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ppc.h (R_PPC_TLSGD, R_PPC_TLSLD): Add new relocs.
|
||||
* ppc64.h (R_PPC64_TLSGD, R_PPC64_TLSLD): Add new relocs.
|
||||
|
||||
2009-03-02 Qinwei <qinwei@sunnorth.com.cn>
|
||||
|
||||
* score.h (RELOC_NUMBER): Add R_SCORE_IMM32.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* PPC ELF support for BFD.
|
||||
Copyright 1995, 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1995, 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2007, 2008,
|
||||
2009 Free Software Foundation, Inc.
|
||||
|
||||
By Michael Meissner, Cygnus Support, <meissner@cygnus.com>, from information
|
||||
in the System V Application Binary Interface, PowerPC Processor Supplement
|
||||
|
@ -100,6 +100,8 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
|
|||
RELOC_NUMBER (R_PPC_GOT_DTPREL16_LO, 92)
|
||||
RELOC_NUMBER (R_PPC_GOT_DTPREL16_HI, 93)
|
||||
RELOC_NUMBER (R_PPC_GOT_DTPREL16_HA, 94)
|
||||
RELOC_NUMBER (R_PPC_TLSGD, 95)
|
||||
RELOC_NUMBER (R_PPC_TLSLD, 96)
|
||||
|
||||
/* The remaining relocs are from the Embedded ELF ABI, and are not
|
||||
in the SVR4 ELF ABI. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* PPC64 ELF support for BFD.
|
||||
Copyright 2003 Free Software Foundation, Inc.
|
||||
Copyright 2003, 2005, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
|
@ -136,6 +136,8 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
|
|||
RELOC_NUMBER (R_PPC64_DTPREL16_HIGHERA, 104)
|
||||
RELOC_NUMBER (R_PPC64_DTPREL16_HIGHEST, 105)
|
||||
RELOC_NUMBER (R_PPC64_DTPREL16_HIGHESTA, 106)
|
||||
RELOC_NUMBER (R_PPC64_TLSGD, 107)
|
||||
RELOC_NUMBER (R_PPC64_TLSLD, 108)
|
||||
|
||||
/* These are GNU extensions to enable C++ vtable garbage collection. */
|
||||
RELOC_NUMBER (R_PPC64_GNU_VTINHERIT, 253)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2009-03-04 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-powerpc/tlsmark.s, * ld-powerpc/tlsmark.d: New test.
|
||||
* ld-powerpc/tlsmark32.s, * ld-powerpc/tlsmark32.d: New test.
|
||||
* ld-powerpc/powerpc.exp: Run them.
|
||||
|
||||
2009-03-02 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* ld-scripts/regions-alias-1.t: New file.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Expect script for ld-powerpc tests
|
||||
# Copyright 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation
|
||||
# Copyright 2002, 2003, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
|
||||
#
|
||||
# This file is part of the GNU Binutils.
|
||||
#
|
||||
|
@ -112,6 +112,9 @@ set ppcelftests {
|
|||
{{readelf -WSsrl tlsso32.r} {objdump -dr tlsso32.d}
|
||||
{objdump -sj.got tlsso32.g} {objdump -sj.tdata tlsso32.t}}
|
||||
"tls32.so"}
|
||||
{"TLS32 markers" "-melf32ppc" "-a32" {tlsmark32.s tlslib32.s}
|
||||
{{objdump -dr tlsmark32.d}}
|
||||
"tlsmark32"}
|
||||
{"Shared library with global symbol" "-shared -melf32ppc" "-a32" {sdalib.s}
|
||||
{} "sdalib.so"}
|
||||
{"Dynamic application with SDA" "-melf32ppc tmpdir/sdalib.so" "-a32" {sdadyn.s}
|
||||
|
@ -145,6 +148,9 @@ set ppc64elftests {
|
|||
{{readelf -WSsrl tlstocso.r} {objdump -dr tlstocso.d}
|
||||
{objdump -sj.got tlstocso.g} {objdump -sj.tdata tlstocso.t}}
|
||||
"tlstoc.so"}
|
||||
{"TLS markers" "-melf64ppc" "-a64" {tlsmark.s tlslib.s}
|
||||
{{objdump -dr tlsmark.d}}
|
||||
"tlsmark"}
|
||||
{"sym@tocbase" "-shared -melf64ppc" "-a64" {symtocbase-1.s symtocbase-2.s}
|
||||
{{objdump -dj.data symtocbase.d}} "symtocbase.so"}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#source: tlsmark.s
|
||||
#source: tlslib.s
|
||||
#as: -a64
|
||||
#ld: -melf64ppc
|
||||
#objdump: -dr
|
||||
#target: powerpc64*-*-*
|
||||
|
||||
.*: +file format elf64-powerpc
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+100000e8 <_start>:
|
||||
100000e8: 48 00 00 18 b 10000100 <_start\+0x18>
|
||||
100000ec: 60 00 00 00 nop
|
||||
100000f0: 38 63 90 00 addi r3,r3,-28672
|
||||
100000f4: e8 83 00 00 ld r4,0\(r3\)
|
||||
100000f8: 3c 6d 00 00 addis r3,r13,0
|
||||
100000fc: 48 00 00 0c b 10000108 <_start\+0x20>
|
||||
10000100: 3c 6d 00 00 addis r3,r13,0
|
||||
10000104: 4b ff ff e8 b 100000ec <_start\+0x4>
|
||||
10000108: 60 00 00 00 nop
|
||||
1000010c: 38 63 10 00 addi r3,r3,4096
|
||||
10000110: e8 83 80 00 ld r4,-32768\(r3\)
|
||||
10000114: 3c 6d 00 00 addis r3,r13,0
|
||||
10000118: 48 00 00 0c b 10000124 <_start\+0x3c>
|
||||
1000011c: 3c 6d 00 00 addis r3,r13,0
|
||||
10000120: 48 00 00 14 b 10000134 <_start\+0x4c>
|
||||
10000124: 60 00 00 00 nop
|
||||
10000128: 38 63 90 04 addi r3,r3,-28668
|
||||
1000012c: e8 a3 00 00 ld r5,0\(r3\)
|
||||
10000130: 4b ff ff ec b 1000011c <_start\+0x34>
|
||||
10000134: 60 00 00 00 nop
|
||||
10000138: 38 63 10 00 addi r3,r3,4096
|
||||
1000013c: e8 a3 80 04 ld r5,-32764\(r3\)
|
||||
10000140: 38 62 80 28 addi r3,r2,-32728
|
||||
10000144: 3f a0 10 01 lis r29,4097
|
||||
10000148: 3b bd 01 68 addi r29,r29,360
|
||||
1000014c: 48 00 00 09 bl 10000154 <\.__tls_get_addr>
|
||||
10000150: 60 00 00 00 nop
|
||||
|
||||
0+10000154 <\.__tls_get_addr>:
|
||||
10000154: 4e 80 00 20 blr
|
|
@ -0,0 +1,55 @@
|
|||
.section ".tdata","awT",@progbits
|
||||
x: .int 1
|
||||
y: .int 2
|
||||
|
||||
.section ".toc","aw",@progbits
|
||||
.p2align 3
|
||||
.LC0:
|
||||
.quad y@dtpmod
|
||||
.quad y@dtprel
|
||||
.LC1:
|
||||
.quad y@dtpmod
|
||||
.quad 0
|
||||
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
b .L2
|
||||
|
||||
.L1:
|
||||
bl __tls_get_addr(x@tlsgd)
|
||||
nop
|
||||
ld 4,0(3)
|
||||
addi 3,2,x@got@tlsld
|
||||
b .L3
|
||||
.L2:
|
||||
addi 3,2,x@got@tlsgd
|
||||
b .L1
|
||||
.L3:
|
||||
bl __tls_get_addr(x@tlsld)
|
||||
nop
|
||||
ld 4,x@dtprel(3)
|
||||
|
||||
addi 3,2,.LC0@toc
|
||||
b .L5
|
||||
.L4:
|
||||
addi 3,2,.LC1@toc
|
||||
b .L6
|
||||
.L5:
|
||||
bl .__tls_get_addr(.LC0@tlsgd)
|
||||
nop
|
||||
ld 5,0(3)
|
||||
b .L4
|
||||
.L6:
|
||||
bl .__tls_get_addr(.LC1@tlsld)
|
||||
nop
|
||||
ld 5,y@dtprel(3)
|
||||
|
||||
|
||||
.section ".text.no","ax",@progbits
|
||||
.p2align 2
|
||||
addi 3,2,gd@got@tlsgd
|
||||
lis 29,__tls_get_addr@ha
|
||||
addi 29,29,__tls_get_addr@l
|
||||
bl __tls_get_addr
|
||||
nop
|
|
@ -0,0 +1,29 @@
|
|||
#source: tlsmark32.s
|
||||
#source: tlslib32.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc
|
||||
#objdump: -dr
|
||||
#target: powerpc*-*-*
|
||||
|
||||
.*: file format elf32-powerpc
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+1800094 <_start>:
|
||||
1800094: 48 00 00 14 b 18000a8 <_start\+0x14>
|
||||
1800098: 38 63 90 00 addi r3,r3,-28672
|
||||
180009c: 80 83 00 00 lwz r4,0\(r3\)
|
||||
18000a0: 3c 62 00 00 addis r3,r2,0
|
||||
18000a4: 48 00 00 0c b 18000b0 <_start\+0x1c>
|
||||
18000a8: 3c 62 00 00 addis r3,r2,0
|
||||
18000ac: 4b ff ff ec b 1800098 <_start\+0x4>
|
||||
18000b0: 38 63 10 00 addi r3,r3,4096
|
||||
18000b4: 80 83 80 00 lwz r4,-32768\(r3\)
|
||||
18000b8: 38 7f ff f4 addi r3,r31,-12
|
||||
18000bc: 3f a0 01 80 lis r29,384
|
||||
18000c0: 3b bd 00 c8 addi r29,r29,200
|
||||
18000c4: 48 00 00 05 bl 18000c8 <__tls_get_addr>
|
||||
|
||||
0+18000c8 <__tls_get_addr>:
|
||||
18000c8: 4e 80 00 20 blr
|
||||
#pass
|
|
@ -0,0 +1,27 @@
|
|||
.section ".tdata","awT",@progbits
|
||||
x: .int 1
|
||||
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
b .L2
|
||||
|
||||
.L1:
|
||||
bl __tls_get_addr(x@tlsgd)
|
||||
lwz 4,0(3)
|
||||
addi 3,31,x@got@tlsld
|
||||
b .L3
|
||||
.L2:
|
||||
addi 3,31,x@got@tlsgd
|
||||
b .L1
|
||||
.L3:
|
||||
bl __tls_get_addr(x@tlsld)
|
||||
lwz 4,x@dtprel(3)
|
||||
|
||||
|
||||
.section ".text.no","ax",@progbits
|
||||
.p2align 2
|
||||
addi 3,31,gd@got@tlsgd
|
||||
lis 29,__tls_get_addr@ha
|
||||
addi 29,29,__tls_get_addr@l
|
||||
bl __tls_get_addr
|
Loading…
Reference in New Issue