[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/12608] TLS relocations issues on alpha
From: |
baryluk at smp dot if.uj.edu.pl |
Subject: |
[Bug ld/12608] TLS relocations issues on alpha |
Date: |
Fri, 1 Apr 2011 04:43:52 +0000 |
http://sourceware.org/bugzilla/show_bug.cgi?id=12608
Witold Baryluk <baryluk at smp dot if.uj.edu.pl> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2011.04.01 04:43:41
Ever Confirmed|0 |1
--- Comment #11 from Witold Baryluk <baryluk at smp dot if.uj.edu.pl>
2011-04-01 04:43:41 UTC ---
After bisecting, I got this as a first bad commit
456af9cfa4c227bddde3bae28cd0a4327bcb7c1c is first bad commit
commit 456af9cfa4c227bddde3bae28cd0a4327bcb7c1c
Author: Richard Henderson <address@hidden>
Date: Mon Aug 9 23:58:51 2010 +0000
PR ld/11891
* elf64-alpha.c (elf64_alpha_relax_tls_get_addr): Disallow relaxing
to tlshi/lo until pos0 and pos1 are adjacent. Use the destination
register from the tldgd insn.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c1c9054..528fa3c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2010-08-09 Richard Henderson <address@hidden>
+
+ PR ld/11891
+ * elf64-alpha.c (elf64_alpha_relax_tls_get_addr): Disallow relaxing
+ to tlshi/lo until pos0 and pos1 are adjacent. Use the destination
+ register from the tldgd insn.
+
2010-08-09 Catherine Moore <address@hidden>
* elfxx-mips.c (mips_elf_perform_relocation): Improve
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index 649d370..083beb1 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -3382,9 +3382,9 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
Elf_Internal_Rela *irel, bfd_boolean is_gd)
{
bfd_byte *pos[5];
- unsigned int insn;
+ unsigned int insn, tlsgd_reg;
Elf_Internal_Rela *gpdisp, *hint;
- bfd_boolean dynamic, use_gottprel, pos1_unusable;
+ bfd_boolean dynamic, use_gottprel;
unsigned long new_symndx;
dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
@@ -3425,7 +3425,6 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
pos[2] = info->contents + irel[2].r_offset;
pos[3] = info->contents + gpdisp->r_offset;
pos[4] = pos[3] + gpdisp->r_addend;
- pos1_unusable = FALSE;
/* Generally, the positions are not allowed to be out of order, lest the
modified insn sequence have different register lifetimes. We can make
@@ -3436,8 +3435,6 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
pos[0] = pos[1];
pos[1] = tmp;
}
- else if (pos[1] < pos[0])
- pos1_unusable = TRUE;
if (pos[1] >= pos[2] || pos[2] >= pos[3])
return TRUE;
@@ -3495,6 +3492,14 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
use_gottprel = FALSE;
new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0;
+
+ /* Beware of the compiler hoisting part of the sequence out a loop
+ and adjusting the destination register for the TLSGD insn. If this
+ happens, there will be a move into $16 before the JSR insn, so only
+ transformations of the first insn pair should use this register. */
+ tlsgd_reg = bfd_get_32 (info->abfd, pos[0]);
+ tlsgd_reg = (tlsgd_reg >> 21) & 31;
+
switch (!dynamic && !info->link_info->shared)
{
case 1:
@@ -3508,7 +3513,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
if (disp >= -0x8000 && disp < 0x8000)
{
- insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
+ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (31 << 16);
bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
@@ -3519,11 +3524,11 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
}
else if (disp >= -(bfd_signed_vma) 0x80000000
&& disp < (bfd_signed_vma) 0x7fff8000
- && !pos1_unusable)
+ && pos[0] + 4 == pos[1])
{
- insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
+ insn = (OP_LDAH << 26) | (tlsgd_reg << 21) | (31 << 16);
bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
- insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
+ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (tlsgd_reg << 16);
bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
irel[0].r_offset = pos[0] - info->contents;
@@ -3538,7 +3543,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info
*info, bfd_vma symval,
default:
use_gottprel = TRUE;
- insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
+ insn = (OP_LDQ << 26) | (tlsgd_reg << 21) | (29 << 16);
bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
- [Bug ld/12608] TLS relocations issues on alpha,
baryluk at smp dot if.uj.edu.pl <=