This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: Symbol visibility revised
On Mon, May 01, 2000 at 09:50:56PM +0200, Martin v. Loewis wrote:
> > Here is the testcase. It failed with your patch.
>
> I can't reproduce the failure:
>
> mira% make
> cc -S -fPIC -O -B./ foo.c
> echo ".hidden bar" >> foo.s
> cc -O -B./ -c foo.s
> cc -shared -o libfoo.so -O -B./ foo.o
> cc -o foo -O -B./ libfoo.so main.c -Wl,-rpath,. -rdynamic
> for f in foo; do echo "Running: $f"; ./$f; \
> if [ $? != 0 ]; then echo Failed; fi; done
> Running: foo
> Hello
>
You are right. Here is the modified patch. We should remove PLT
only for hidden and internal symbols.
H.J.
--- bfd/elflink.c.visi Mon May 1 13:17:51 2000
+++ bfd/elflink.c Mon May 1 13:17:58 2000
@@ -238,8 +238,8 @@ _bfd_elf_link_record_dynamic_symbol (inf
}
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
- break;
-
+ return true;
+
default:
break;
}
--- bfd/elflink.h.visi Mon May 1 13:17:54 2000
+++ bfd/elflink.h Mon May 1 13:36:39 2000
@@ -891,6 +891,7 @@ elf_link_add_object_symbols (abfd, info)
Elf_External_Sym *esym;
Elf_External_Sym *esymend;
struct elf_backend_data *bed;
+ boolean visibility_changed = false;
bed = get_elf_backend_data (abfd);
add_symbol_hook = bed->elf_add_symbol_hook;
@@ -1581,7 +1582,10 @@ elf_link_add_object_symbols (abfd, info)
unsigned char symvis = ELF_ST_VISIBILITY (sym.st_other);
if (symvis && (hvis > symvis || hvis == 0))
- h->other = sym.st_other;
+ {
+ visibility_changed = true;
+ h->other = sym.st_other;
+ }
/* If neither has visibility, use the st_other of the
definition. This is an arbitrary choice, since the
@@ -1852,6 +1856,18 @@ elf_link_add_object_symbols (abfd, info)
goto error_return;
}
}
+ else if (dynsym && h->dynindx != -1 && visibility_changed)
+ /* If the symbol already has a dynamic index, but
+ visibility says it should not be visible, turn it into
+ a local symbol. */
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+ (*bed->elf_backend_hide_symbol) (h);
+ break;
+ }
}
}
@@ -3339,10 +3355,13 @@ elf_fix_symbol_flags (h, eif)
/* If -Bsymbolic was used (which means to bind references to global
symbols to the definition within the shared object), and this
symbol was defined in a regular object, then it actually doesn't
- need a PLT entry. */
+ need a PLT entry. Likewise, if the symbol has internal or
+ hidden visibility, it doesn't need a PLT. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
&& eif->info->shared
- && eif->info->symbolic
+ && (eif->info->symbolic
+ || (ELF_ST_VISIBILITY (h->other)
+ & (STV_INTERNAL | STV_HIDDEN)))
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
{
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;