From c95b8a7acedca8d6f3dcc368d116ca8b7339f13a Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Mon, 10 Feb 2003 22:17:18 +0000 Subject: [PATCH] * elf32-sh.c (elf_sh_dyn_relocs): Add tls_tpoff32 field. (elf_sh_link_hash_entry): Remove tls_tpoff32 field. (sh_elf_link_hash_newfunc): Remove the initialization of tls_tpoff32 field. (allocate_dynrelocs): Keep dyn_relocs if it includes the entry for which tls_tpoff32 flag is set. (sh_elf_relocate_section): Covert to LE only if the dyn_relocs of the symbol includes the entry matched with the input_section and having tls_tpoff32 flag on. When linking statically, set symbol index of R_SH_TLS_TPOFF32 relocation to zero if the symbol is defined in this executable. (sh_elf_check_relocs): Set tls_tpoff32 flag appropriately. --- bfd/ChangeLog | 15 +++++++++++++++ bfd/elf32-sh.c | 49 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1c0e8412993..0741c55d1f4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2003-02-10 Kaz kojima + + * elf32-sh.c (elf_sh_dyn_relocs): Add tls_tpoff32 field. + (elf_sh_link_hash_entry): Remove tls_tpoff32 field. + (sh_elf_link_hash_newfunc): Remove the initialization of + tls_tpoff32 field. + (allocate_dynrelocs): Keep dyn_relocs if it includes the entry + for which tls_tpoff32 flag is set. + (sh_elf_relocate_section): Covert to LE only if the dyn_relocs + of the symbol includes the entry matched with the input_section + and having tls_tpoff32 flag on. When linking statically, set + symbol index of R_SH_TLS_TPOFF32 relocation to zero if the symbol + is defined in this executable. + (sh_elf_check_relocs): Set tls_tpoff32 flag appropriately. + 2003-02-10 Jakub Jelinek * elf32-s390.c (elf_s390_size_dynamic_sections): Set relocs to TRUE diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index f0e01772ec3..c3aef15106b 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3500,6 +3500,9 @@ struct elf_sh_dyn_relocs /* Number of pc-relative relocs copied for the input section. */ bfd_size_type pc_count; + + /* If TRUE, R_SH_TLS_TPOFF32 relocation is generated. */ + bfd_boolean tls_tpoff32; }; /* sh ELF linker hash entry. */ @@ -3524,9 +3527,6 @@ struct elf_sh_link_hash_entry enum { GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE } tls_type; - - /* If TRUE, R_SH_TLS_TPOFF32 relocation is generated. */ - bfd_boolean tls_tpoff32; }; #define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent)) @@ -3630,7 +3630,6 @@ sh_elf_link_hash_newfunc (entry, table, string) ret->datalabel_got.refcount = ret->root.got.refcount; #endif ret->tls_type = GOT_UNKNOWN; - ret->tls_tpoff32 = FALSE; } return (struct bfd_hash_entry *) ret; @@ -4207,8 +4206,9 @@ allocate_dynrelocs (h, inf) } else { - if (sh_elf_hash_entry (h)->tls_tpoff32) - goto keep; + for (p = eh->dyn_relocs; p; p = p->next) + if (p->tls_tpoff32) + goto keep; /* For the non-shared case, discard space for relocs against symbols which turn out to need copy relocs or are not @@ -5256,10 +5256,18 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, tls_type = sh_elf_hash_entry (h)->tls_type; if (! info->shared && (h->dynindx == -1 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - && (tls_type == GOT_TLS_IE - || sh_elf_hash_entry (h)->tls_tpoff32)) - r_type = R_SH_TLS_LE_32; + || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + struct elf_sh_dyn_relocs *p; + + /* If TPOFF32 relocation can be created, convert it. */ + for (p = sh_elf_hash_entry (h)->dyn_relocs; p; p = p->next) + if (p->sec == input_section && p->tls_tpoff32) + { + r_type = R_SH_TLS_LE_32; + break; + } + } } if (r_type == R_SH_TLS_GD_32 && tls_type == GOT_TLS_IE) @@ -5368,7 +5376,13 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sreloc != NULL); } - indx = (h && h->dynindx != -1) ? h->dynindx : 0; + if (h == NULL + || h->dynindx == -1 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + indx = 0; + else + indx = h->dynindx; outrel.r_offset = (input_section->output_section->vma + input_section->output_offset + rel->r_offset); @@ -5415,7 +5429,13 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); - indx = (h && h->dynindx != -1) ? h->dynindx : 0; + if (h == NULL + || h->dynindx == -1 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + indx = 0; + else + indx = h->dynindx; dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 : R_SH_TLS_TPOFF32); if (dr_type == R_SH_TLS_TPOFF32 && indx == 0) @@ -6596,6 +6616,7 @@ sh_elf_check_relocs (abfd, info, sec, relocs) p->sec = sec; p->count = 0; p->pc_count = 0; + p->tls_tpoff32 = FALSE; } p->count += 1; @@ -6693,11 +6714,11 @@ sh_elf_check_relocs (abfd, info, sec, relocs) p->sec = sec; p->count = 0; p->pc_count = 0; + p->tls_tpoff32 = FALSE; } p->count += 1; - if (h) - sh_elf_hash_entry (h)->tls_tpoff32 = TRUE; + p->tls_tpoff32 = TRUE; } break; -- 2.30.2