aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog23
-rw-r--r--bfd/elf32-i386.c19
-rw-r--r--bfd/elflink.h14
-rw-r--r--bfd/elfxx-ia64.c34
-rw-r--r--ld/testsuite/ChangeLog5
-rw-r--r--ld/testsuite/ld-elfvsb/main.c31
-rw-r--r--ld/testsuite/ld-elfvsb/sh1.c31
7 files changed, 143 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index dfbc26d..e209e3d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,28 @@
2003-05-04 H.J. Lu <hjl@gnu.org>
+ * elf32-i386.c (allocate_dynrelocs): Don't allocate dynamic
+ relocation entries for weak undefined symbols with non-default
+ visibility.
+ (elf_i386_relocate_section): Initialize the GOT entries and
+ skip R_386_32/R_386_PC32 for weak undefined symbols with
+ non-default visibility.
+
+ * elfxx-ia64.c (allocate_fptr): Don't allocate function
+ descriptors for weak undefined symbols with non-default
+ visibility.
+ (allocate_dynrel_entries): Don't allocate relocation entries
+ for symbols resolved to 0.
+ (set_got_entry): Don't install dynamic relocation for weak
+ undefined symbols with non-default visibility.
+ (set_pltoff_entry): Likewise.
+
+ * elflink.h (elf_fix_symbol_flags): Hide weak undefined symbols
+ with non-default visibility.
+ (elf_link_output_extsym): Don't make weak undefined symbols
+ with non-default visibility dynamic.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
* elflink.h (elf_merge_symbol): Correctly handle weak definiton.
2003-05-04 H.J. Lu <hjl@gnu.org>
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 060d66c..ac292a1 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1569,8 +1569,10 @@ allocate_dynrelocs (h, inf)
return FALSE;
}
- if (info->shared
- || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)))
{
asection *s = htab->splt;
@@ -1656,8 +1658,10 @@ allocate_dynrelocs (h, inf)
htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
else if (tls_type == GOT_TLS_GD)
htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
- 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_Rel);
}
else
@@ -2298,7 +2302,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
&& (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
@@ -2422,6 +2428,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
break;
if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
&& (r_type != R_386_PC32
|| (h != NULL
&& h->dynindx != -1
diff --git a/bfd/elflink.h b/bfd/elflink.h
index dfcce7d..0f590a4 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -4151,6 +4151,16 @@ elf_fix_symbol_flags (h, eif)
(*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
}
+ /* If a weak undefined symbol has non-default visibility, we also
+ hide it from the dynamic linker. */
+ if (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ struct elf_backend_data *bed;
+ bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
+ (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
+ }
+
/* If this is a weak defined symbol in a dynamic object, and we know
the real definition in the dynamic object, copy interesting flags
over to the real definition. */
@@ -6546,7 +6556,9 @@ elf_link_output_extsym (h, data)
forced local syms when non-shared is due to a historical quirk. */
if ((h->dynindx != -1
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
- && (finfo->info->shared
+ && ((finfo->info->shared
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
&& elf_hash_table (finfo->info)->dynamic_sections_created)
{
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index 946157f..31f05e9 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -2635,7 +2635,10 @@ allocate_fptr (dyn_i, data)
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- if (x->info->shared
+ if ((x->info->shared
+ && (!h
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
/* AIX needs an FPTR in this case. */
|| (elfNN_ia64_aix_vec (x->info->hash->creator)
&& (!h
@@ -2760,15 +2763,18 @@ allocate_dynrel_entries (dyn_i, data)
struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
struct elfNN_ia64_link_hash_table *ia64_info;
struct elfNN_ia64_dyn_reloc_entry *rent;
- bfd_boolean dynamic_symbol, shared;
+ bfd_boolean dynamic_symbol, shared, resolved_zero;
ia64_info = elfNN_ia64_hash_table (x->info);
dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
|| (elfNN_ia64_aix_vec (x->info->hash->creator)
/* Don't allocate an entry for __GLOB_DATA_PTR */
&& (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
- "__GLOB_DATA_PTR") != 0));
+ "__GLOB_DATA_PTR") != 0));
shared = x->info->shared;
+ resolved_zero = (dyn_i->h
+ && ELF_ST_VISIBILITY (dyn_i->h->other)
+ && dyn_i->h->root.type == bfd_link_hash_undefweak);
/* Take care of the normal data relocations. */
@@ -2813,8 +2819,12 @@ allocate_dynrel_entries (dyn_i, data)
/* Take care of the GOT and PLT relocations. */
- if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx))
- || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
+ if ((!resolved_zero
+ && (dynamic_symbol || shared)
+ && (dyn_i->want_got || dyn_i->want_gotx))
+ || (dyn_i->want_ltoff_fptr
+ && dyn_i->h
+ && dyn_i->h->dynindx != -1))
ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
if ((dynamic_symbol || shared) && dyn_i->want_tprel)
ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
@@ -2823,7 +2833,7 @@ allocate_dynrel_entries (dyn_i, data)
if (dynamic_symbol && dyn_i->want_dtprel)
ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
- if (dyn_i->want_pltoff)
+ if (!resolved_zero && dyn_i->want_pltoff)
{
bfd_size_type t = 0;
@@ -3431,7 +3441,11 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
bfd_put_64 (abfd, value, got_sec->contents + got_offset);
/* Install a dynamic relocation if needed. */
- if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
+ if ((info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ && dyn_r_type != R_IA64_DTPREL64LSB)
|| elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
|| elfNN_ia64_aix_vec (abfd->xvec)
|| (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
@@ -3552,7 +3566,11 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
/* Install dynamic relocations if needed. */
- if (!is_plt && info->shared)
+ if (!is_plt
+ && info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
{
unsigned int dyn_r_type;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index dcd5724..10d1ddd 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2003-05-04 H.J. Lu <hjl@gnu.org>
+ * ld-elfvsb/main.c: Updated.
+ * ld-elfvsb/sh1.c: Likewise.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
* ld-elfvers/vers18.dsym: Updated for weak definiton change.
* ld-elfvers/vers18.ver: Likewise.
* ld-elfvers/vers19.ver: Likewise.
diff --git a/ld/testsuite/ld-elfvsb/main.c b/ld/testsuite/ld-elfvsb/main.c
index 6ce97bf..1ce2e3e 100644
--- a/ld/testsuite/ld-elfvsb/main.c
+++ b/ld/testsuite/ld-elfvsb/main.c
@@ -165,6 +165,37 @@ main_visibility_checkweak ()
{
return 1;
}
+#elif defined (HIDDEN_WEAK_TEST)
+int
+main_visibility_checkcom ()
+{
+ return 1;
+}
+
+#pragma weak visibility_undef_var_weak
+extern int visibility_undef_var_weak;
+asm (".hidden visibility_undef_var_weak");
+
+#pragma weak visibility_undef_func_weak
+extern int visibility_undef_func_weak ();
+asm (".hidden visibility_undef_func_weak");
+
+#pragma weak visibility_var_weak
+extern int visibility_var_weak;
+asm (".hidden visibility_var_weak");
+
+#pragma weak visibility_func_weak
+extern int visibility_func_weak ();
+asm (".hidden visibility_func_weak");
+
+int
+main_visibility_checkweak ()
+{
+ return &visibility_undef_var_weak == NULL
+ && &visibility_undef_func_weak == NULL
+ && &visibility_func_weak == NULL
+ && &visibility_var_weak == NULL;
+}
#elif defined (HIDDEN_UNDEF_TEST)
extern int visibility_def;
asm (".hidden visibility_def");
diff --git a/ld/testsuite/ld-elfvsb/sh1.c b/ld/testsuite/ld-elfvsb/sh1.c
index 2b9b9ee..8d9fcdb 100644
--- a/ld/testsuite/ld-elfvsb/sh1.c
+++ b/ld/testsuite/ld-elfvsb/sh1.c
@@ -339,6 +339,37 @@ shlib_visibility_checkweak ()
{
return 1;
}
+#elif defined (HIDDEN_WEAK_TEST)
+#pragma weak shlib_visibility_undef_var_weak
+extern int shlib_visibility_undef_var_weak;
+asm (".hidden shlib_visibility_undef_var_weak");
+
+#pragma weak shlib_visibility_undef_func_weak
+extern int shlib_visibility_undef_func_weak ();
+asm (".hidden shlib_visibility_undef_func_weak");
+
+#pragma weak shlib_visibility_var_weak
+extern int shlib_visibility_var_weak;
+asm (".hidden shlib_visibility_var_weak");
+
+#pragma weak shlib_visibility_func_weak
+extern int shlib_visibility_func_weak ();
+asm (".hidden shlib_visibility_func_weak");
+
+int
+shlib_visibility_checkcom ()
+{
+ return 1;
+}
+
+int
+shlib_visibility_checkweak ()
+{
+ return &shlib_visibility_undef_var_weak == NULL
+ && &shlib_visibility_undef_func_weak == NULL
+ && &shlib_visibility_func_weak == NULL
+ && &shlib_visibility_var_weak == NULL;
+}
#else
int
shlib_visibility_checkcom ()