summaryrefslogtreecommitdiff
path: root/bfd/elf64-alpha.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-06-22 16:18:24 +0000
committerRichard Henderson <rth@redhat.com>2011-06-22 16:18:24 +0000
commit25d9aeb634cbdd7c6a4f2e51856f22cda98e1764 (patch)
tree9f9f3d875cc3e8a198ca608b34d71434347cf973 /bfd/elf64-alpha.c
parente4a12da1a46e457f823e9ede236394a2ffadb8a3 (diff)
downloadbinutils-redhat-25d9aeb634cbdd7c6a4f2e51856f22cda98e1764.tar.gz
* elf64-alpha.c (elf64_alpha_check_relocs): No dynamic reloc for
TPREL in a PIE image. (alpha_dynamic_entries_for_reloc): Likewise. (elf64_alpha_relocate_section): Allow TPREL in PIE images. (elf64_alpha_relax_got_load): Likewise.
Diffstat (limited to 'bfd/elf64-alpha.c')
-rw-r--r--bfd/elf64-alpha.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index ee8ce5a80e..46078ea4a4 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1882,10 +1882,13 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
case R_ALPHA_TPREL64:
- if (info->shared || maybe_dynamic)
+ if (info->shared && !info->pie)
+ {
+ info->flags |= DF_STATIC_TLS;
+ need = NEED_DYNREL;
+ }
+ else if (maybe_dynamic)
need = NEED_DYNREL;
- if (info->shared)
- info->flags |= DF_STATIC_TLS;
break;
}
@@ -2651,7 +2654,7 @@ elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
/* The number of dynamic relocations required by a static relocation. */
static int
-alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
+alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared, int pie)
{
switch (r_type)
{
@@ -2661,16 +2664,18 @@ alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
case R_ALPHA_TLSLDM:
return shared;
case R_ALPHA_LITERAL:
- case R_ALPHA_GOTTPREL:
return dynamic || shared;
+ case R_ALPHA_GOTTPREL:
+ return dynamic || (shared && !pie);
case R_ALPHA_GOTDTPREL:
return dynamic;
/* May appear in data sections. */
case R_ALPHA_REFLONG:
case R_ALPHA_REFQUAD:
- case R_ALPHA_TPREL64:
return dynamic || shared;
+ case R_ALPHA_TPREL64:
+ return dynamic || (shared && !pie);
/* Everything else is illegal. We'll issue an error during
relocate_section. */
@@ -2718,7 +2723,7 @@ elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
for (relent = h->reloc_entries; relent; relent = relent->next)
{
entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
- info->shared);
+ info->shared, info->pie);
if (entries)
{
relent->srel->size +=
@@ -2761,8 +2766,8 @@ elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
entries = 0;
for (gotent = h->got_entries; gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
- entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
- dynamic, info->shared);
+ entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type, dynamic,
+ info->shared, info->pie);
if (entries > 0)
{
@@ -2812,7 +2817,7 @@ elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
entries += (alpha_dynamic_entries_for_reloc
- (gotent->reloc_type, 0, info->shared));
+ (gotent->reloc_type, 0, info->shared, info->pie));
}
}
@@ -3044,7 +3049,8 @@ elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
return TRUE;
/* Can't use local-exec relocations in shared libraries. */
- if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
+ if (r_type == R_ALPHA_GOTTPREL
+ && (info->link_info->shared && !info->link_info->pie))
return TRUE;
if (r_type == R_ALPHA_LITERAL)
@@ -4509,7 +4515,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else if (r_type == R_ALPHA_TPREL64)
{
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
- if (!info->shared)
+ if (!info->shared || info->pie)
{
value -= tp_base;
goto default_reloc;
@@ -4630,7 +4636,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_TPRELHI:
case R_ALPHA_TPRELLO:
case R_ALPHA_TPREL16:
- if (info->shared)
+ if (info->shared && !info->pie)
{
(*_bfd_error_handler)
(_("%B: TLS local exec code cannot be linked into shared objects"),