* elflink.h (NAME(bfd_elf,size_dynamic_sections)): Call

elf_link_assign_sym_version before elf_adjust_dynamic_symbol.
	(elf_fix_symbol_flags): New static function, broken out of
	elf_adjust_dynamic_symbol.
	(elf_adjust_dynamic_symbol): Call elf_fix_symbol_flags.
	(elf_link_assign_sym_version): Likewise.  Permit a symbol to be
	forced local even if NEEDS_PLT is set.  When forcing a symbol to
	be local, clear NEEDS_PLT.
	(elf_link_output_extsym): Remove unused local bed.
This commit is contained in:
Ian Lance Taylor 1997-06-16 18:41:19 +00:00
parent b04d9d8a19
commit c19fbe0f57
2 changed files with 93 additions and 52 deletions

View File

@ -1,3 +1,15 @@
Mon Jun 16 12:31:29 1997 Ian Lance Taylor <ian@cygnus.com>
* elflink.h (NAME(bfd_elf,size_dynamic_sections)): Call
elf_link_assign_sym_version before elf_adjust_dynamic_symbol.
(elf_fix_symbol_flags): New static function, broken out of
elf_adjust_dynamic_symbol.
(elf_adjust_dynamic_symbol): Call elf_fix_symbol_flags.
(elf_link_assign_sym_version): Likewise. Permit a symbol to be
forced local even if NEEDS_PLT is set. When forcing a symbol to
be local, clear NEEDS_PLT.
(elf_link_output_extsym): Remove unused local bed.
Wed Jun 11 22:44:20 1997 Jeffrey A Law (law@cygnus.com)
* elf32-mn10300.c (elf32_mn10300_link_hash_entry): New structure

View File

