This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] SH: weak and visibility patch
- From: kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: binutils at sources dot redhat dot com
- Date: Wed, 07 May 2003 20:48:52 +0900
- Subject: [PATCH] SH: weak and visibility patch
Hi,
The attached patch is the SH version of the recent change for
the weak symbols and the visibility for other architectures.
It is tested on sh4-unknown-linux-gnu and sh64-unknown-linux-gnu,
without no new regressions and some regressions went away.
It seems that some remained FAILs come from gcc optimization.
I'd like to check in the change of elf32-sh.c, but I'm afraid
bothering 2.14 releasing work. So I'm waiting for comments.
Even if it's ok, I need an approvement for ld/testsuite part.
Regards,
kaz
--
2003-05-07 Kaz Kojima <kkojima@rr.iij4u.or.jp>
[bfd/ChangeLog]
* elf32-sh.c (sh_elf_adjust_dynamic_symbol): For weak symbols,
copy ELF_LINK_NON_GOT_REF from weakdef.
(allocate_dynrelocs): For undef weak syms with non-default
visibility, a) don't allocate plt entries, b) don't allocate
.got relocs, c) discard dyn rel space
(sh_elf_relocate_section): d) don't generate .got relocs, e)
don't generate dynamic relocs.
(sh_elf_copy_indirect_symbol): Don't copy ELF_LINK_NON_GOT_REF
for weakdefs when symbol already adjusted.
[ld/testsuite/ChangeLog]
* ld-elfvers/vers.exp: Run on sh[34]*-*-linux*.
* ld-elfvsb/elfvsb.exp: Likewise.
* ld-elfweak/elfweak.exp: Likewise.
diff -u3prN ORIG/src/bfd/elf32-sh.c LOCAL/src/bfd/elf32-sh.c
--- ORIG/src/bfd/elf32-sh.c Thu Apr 24 13:58:25 2003
+++ LOCAL/src/bfd/elf32-sh.c Wed May 7 18:29:29 2003
@@ -3940,6 +3940,10 @@ sh_elf_adjust_dynamic_symbol (info, h)
|| h->weakdef->root.type == bfd_link_hash_defweak);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
+ if (info->nocopyreloc)
+ h->elf_link_hash_flags
+ = ((h->elf_link_hash_flags & ~ELF_LINK_NON_GOT_REF)
+ | (h->weakdef->elf_link_hash_flags & ELF_LINK_NON_GOT_REF));
return TRUE;
}
@@ -4083,7 +4087,9 @@ allocate_dynrelocs (h, inf)
}
if (htab->root.dynamic_sections_created
- && h->plt.refcount > 0)
+ && h->plt.refcount > 0
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
{
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
@@ -4169,8 +4175,10 @@ allocate_dynrelocs (h, inf)
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
else if (tls_type == GOT_TLS_GD)
htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
- else if (info->shared ||
- WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+ else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
else
@@ -4229,6 +4237,12 @@ allocate_dynrelocs (h, inf)
pp = &p->next;
}
}
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)
+ eh->dyn_relocs = NULL;
}
else
{
@@ -4885,6 +4899,9 @@ sh_elf_relocate_section (output_bfd, inf
case R_SH_DIR32:
case R_SH_REL32:
if (info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
&& r_symndx != 0
&& (input_section->flags & SEC_ALLOC) != 0
&& (r_type != R_SH_REL32
@@ -5053,7 +5070,9 @@ sh_elf_relocate_section (output_bfd, inf
|| (info->shared
&& (info->symbolic || h->dynindx == -1
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
@@ -6128,7 +6147,17 @@ sh_elf_copy_indirect_symbol (bed, dir, i
eind->tls_type = GOT_UNKNOWN;
}
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ if (ind->root.type != bfd_link_hash_indirect
+ && (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->elf_link_hash_flags |=
+ (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+ else
+ _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
static int
Binary files ORIG/src/bfd/po/zh_CN.gmo and LOCAL/src/bfd/po/zh_CN.gmo differ
diff -u3prN ORIG/src/ld/testsuite/ld-elfvers/vers.exp LOCAL/src/ld/testsuite/ld-elfvers/vers.exp
--- ORIG/src/ld/testsuite/ld-elfvers/vers.exp Sun May 4 08:27:49 2003
+++ LOCAL/src/ld/testsuite/ld-elfvers/vers.exp Wed May 7 18:36:02 2003
@@ -45,7 +45,8 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget mips*-*-linux*] \
&& ![istarget alpha*-*-linux*] \
&& ![istarget s390*-*-linux*] \
- && ![istarget x86_64-*-linux*] } {
+ && ![istarget x86_64-*-linux*] \
+ && ![istarget sh\[34\]*-*-linux*] } {
return
}
diff -u3prN ORIG/src/ld/testsuite/ld-elfvsb/elfvsb.exp LOCAL/src/ld/testsuite/ld-elfvsb/elfvsb.exp
--- ORIG/src/ld/testsuite/ld-elfvsb/elfvsb.exp Wed Apr 30 12:21:50 2003
+++ LOCAL/src/ld/testsuite/ld-elfvsb/elfvsb.exp Wed May 7 18:35:37 2003
@@ -37,7 +37,8 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget alpha*-*-linux*] \
&& ![istarget sparc*-*-linux*] \
&& ![istarget s390*-*-linux*] \
- && ![istarget x86_64-*-linux*] } {
+ && ![istarget x86_64-*-linux*] \
+ && ![istarget sh\[34\]*-*-linux*] } {
return
}
diff -u3prN ORIG/src/ld/testsuite/ld-elfweak/elfweak.exp LOCAL/src/ld/testsuite/ld-elfweak/elfweak.exp
--- ORIG/src/ld/testsuite/ld-elfweak/elfweak.exp Tue May 6 22:39:03 2003
+++ LOCAL/src/ld/testsuite/ld-elfweak/elfweak.exp Wed May 7 18:36:21 2003
@@ -43,7 +43,8 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget sparc*-*-linux*] \
&& ![istarget arm*-*-linux*] \
&& ![istarget mips*-*-linux*] \
- && ![istarget alpha*-*-linux*] } {
+ && ![istarget alpha*-*-linux*] \
+ && ![istarget sh\[34\]*-*-linux*] } {
return
}