* PATCH: Fix ELF visibility handling
@ 2003-04-01 20:20 H. J. Lu
2003-04-09 16:22 ` H. J. Lu
0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2003-04-01 20:20 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 619 bytes --]
The currenr ELF visibility handling is wrong on several things:
1. Ld doesn't report an error for undefined symbols with non-default
visibility when there is a definition from a shared library.
2. Weak undefined symbols with non-default visibility results in
undetermined run-time behavior depending on if there is a definition
at run-time.
3. Ld gives no warnings when a shared library refeneces a hidden symbol.
4. ld merges visibility with symbols from shared libraries.
This patch fixes those problems with testcases. As for weak undefined
symbols with non-default visibility, I only fixed x86 and ia64.
H.J.
[-- Attachment #2: binutils-vsb.patch --]
[-- Type: text/plain, Size: 22582 bytes --]
bfd/
2003-04-01 H.J. Lu <hjl@gnu.org>
* elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New.
* 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.
(set_got_entry): Don't install dynamic relocation for weak
undefined symbols with non-default visibility.
(set_pltoff_entry): Likewise.
* elflink.h (ELF_LINK_DYNAMIC_WEAK): New.
(elf_merge_symbol): Add one argument to indicate if a symbol
should be skipped. Ignore definitions in dynamic objects for
symbols with non-default visibility.
(elf_add_default_symbol): Adjusted.
(elf_link_add_object_symbols): Check if a symbol should be
skipped. Don't merge the visibility field with the one from
a dynamic object.
(elf_fix_symbol_flags): Hide weak undefined symbols with
non-default visibility.
(elf_link_check_versioned_symbol): Use undef_bfd.
(elf_link_output_extsym): Warn if a forced local symbol is
referenced from dynamic objects. Make non-weak undefined symbol
with non-default visibility a fatal error.
ld/testsuite/
2003-04-01 H.J. Lu <hjl@gnu.org>
* ld-elfvsb/elfvsb.dat: Updated.
* ld-elfvsb/elfvsb.exp: Likewise.
* ld-elfvsb/main.c: Likewise.
* ld-elfvsb/sh1.c: Likewise.
* ld-elfvsb/sh2.c: Likewise.
--- binutils/bfd/elf-bfd.h.vsb 2003-02-27 11:26:52.000000000 -0800
+++ binutils/bfd/elf-bfd.h 2003-03-31 10:11:34.000000000 -0800
@@ -204,6 +204,10 @@ struct elf_link_hash_entry
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
not currently set by all the backends. */
#define ELF_LINK_NON_GOT_REF 010000
+ /* Symbol has a definition in a shared object. */
+#define ELF_LINK_DYNAMIC_DEF 020000
+ /* Symbol is weak in all shared objects. */
+#define ELF_LINK_DYNAMIC_WEAK 040000
};
/* Records local symbols to be emitted in the dynamic symbol table. */
--- binutils/bfd/elf32-i386.c.vsb 2003-03-31 10:11:34.000000000 -0800
+++ binutils/bfd/elf32-i386.c 2003-04-01 10:21:52.000000000 -0800
@@ -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, i
&& (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, i
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
--- binutils/bfd/elflink.h.vsb 2003-03-31 10:02:52.000000000 -0800
+++ binutils/bfd/elflink.h 2003-04-01 11:48:42.000000000 -0800
@@ -42,7 +42,7 @@ static bfd_boolean elf_merge_symbol
PARAMS ((bfd *, struct bfd_link_info *, const char *,
Elf_Internal_Sym *, asection **, bfd_vma *,
struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *,
- bfd_boolean *, bfd_boolean));
+ bfd_boolean *, bfd_boolean *, bfd_boolean));
static bfd_boolean elf_add_default_symbol
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
@@ -463,7 +463,7 @@ elf_link_add_archive_symbols (abfd, info
a shared object. */
static bfd_boolean
-elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
+elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
override, type_change_ok, size_change_ok, dt_needed)
bfd *abfd;
struct bfd_link_info *info;
@@ -472,6 +472,7 @@ elf_merge_symbol (abfd, info, name, sym,
asection **psec;
bfd_vma *pvalue;
struct elf_link_hash_entry **sym_hash;
+ bfd_boolean *skip;
bfd_boolean *override;
bfd_boolean *type_change_ok;
bfd_boolean *size_change_ok;
@@ -483,6 +484,7 @@ elf_merge_symbol (abfd, info, name, sym,
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+ *skip = FALSE;
*override = FALSE;
sec = *psec;
@@ -605,6 +607,57 @@ elf_merge_symbol (abfd, info, name, sym,
else
olddef = TRUE;
+ /* We need to rememeber if a symbol has a definition in a dynamic
+ object or is weak in all dynamic objects. Internal and hidden
+ visibility will make it unavailable to dynamic objects. */
+ if (newdyn && (h->elf_link_hash_flags & ELF_LINK_DYNAMIC_DEF) == 0)
+ {
+ if (!bfd_is_und_section (sec))
+ h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_DEF;
+ else
+ {
+ /* Check if this symbol is weak in all dynamic objects. If it
+ is the first time we see it in a dynamic object, we mark
+ if it is weak. Otherwise, we clear it. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ {
+ if (bind == STB_WEAK)
+ h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_WEAK;
+ }
+ else if (bind != STB_WEAK)
+ h->elf_link_hash_flags &= ~ELF_LINK_DYNAMIC_WEAK;
+ }
+ }
+
+ /* If the old symbol has non-default visibility, we ignore the new
+ definition from a dynamic object. */
+ if (newdyn
+ && ELF_ST_VISIBILITY (h->other)
+ && !bfd_is_und_section (sec))
+ {
+ *skip = TRUE;
+ /* Make sure this symbol is dynamic. */
+ h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ /* FIXME: Should we check type and size for protected symbol? */
+ return _bfd_elf_link_record_dynamic_symbol (info, h);
+ }
+ else if (!newdyn
+ && ELF_ST_VISIBILITY (sym->st_other)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+ {
+ /* If the new symbol with non-default visibility comes from a
+ relocatable file and the old definition comes from a dynamic
+ object, we remove the old definition. */
+ h->root.type = bfd_link_hash_new;
+ h->root.u.undef.abfd = NULL;
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ /* FIXME: Should we check type and size for protected symbol? */
+ h->size = 0;
+ h->type = 0;
+ return TRUE;
+ }
+
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
object. If a symbol appears in an uninitialized section, and is
@@ -919,6 +972,7 @@ elf_add_default_symbol (abfd, info, h, n
{
bfd_boolean type_change_ok;
bfd_boolean size_change_ok;
+ bfd_boolean skip;
char *shortname;
struct elf_link_hash_entry *hi;
struct bfd_link_hash_entry *bh;
@@ -974,7 +1028,7 @@ elf_add_default_symbol (abfd, info, h, n
size_change_ok = FALSE;
sec = *psec;
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &override, &type_change_ok,
+ &hi, &skip, &override, &type_change_ok,
&size_change_ok, dt_needed))
return FALSE;
@@ -1083,7 +1137,7 @@ elf_add_default_symbol (abfd, info, h, n
size_change_ok = FALSE;
sec = *psec;
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &override, &type_change_ok,
+ &hi, &skip, &override, &type_change_ok,
&size_change_ok, dt_needed))
return FALSE;
@@ -1721,6 +1775,7 @@ elf_link_add_object_symbols (abfd, info)
{
Elf_Internal_Versym iver;
unsigned int vernum = 0;
+ bfd_boolean skip;
if (ever != NULL)
{
@@ -1818,10 +1873,14 @@ elf_link_add_object_symbols (abfd, info)
}
if (! elf_merge_symbol (abfd, info, name, isym, &sec, &value,
- sym_hash, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ sym_hash, &skip, &override,
+ &type_change_ok, &size_change_ok,
+ dt_needed))
goto error_free_vers;
+ if (skip)
+ continue;
+
if (override)
definition = FALSE;
@@ -1936,9 +1995,10 @@ elf_link_add_object_symbols (abfd, info)
h->type = ELF_ST_TYPE (isym->st_info);
}
- /* If st_other has a processor-specific meaning, specific code
- might be needed here. */
- if (isym->st_other != 0)
+ /* If st_other has a processor-specific meaning, specific
+ code might be needed here. We never merge the visibility
+ attribute with the one from a dynamic object. */
+ if (isym->st_other != 0 && !dynamic)
{
unsigned char hvis, symvis, other, nvis;
@@ -2005,7 +2065,7 @@ elf_link_add_object_symbols (abfd, info)
override, dt_needed))
goto error_free_vers;
- if (definition && (abfd->flags & DYNAMIC) == 0)
+ if (definition && !dynamic)
{
char *p = strchr (name, ELF_VER_CHR);
if (p != NULL && p[1] != ELF_VER_CHR)
@@ -3941,6 +4001,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. */
@@ -6021,7 +6091,7 @@ elf_link_check_versioned_symbol (info, h
if ((undef_bfd->flags & DYNAMIC) == 0
|| info->hash->creator->flavour != bfd_target_elf_flavour
- || elf_dt_soname (h->root.u.undef.abfd) == NULL)
+ || elf_dt_soname (undef_bfd) == NULL)
return FALSE;
for (loaded = elf_hash_table (info)->loaded;
@@ -6188,6 +6258,28 @@ elf_link_output_extsym (h, data)
}
}
+ /* We should also warn if a forced local symbol is referenced from
+ shared libraries. */
+ if (! finfo->info->relocateable
+ && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
+ && (h->elf_link_hash_flags
+ & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
+ == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC))
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s symbol `%s' in %s is referenced by DSO"),
+ bfd_get_filename (finfo->output_bfd),
+ ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ ? "internal"
+ : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ ? "hidden" : "local",
+ h->root.root.string,
+ bfd_archive_filename (h->root.u.def.section->owner));
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+
/* We don't want to output symbols that have never been mentioned by
a regular file, or that we have been told to strip. However, if
h->indx is set to -2, the symbol is used by a reloc and we must
@@ -6313,7 +6405,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)
{
@@ -6348,10 +6442,25 @@ elf_link_output_extsym (h, data)
sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
}
- /* If a symbol is not defined locally, we clear the visibility field. */
+ /* If a non-weak symbol with non-default visibility is not defined
+ locally, it is a fatal error. */
if (! finfo->info->relocateable
+ && ELF_ST_VISIBILITY (sym.st_other)
+ && ELF_ST_BIND (sym.st_info) != STB_WEAK
+ && h->root.type != bfd_link_hash_undefweak
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- sym.st_other &= ~ ELF_ST_VISIBILITY (-1);
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s symbol `%s' isn't defined"),
+ bfd_get_filename (finfo->output_bfd),
+ ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED
+ ? "protected"
+ : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
+ ? "internal" : "hidden",
+ h->root.root.string);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
/* If this symbol should be put in the .dynsym section, then put it
there now. We already know the symbol index. We also fill in
--- binutils/bfd/elfxx-ia64.c.vsb 2003-03-28 11:58:01.000000000 -0800
+++ binutils/bfd/elfxx-ia64.c 2003-04-01 11:28:33.000000000 -0800
@@ -2613,7 +2613,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
@@ -3409,7 +3412,11 @@ set_got_entry (abfd, info, dyn_i, dynind
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))
@@ -3530,7 +3537,11 @@ set_pltoff_entry (abfd, info, dyn_i, val
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;
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.dat.vsb 2000-06-05 15:55:02.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.dat 2003-03-31 10:11:34.000000000 -0800
@@ -20,3 +20,7 @@ main_visibility_check () == 1
visibility_checkvar () == 1
visibility_checkvarptr () == 1
main_visibility_checkvar () == 1
+main_visibility_checkcom () == 1
+shlib_visibility_checkcom () == 1
+main_visibility_checkweak () == 1
+shlib_visibility_checkweak () == 1
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.exp.vsb 2003-03-31 10:11:34.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.exp 2003-03-31 10:11:34.000000000 -0800
@@ -144,6 +144,8 @@ proc visibility_test { visibility progna
pass "$testname"
} else { if { [ string match $visibility "hidden_undef_def" ]
&& [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
+ && [regexp ".*/main.c.*: undefined reference to \`visibility_def\'" $link_output]
+ && [regexp ".*/main.c.*: undefined reference to \`visibility_func\'" $link_output]
&& [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
pass "$testname"
} else {
--- binutils/ld/testsuite/ld-elfvsb/main.c.vsb 2000-11-07 16:34:01.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/main.c 2003-03-31 10:11:34.000000000 -0800
@@ -42,6 +42,18 @@ extern int visibility_checkvar ();
extern int visibility_checkvarptr ();
extern int visibility_varval ();
extern void *visibility_varptr ();
+extern int shlib_visibility_checkcom ();
+extern int shlib_visibility_checkweak ();
+
+int shlib_visibility_com = 1;
+
+int shlib_visibility_var_weak = 1;
+
+int
+shlib_visibility_func_weak ()
+{
+ return 1;
+}
#ifdef HIDDEN_WEAK_TEST
#define WEAK_TEST
@@ -81,6 +93,23 @@ main_visibility_checkvar ()
return visibility_varval () != visibility_var
&& visibility_varptr () != &visibility_var;
}
+
+#ifndef PROTECTED_UNDEF_TEST
+int shared_data = 1;
+asm (".protected shared_data");
+
+int
+shared_func ()
+{
+ return 1;
+}
+
+asm (".protected shared_func");
+
+extern int * shared_data_p ();
+typedef int (*func) ();
+extern func shared_func_p ();
+#endif
#else
static int
main_visibility_check ()
@@ -121,10 +150,88 @@ shlib_overriddencall2 ()
return 8;
}
+#ifdef HIDDEN_NORMAL_TEST
+int visibility_com;
+asm (".hidden visibility_com");
+
+int
+main_visibility_checkcom ()
+{
+ return visibility_com == 0;
+}
+
+int
+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");
+extern int visibility_func ();
+asm (".hidden visibility_func");
+
+int
+main_visibility_checkcom ()
+{
+ return &visibility_def != NULL;
+}
+
+int
+main_visibility_checkweak ()
+{
+ return &visibility_func != NULL;
+}
+#else
+int
+main_visibility_checkcom ()
+{
+ return 1;
+}
+
+int
+main_visibility_checkweak ()
+{
+ return 1;
+}
+#endif
+
int
main ()
{
int (*p) ();
+ int ret = 0;
printf ("mainvar == %d\n", mainvar);
printf ("overriddenvar == %d\n", overriddenvar);
@@ -173,6 +280,27 @@ main ()
visibility_checkvarptr ());
printf ("main_visibility_checkvar () == %d\n",
main_visibility_checkvar ());
- return 0;
+ printf ("main_visibility_checkcom () == %d\n",
+ main_visibility_checkcom ());
+ printf ("shlib_visibility_checkcom () == %d\n",
+ shlib_visibility_checkcom ());
+ printf ("main_visibility_checkweak () == %d\n",
+ main_visibility_checkweak ());
+ printf ("shlib_visibility_checkweak () == %d\n",
+ shlib_visibility_checkweak ());
+
+#if !defined (PROTECTED_UNDEF_TEST) && defined (PROTECTED_TEST)
+ if (&shared_data != shared_data_p ())
+ ret = 1;
+ p = shared_func_p ();
+ if (shared_func != p)
+ ret = 1;
+ if (shared_data != *shared_data_p ())
+ ret = 1;
+ if (shared_func () != (*p) () )
+ ret = 1;
+#endif
+
+ return ret;
}
#endif
--- binutils/ld/testsuite/ld-elfvsb/sh1.c.vsb 2003-03-31 10:11:34.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/sh1.c 2003-04-01 09:15:57.000000000 -0800
@@ -326,3 +326,85 @@ asm (".protected visibility");
asm (".protected visibility_var");
#endif
#endif
+
+#ifdef HIDDEN_NORMAL_TEST
+int shlib_visibility_com;
+asm (".hidden shlib_visibility_com");
+
+int
+shlib_visibility_checkcom ()
+{
+ return shlib_visibility_com == 0;
+}
+
+int
+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 ()
+{
+ return 1;
+}
+
+int
+shlib_visibility_checkweak ()
+{
+ return 1;
+}
+#endif
+
+#ifdef PROTECTED_TEST
+int shared_data = 100;
+
+int *
+shared_data_p ()
+{
+ return &shared_data;
+}
+
+int
+shared_func ()
+{
+ return 100;
+}
+
+void *
+shared_func_p ()
+{
+ return shared_func;
+}
+#endif
--- binutils/ld/testsuite/ld-elfvsb/sh2.c.vsb 2000-06-05 15:55:02.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/sh2.c 2003-03-31 10:11:34.000000000 -0800
@@ -5,6 +5,10 @@
the shared library. */
int shlibvar2 = 4;
+/* This variable is defined here, and shouldn't be used to resolve a
+ reference with non-default visibility in another shared library. */
+int visibility_com = 2;
+
/* This function is called by another file in the shared library. */
int
@@ -21,4 +25,22 @@ visibility ()
}
int visibility_var = 2;
+
+int visibility_def = 2;
+
+int
+visibility_func ()
+{
+ return 2;
+}
+#endif
+
+#ifdef HIDDEN_WEAK_TEST
+int visibility_var_weak = 2;
+
+int
+visibility_func_weak ()
+{
+ return 2;
+}
#endif
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-04-01 20:20 PATCH: Fix ELF visibility handling H. J. Lu
@ 2003-04-09 16:22 ` H. J. Lu
2003-04-27 23:08 ` Alan Modra
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: H. J. Lu @ 2003-04-09 16:22 UTC (permalink / raw)
To: binutils; +Cc: amodra
[-- Attachment #1: Type: text/plain, Size: 844 bytes --]
On Tue, Apr 01, 2003 at 12:19:58PM -0800, H. J. Lu wrote:
> The currenr ELF visibility handling is wrong on several things:
>
> 1. Ld doesn't report an error for undefined symbols with non-default
> visibility when there is a definition from a shared library.
> 2. Weak undefined symbols with non-default visibility results in
> undetermined run-time behavior depending on if there is a definition
> at run-time.
> 3. Ld gives no warnings when a shared library refeneces a hidden symbol.
> 4. ld merges visibility with symbols from shared libraries.
>
> This patch fixes those problems with testcases. As for weak undefined
> symbols with non-default visibility, I only fixed x86 and ia64.
>
I modified the patch to separate handling of weak undefined symbols
with non-default visibility. Alan, could you take a look at it?
Thanks.
H.J.
[-- Attachment #2: binutils-vsb.patch --]
[-- Type: text/plain, Size: 15572 bytes --]
bfd/
2003-04-01 H.J. Lu <hjl@gnu.org>
* elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New.
(ELF_LINK_DYNAMIC_WEAK): New.
* elflink.h (elf_merge_symbol): Add one argument to indicate if
a symbol should be skipped. Ignore definitions in dynamic
objects for symbols with non-default visibility.
(elf_add_default_symbol): Adjusted.
(elf_link_add_object_symbols): Check if a symbol should be
skipped. Don't merge the visibility field with the one from
a dynamic object.
(elf_link_check_versioned_symbol): Use undef_bfd.
(elf_link_output_extsym): Warn if a forced local symbol is
referenced from dynamic objects. Make non-weak undefined symbol
with non-default visibility a fatal error.
ld/testsuite/
2003-04-01 H.J. Lu <hjl@gnu.org>
* ld-elfvsb/elfvsb.dat: Updated.
* ld-elfvsb/elfvsb.exp: Likewise.
* ld-elfvsb/main.c: Likewise.
* ld-elfvsb/sh1.c: Likewise.
* ld-elfvsb/sh2.c: Likewise.
--- binutils/bfd/elf-bfd.h.vsb 2003-02-27 11:26:52.000000000 -0800
+++ binutils/bfd/elf-bfd.h 2003-04-07 17:08:01.000000000 -0700
@@ -204,6 +204,10 @@ struct elf_link_hash_entry
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
not currently set by all the backends. */
#define ELF_LINK_NON_GOT_REF 010000
+ /* Symbol has a definition in a shared object. */
+#define ELF_LINK_DYNAMIC_DEF 020000
+ /* Symbol is weak in all shared objects. */
+#define ELF_LINK_DYNAMIC_WEAK 040000
};
/* Records local symbols to be emitted in the dynamic symbol table. */
--- binutils/bfd/elflink.h.vsb 2003-04-01 14:28:52.000000000 -0800
+++ binutils/bfd/elflink.h 2003-04-08 08:57:59.000000000 -0700
@@ -42,7 +42,7 @@ static bfd_boolean elf_merge_symbol
PARAMS ((bfd *, struct bfd_link_info *, const char *,
Elf_Internal_Sym *, asection **, bfd_vma *,
struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *,
- bfd_boolean *, bfd_boolean));
+ bfd_boolean *, bfd_boolean *, bfd_boolean));
static bfd_boolean elf_add_default_symbol
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
@@ -463,7 +463,7 @@ elf_link_add_archive_symbols (abfd, info
a shared object. */
static bfd_boolean
-elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
+elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
override, type_change_ok, size_change_ok, dt_needed)
bfd *abfd;
struct bfd_link_info *info;
@@ -472,6 +472,7 @@ elf_merge_symbol (abfd, info, name, sym,
asection **psec;
bfd_vma *pvalue;
struct elf_link_hash_entry **sym_hash;
+ bfd_boolean *skip;
bfd_boolean *override;
bfd_boolean *type_change_ok;
bfd_boolean *size_change_ok;
@@ -483,6 +484,7 @@ elf_merge_symbol (abfd, info, name, sym,
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+ *skip = FALSE;
*override = FALSE;
sec = *psec;
@@ -605,6 +607,57 @@ elf_merge_symbol (abfd, info, name, sym,
else
olddef = TRUE;
+ /* We need to rememeber if a symbol has a definition in a dynamic
+ object or is weak in all dynamic objects. Internal and hidden
+ visibility will make it unavailable to dynamic objects. */
+ if (newdyn && (h->elf_link_hash_flags & ELF_LINK_DYNAMIC_DEF) == 0)
+ {
+ if (!bfd_is_und_section (sec))
+ h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_DEF;
+ else
+ {
+ /* Check if this symbol is weak in all dynamic objects. If it
+ is the first time we see it in a dynamic object, we mark
+ if it is weak. Otherwise, we clear it. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ {
+ if (bind == STB_WEAK)
+ h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_WEAK;
+ }
+ else if (bind != STB_WEAK)
+ h->elf_link_hash_flags &= ~ELF_LINK_DYNAMIC_WEAK;
+ }
+ }
+
+ /* If the old symbol has non-default visibility, we ignore the new
+ definition from a dynamic object. */
+ if (newdyn
+ && ELF_ST_VISIBILITY (h->other)
+ && !bfd_is_und_section (sec))
+ {
+ *skip = TRUE;
+ /* Make sure this symbol is dynamic. */
+ h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ /* FIXME: Should we check type and size for protected symbol? */
+ return _bfd_elf_link_record_dynamic_symbol (info, h);
+ }
+ else if (!newdyn
+ && ELF_ST_VISIBILITY (sym->st_other)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+ {
+ /* If the new symbol with non-default visibility comes from a
+ relocatable file and the old definition comes from a dynamic
+ object, we remove the old definition. */
+ h->root.type = bfd_link_hash_new;
+ h->root.u.undef.abfd = NULL;
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ /* FIXME: Should we check type and size for protected symbol? */
+ h->size = 0;
+ h->type = 0;
+ return TRUE;
+ }
+
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
object. If a symbol appears in an uninitialized section, and is
@@ -919,6 +972,7 @@ elf_add_default_symbol (abfd, info, h, n
{
bfd_boolean type_change_ok;
bfd_boolean size_change_ok;
+ bfd_boolean skip;
char *shortname;
struct elf_link_hash_entry *hi;
struct bfd_link_hash_entry *bh;
@@ -974,7 +1028,7 @@ elf_add_default_symbol (abfd, info, h, n
size_change_ok = FALSE;
sec = *psec;
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &override, &type_change_ok,
+ &hi, &skip, &override, &type_change_ok,
&size_change_ok, dt_needed))
return FALSE;
@@ -1083,7 +1137,7 @@ elf_add_default_symbol (abfd, info, h, n
size_change_ok = FALSE;
sec = *psec;
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &override, &type_change_ok,
+ &hi, &skip, &override, &type_change_ok,
&size_change_ok, dt_needed))
return FALSE;
@@ -1721,6 +1775,7 @@ elf_link_add_object_symbols (abfd, info)
{
Elf_Internal_Versym iver;
unsigned int vernum = 0;
+ bfd_boolean skip;
if (ever != NULL)
{
@@ -1818,10 +1873,14 @@ elf_link_add_object_symbols (abfd, info)
}
if (! elf_merge_symbol (abfd, info, name, isym, &sec, &value,
- sym_hash, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ sym_hash, &skip, &override,
+ &type_change_ok, &size_change_ok,
+ dt_needed))
goto error_free_vers;
+ if (skip)
+ continue;
+
if (override)
definition = FALSE;
@@ -1936,9 +1995,10 @@ elf_link_add_object_symbols (abfd, info)
h->type = ELF_ST_TYPE (isym->st_info);
}
- /* If st_other has a processor-specific meaning, specific code
- might be needed here. */
- if (isym->st_other != 0)
+ /* If st_other has a processor-specific meaning, specific
+ code might be needed here. We never merge the visibility
+ attribute with the one from a dynamic object. */
+ if (isym->st_other != 0 && !dynamic)
{
unsigned char hvis, symvis, other, nvis;
@@ -2005,7 +2065,7 @@ elf_link_add_object_symbols (abfd, info)
override, dt_needed))
goto error_free_vers;
- if (definition && (abfd->flags & DYNAMIC) == 0)
+ if (definition && !dynamic)
{
char *p = strchr (name, ELF_VER_CHR);
if (p != NULL && p[1] != ELF_VER_CHR)
@@ -6022,7 +6082,7 @@ elf_link_check_versioned_symbol (info, h
if ((undef_bfd->flags & DYNAMIC) == 0
|| info->hash->creator->flavour != bfd_target_elf_flavour
- || elf_dt_soname (h->root.u.undef.abfd) == NULL)
+ || elf_dt_soname (undef_bfd) == NULL)
return FALSE;
for (loaded = elf_hash_table (info)->loaded;
@@ -6189,6 +6249,28 @@ elf_link_output_extsym (h, data)
}
}
+ /* We should also warn if a forced local symbol is referenced from
+ shared libraries. */
+ if (! finfo->info->relocateable
+ && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
+ && (h->elf_link_hash_flags
+ & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
+ == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC))
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s symbol `%s' in %s is referenced by DSO"),
+ bfd_get_filename (finfo->output_bfd),
+ ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ ? "internal"
+ : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ ? "hidden" : "local",
+ h->root.root.string,
+ bfd_archive_filename (h->root.u.def.section->owner));
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+
/* We don't want to output symbols that have never been mentioned by
a regular file, or that we have been told to strip. However, if
h->indx is set to -2, the symbol is used by a reloc and we must
@@ -6349,10 +6431,25 @@ elf_link_output_extsym (h, data)
sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
}
- /* If a symbol is not defined locally, we clear the visibility field. */
+ /* If a non-weak symbol with non-default visibility is not defined
+ locally, it is a fatal error. */
if (! finfo->info->relocateable
+ && ELF_ST_VISIBILITY (sym.st_other)
+ && ELF_ST_BIND (sym.st_info) != STB_WEAK
+ && h->root.type != bfd_link_hash_undefweak
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- sym.st_other &= ~ ELF_ST_VISIBILITY (-1);
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s symbol `%s' isn't defined"),
+ bfd_get_filename (finfo->output_bfd),
+ ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED
+ ? "protected"
+ : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
+ ? "internal" : "hidden",
+ h->root.root.string);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
/* If this symbol should be put in the .dynsym section, then put it
there now. We already know the symbol index. We also fill in
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.dat.vsb 2000-06-05 15:55:02.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.dat 2003-04-07 17:08:01.000000000 -0700
@@ -20,3 +20,7 @@ main_visibility_check () == 1
visibility_checkvar () == 1
visibility_checkvarptr () == 1
main_visibility_checkvar () == 1
+main_visibility_checkcom () == 1
+shlib_visibility_checkcom () == 1
+main_visibility_checkweak () == 1
+shlib_visibility_checkweak () == 1
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.exp.vsb 2003-02-27 11:27:18.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.exp 2003-04-07 17:08:01.000000000 -0700
@@ -144,6 +144,8 @@ proc visibility_test { visibility progna
pass "$testname"
} else { if { [ string match $visibility "hidden_undef_def" ]
&& [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
+ && [regexp ".*/main.c.*: undefined reference to \`visibility_def\'" $link_output]
+ && [regexp ".*/main.c.*: undefined reference to \`visibility_func\'" $link_output]
&& [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
pass "$testname"
} else {
--- binutils/ld/testsuite/ld-elfvsb/main.c.vsb 2000-11-07 16:34:01.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/main.c 2003-04-08 09:22:47.000000000 -0700
@@ -42,6 +42,18 @@ extern int visibility_checkvar ();
extern int visibility_checkvarptr ();
extern int visibility_varval ();
extern void *visibility_varptr ();
+extern int shlib_visibility_checkcom ();
+extern int shlib_visibility_checkweak ();
+
+int shlib_visibility_com = 1;
+
+int shlib_visibility_var_weak = 1;
+
+int
+shlib_visibility_func_weak ()
+{
+ return 1;
+}
#ifdef HIDDEN_WEAK_TEST
#define WEAK_TEST
@@ -81,6 +93,23 @@ main_visibility_checkvar ()
return visibility_varval () != visibility_var
&& visibility_varptr () != &visibility_var;
}
+
+#ifndef PROTECTED_UNDEF_TEST
+int shared_data = 1;
+asm (".protected shared_data");
+
+int
+shared_func ()
+{
+ return 1;
+}
+
+asm (".protected shared_func");
+
+extern int * shared_data_p ();
+typedef int (*func) ();
+extern func shared_func_p ();
+#endif
#else
static int
main_visibility_check ()
@@ -121,10 +150,57 @@ shlib_overriddencall2 ()
return 8;
}
+#ifdef HIDDEN_NORMAL_TEST
+int visibility_com;
+asm (".hidden visibility_com");
+
+int
+main_visibility_checkcom ()
+{
+ return visibility_com == 0;
+}
+
+int
+main_visibility_checkweak ()
+{
+ return 1;
+}
+#elif defined (HIDDEN_UNDEF_TEST)
+extern int visibility_def;
+asm (".hidden visibility_def");
+extern int visibility_func ();
+asm (".hidden visibility_func");
+
+int
+main_visibility_checkcom ()
+{
+ return &visibility_def != NULL;
+}
+
+int
+main_visibility_checkweak ()
+{
+ return &visibility_func != NULL;
+}
+#else
+int
+main_visibility_checkcom ()
+{
+ return 1;
+}
+
+int
+main_visibility_checkweak ()
+{
+ return 1;
+}
+#endif
+
int
main ()
{
int (*p) ();
+ int ret = 0;
printf ("mainvar == %d\n", mainvar);
printf ("overriddenvar == %d\n", overriddenvar);
@@ -173,6 +249,27 @@ main ()
visibility_checkvarptr ());
printf ("main_visibility_checkvar () == %d\n",
main_visibility_checkvar ());
- return 0;
+ printf ("main_visibility_checkcom () == %d\n",
+ main_visibility_checkcom ());
+ printf ("shlib_visibility_checkcom () == %d\n",
+ shlib_visibility_checkcom ());
+ printf ("main_visibility_checkweak () == %d\n",
+ main_visibility_checkweak ());
+ printf ("shlib_visibility_checkweak () == %d\n",
+ shlib_visibility_checkweak ());
+
+#if !defined (PROTECTED_UNDEF_TEST) && defined (PROTECTED_TEST)
+ if (&shared_data != shared_data_p ())
+ ret = 1;
+ p = shared_func_p ();
+ if (shared_func != p)
+ ret = 1;
+ if (shared_data != *shared_data_p ())
+ ret = 1;
+ if (shared_func () != (*p) () )
+ ret = 1;
+#endif
+
+ return ret;
}
#endif
--- binutils/ld/testsuite/ld-elfvsb/sh1.c.vsb 2003-03-28 12:30:50.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvsb/sh1.c 2003-04-08 09:22:18.000000000 -0700
@@ -323,3 +323,54 @@ asm (".protected visibility");
asm (".protected visibility_var");
#endif
#endif
+
+#ifdef HIDDEN_NORMAL_TEST
+int shlib_visibility_com;
+asm (".hidden shlib_visibility_com");
+
+int
+shlib_visibility_checkcom ()
+{
+ return shlib_visibility_com == 0;
+}
+
+int
+shlib_visibility_checkweak ()
+{
+ return 1;
+}
+#else
+int
+shlib_visibility_checkcom ()
+{
+ return 1;
+}
+
+int
+shlib_visibility_checkweak ()
+{
+ return 1;
+}
+#endif
+
+#ifdef PROTECTED_TEST
+int shared_data = 100;
+
+int *
+shared_data_p ()
+{
+ return &shared_data;
+}
+
+int
+shared_func ()
+{
+ return 100;
+}
+
+void *
+shared_func_p ()
+{
+ return shared_func;
+}
+#endif
--- binutils/ld/testsuite/ld-elfvsb/sh2.c.vsb 2000-06-05 15:55:02.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/sh2.c 2003-04-07 17:08:01.000000000 -0700
@@ -5,6 +5,10 @@
the shared library. */
int shlibvar2 = 4;
+/* This variable is defined here, and shouldn't be used to resolve a
+ reference with non-default visibility in another shared library. */
+int visibility_com = 2;
+
/* This function is called by another file in the shared library. */
int
@@ -21,4 +25,22 @@ visibility ()
}
int visibility_var = 2;
+
+int visibility_def = 2;
+
+int
+visibility_func ()
+{
+ return 2;
+}
+#endif
+
+#ifdef HIDDEN_WEAK_TEST
+int visibility_var_weak = 2;
+
+int
+visibility_func_weak ()
+{
+ return 2;
+}
#endif
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-04-09 16:22 ` H. J. Lu
@ 2003-04-27 23:08 ` Alan Modra
2003-05-19 22:19 ` Jakub Jelinek
2013-01-13 12:30 ` Alan Modra
2 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2003-04-27 23:08 UTC (permalink / raw)
To: H. J. Lu; +Cc: binutils
On Wed, Apr 09, 2003 at 09:22:52AM -0700, H. J. Lu wrote:
> * elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New.
> (ELF_LINK_DYNAMIC_WEAK): New.
>
> * elflink.h (elf_merge_symbol): Add one argument to indicate if
> a symbol should be skipped. Ignore definitions in dynamic
> objects for symbols with non-default visibility.
> (elf_add_default_symbol): Adjusted.
> (elf_link_add_object_symbols): Check if a symbol should be
> skipped. Don't merge the visibility field with the one from
> a dynamic object.
> (elf_link_check_versioned_symbol): Use undef_bfd.
> (elf_link_output_extsym): Warn if a forced local symbol is
> referenced from dynamic objects. Make non-weak undefined symbol
> with non-default visibility a fatal error.
>
> ld/testsuite/
>
> 2003-04-01 H.J. Lu <hjl@gnu.org>
>
> * ld-elfvsb/elfvsb.dat: Updated.
> * ld-elfvsb/elfvsb.exp: Likewise.
> * ld-elfvsb/main.c: Likewise.
> * ld-elfvsb/sh1.c: Likewise.
> * ld-elfvsb/sh2.c: Likewise.
OK.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-04-09 16:22 ` H. J. Lu
2003-04-27 23:08 ` Alan Modra
@ 2003-05-19 22:19 ` Jakub Jelinek
2003-05-20 0:38 ` H. J. Lu
2013-01-13 12:30 ` Alan Modra
2 siblings, 1 reply; 8+ messages in thread
From: Jakub Jelinek @ 2003-05-19 22:19 UTC (permalink / raw)
To: H. J. Lu; +Cc: binutils, amodra
On Wed, Apr 09, 2003 at 09:22:52AM -0700, H. J. Lu wrote:
> 2003-04-01 H.J. Lu <hjl@gnu.org>
>
> (elf_link_output_extsym): Warn if a forced local symbol is
> referenced from dynamic objects. Make non-weak undefined symbol
> with non-default visibility a fatal error.
This change broke static linking with hidden common symbols
(testcase included in the patch below).
Any reason why you use h->root.type != bfd_link_hash_undefweak
which can well be a normal bfd_link_hash_defined symbol?
2003-05-20 Jakub Jelinek <jakub@redhat.com>
* elflink.h (elf_link_output_extsym): Only issue error about !=
STV_DEFAULT symbols if they are bfd_link_hash_undefined.
* ld-elfvsb/sh3.c: New test.
* ld-elfvsb/elfvsb.exp: Add sh3.
--- bfd/elflink.h.jj 2003-05-19 17:12:39.000000000 -0400
+++ bfd/elflink.h 2003-05-19 17:43:12.000000000 -0400
@@ -4622,7 +4622,7 @@ elf_link_output_extsym (h, data)
if (! finfo->info->relocateable
&& ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
- && h->root.type != bfd_link_hash_undefweak
+ && h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
(*_bfd_error_handler)
--- ld/testsuite/ld-elfvsb/sh3.c.jj 2003-05-19 17:51:14.000000000 -0400
+++ ld/testsuite/ld-elfvsb/sh3.c 2003-05-19 17:51:08.000000000 -0400
@@ -0,0 +1,7 @@
+int foo;
+asm (".hidden foo");
+
+int main (void)
+{
+ return foo;
+}
--- ld/testsuite/ld-elfvsb/elfvsb.exp.jj 2003-05-19 17:12:47.000000000 -0400
+++ ld/testsuite/ld-elfvsb/elfvsb.exp 2003-05-19 18:08:22.000000000 -0400
@@ -412,6 +412,16 @@ visibility_run protected_undef_def
visibility_run protected_weak
visibility_run normal
+if { ![ld_compile "$CC -g $CFLAGS $SHCFLAG" $srcdir/$subdir/sh3.c $tmpdir/sh3.o] } {
+ unresolved "static visibility"
+} else {
+ if ![ld_simple_link $CC $tmpdir/sh3 "-static $tmpdir/sh3.o"] {
+ fail "static visibility"
+ } else {
+ pass "static visibility"
+ }
+}
+
if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
# Remove the temporary directory.
catch "exec rm -rf $tmpdir" exec_status
Jakub
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-05-19 22:19 ` Jakub Jelinek
@ 2003-05-20 0:38 ` H. J. Lu
2003-05-20 1:27 ` H. J. Lu
0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2003-05-20 0:38 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: binutils, amodra
On Tue, May 20, 2003 at 12:19:19AM +0200, Jakub Jelinek wrote:
> On Wed, Apr 09, 2003 at 09:22:52AM -0700, H. J. Lu wrote:
> > 2003-04-01 H.J. Lu <hjl@gnu.org>
> >
> > (elf_link_output_extsym): Warn if a forced local symbol is
> > referenced from dynamic objects. Make non-weak undefined symbol
> > with non-default visibility a fatal error.
>
> This change broke static linking with hidden common symbols
> (testcase included in the patch below).
I don't think it works with dynamic linking either. I found another
bug. I will post a testcase and a patch later.
> Any reason why you use h->root.type != bfd_link_hash_undefweak
> which can well be a normal bfd_link_hash_defined symbol?
I have an old patch to fix a related problem:
http://sources.redhat.com/ml/binutils/2003-03/msg00080.html
in a different way. Then I changed it and forgot to update another
patch. That is what happened when you had so many patches on top
of each other.
>
> 2003-05-20 Jakub Jelinek <jakub@redhat.com>
>
> * elflink.h (elf_link_output_extsym): Only issue error about !=
> STV_DEFAULT symbols if they are bfd_link_hash_undefined.
>
> * ld-elfvsb/sh3.c: New test.
> * ld-elfvsb/elfvsb.exp: Add sh3.
>
> --- bfd/elflink.h.jj 2003-05-19 17:12:39.000000000 -0400
> +++ bfd/elflink.h 2003-05-19 17:43:12.000000000 -0400
> @@ -4622,7 +4622,7 @@ elf_link_output_extsym (h, data)
> if (! finfo->info->relocateable
> && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
> && ELF_ST_BIND (sym.st_info) != STB_WEAK
> - && h->root.type != bfd_link_hash_undefweak
> + && h->root.type == bfd_link_hash_undefined
> && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
> {
> (*_bfd_error_handler)
> --- ld/testsuite/ld-elfvsb/sh3.c.jj 2003-05-19 17:51:14.000000000 -0400
> +++ ld/testsuite/ld-elfvsb/sh3.c 2003-05-19 17:51:08.000000000 -0400
> @@ -0,0 +1,7 @@
> +int foo;
> +asm (".hidden foo");
> +
> +int main (void)
> +{
> + return foo;
> +}
> --- ld/testsuite/ld-elfvsb/elfvsb.exp.jj 2003-05-19 17:12:47.000000000 -0400
> +++ ld/testsuite/ld-elfvsb/elfvsb.exp 2003-05-19 18:08:22.000000000 -0400
> @@ -412,6 +412,16 @@ visibility_run protected_undef_def
> visibility_run protected_weak
> visibility_run normal
>
> +if { ![ld_compile "$CC -g $CFLAGS $SHCFLAG" $srcdir/$subdir/sh3.c $tmpdir/sh3.o] } {
> + unresolved "static visibility"
> +} else {
> + if ![ld_simple_link $CC $tmpdir/sh3 "-static $tmpdir/sh3.o"] {
> + fail "static visibility"
> + } else {
> + pass "static visibility"
> + }
> +}
> +
> if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
> # Remove the temporary directory.
> catch "exec rm -rf $tmpdir" exec_status
>
>
> Jakub
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-05-20 0:38 ` H. J. Lu
@ 2003-05-20 1:27 ` H. J. Lu
2003-05-20 11:14 ` Alan Modra
0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2003-05-20 1:27 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: binutils, amodra
[-- Attachment #1: Type: text/plain, Size: 1091 bytes --]
On Mon, May 19, 2003 at 05:38:02PM -0700, H. J. Lu wrote:
> On Tue, May 20, 2003 at 12:19:19AM +0200, Jakub Jelinek wrote:
> > On Wed, Apr 09, 2003 at 09:22:52AM -0700, H. J. Lu wrote:
> > > 2003-04-01 H.J. Lu <hjl@gnu.org>
> > >
> > > (elf_link_output_extsym): Warn if a forced local symbol is
> > > referenced from dynamic objects. Make non-weak undefined symbol
> > > with non-default visibility a fatal error.
> >
> > This change broke static linking with hidden common symbols
> > (testcase included in the patch below).
>
> I don't think it works with dynamic linking either. I found another
> bug. I will post a testcase and a patch later.
>
> > Any reason why you use h->root.type != bfd_link_hash_undefweak
> > which can well be a normal bfd_link_hash_defined symbol?
>
> I have an old patch to fix a related problem:
>
> http://sources.redhat.com/ml/binutils/2003-03/msg00080.html
>
> in a different way. Then I changed it and forgot to update another
> patch. That is what happened when you had so many patches on top
> of each other.
>
Here is the new patch.
H.J.
[-- Attachment #2: binutils-vsb-3.patch --]
[-- Type: text/plain, Size: 4340 bytes --]
bfd/
2003-05-20 Jakub Jelinek <jakub@redhat.com>
* elflink.h (elf_link_output_extsym): Only issue error about !=
STV_DEFAULT symbols if they are bfd_link_hash_undefined.
2003-05-20 H.J. Lu <hongjiu.lu@intel.com>
* elflink.c (_bfd_elf_merge_symbol): Check ELF_LINK_DYNAMIC_DEF
when removing the old definition for symbols with non-default
visibility.
ld/testsuite/
2003-05-20 Jakub Jelinek <jakub@redhat.com>
* ld-elfvsb/common.c: New file.
* ld-elfvsb/elfvsb.exp: Add common.
2003-05-20 H.J. Lu <hongjiu.lu@intel.com>
* ld-elfvsb/sh3.c: New file.
* ld-elfvsb/test.c: Likewise.
* ld-elfvsb/elfvsb.exp: Add new weak hidden symbol tests.
--- binutils/bfd/elflink.c.vsb 2003-05-18 21:48:09.000000000 -0700
+++ binutils/bfd/elflink.c 2003-05-19 18:17:55.000000000 -0700
@@ -884,7 +884,8 @@ _bfd_elf_merge_symbol (abfd, info, name,
if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
{
h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
- h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ h->elf_link_hash_flags |= (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_DYNAMIC_DEF);
}
/* FIXME: Should we check type and size for protected symbol? */
h->size = 0;
--- binutils/bfd/elflink.h.vsb 2003-05-18 21:48:10.000000000 -0700
+++ binutils/bfd/elflink.h 2003-05-19 17:42:25.000000000 -0700
@@ -4622,7 +4622,7 @@ elf_link_output_extsym (h, data)
if (! finfo->info->relocateable
&& ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
- && h->root.type != bfd_link_hash_undefweak
+ && h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
(*_bfd_error_handler)
--- binutils/ld/testsuite/ld-elfvsb/common.c.vsb 2003-05-19 17:42:25.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/common.c 2003-05-19 17:51:43.000000000 -0700
@@ -0,0 +1,14 @@
+int foo;
+asm (".hidden foo");
+
+int
+_start (void)
+{
+ return foo;
+}
+
+int
+__start (void)
+{
+ return _start ();
+}
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.exp.vsb 2003-05-18 21:48:13.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.exp 2003-05-19 18:19:04.000000000 -0700
@@ -412,6 +412,39 @@ visibility_run protected_undef_def
visibility_run protected_weak
visibility_run normal
+if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/common.c tmpdir/common.o] } {
+ unresolved "common hidden symbol"
+} else {
+ if ![ld_simple_link $ld tmpdir/common "tmpdir/common.o"] {
+ fail "common hidden symbol"
+ } else {
+ pass "common hidden symbol"
+ }
+}
+
+if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/test.c tmpdir/test.o] } {
+ unresolved "weak hidden symbol"
+} else {
+ if { ![ld_compile "$CC -g $CFLAGS $picflag" $srcdir/$subdir/sh3.c tmpdir/sh3.o] } {
+ unresolved "weak hidden symbol"
+ } else {
+ if ![ld_simple_link $ld tmpdir/sh3.so "-shared tmpdir/sh3.o"] {
+ fail "weak hidden symbol"
+ } else {
+ if ![ld_simple_link $ld tmpdir/weak "tmpdir/test.o tmpdir/sh3.o"] {
+ fail "weak hidden symbol DSO last"
+ } else {
+ pass "weak hidden symbol DSO last"
+ }
+ if ![ld_simple_link $ld tmpdir/weak "tmpdir/sh3.so tmpdir/test.o"] {
+ fail "weak hidden symbol DSO first"
+ } else {
+ pass "weak hidden symbol DSO first"
+ }
+ }
+ }
+}
+
if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
# Remove the temporary directory.
catch "exec rm -rf $tmpdir" exec_status
--- binutils/ld/testsuite/ld-elfvsb/sh3.c.vsb 2003-05-19 18:17:08.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/sh3.c 2003-05-19 17:58:53.000000000 -0700
@@ -0,0 +1,7 @@
+int main_hidden_data = 1;
+
+int
+main_hidden_func ()
+{
+ return 1;
+}
--- binutils/ld/testsuite/ld-elfvsb/test.c.vsb 2003-05-19 18:17:26.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/test.c 2003-05-19 18:00:38.000000000 -0700
@@ -0,0 +1,26 @@
+#pragma weak main_hidden_data
+extern int main_hidden_data;
+asm (".hidden main_hidden_data");
+
+#pragma weak main_hidden_func
+extern int main_hidden_func ();
+asm (".hidden main_hidden_func");
+
+int
+_start (void)
+{
+ int ret = 0;
+
+ if (&main_hidden_data != 0)
+ ret = 1;
+ if (main_hidden_func != 0)
+ ret = 1;
+
+ return ret;
+}
+
+int
+__start (void)
+{
+ return _start ();
+}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-05-20 1:27 ` H. J. Lu
@ 2003-05-20 11:14 ` Alan Modra
0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2003-05-20 11:14 UTC (permalink / raw)
To: H. J. Lu; +Cc: Jakub Jelinek, binutils
On Mon, May 19, 2003 at 06:27:00PM -0700, H. J. Lu wrote:
> 2003-05-20 Jakub Jelinek <jakub@redhat.com>
>
> * elflink.h (elf_link_output_extsym): Only issue error about !=
> STV_DEFAULT symbols if they are bfd_link_hash_undefined.
>
> 2003-05-20 H.J. Lu <hongjiu.lu@intel.com>
>
> * elflink.c (_bfd_elf_merge_symbol): Check ELF_LINK_DYNAMIC_DEF
> when removing the old definition for symbols with non-default
> visibility.
>
> ld/testsuite/
>
> 2003-05-20 Jakub Jelinek <jakub@redhat.com>
>
> * ld-elfvsb/common.c: New file.
> * ld-elfvsb/elfvsb.exp: Add common.
>
> 2003-05-20 H.J. Lu <hongjiu.lu@intel.com>
>
> * ld-elfvsb/sh3.c: New file.
> * ld-elfvsb/test.c: Likewise.
>
> * ld-elfvsb/elfvsb.exp: Add new weak hidden symbol tests.
OK.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PATCH: Fix ELF visibility handling
2003-04-09 16:22 ` H. J. Lu
2003-04-27 23:08 ` Alan Modra
2003-05-19 22:19 ` Jakub Jelinek
@ 2013-01-13 12:30 ` Alan Modra
2 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2013-01-13 12:30 UTC (permalink / raw)
To: binutils
This tidies usage of dynamic_def and dynamic_weak, two flags added a
long time ago http://sourceware.org/ml/binutils/2003-04/msg00239.html
to report errors when symbols referenced by dynamic libraries are
forced local for some reason. I flipped the sense of dynamic_weak,
calling it ref_dynamic_nonweak (cf. ref_regular_nonweak) since that
simplifies setting of the flag. There's no need then to special case
the first time setting as was done in _bfd_elf_mark_dynamic_def_weak.
I also moved setting of the flag earlier, before any of the early
returns in _bfd_elf_merge_symbol. That removes the need to fiddle
with dynamic_def elsewhere.
* elf-bfd.h (struct elf_link_hash_entry): Delete dynamic_weak.
Add ref_dynamic_nonweak.
* elflink.c (_bfd_elf_mark_dynamic_def_weak): Delete.
(_bfd_elf_merge_symbol): Don't call above function. Move
setting of ref_dynamic_nonweak and dynamic_def earlier. Don't
clear dynamic_def.
(elf_link_add_object_symbols): Delete redundant "override" test.
Don't set dynamic_def here.
(elf_link_output_extsym): Update.
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.354
diff -u -p -r1.354 elf-bfd.h
--- bfd/elf-bfd.h 11 Jan 2013 14:09:58 -0000 1.354
+++ bfd/elf-bfd.h 13 Jan 2013 03:08:34 -0000
@@ -191,8 +191,8 @@ struct elf_link_hash_entry
FIXME: There is no real need for this field if def_dynamic is never
cleared and all places that test def_dynamic also test def_regular. */
unsigned int dynamic_def : 1;
- /* Symbol is weak in all shared objects. */
- unsigned int dynamic_weak : 1;
+ /* Symbol has a non-weak reference from a shared object. */
+ unsigned int ref_dynamic_nonweak : 1;
/* Symbol is referenced with a relocation where C/C++ pointer equality
matters. */
unsigned int pointer_equality_needed : 1;
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.462
diff -u -p -r1.462 elflink.c
--- bfd/elflink.c 11 Jan 2013 14:09:59 -0000 1.462
+++ bfd/elflink.c 13 Jan 2013 05:25:05 -0000
@@ -895,33 +895,6 @@ elf_merge_st_other (bfd *abfd, struct el
}
}
-/* Mark if a symbol has a definition in a dynamic object or is
- weak in all dynamic objects. */
-
-static void
-_bfd_elf_mark_dynamic_def_weak (struct elf_link_hash_entry *h,
- asection *sec, int bind)
-{
- if (!h->dynamic_def)
- {
- if (!bfd_is_und_section (sec))
- h->dynamic_def = 1;
- else
- {
- /* Check if this symbol is weak in all dynamic objects. If it
- is the first time we see it in a dynamic object, we mark
- if it is weak. Otherwise, we clear it. */
- if (!h->ref_dynamic)
- {
- if (bind == STB_WEAK)
- h->dynamic_weak = 1;
- }
- else if (bind != STB_WEAK)
- h->dynamic_weak = 0;
- }
- }
-}
-
/* This function is called when we want to define a new symbol. It
handles the various cases which arise when we find a definition in
a dynamic object, or when there is already a definition in a
@@ -998,10 +971,39 @@ _bfd_elf_merge_symbol (bfd *abfd,
h = (struct elf_link_hash_entry *) h->root.u.i.link;
/* We have to check it for every instance since the first few may be
- refereences and not all compilers emit symbol type for undefined
+ references and not all compilers emit symbol type for undefined
symbols. */
bfd_elf_link_mark_dynamic_symbol (info, h, sym);
+ /* NEWDYN and OLDDYN indicate whether the new or old symbol,
+ respectively, is from a dynamic object. */
+
+ newdyn = (abfd->flags & DYNAMIC) != 0;
+
+ /* ref_dynamic_nonweak and dynamic_def flags track actual undefined
+ syms and defined syms in dynamic libraries respectively.
+ ref_dynamic on the other hand can be set for a symbol defined in
+ a dynamic library, and def_dynamic may not be set; When the
+ definition in a dynamic lib is overridden by a definition in the
+ executable use of the symbol in the dynamic lib becomes a
+ reference to the executable symbol. */
+ if (newdyn)
+ {
+ if (bfd_is_und_section (sec))
+ {
+ if (bind != STB_WEAK)
+ {
+ h->ref_dynamic_nonweak = 1;
+ hi->ref_dynamic_nonweak = 1;
+ }
+ }
+ else
+ {
+ h->dynamic_def = 1;
+ hi->dynamic_def = 1;
+ }
+ }
+
/* If we just created the symbol, mark it as being an ELF symbol.
Other than that, there is nothing to do--there is no merge issue
with a newly defined symbol--so we just return. */
@@ -1059,11 +1061,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
|| !h->def_regular))
return TRUE;
- /* NEWDYN and OLDDYN indicate whether the new or old symbol,
- respectively, is from a dynamic object. */
-
- newdyn = (abfd->flags & DYNAMIC) != 0;
-
olddyn = FALSE;
if (oldbfd != NULL)
olddyn = (oldbfd->flags & DYNAMIC) != 0;
@@ -1167,16 +1164,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
return FALSE;
}
- /* We need to remember if a symbol has a definition in a dynamic
- object or is weak in all dynamic objects. Internal and hidden
- visibility will make it unavailable to dynamic objects. */
- if (newdyn)
- {
- _bfd_elf_mark_dynamic_def_weak (h, sec, bind);
- if (h != hi)
- _bfd_elf_mark_dynamic_def_weak (hi, sec, bind);
- }
-
/* If the old symbol has non-default visibility, we ignore the new
definition from a dynamic object. */
if (newdyn
@@ -1230,7 +1217,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
h->ref_dynamic = 1;
h->def_dynamic = 0;
- h->dynamic_def = 0;
/* FIXME: Should we check type and size for protected symbol? */
h->size = 0;
h->type = 0;
@@ -1270,7 +1256,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
else
h->ref_dynamic = 1;
h->def_dynamic = 0;
- h->dynamic_def = 0;
/* FIXME: Should we check type and size for protected symbol? */
h->size = 0;
h->type = 0;
@@ -4190,7 +4175,6 @@ error_free_dyn:
}
if (elf_tdata (abfd)->verdef != NULL
- && ! override
&& vernum > 1
&& definition)
h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
@@ -4415,9 +4399,7 @@ error_free_dyn:
else
{
h->def_dynamic = 1;
- h->dynamic_def = 1;
hi->def_dynamic = 1;
- hi->dynamic_def = 1;
}
/* If the indirect symbol has been forced local, don't
@@ -8811,7 +8793,7 @@ elf_link_output_extsym (struct bfd_hash_
&& h->ref_dynamic
&& h->def_regular
&& !h->dynamic_def
- && !h->dynamic_weak
+ && h->ref_dynamic_nonweak
&& !elf_link_check_versioned_symbol (flinfo->info, bed, h))
{
bfd *def_bfd;
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-01-13 12:30 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-01 20:20 PATCH: Fix ELF visibility handling H. J. Lu
2003-04-09 16:22 ` H. J. Lu
2003-04-27 23:08 ` Alan Modra
2003-05-19 22:19 ` Jakub Jelinek
2003-05-20 0:38 ` H. J. Lu
2003-05-20 1:27 ` H. J. Lu
2003-05-20 11:14 ` Alan Modra
2013-01-13 12:30 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).