From e366eeae1287622a7ed40c75ec1e7980cc5f71ac Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 22 Jun 2011 16:18:24 +0000 Subject: * 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. --- bfd/ChangeLog | 8 ++++++++ bfd/elf64-alpha.c | 32 +++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5084b7d..59cfd13 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2011-06-22 Richard Henderson + + * 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. + 2011-06-22 Ramana Radhakrishnan * elf32-arm.c (elf32_arm_final_link_relocate): Allow R_ARM_TLS_LE32 diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index ee8ce5a..46078ea 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"), -- cgit v1.1