@ -19,12 +19,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ELF linker code. */
/* This struct is used to pass information to routines called via
elf_link_hash_traverse which must return failure. */
struct elf_info_failed
{
boolean failed;
struct bfd_link_info *info;
};
static boolean elf_link_add_object_symbols
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf_link_add_archive_symbols
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf_export_symbol
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_fix_symbol_flags
PARAMS ((struct elf_link_hash_entry *, struct elf_info_failed *));
static boolean elf_adjust_dynamic_symbol
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_link_find_version_dependencies
@ -36,15 +47,6 @@ static boolean elf_link_assign_sym_version
static boolean elf_link_renumber_dynsyms
PARAMS ((struct elf_link_hash_entry *, PTR));
/* This struct is used to pass information to routines called via
elf_link_hash_traverse which must return failure. */
struct elf_info_failed
{
boolean failed;
struct bfd_link_info *info;
};
/* Given an ELF BFD, add symbols to the global hash table as
appropriate. */
@ -2040,6 +2042,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
bfd *dynobj;
struct elf_backend_data *bed;
bfd_size_type old_dynsymcount;
struct elf_assign_sym_version_info asvinfo;
*sinterpptr = NULL;
@ -2138,6 +2141,20 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
}
}
/* Attach all the symbols to their version information. */
asvinfo.output_bfd = output_bfd;
asvinfo.info = info;
asvinfo.verdefs = verdefs;
asvinfo.export_dynamic = export_dynamic;
asvinfo.removed_dynamic = false;
asvinfo.failed = false;
elf_link_hash_traverse (elf_hash_table (info),
elf_link_assign_sym_version,
(PTR) &asvinfo);
if (asvinfo.failed)
return false;
/* Find all symbols which were defined in a dynamic object and make
the backend pick a reasonable value for them. */
eif.failed = false;
@ -2192,30 +2209,14 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
size_t i;
size_t bucketcount = 0;
Elf_Internal_Sym isym;
struct elf_assign_sym_version_info sinfo;
/* Set up the version definition section. */
s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
BFD_ASSERT (s != NULL);
/* Attach all the symbols to their version information. This
may cause some symbols to be unexported. */
sinfo.output_bfd = output_bfd;
sinfo.info = info;
sinfo.verdefs = verdefs;
sinfo.export_dynamic = export_dynamic;
sinfo.removed_dynamic = false;
sinfo.failed = false;
elf_link_hash_traverse (elf_hash_table (info),
elf_link_assign_sym_version,
(PTR) &sinfo);
if (sinfo.failed)
return false;
/* We may have created additional version definitions if we are
just linking a regular application. */
verdefs = sinfo.verdefs;
verdefs = asvinfo.verdefs;
if (verdefs == NULL)
{
@ -2238,7 +2239,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
Elf_Internal_Verdef def;
Elf_Internal_Verdaux defaux;
if (sinfo.removed_dynamic)
if (asvinfo.removed_dynamic)
{
/* Some dynamic symbols were changed to be local
symbols. In this case, we renumber all of the
@ -2602,23 +2603,17 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
return true;
}
/* Make the backend pick a good value for a dynamic symbol. This is
called via elf_link_hash_traverse, and also calls itself
recursively. */
/* Fix up the flags for a symbol. This handles various cases which
can only be fixed after all the input files are seen. This is
currently called by both adjust_dynamic_symbol and
assign_sym_version, which is unnecessary but perhaps more robust in
the face of future changes. */
static boolean
elf_adjust_dynamic_symbol (h, data)
elf_fix_symbol_flags (h, eif)
struct elf_link_hash_entry *h;
PTR data;
struct elf_info_failed *eif;
{
struct elf_info_failed *eif = (struct elf_info_failed *) data;
bfd *dynobj;
struct elf_backend_data *bed;
/* Ignore indirect symbols. These are added by the versioning code. */
if (h->root.type == bfd_link_hash_indirect)
return true;
/* If this symbol was mentioned in a non-ELF file, try to set
DEF_REGULAR and REF_REGULAR correctly. This is the only way to
permit a non-ELF file to correctly refer to a symbol defined in
@ -2638,8 +2633,9 @@ elf_adjust_dynamic_symbol (h, data)
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
}
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
|| (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
if (h->dynindx == -1
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
|| (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0))
{
if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h))
{
@ -2671,6 +2667,30 @@ elf_adjust_dynamic_symbol (h, data)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
return true;
}
/* Make the backend pick a good value for a dynamic symbol. This is
called via elf_link_hash_traverse, and also calls itself
recursively. */
static boolean
elf_adjust_dynamic_symbol (h, data)
struct elf_link_hash_entry *h;
PTR data;
{
struct elf_info_failed *eif = (struct elf_info_failed *) data;
bfd *dynobj;
struct elf_backend_data *bed;
/* Ignore indirect symbols. These are added by the versioning code. */
if (h->root.type == bfd_link_hash_indirect)
return true;
/* Fix the symbol flags. */
if (! elf_fix_symbol_flags (h, eif))
return false;
/* If this symbol does not require a PLT entry, and it is not
defined by a dynamic object, or is not referenced by a regular
object, ignore it. We do have to handle a weak defined symbol,
@ -2875,8 +2895,19 @@ elf_link_assign_sym_version (h, data)
struct elf_assign_sym_version_info *sinfo =
(struct elf_assign_sym_version_info *) data;
struct bfd_link_info *info = sinfo->info;
struct elf_info_failed eif;
char *p;
/* Fix the symbol flags. */
eif.failed = false;
eif.info = info;
if (! elf_fix_symbol_flags (h, &eif))
{
if (eif.failed)
sinfo->failed = true;
return false;
}
/* We only need version numbers for symbols defined in regular
objects. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
@ -2939,12 +2970,12 @@ elf_link_assign_sym_version (h, data)
{
if (h->dynindx != -1
&& info->shared
&& ! sinfo->export_dynamic
&& (h->elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT) == 0)
&& ! sinfo->export_dynamic)
{
sinfo->removed_dynamic = true;
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~
ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
/* FIXME: The name of the symbol has
already been recorded in the dynamic
@ -3024,7 +3055,7 @@ elf_link_assign_sym_version (h, data)
struct bfd_elf_version_expr *d;
/* See if can find what version this symbol is in. If the
symbol is supposed to eb local, then don't actually register
symbol is supposed to be local, then don't actually register
it. */
deflt = NULL;
for (t = sinfo->verdefs; t != NULL; t = t->next)
@ -3055,12 +3086,11 @@ elf_link_assign_sym_version (h, data)
h->verinfo.vertree = t;
if (h->dynindx != -1
&& info->shared
&& ! sinfo->export_dynamic
&& (h->elf_link_hash_flags
& ELF_LINK_HASH_NEEDS_PLT) == 0)
&& ! sinfo->export_dynamic)
{
sinfo->removed_dynamic = true;
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
/* FIXME: The name of the symbol has already
been recorded in the dynamic string table
@ -3080,11 +3110,11 @@ elf_link_assign_sym_version (h, data)
h->verinfo.vertree = deflt;
if (h->dynindx != -1
&& info->shared
&& ! sinfo->export_dynamic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0)
&& ! sinfo->export_dynamic)
{
sinfo->removed_dynamic = true;
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
/* FIXME: The name of the symbol has already been
recorded in the dynamic string table section. */
@ -4147,7 +4177,6 @@ elf_link_output_extsym (h, data)
if (h->dynindx != -1
&& elf_hash_table (finfo->info)->dynamic_sections_created)
{
struct elf_backend_data *bed;
char *p, *copy;
const char *name;
size_t bucketcount;